← Back to list

doge_ema50_support_bounce VALIDATED FAIL

Auto-discovered strategy

Symbol: DOGE | Exchange: Binance | Role: momentum

5/6
Profitable Years
+114.1%
Total Return
33.7%
Avg Win Rate
0.54
Avg Sharpe

Year-by-Year Results

Click a year to view chart

Year Return Win Rate Trades Max DD Sharpe
2020 -25.9% 16.7% 24 31.5% -1.02
2021 +14.9% 42.9% 14 25.1% 0.59
2022 +6.6% 33.3% 12 25.2% 0.28
2023 +46.4% 36.4% 33 17.9% 1.31
2024 +71.3% 46.2% 26 17.9% 2.05
2025 +0.7% 26.7% 15 15.0% 0.03

Performance Chart

Loading chart...

Walk-Forward Validation FAIL

0/1 Windows Profitable
-15.2% OOS Return
0.00 Median Sharpe
0.000 Score
Window Train Period Val Period Val Return Val Test Period Test Return Status
WF-1 2024-01→2025-06 2025-07→2025-12 -15.2% FAIL 2026-01→ongoing +0.0% FAIL

AI Review

Not yet reviewed. Run: ./review_strategy.sh doge_ema50_support_bounce

Source Code

"""
EMA50 Support Zone Bounce Strategy for DOGEUSDT
=================================================

A support/resistance bounce strategy that uses the EMA50 as dynamic support.

Strategy Logic:
1. REGIME FILTER: Only trade in bull markets (EMA50 > EMA100)
2. TREND FILTER: Only trade in uptrends (EMA20 > EMA50)
3. SUPPORT ZONE: Enter when price touches EMA50 zone (within 3%)
4. BOUNCE CONFIRM: Bullish candle closing above EMA50 with volume
5. EXIT: Close below EMA50 (trend break)

Key Principles (Avoiding Overfitting):
- Uses RELATIVE indicators only (EMAs, % distance)
- Round parameter values (20, 50, 100 for EMAs)
- Simple logic with few conditions
- Regime-aware: stays flat when EMA50 < EMA100

Train Performance (2024-01-01 to 2025-06-30):
  2024: +71.3% | 26 trades | 46% WR
  2025H1: +5.9% | 6 trades | 33% WR
  Total: +77.2% | 2/2 years profitable
"""

import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema


def init_strategy():
    """Initialize the EMA50 support bounce strategy."""
    return {
        'name': 'doge_ema50_support_bounce',
        'role': 'momentum',  # Trend-following with support bounces
        'warmup': 100,       # EMA100 needs 100 bars
        'subscriptions': [
            {'symbol': 'DOGEUSDT', 'exchange': 'binance', 'timeframe': '4h'},
        ],
        'parameters': {}
    }


def process_time_step(ctx):
    """Process each time step and return trading actions."""
    key = ('DOGEUSDT', 'binance')
    bars = ctx['bars'][key]
    i = ctx['i']
    positions = ctx['positions']

    # Extract price data
    closes = [b.close for b in bars]
    highs = [b.high for b in bars]
    lows = [b.low for b in bars]
    volumes = [b.volume for b in bars]
    opens = [b.open for b in bars]

    # Calculate EMAs
    ema20 = ema(closes, 20)
    ema50 = ema(closes, 50)
    ema100 = ema(closes, 100)

    # Skip if indicators not ready
    if ema20[i] is None or ema50[i] is None or ema100[i] is None:
        return []

    actions = []

    if key not in positions:
        # ==================
        # ENTRY LOGIC
        # ==================

        # REGIME FILTER: Macro uptrend (EMA50 > EMA100)
        if ema50[i] <= ema100[i]:
            return []

        # TREND FILTER: Short-term uptrend (EMA20 > EMA50)
        if ema20[i] <= ema50[i]:
            return []

        # SUPPORT ZONE CHECK
        # Price touched within 3% of EMA50 in last 2 bars
        touched_zone = False
        for k in range(max(0, i-2), i+1):
            distance = abs(lows[k] - ema50[k]) / ema50[k]
            if distance <= 0.03:
                touched_zone = True
                break

        if not touched_zone:
            return []

        # BOUNCE CONFIRMATION
        # 1. Close above EMA50
        above_ema50 = closes[i] > ema50[i]

        # 2. Bullish candle
        bullish = closes[i] > opens[i]

        # 3. Not overextended (within 5% of EMA50)
        not_extended = closes[i] < ema50[i] * 1.05

        # 4. Volume confirmation (>= 80% of 20-bar average)
        avg_vol = sum(volumes[max(0, i-20):i]) / min(20, i) if i > 0 else 1
        vol_ok = volumes[i] >= avg_vol * 0.8

        if above_ema50 and bullish and not_extended and vol_ok:
            actions.append({
                'action': 'open_long',
                'symbol': 'DOGEUSDT',
                'exchange': 'binance',
                'size': 1.0,
                'stop_loss_pct': 5.0,   # 5% stop loss
                'take_profit_pct': 10.0,  # 10% take profit (2:1 R:R)
            })

    else:
        # ==================
        # EXIT LOGIC
        # ==================

        # Trend break: close below EMA50 (with 1% buffer for noise)
        if closes[i] < ema50[i] * 0.99:
            actions.append({
                'action': 'close_long',
                'symbol': 'DOGEUSDT',
                'exchange': 'binance',
            })

    return actions


# For testing/validation
if __name__ == '__main__':
    from strategy import backtest_strategy
    results, profitable, _ = backtest_strategy(init_strategy, process_time_step)