Seb Strategy Analysis
Strategy ID: #382 (382nd of 465 strategies) Strategy Type: EMA Trend Following + Heikin Ashi Candle Confirmation Timeframe: 5 minutes (5m)
I. Strategy Overview
Seb is a classic EMA crossover trend following strategy, combined with Heikin Ashi candle confirmation for trend direction. Developed by Gerald Lonlas, it is one of the standard example strategies in the freqtrade-strategies project, with clean and clear code suitable as a learning template and foundation for live optimization.
Core Characteristics
| Feature | Description |
|---|---|
| Buy Conditions | 1: EMA20 crosses above EMA50 + HA candle confirmation |
| Sell Conditions | 1: EMA50 crosses above EMA100 + HA candle confirmation |
| Protection Mechanisms | Trailing stop (1% positive offset 2%) |
| Timeframe | 5m |
| Dependencies | freqtrade.strategy, pandas, numpy, talib, qtpylib |
II. Strategy Configuration Analysis
2.1 Basic Risk Parameters
# ROI exit table
minimal_roi = {
"0": 0.05, # 5% profit immediately
"20": 0.04, # Drop to 4% after 20 minutes
"30": 0.03, # Drop to 3% after 30 minutes
"60": 0.01 # Drop to 1% after 60 minutes
}
# Stop-loss setting
stoploss = -0.10 # 10% hard stop-loss
# Trailing stop
trailing_stop = True
trailing_stop_positive = 0.01 # Activate after 1% profit
trailing_stop_positive_offset = 0.02 # Start trailing from 2% peak
Design Philosophy:
- Uses declining ROI to encourage short-term profits
- Trailing stop mechanism locks in profits, avoiding excessive drawdowns
- 10% hard stop-loss as final defense
2.2 Order Type Configuration
order_types = {
'buy': 'limit',
'sell': 'limit',
'stoploss': 'market',
'stoploss_on_exchange': False
}
Note: Buy and sell use limit orders, stop-loss uses market orders.
2.3 Buy Parameters
buy_params = {
"buy_fastd": 1,
"buy_fishRsiNorma": 5,
"buy_rsi": 26,
"buy_volumeAVG": 150,
}
Note: These parameters are defined but not used in entry logic, reserved for Hyperopt optimization.
2.4 Sell Parameters
sell_params = {
"sell_fishRsiNorma": 30,
"sell_minusDI": 4,
"sell_rsi": 74,
"sell_trigger": "rsi-macd-minusdi",
}
Note: Also not used in exit logic, reserved for future expansion.
III. Buy Conditions Explained
3.1 Single Buy Signal
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
qtpylib.crossed_above(dataframe['ema20'], dataframe['ema50']) &
(dataframe['ha_close'] > dataframe['ema20']) &
(dataframe['ha_open'] < dataframe['ha_close']) # Green candle
),
'buy'] = 1
return dataframe
Condition Breakdown:
| Condition | Meaning | Purpose |
|---|---|---|
| EMA20 crosses above EMA50 | Short-term MA crosses above medium-term MA | Trend initiation signal |
| HA close > EMA20 | Heikin Ashi close above MA | Trend confirmation |
| HA open < HA close | Green candle | Bullish confirmation |
Design Philosophy:
- Use EMA crossover to identify trend transitions
- Heikin Ashi candles filter false signals
- Triple confirmation improves win rate
3.2 Heikin Ashi Candles
Heikin Ashi is a candle calculation method that smooths price fluctuations:
heikinashi = qtpylib.heikinashi(dataframe)
dataframe['ha_open'] = heikinashi['open']
dataframe['ha_close'] = heikinashi['close']
Advantages:
- Filters noise, clearer trends
- Green candles indicate bullish, red candles indicate bearish
- Consecutive same-color candles confirm trend
IV. Sell Logic Explained
4.1 Single Sell Signal
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
qtpylib.crossed_above(dataframe['ema50'], dataframe['ema100']) &
(dataframe['ha_close'] < dataframe['ema20']) &
(dataframe['ha_open'] > dataframe['ha_close']) # Red candle
),
'sell'] = 1
return dataframe
Condition Breakdown:
| Condition | Meaning | Purpose |
|---|---|---|
| EMA50 crosses above EMA100 | Medium-term MA crosses above long-term MA | Trend reversal signal |
| HA close < EMA20 | Heikin Ashi close below MA | Trend confirmation |
| HA open > HA close | Red candle | Bearish confirmation |
Design Philosophy:
- Use longer-term MA crossover to confirm trend reversal
- Symmetrical with buy logic, forming complete trading cycle
4.2 Trailing Stop Mechanism
trailing_stop = True
trailing_stop_positive = 0.01 # Activate after 1% profit
trailing_stop_positive_offset = 0.02 # Start trailing from 2% peak
Working Mechanism:
- When profit reaches 2%, trailing stop activates
- Stop level trails 1% below peak
- As price continues up, stop level follows
- When price retraces and hits stop, locks in profit
Example:
- Entry at 100, price rises to 102 (2% profit)
- Stop set at 101 (102 × 0.99 = 101.0)
- Price continues to 105, stop rises to 103.95
- Price retraces to 103.95, stop triggers
4.3 Tiered ROI Exit
| Holding Time | Target Profit | Cumulative Return |
|---|---|---|
| 0 minutes | 5% | High target |
| 20 minutes | 4% | Gradually decreasing |
| 30 minutes | 3% | Continuing decrease |
| 60 minutes | 1% | Break-even micro-profit |
V. Technical Indicator System
5.1 Core Indicators
Although strategy entry/exit logic is simple, populate_indicators calculates extensive indicators:
| Indicator Category | Specific Indicators | Purpose |
|---|---|---|
| Trend | EMA (20, 50, 100) | Entry/exit signals |
| Candle | Heikin Ashi | Trend confirmation |
| Momentum | RSI (14) | Overbought/oversold |
| Trend | ADX | Trend strength |
| Oscillator | MACD | Momentum direction |
| Volatility | Bollinger Bands (20, 2) | Volatility range |
| Oscillator | Stochastic (fast/slow) | Overbought/oversold |
| Trend | SAR Parabolic | Trend reversal |
| Special | Fisher RSI | RSI variant |
| Candle | Hammer | Reversal pattern |
5.2 Indicator Calculation Code
# EMA series
dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20)
dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
# Heikin Ashi
heikinashi = qtpylib.heikinashi(dataframe)
dataframe['ha_open'] = heikinashi['open']
dataframe['ha_close'] = heikinashi['close']
# MACD
macd = ta.MACD(dataframe)
dataframe['macd'] = macd['macd']
dataframe['macdsignal'] = macd['macdsignal']
dataframe['macdhist'] = macd['macdhist']
# Fisher RSI
rsi = 0.1 * (dataframe['rsi'] - 50)
dataframe['fisher_rsi'] = (numpy.exp(2 * rsi) - 1) / (numpy.exp(2 * rsi) + 1)
# Stochastic
stoch = ta.STOCHF(dataframe, 5)
dataframe['fastd'] = stoch['fastd']
dataframe['fastk'] = stoch['fastk']
# Bollinger Bands
bollinger = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.0, nbdevdn=2.0)
dataframe['bb_lowerband'] = bollinger['lowerband']
dataframe['bb_middleband'] = bollinger['middleband']
dataframe['bb_upperband'] = bollinger['upperband']
Note: Most of these indicators are not used in current entry/exit logic, reserved for future optimization.
VI. Risk Management Features
6.1 Trailing Stop Configuration
| Parameter | Value | Description |
|---|---|---|
| trailing_stop | True | Enable trailing stop |
| trailing_stop_positive | 0.01 | Trail distance 1% |
| trailing_stop_positive_offset | 0.02 | Activation threshold 2% |
6.2 Sell Priority
use_sell_signal = True # Enable sell signals
sell_profit_only = True # Only use sell signals when profitable
ignore_roi_if_buy_signal = False # Don't ignore ROI
Mechanism:
- Check trailing stop first
- Then check sell signal (only when profitable)
- Finally check ROI table
6.3 Order Execution Protection
- Buy uses limit orders to control cost
- Sell uses limit orders to ensure execution price
- Stop-loss uses market orders to ensure execution
VII. Strategy Advantages and Limitations
Advantages
- Simple Logic: Single entry/exit signals, easy to understand and debug
- Trend Confirmation: EMA crossover + HA candle dual confirmation
- Trailing Stop: Locks in profits, avoids large drawdowns
- Rich Indicators: Reserved many indicators for Hyperopt optimization
- Standard Code: Official example strategy, clear structure
Limitations
- Few Signals: Single entry signal, low trading frequency
- Trend Dependent: May frequently stop out in oscillating markets
- Unused Indicators: Many indicators calculated but not used
- Fixed Parameters: Buy parameters not optimized, may need adjustment
VIII. Applicable Scenario Recommendations
| Market Environment | Recommended Configuration | Description |
|---|---|---|
| Trending Market | Default parameters | EMA crossover strategy's home ground |
| Oscillating Market | Widen trailing stop | Reduce stop-out frequency |
| Fast Volatility | Shorten timeframe | Can try 1m or 3m |
| Low Volatility | Extend timeframe | Can try 15m or 1h |
IX. Applicable Market Environment Details
Seb is a classic trend following strategy. Based on its code architecture, it performs best in markets with clear trends, and performs poorly in sideways oscillations.
9.1 Core Strategy Logic
- Trend Identification: EMA20 crossing above EMA50 identifies uptrend initiation
- Trend Confirmation: Heikin Ashi green candle confirms bullish strength
- Trend Exit: EMA50 crossing above EMA100 identifies trend reversal
9.2 Performance in Different Market Environments
| Market Type | Rating | Analysis |
|---|---|---|
| Uptrend | Excellent | EMA crossover perfectly captures trend |
| Oscillating Market | Poor | Frequent false crossovers, accumulated stop-losses |
| Downtrend | Very Poor | Very few buy signals, no short protection |
| Fast Volatility | Average | Trailing stop can protect some profits |
9.3 Key Configuration Recommendations
| Configuration | Recommended Value | Description |
|---|---|---|
| timeframe | 5m | Default, can try 3m or 15m |
| trailing_stop_positive | 0.01-0.02 | Adjust based on volatility |
| minimal_roi | Default | Can adjust based on market |
X. Important Note: Indicator Redundancy
10.1 Calculated But Not Used
populate_indicators calculates many indicators:
Used: EMA20, EMA50, EMA100, Heikin Ashi
Unused: RSI, MACD, Bollinger, Stochastic, ADX, CCI, SAR, Fisher RSI, Hammer
Impact:
- Wasted computational resources
- May affect backtesting speed
- Reserved space for optimization
10.2 Optimization Suggestions
Can use unused indicators through Hyperopt:
# Example: Add RSI filter
dataframe.loc[
(
qtpylib.crossed_above(dataframe['ema20'], dataframe['ema50']) &
(dataframe['ha_close'] > dataframe['ema20']) &
(dataframe['ha_open'] < dataframe['ha_close']) &
(dataframe['rsi'] < 70) # Add RSI filter
),
'buy'] = 1
10.3 Learning Value
Seb as a freqtrade official example strategy:
- Standard code structure
- Complete indicator calculations
- Clear entry/exit logic
- Suitable as learning template
XI. Summary
Seb is a clean and elegant trend following strategy. Its core value lies in:
- Clear Logic: Single entry/exit signals, easy to understand
- Trend Confirmation: EMA crossover + Heikin Ashi dual verification
- Risk Control: Trailing stop locks in profits
- High Extensibility: Reserved many indicators for optimization
For quantitative traders, Seb is an excellent starting strategy, suitable as a learning template and optimization foundation.