Skip to main content

RalliV1 Strategy In-Depth Analysis

Strategy ID: #343 (3rd of strategies #341-350 out of 465 total) Strategy Type: Multi-condition EMA Offset + Elliott Wave Oscillator Trend Following Strategy Timeframe: 5 minutes (5m) + 1 hour (1h)


I. Strategy Overview

RalliV1 is a complex multi-condition trend following strategy that combines EMA offset price entries, Elliott Wave Oscillator (EWO) for trend determination, and multi-layer RSI filtering. With 6 independent buy conditions and 2 sell conditions, along with extensive hyperparameter optimization space, this strategy offers high customizability. The strategy also includes custom stop-loss logic and trade confirmation mechanisms, demonstrating professional strategy design principles.

Core Features

FeatureDescription
Buy Conditions6 independent buy signals, individually optimizable
Sell Conditions2 base sell signals + ROI table + custom stop-loss
Protection MechanismsFixed stop-loss -30% + trailing stop + custom stop-loss function
Timeframe5 minutes (main) + 1 hour (information layer)
Dependenciestalib, qtpylib, technical, freqtrade.persistence
Hyperparameters12 optimizable parameters (7 buy + 2 sell + 3 EWO)

II. Strategy Configuration Analysis

2.1 Basic Risk Parameters

# ROI exit table
minimal_roi = {
"0": 0.04, # Exit at 4% immediately
"40": 0.032, # Exit at 3.2% after 40 minutes
"87": 0.018, # Exit at 1.8% after 87 minutes
"201": 0 # No limit after 201 minutes
}

# Stop-loss setting
stoploss = -0.30 # Fixed stop-loss 30%

Design Philosophy:

  • Staged ROI: Pursue higher profits upon entry (4%), gradually lower expectations over time
  • Wide stop-loss (-30%): Provides ample room for price fluctuation
  • Remove ROI limit after 201 minutes: Let trailing stop dominate exits

2.2 Trailing Stop Configuration

trailing_stop = True
trailing_stop_positive = 0.005 # Activate trailing after 0.5% profit
trailing_stop_positive_offset = 0.03 # Trigger stop when price retraces 3% from high
trailing_only_offset_is_reached = True # Only activate after offset is reached

Trailing Stop Logic:

  • When profit reaches 3%, trailing stop is activated
  • Stop-loss line rises with price increases
  • Retracement of 0.5% triggers stop

2.3 Order Type Configuration

order_time_in_force = {
'buy': 'gtc', # Good Till Cancelled
'sell': 'gtc' # Good Till Cancelled
}

2.4 Sell Signal Configuration

use_sell_signal = True           # Enable sell signals
sell_profit_only = True # Only respond to sell signals when profitable
sell_profit_offset = 0.01 # Only allow sell when profit > 1%
ignore_roi_if_buy_signal = False # ROI takes priority

III. Buy Conditions In Detail

3.1 Hyperparameter System

The strategy includes 12 optimizable parameters:

Parameter TypeParameter NameDefaultOptimization Range
Buy Parametersbase_nb_candles_buy145-80
Buy Parameterslow_offset0.9750.9-0.99
Buy Parameterslow_offset_20.9550.9-0.99
Buy Parametersrsi_buy6030-70
Buy Parametersrsi_buy_24530-70
EWO Parametersewo_high2.3272.0-12.0
EWO Parametersewo_high_2-2.327-6.0-12.0
EWO Parametersewo_low-20.988-20.0--8.0
Sell Parametersbase_nb_candles_sell245-80
Sell Parametershigh_offset0.9910.95-1.1
Sell Parametershigh_offset_20.9970.99-1.5

3.2 Six Buy Conditions In Detail

Condition #1: Downtrend EWO High Value Buy

# Condition 1: MA < EMA100, SMA9 < MA, price below MA * low_offset
(dataframe[f'ma_buy_{base_nb_candles_buy}'] < dataframe['ema_100']) &
(dataframe['sma_9'] < dataframe[f'ma_buy_{base_nb_candles_buy}']) &
(dataframe['rsi_fast'] < 35) &
(dataframe['rsi_fast'] > 4) &
(dataframe['close'] < dataframe[f'ma_buy_{base_nb_candles_buy}'] * low_offset) &
(dataframe['EWO'] > ewo_high) &
(dataframe['rsi'] < rsi_buy_2) &
(dataframe['volume'] > 0) &
(dataframe['close'] < dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset)

