DEV Community

Henry Lin
Henry Lin

Posted on

Lesson 12: Advanced Strategy Analysis

Lesson 12: Advanced Strategy Analysis

⏱ Duration: 2 hours
🎯 Learning Objectives: Deep understanding of strategy logic
📚 Difficulty: ⭐⭐⭐ Strategy Optimization


📖 Course Overview

Through previous learning, you already know how to run and compare strategies. This lesson will take you deep into analyzing the internal logic of strategies, understanding the essential differences between different strategy types, and learning how to optimize entry and exit rules.


12.1 Strategy Type Comparison

Mainstream Strategy Categories

1. Trend Following Strategies

Core Idea: Follow the trend, the trend is your friend.

Representative Strategies:

  • MovingAverageCrossStrategy (Moving Average Crossover)
  • ADXTrendStrategy (ADX Trend Strength)
  • BreakoutTrendStrategy (Breakout Strategy)

Entry Logic:

# Typical trend following entry
dataframe.loc[
    (
        # Short-term MA crosses above long-term MA (Golden Cross)
        qtpylib.crossed_above(dataframe['ema20'], dataframe['ema50']) &
        # Price is above MA (trend confirmation)
        (dataframe['close'] > dataframe['ema20']) &
        # ADX > 25 (sufficient trend strength)
        (dataframe['adx'] > 25) &
        # Volume expansion
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean())
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Can capture major trends
  • ✅ High risk-reward ratio (average profit > average loss)
  • ✅ Simple and clear logic
  • ✅ Suitable for one-sided markets

Disadvantages:

  • ❌ Poor performance in ranging markets
  • ❌ Relatively low win rate (40-60%)
  • ❌ Requires larger stop-loss space
  • ❌ Entry may lag

Suitable Market Conditions:

  • 🟢 Bull Market: ⭐⭐⭐⭐⭐
  • 🔴 Bear Market: ⭐⭐⭐⭐
  • 🟡 Ranging Market: ⭐⭐

Key Parameters:

  • EMA periods (10, 20, 50, 200)
  • ADX threshold (20-30)
  • Stop-loss range (-5% ~ -10%)

2. Mean Reversion Strategies

Core Idea: Prices return to the mean after deviation, buy low, sell high.

Representative Strategies:

  • MeanReversionStrategy (Mean Reversion)
  • RSI Overbought/Oversold Strategy
  • Bollinger Bands Reversal Strategy

Entry Logic:

# Typical mean reversion entry
dataframe.loc[
    (
        # RSI oversold (< 30)
        (dataframe['rsi'] < 30) &
        # Price touches Bollinger Bands lower band
        (dataframe['close'] <= dataframe['bb_lowerband']) &
        # Reversal signal appears (candle body points up)
        (dataframe['close'] > dataframe['open']) &
        # Normal volume
        (dataframe['volume'] > 0)
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Good performance in ranging markets
  • ✅ High win rate (70-85%)
  • ✅ Moderate trading frequency
  • ✅ Small stop-loss space

Disadvantages:

  • ❌ Easily trapped in trending markets
  • ❌ Low risk-reward ratio
  • ❌ Requires precise exit timing
  • ❌ Pressure from consecutive losses

Suitable Market Conditions:

  • 🟢 Bull Market: ⭐⭐
  • 🔴 Bear Market: ⭐⭐
  • 🟡 Ranging Market: ⭐⭐⭐⭐⭐

Key Parameters:

  • RSI thresholds (25-35 oversold, 65-75 overbought)
  • Bollinger Bands period (20) and standard deviation (2)
  • Stop-loss range (-3% ~ -5%)

3. Momentum Strategies

Core Idea: The strong get stronger, chase the rise.

Representative Strategies:

  • MomentumTrendStrategy (Momentum Trend)
  • MACD Fast Strategy

Entry Logic:

# Typical momentum strategy entry
dataframe.loc[
    (
        # RSI enters strong zone (> 60)
        (dataframe['rsi'] > 60) &
        # MACD golden cross
        qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']) &
        # Price makes new high
        (dataframe['close'] > dataframe['close'].rolling(20).max().shift(1)) &
        # Volume explosion
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean() * 1.5)
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Capture fast market movements
  • ✅ High single-trade returns
  • ✅ Suitable for bull markets
  • ✅ Easy to execute psychologically

Disadvantages:

  • ❌ Easily trapped by chasing highs
  • ❌ Low win rate (50-70%)
  • ❌ Drawdowns can be large
  • ❌ Many false breakouts

Suitable Market Conditions:

  • 🟢 Bull Market: ⭐⭐⭐⭐⭐
  • 🔴 Bear Market: ⭐
  • 🟡 Ranging Market: ⭐⭐

Key Parameters:

  • RSI threshold (50-70)
  • Momentum period (10-20)
  • Stop-loss range (-7% ~ -12%)

4. Breakout Strategies

Core Idea: After price breaks key levels, the trend continues.

Representative Strategies:

  • BreakoutTrendStrategy (Breakout Trend)
  • Donchian Channel Breakout

Entry Logic:

# Typical breakout strategy entry
dataframe.loc[
    (
        # Price breaks 20-day high
        (dataframe['close'] > dataframe['high'].rolling(20).max().shift(1)) &
        # Volume confirmation (volume breakout)
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean() * 1.3) &
        # Volatility expansion (ATR increase)
        (dataframe['atr'] > dataframe['atr'].shift(1)) &
        # Not in overbought zone (avoid chasing highs)
        (dataframe['rsi'] < 75)
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Capture trend beginnings
  • ✅ High risk-reward ratio
  • ✅ Clear logic
  • ✅ Suitable for swing trading

Disadvantages:

  • ❌ Frequent false breakouts
  • ❌ Medium win rate (50-65%)
  • ❌ Requires larger stop-loss
  • ❌ Few signals during consolidation

Suitable Market Conditions:

  • 🟢 Bull Market: ⭐⭐⭐⭐
  • 🔴 Bear Market: ⭐⭐⭐
  • 🟡 Ranging Market: ⭐⭐

Key Parameters:

  • Breakout period (10-30 days)
  • Volume confirmation multiplier (1.2-1.5)
  • Stop-loss range (-5% ~ -10%)

Strategy Type Comparison Table

Strategy Type Win Rate Risk-Reward Trading Frequency Max Drawdown Bull Market Bear Market Ranging Market Beginner Friendly
Trend Following 50% 2:1 Low Medium ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐
Mean Reversion 75% 1:1 Medium-High Low ⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
Momentum Strategy 60% 1.5:1 Medium Medium-High ⭐⭐⭐⭐⭐ ⭐⭐ ⚠️
Breakout Strategy 55% 2:1 Low-Medium Medium ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐ ⚠️

12.2 Indicator Combination Analysis

Effective Indicator Combination Principles

Principle 1: Trend + Momentum + Confirmation

Golden Triangle Combination:

# Combination 1: EMA + RSI + Volume
dataframe.loc[
    (
        # Trend confirmation: EMA20 > EMA50
        (dataframe['ema20'] > dataframe['ema50']) &
        # Momentum confirmation: RSI > 50 (bullish strength)
        (dataframe['rsi'] > 50) &
        # Volume confirmation: Volume > average
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean())
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Why is it effective?

  • EMA: Judge overall direction
  • RSI: Judge strength
  • Volume: Judge authenticity

Principle 2: Avoid Redundant Indicators

Redundant Combination (❌ Not Recommended):

# Wrong example: Using EMA5, EMA10, EMA20, EMA50 all together
# These indicators are highly correlated, providing duplicate information

dataframe.loc[
    (
        (dataframe['ema5'] > dataframe['ema10']) &  # Redundant
        (dataframe['ema10'] > dataframe['ema20']) &  # Redundant
        (dataframe['ema20'] > dataframe['ema50'])  # Redundant
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Optimized (✅ Recommended):

# Use only one pair of EMAs
dataframe.loc[
    (
        (dataframe['ema20'] > dataframe['ema50'])  # Trend
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Principle 3: Combine Fast and Slow Indicators

Fast Indicators (sensitive):

  • RSI (14)
  • MACD
  • Stochastic

Slow Indicators (smooth and stable):

  • EMA50, EMA200
  • ADX
  • ATR

Effective Combination:

# Fast indicators (entry timing) + Slow indicators (direction confirmation)
dataframe.loc[
    (
        # Slow indicator: Confirm uptrend
        (dataframe['ema50'] > dataframe['ema200']) &
        # Fast indicator: Find entry point
        qtpylib.crossed_above(dataframe['rsi'], 30)
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Common Indicator Combination Analysis

Combination 1: EMA + RSI (Recommended ⭐⭐⭐⭐⭐)

Suitable for: Trend + Mean Reversion hybrid strategy

# Buy: Uptrend + RSI oversold bounce
(dataframe['ema20'] > dataframe['ema50']) &  # Uptrend
(dataframe['rsi'] > 30) &  # RSI recovers from oversold
(dataframe['rsi'].shift(1) <= 30)
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Simple and effective
  • ✅ Suitable for beginners
  • ✅ Works in all market conditions

Combination 2: MACD + Bollinger Bands (Recommended ⭐⭐⭐⭐)

Suitable for: Breakout + Confirmation strategy

# Buy: MACD golden cross + Price breaks above Bollinger Bands middle band
qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']) &
(dataframe['close'] > dataframe['bb_middleband'])
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Capture trend beginnings
  • ✅ Fewer false signals
  • ✅ Suitable for swing trading

Combination 3: ADX + EMA + RSI (Recommended ⭐⭐⭐⭐⭐)

Suitable for: Complete trend following system

# Buy: Strong trend + MA bullish + RSI not overbought
(dataframe['adx'] > 25) &  # Trend strength
(dataframe['ema20'] > dataframe['ema50']) &  # Trend direction
(dataframe['rsi'] < 70) &  # Avoid chasing highs
(dataframe['rsi'] > 50)  # Bullish strength
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Comprehensive signal confirmation
  • ✅ Filter ranging markets
  • ✅ Balanced win rate and risk-reward ratio

Combination 4: Price + Volume (Recommended ⭐⭐⭐)

Suitable for: Simple and effective breakout strategy

# Buy: Price makes new high + Volume expansion
(dataframe['close'] > dataframe['high'].rolling(20).max().shift(1)) &
(dataframe['volume'] > dataframe['volume'].rolling(20).mean() * 1.5)
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • ✅ Simplest logic
  • ✅ No lag
  • ✅ Suitable for short-term

Indicator Combination Testing Methods

A/B Testing:

# Strategy A: EMA only
freqtrade backtesting -c config.json --strategy StrategyEMAOnly --timerange 20250701-20250930

# Strategy B: EMA + RSI
freqtrade backtesting -c config.json --strategy StrategyEMARSI --timerange 20250701-20250930

# Strategy C: EMA + RSI + Volume
freqtrade backtesting -c config.json --strategy StrategyEMARSIVolume --timerange 20250701-20250930
Enter fullscreen mode Exit fullscreen mode

Compare Results:

Strategy A (EMA):        Return +12%, Trades 80, Win Rate 68%
Strategy B (EMA+RSI):    Return +15%, Trades 52, Win Rate 75% ✅
Strategy C (EMA+RSI+Vol):Return +14%, Trades 48, Win Rate 77%

Conclusion: Strategy B is optimal (adding RSI improves performance, Volume adds no extra value)
Enter fullscreen mode Exit fullscreen mode

12.3 Entry/Exit Logic Optimization

Entry Logic Optimization

Problem 1: Too Frequent Entries

Symptoms:

  • Trade count > 100/month
  • Many small wins and losses
  • Fee ratio > 15%

Optimization Method: Add entry conditions

# Before optimization: Loose conditions
dataframe.loc[
    (
        (dataframe['rsi'] < 40)  # Range too wide
    ),
    'enter_long'] = 1

# After optimization: Strict conditions
dataframe.loc[
    (
        (dataframe['rsi'] < 30) &  # Narrower range
        (dataframe['rsi'].shift(1) < 30) &  # Confirm sustained oversold
        (dataframe['ema20'] > dataframe['ema50']) &  # Add trend confirmation
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean())  # Add volume confirmation
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Effects:

  • Trade count reduced by 50%
  • Win rate increased by 10%
  • Fee ratio reduced

Problem 2: Too Conservative Entries

Symptoms:

  • Trade count < 10/month
  • Missing many opportunities
  • Low capital utilization

Optimization Method: Loosen entry conditions or add trading pairs

# Before optimization: Too strict conditions
dataframe.loc[
    (
        (dataframe['rsi'] < 25) &  # Too strict
        (dataframe['ema5'] > dataframe['ema10']) &
        (dataframe['ema10'] > dataframe['ema20']) &
        (dataframe['ema20'] > dataframe['ema50']) &
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean() * 2)  # Too strict
    ),
    'enter_long'] = 1

# After optimization: Reasonable conditions
dataframe.loc[
    (
        (dataframe['rsi'] < 35) &  # Loosen
        (dataframe['ema20'] > dataframe['ema50']) &  # Simplify
        (dataframe['volume'] > dataframe['volume'].rolling(20).mean())  # Loosen
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Problem 3: Lagging Entry Timing

Symptoms:

  • Often chase highs to buy
  • Immediate pullback after purchase
  • Very low average profit

Optimization Method: Use faster indicators or enter earlier

# Before optimization: Lagging indicators
dataframe.loc[
    (
        qtpylib.crossed_above(dataframe['ema50'], dataframe['ema200'])  # Serious lag
    ),
    'enter_long'] = 1

# After optimization: Use fast indicators
dataframe.loc[
    (
        (dataframe['ema20'] > dataframe['ema50']) &  # Faster
        qtpylib.crossed_above(dataframe['rsi'], 50) &  # Momentum confirmation
        (dataframe['macd'] > 0)  # Trend confirmation
    ),
    'enter_long'] = 1
Enter fullscreen mode Exit fullscreen mode

Exit Logic Optimization

Problem 1: Early Profit Taking

Symptoms:

  • Most trades exit by ROI
  • Average profit < 2%
  • Missing big moves

Optimization Method: Use trailing stop or loosen ROI

# Before optimization: ROI too tight
minimal_roi = {
    "0": 0.03,   # Exit immediately at 3%
    "30": 0.02,
    "60": 0.01
}

# After optimization: Use trailing stop
minimal_roi = {
    "0": 0.10,   # Increase target
    "120": 0.05,
    "240": 0.02
}

trailing_stop = True
trailing_stop_positive = 0.01  # Enable after 1% profit
trailing_stop_positive_offset = 0.03  # Stop loss 3% from price
Enter fullscreen mode Exit fullscreen mode

Problem 2: Stop Loss Too Tight

Symptoms:

  • Stop loss ratio > 30%
  • Many trades stopped out by normal volatility
  • Very low win rate

Optimization Method: Loosen stop loss or use ATR dynamic stop loss

# Before optimization: Fixed stop loss too tight
stoploss = -0.03  # 3%

# After optimization: Adjust based on volatility
stoploss = -0.07  # 7% (low volatility coins)
# or
stoploss = -0.12  # 12% (high volatility coins)
Enter fullscreen mode Exit fullscreen mode

Problem 3: Missing Clear Exit Signals

Symptoms:

  • Most trades wait for ROI or forced exit
  • Serious profit giveback
  • Holding time too long

Optimization Method: Add exit signals

# Before optimization: No exit signals
def populate_exit_trend(self, dataframe, metadata):
    dataframe['exit_long'] = 0  # Never actively exit
    return dataframe

# After optimization: Add clear exit signals
def populate_exit_trend(self, dataframe, metadata):
    dataframe.loc[
        (
            # Death cross
            qtpylib.crossed_below(dataframe['ema20'], dataframe['ema50']) |
            # RSI overbought
            (dataframe['rsi'] > 75) |
            # MACD death cross
            qtpylib.crossed_below(dataframe['macd'], dataframe['macdsignal'])
        ),
        'exit_long'] = 1
    return dataframe
Enter fullscreen mode Exit fullscreen mode

12.4 Risk Management Strategies

Position Management

Fixed Position (Recommended for Beginners)

{
  "stake_amount": 100,  // Fixed 100 USDT per trade
  "max_open_trades": 3   // Maximum 3 simultaneous trades
}
Enter fullscreen mode Exit fullscreen mode

Advantages: Simple, controllable risk
Disadvantages: Not adjusted based on volatility

Percentage Position

{
  "stake_amount": "unlimited",
  "stake_percentage": 20,  // Use 20% of available funds per trade
  "max_open_trades": 3
}
Enter fullscreen mode Exit fullscreen mode

Advantages: Dynamic adjustment, more flexible
Disadvantages: Requires careful calculation

Kelly Formula Position (Advanced)

# Kelly % = (Win Rate × Risk-Reward Ratio - Loss Rate) / Risk-Reward Ratio
# Example: Win rate 60%, risk-reward ratio 2:1
kelly = (0.60 × 2 - 0.40) / 2 = 0.40 = 40%

# Be conservative, use 1/2 Kelly
position_size = 0.40 / 2 = 20%
Enter fullscreen mode Exit fullscreen mode

Protection Mechanisms

Cooldown Period

# Rest after losses to avoid revenge trading
@property
def protections(self):
    return [
        {
            "method": "CooldownPeriod",
            "stop_duration_candles": 5  # Rest 5 candles after stop loss
        }
    ]
Enter fullscreen mode Exit fullscreen mode

Maximum Position Limit

# Maximum 1 position per trading pair
max_entry_position_adjustment = 1
Enter fullscreen mode Exit fullscreen mode

Daily Loss Limit

# Maximum daily loss 5%
@property
def protections(self):
    return [
        {
            "method": "MaxDrawdown",
            "lookback_period_candles": 24,  # 24 hours
            "trade_limit": 10,
            "stop_duration_candles": 24,
            "max_allowed_drawdown": 0.05  # 5%
        }
    ]
Enter fullscreen mode Exit fullscreen mode

💡 Practical Tasks

Task 1: Compare Two Strategy Types

Choose two different strategy types to compare:

# Trend strategy
freqtrade backtesting -c config.json --strategy MovingAverageCrossStrategy --timerange 20250701-20250930

# Mean reversion strategy
freqtrade backtesting -c config.json --strategy MeanReversionStrategy --timerange 20250701-20250930
Enter fullscreen mode Exit fullscreen mode

Record comparison results:

            | Trend Strategy | Mean Reversion |
------------|---------------|----------------|
Trade Count | ____          | ____           |
Win Rate %  | ____%         | ____%          |
Total Return| ____%         | ____%          |
Max Drawdown| ____%         | ____%          |
Avg Holding | ____          | ____           |
Enter fullscreen mode Exit fullscreen mode

Task 2: Test Indicator Combinations

Modify a strategy to test different indicator combinations:

Version A: EMA only
Version B: EMA + RSI
Version C: EMA + RSI + Volume

Compare which version performs best.

Task 3: Optimize Entry Logic

Find a strategy with too high trading frequency, reduce trade count by adding conditions, and observe the impact on win rate and returns.

Task 4: Add Exit Signals

Add clear exit logic to a strategy lacking exit signals, and compare performance before and after addition.


📚 Knowledge Check

Basic Questions

  1. What is the core idea of trend following strategies?
  2. What market conditions are mean reversion strategies suitable for?
  3. Why should we avoid using redundant indicators?

Answers

  1. Follow the trend, trade in the direction of the trend after it forms
  2. Ranging markets, prices oscillate within ranges
  3. Provided information is duplicated, increases complexity but adds no value, easily overfits

Advanced Questions

  1. How to determine if a strategy's entries are too frequent?
  2. When should trailing stop be used?
  3. What are the disadvantages of the Kelly formula?

📌 Key Points Summary

  1. Different strategy types suit different market conditions: Trend strategies for bull markets, mean reversion for ranging markets
  2. Effective indicator combinations: Trend + Momentum + Confirmation
  3. Avoid redundant indicators: More is not better
  4. Entry frequency should be moderate: Don't overtrade
  5. Exit is equally important: Strategies without exit signals are incomplete
  6. Risk management is fundamental: Position control and protection mechanisms

➡️ Next Lesson Preview

Lesson 13: Strategy Scoring System

In the next lesson, we will:

  • Establish scientific strategy evaluation criteria
  • Learn multi-dimensional scoring methods
  • Create strategy scorecards
  • Select the most suitable strategies for you

🎯 Learning Assessment Criteria:

  • ✅ Understand differences between strategy types
  • ✅ Can analyze effectiveness of indicator combinations
  • ✅ Can optimize entry and exit logic
  • ✅ Master basic risk management methods

After completing these tasks, you have acquired advanced strategy analysis capabilities! 🚀

Top comments (0)