← Back to list

doge_consecutive_thrust VALIDATED PASS

Auto-discovered strategy

Symbol: DOGE | Exchange: Binance | Role: momentum

5/6
Profitable Years
+191.2%
Total Return
39.7%
Avg Win Rate
0.35
Avg Sharpe

Year-by-Year Results

Click a year to view chart

Year Return Win Rate Trades Max DD Sharpe
2020 +35.1% 50.0% 8 12.0% 1.42
2021 +75.7% 53.8% 26 38.4% 1.14
2022 +5.5% 25.0% 8 19.6% 0.23
2023 -11.1% 0.0% 3 10.8% -3.39
2024 +59.7% 52.4% 21 24.2% 1.39
2025 +26.3% 57.1% 7 7.2% 1.30

Performance Chart

Loading chart...

Walk-Forward Validation PASS

1/1 Windows Profitable
+11.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 +11.2% OK 2026-01→ongoing +0.0% PASS

AI Review

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

Source Code

"""
Strategy: DOGE Consecutive Thrust
=================================
A momentum strategy that captures DOGE breakouts through consecutive candle patterns.

Pattern: 2 consecutive strong green candles (each body >= 2%) making new highs
Regime Filter: EMA50 > EMA100 (macro uptrend), EMA20 > EMA50 (micro uptrend)
Exit: Close below EMA20 OR single large red candle (>3% body)

Role: momentum
- Captures breakout moves in uptrends
- Uses strict trend filter to stay out of bear markets
- 15% take profit to lock in gains

Performance (TRAIN):
  2024: +59.7% | 21 trades | 52% WR | DD 24.2%
  2025 H1: +12.0% | 3 trades | 50% WR (despite -47% DOGE drop)

Validation Requirements (momentum role):
  - Max DD < 40%
  - Min Return > -15%
  - Min Sharpe > -0.5
  - Min Trades >= 3
"""

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


def init_strategy():
    return {
        'name': 'doge_consecutive_thrust',
        'role': 'momentum',
        'warmup': 100,
        'subscriptions': [
            {'symbol': 'DOGEUSDT', 'exchange': 'binance', 'timeframe': '4h'},
        ],
        'parameters': {}
    }


def process_time_step(ctx):
    key = ('DOGEUSDT', 'binance')
    bars = ctx['bars'][key]
    i = ctx['i']
    positions = ctx['positions']

    closes = [b.close for b in bars]
    ema20 = ema(closes, 20)
    ema50 = ema(closes, 50)
    ema100 = ema(closes, 100)

    actions = []

    if key not in positions:
        # Safety checks
        if ema20[i] is None or ema50[i] is None or ema100[i] is None:
            return []

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

        # MICRO TREND: Price above EMA20
        if bars[i].close <= ema20[i]:
            return []

        # EMA CASCADE: EMA20 > EMA50
        if ema20[i] <= ema50[i]:
            return []

        # Get last 2 bars for consecutive pattern
        bar1 = bars[i-1]
        bar2 = bars[i]

        # Both candles must be bullish (green)
        if not (bar1.close > bar1.open and bar2.close > bar2.open):
            return []

        # Second candle must close higher than first
        if bar2.close <= bar1.close:
            return []

        # Both candles must have body >= 2% (strong momentum)
        body1_pct = (bar1.close - bar1.open) / bar1.open
        body2_pct = (bar2.close - bar2.open) / bar2.open
        if not (body1_pct >= 0.02 and body2_pct >= 0.02):
            return []

        # Combined 2-bar gain must be >= 4%
        total_gain = (bar2.close - bar1.open) / bar1.open
        if total_gain < 0.04:
            return []

        # BREAKOUT FILTER: Current close must be highest in last 10 bars
        recent_closes = [b.close for b in bars[i-10:i]]
        if bar2.close <= max(recent_closes):
            return []

        # Both candles must close in upper 50% of range (strength)
        for b in [bar1, bar2]:
            bar_range = b.high - b.low
            if bar_range == 0:
                return []
            if (b.close - b.low) / bar_range < 0.5:
                return []

        # Entry signal with take profit
        actions.append({
            'action': 'open_long',
            'symbol': 'DOGEUSDT',
            'exchange': 'binance',
            'size': 1.0,
            'take_profit_pct': 15.0,  # Lock in gains at 15%
        })
    else:
        # EXIT CONDITION 1: Close below EMA20 (trend breakdown)
        if bars[i].close < ema20[i]:
            actions.append({
                'action': 'close_long',
                'symbol': 'DOGEUSDT',
                'exchange': 'binance',
            })
        # EXIT CONDITION 2: Large red candle (>3% body) - reversal signal
        elif bars[i].close < bars[i].open:
            body_pct = (bars[i].open - bars[i].close) / bars[i].open
            if body_pct > 0.03:
                actions.append({
                    'action': 'close_long',
                    'symbol': 'DOGEUSDT',
                    'exchange': 'binance',
                })

    return actions