Logic Breakdown:

  • Trend determination: MA < EMA100, in downtrend
  • Price position: Close price below 97.5% of MA
  • EWO condition: EWO > 2.327 (positive value, indicates possible trend reversal)
  • RSI filter: RSI < 45, fast RSI between 4-35

Condition #2: Downtrend EWO Negative Value Buy (Enhanced)

# Condition 2: Similar to condition 1, but looser EWO condition, stricter RSI requirement
(dataframe[f'ma_buy_{base_nb_candles_buy}'] < dataframe['ema_100']) &
(dataframe['sma_9'] < dataframe[f'ma_buy_{base_nb_candles_buy}']) &
(dataframe['rsi_fast'] < 35) &
(dataframe['rsi_fast'] > 4) &
(dataframe['close'] < dataframe[f'ma_buy_{base_nb_candles_buy}'] * low_offset_2) &
(dataframe['EWO'] > ewo_high_2) &
(dataframe['rsi'] < rsi_buy_2) &
(dataframe['volume'] > 0) &
(dataframe['close'] < dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset) &
(dataframe['rsi'] < 25) # Additional condition: RSI < 25

Feature: Larger price discount (95.5%), but requires RSI < 25

Condition #3: Downtrend EWO Low Value Buy

# Condition 3: Buy when EWO is negative
(dataframe[f'ma_buy_{base_nb_candles_buy}'] < dataframe['ema_100']) &
(dataframe['sma_9'] < dataframe[f'ma_buy_{base_nb_candles_buy}']) &
(dataframe['rsi_fast'] < 35) &
(dataframe['rsi_fast'] > 4) &
(dataframe['close'] < dataframe[f'ma_buy_{base_nb_candles_buy}'] * low_offset) &
(dataframe['EWO'] < ewo_low) & # EWO < -20.988, deep negative value
(dataframe['volume'] > 0) &
(dataframe['close'] < dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset)

Feature: Enter when EWO is extremely negative, catching oversold bounces

Condition #4: Uptrend EWO High Value Buy

# Condition 4: MA > EMA100, in uptrend
(dataframe[f'ma_buy_{base_nb_candles_buy}'] > dataframe['ema_100']) &
(dataframe['rsi_fast'] < 35) &
(dataframe['rsi_fast'] > 4) &
(dataframe['close'] < dataframe[f'ma_buy_{base_nb_candles_buy}'] * low_offset) &
(dataframe['EWO'] > ewo_high) &
(dataframe['rsi'] < rsi_buy) & # Use rsi_buy (default 60)
(dataframe['volume'] > 0) &
(dataframe['close'] < dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset)

Feature: Finding pullback buying opportunities in uptrend

Condition #5: Uptrend EWO Negative Value Buy (Enhanced)

# Condition 5: Similar to condition 4, but requires RSI < 25
(dataframe[f'ma_buy_{base_nb_candles_buy}'] > dataframe['ema_100']) &
(dataframe['rsi_fast'] < 35) &
(dataframe['rsi_fast'] > 4) &
(dataframe['close'] < dataframe[f'ma_buy_{base_nb_candles_buy}'] * low_offset_2) &
(dataframe['EWO'] > ewo_high_2) &
(dataframe['rsi'] < rsi_buy) &
(dataframe['volume'] > 0) &
(dataframe['close'] < dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset) &
(dataframe['rsi'] < 25)

Condition #6: Uptrend EWO Low Value Buy

# Condition 6: EWO is negative in uptrend
(dataframe[f'ma_buy_{base_nb_candles_buy}'] > dataframe['ema_100']) &
(dataframe['rsi_fast'] < 35) &
(dataframe['rsi_fast'] > 4) &
(dataframe['close'] < dataframe[f'ma_buy_{base_nb_candles_buy}'] * low_offset) &
(dataframe['EWO'] < ewo_low) &
(dataframe['volume'] > 0) &
(dataframe['close'] < dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset)

3.3 Six Buy Conditions Classification

Condition GroupCondition #Core Logic
Downtrend Group#1, #2, #3MA < EMA100, looking for reversal in downtrend
Uptrend Group#4, #5, #6MA > EMA100, looking for pullback in uptrend
EWO High Value Group#1, #4EWO > ewo_high, trend strength confirmation
EWO Negative Value Group#2, #5EWO > ewo_high_2 + RSI < 25, dual confirmation
EWO Low Value Group#3, #6EWO < ewo_low, oversold bounce

IV. Sell Logic In Detail

4.1 Tiered ROI Take-Profit System

The strategy uses a tiered ROI mechanism:

Time (minutes)    ROI Threshold    Description
────────────────────────────────────
0 4% Pursue 4% profit upon entry
40 3.2% Lower expectations after 40 minutes
87 1.8% Further lower after 87 minutes
201 0% Remove ROI limit

Design Philosophy: High confidence upon entry expecting high profits; as time passes, lower expectations and let trailing stop dominate.

4.2 Sell Signals (2 Conditions)

Sell Signal #1: Uptrend Confirmation

(dataframe['hma_50'] > dataframe['ema_100']) &           # HMA50 > EMA100
(dataframe['close'] > dataframe['sma_9']) & # Price > SMA9
(dataframe['close'] > dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset_2) & # Price above sell MA
(dataframe['volume'] > 0) &
(dataframe['rsi_fast'] > dataframe['rsi_slow']) # Fast RSI > Slow RSI

Logic: Sell when price breaks above multiple moving averages and RSI shows upward momentum.

Sell Signal #2: Downtrend Exit

(dataframe['close'] < dataframe['ema_100']) &             # Price < EMA100
(dataframe['close'] > dataframe[f'ma_sell_{base_nb_candles_sell}'] * high_offset) & # Price above sell MA
(dataframe['volume'] > 0) &
(dataframe['rsi_fast'] > dataframe['rsi_slow']) # Fast RSI > Slow RSI

Logic: In downtrend, exit when price rebounds to a certain level.

4.3 Custom Stop-Loss Function

def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
if current_profit < 0.001 and current_time - timedelta(minutes=140) > trade.open_date_utc:
return -0.005 # Set 0.5% stop-loss if holding > 140 minutes with no profit
return 1 # Use default stop-loss otherwise

Logic: If position held for more than 140 minutes (approximately 2.3 hours) with no profit, trigger a tight 0.5% stop-loss.

4.4 Sell Confirmation Function

def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
rate: float, time_in_force: str, sell_reason: str,
current_time: datetime, **kwargs) -> bool:
if sell_reason in ['sell_signal']:
if (last_candle['rsi'] < 45) and (last_candle['hma_50'] > last_candle['ema_100']):
return False # Reject sell
return True

Logic: If RSI < 45 and HMA50 > EMA100 (uptrend), reject sell signal and continue holding.


V. Technical Indicator System

5.1 Core Indicators

Indicator CategorySpecific IndicatorsPurpose
TrendEMA(9, 14, 100)Trend determination and price offset baseline
TrendSMA(9)Short-term trend confirmation
TrendHMA(50, 9)Hull Moving Average, for sell determination
OscillatorRSI(14)Standard RSI
OscillatorRSI_fast(4)Fast RSI, for buy filtering
OscillatorRSI_slow(20)Slow RSI, for sell filtering
SpecialEWO(50, 200)Elliott Wave Oscillator, trend strength determination

5.2 Elliott Wave Oscillator (EWO)

def EWO(dataframe, ema_length=5, ema2_length=35):
ema1 = ta.EMA(df, timeperiod=ema_length)
ema2 = ta.EMA(df, timeperiod=ema2_length)
emadif = (ema1 - ema2) / df['low'] * 100
return emadif

EWO Usage:

  • Positive value (> ewo_high): Trend upward, possible buy
  • Negative value (< ewo_low): Oversold condition, possible bounce
  • Between -20.988 and 2.327: Neutral zone

5.3 Information Timeframe (1h)

The strategy declares 1 hour as information timeframe, but it's not actually used in the code. This may be a reserved extension interface.


VI. Risk Management Features

6.1 Multiple Stop-Loss Mechanisms

Stop-Loss Priority: ROI Take-Profit > Trailing Stop > Custom Stop-Loss > Fixed Stop-Loss

1. ROI Take-Profit: Staged exits, from 4% down to 0%
2. Trailing Stop: Activates at 3% profit, triggers on 0.5% retracement
3. Custom Stop-Loss: Triggers 0.5% stop-loss after 140 minutes without profit
4. Fixed Stop-Loss: Maximum 30% loss

6.2 Sell Signal Filtering

Filter ConditionEffect
sell_profit_only = TrueOnly respond to sell signals when profitable
sell_profit_offset = 0.01Only allow sell when profit > 1%
confirm_trade_exitReject sell when RSI < 45 and in uptrend

6.3 Dynamic MA Offset

The strategy uses dynamically calculated MA values as price offset baselines:

# Price discount when buying
close < ma_buy * low_offset # Discounted buy

# Price premium when selling
close > ma_sell * high_offset # Premium sell

VII. Strategy Advantages and Limitations

✅ Advantages

  1. Multi-dimensional entry: 6 buy conditions covering uptrend and downtrend, increasing signal opportunities
  2. Rich hyperparameters: 12 optimizable parameters for different market adaptation
  3. Smart stop-loss: Custom stop-loss function tightens when position held too long
  4. Sell confirmation mechanism: confirm_trade_exit prevents premature selling in uptrend
  5. EWO innovative application: Uses Elliott Wave Oscillator to determine trend strength

⚠️ Limitations

  1. High complexity: 6 buy conditions + multiple indicators, difficult to understand and optimize
  2. Many hyperparameters: 12 parameters need extensive backtesting to optimize, overfitting risk
  3. High computational load: Requires calculating multiple EMAs and EWO, performance demanding
  4. Overlapping conditions: Some buy conditions overlap, may reduce actual effectiveness
  5. Unused 1-hour timeframe: Declared but not implemented in code

VIII. Applicable Scenarios Recommendations

Market EnvironmentRecommended ConfigurationDescription
Oscillating uptrendDefault configurationFind entry opportunities during pullbacks
Strong trend uptrendAdjust ewo_highRaise high value threshold to reduce signals
Weak trend/sidewaysAdjust stop-lossTighten stop-loss, reduce holding time
High volatility assetsAdjust offset parametersRelax low_offset and high_offset

IX. Applicable Market Environment In Detail

RalliV1 is a multi-condition comprehensive strategy. Based on its code architecture, it is most suitable for oscillating uptrend or trend pullback market environments, while potentially unstable in extreme one-sided markets.

9.1 Core Strategy Logic

  • Multi-dimensional entry: Cover different market states through 6 conditions
  • Trend + reversal combination: Capture both trend continuation and reversal opportunities
  • EWO filtering: Use Elliott Wave Oscillator to determine trend strength

9.2 Performance in Different Markets

Market TypeRatingReason Analysis
📈 Slow bull oscillation⭐⭐⭐⭐⭐Multiple conditions capture pullback opportunities, excellent performance
🔄 Range oscillation⭐⭐⭐⭐☆Many signals, watch for fees
📉 One-sided downtrend⭐⭐☆☆☆May trigger frequent stop-losses
⚡️ Rapid surge⭐⭐⭐☆☆Some conditions may miss entries

9.3 Key Configuration Recommendations

ConfigurationRecommended ValueDescription
stoploss-0.30Default is wide, adjust based on risk tolerance
trailing_stop_positive_offset0.03Activate trailing after 3% profit
sell_profit_offset0.01Only respond to sell when profit > 1%

X. Important Note: The Cost of Complexity

10.1 Learning Curve

RalliV1 is a complex strategy containing:

  • 6 buy conditions
  • 2 sell conditions
  • 12 optimizable parameters
  • Custom stop-loss function
  • Sell confirmation mechanism

Beginners need considerable time to understand each component's function.

10.2 Hardware Requirements

Trading PairsMinimum MemoryRecommended Memory
1-10 pairs2GB4GB
10-30 pairs4GB8GB
30+ pairs8GB16GB

Due to multiple EMA and EWO calculations, a capable VPS is recommended.

10.3 Backtest vs. Live Trading Differences

  • Backtest risk: 12 parameters极易 lead to overfitting
  • Live recommendation: Use Walk-Forward analysis to verify parameter stability
  • Optimization strategy: Optimize parameters in batches, avoid optimizing all at once

10.4 Manual Trader Recommendations

Not recommended for manual traders to directly replicate this strategy because:

  • Too many conditions, difficult to judge manually
  • Need real-time calculation of multiple EMAs and EWO
  • Suggest borrowing EWO indicator concept, simplify conditions

XI. Summary

RalliV1 is a complex yet flexible multi-condition trend following strategy. Its core value lies in:

  1. Multi-dimensional coverage: 6 buy conditions cover different market states, increasing signal opportunities
  2. Tunable parameters: 12 optimizable parameters adapt to different assets and markets
  3. Smart risk control: Custom stop-loss + sell confirmation, multi-layer protection

For quantitative traders, RalliV1 is a good example for learning complex strategy design. It demonstrates how to combine multiple technical indicators into a complete trading system, while also reminding us: complexity is a double-edged sword that needs to be used cautiously.

If using this strategy, it is recommended to:

  • Backtest with default parameters first to understand baseline performance
  • Optimize a small number of parameters at a time to avoid overfitting
  • Use Walk-Forward analysis to verify parameter stability
  • Practice proper money management and diversify risk