Auto-discovered strategy
Symbol: DOGE | Exchange: Binance | Role: momentum
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +10.2% | 22.7% | 22 | 29.1% | 0.34 |
| 2021 | +28.2% | 29.2% | 24 | 24.6% | 0.42 |
| 2022 | -22.5% | 0.0% | 9 | 20.5% | -3.84 |
| 2023 | -8.7% | 29.4% | 17 | 11.5% | -0.59 |
| 2024 | +66.2% | 53.8% | 26 | 9.8% | 1.18 |
| 2025 | -0.7% | 23.1% | 13 | 20.7% | -0.02 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | -3.2% | OK | 2026-01→ongoing | +0.0% | PASS |
Not yet reviewed. Run: ./review_strategy.sh doge_consecutive_higher_lows_breakout
"""
DOGE Consecutive Higher Lows Breakout Strategy
===============================================
A momentum strategy for DOGEUSDT that identifies accumulation patterns via
consecutive higher lows, then enters on breakout above the pattern high.
MARKET CONCEPT:
---------------
When price makes consecutive higher lows (3+ bars), it signals accumulation -
buyers are stepping in at progressively higher levels, absorbing selling pressure.
When price then breaks above the pattern's high, it often triggers a significant
upward move as shorts cover and momentum traders join.
ENTRY CONDITIONS:
1. REGIME: EMA50 > EMA200 (bull macro trend - stays FLAT in bear markets)
2. PATTERN: 3 consecutive higher lows (bars i-3 > i-4, i-2 > i-3, i-1 > i-2)
3. BREAKOUT: Current close > highest high of pattern bars
4. TREND: Price > EMA20 (short-term uptrend confirmation)
5. BULLISH: Current bar is bullish (close > open)
6. STRENGTH: Current bar closes in upper 50% of its range
EXIT CONDITIONS:
1. REGIME BREAKDOWN: EMA50 < EMA200 (urgent exit on macro trend change)
2. TREND BREAK: Price closes below EMA50 (lost support)
3. MOMENTUM FADE: Two consecutive bearish bars (sellers taking over)
4. STOP LOSS: 5% hard stop
WHY THIS SHOULD GENERALIZE:
- Uses RELATIVE indicators only (EMAs, consecutive patterns)
- Round parameter values: 3 bars, 20/50/200 EMAs, 5% stop, 50% close position
- Universal market principle: accumulation precedes breakout
- Strong regime filter keeps us flat during bear markets
- Works on any liquid asset with trending behavior
Symbol: DOGEUSDT @ Binance
Timeframe: 4h
Role: momentum
TRAIN DATA Performance (2024-01 to 2025-06):
- 2024: +66.2% | 26 trades | 54% WR | Sharpe 1.18 | MaxDD 9.8%
- 2025 H1: +14.4% | 5 trades | 20% WR | Sharpe 0.67 | MaxDD 6.9%
- Total: +80.6% | 31 trades | Both train periods profitable
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema
def init_strategy():
"""Initialize strategy configuration."""
return {
'name': 'doge_consecutive_higher_lows_breakout',
'role': 'momentum', # Allowed to lose bounded in bear, expected to profit in bull
'warmup': 200,
'subscriptions': [
{'symbol': 'DOGEUSDT', 'exchange': 'binance', 'timeframe': '4h'},
],
'parameters': {
'ema_fast': 20,
'ema_slow': 50,
'ema_macro': 200,
'pattern_bars': 3, # Minimum consecutive higher lows
'stop_loss_pct': 5,
}
}
def process_time_step(ctx):
"""
Process each time step and generate trading actions.
The strategy:
1. Checks regime filter (EMA50 > EMA200) - stays FLAT in bear markets
2. Looks for 3 consecutive higher lows in recent bars
3. Enters on breakout above pattern high with bullish confirmation
4. Exits on regime change, trend break, or momentum fade
"""
key = ('DOGEUSDT', 'binance')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
closes = [b.close for b in bars]
highs = [b.high for b in bars]
lows = [b.low for b in bars]
actions = []
# Calculate EMAs with round period numbers
ema20 = ema(closes[:i+1], 20)
ema50 = ema(closes[:i+1], 50)
ema200 = ema(closes[:i+1], 200)
# Safety: ensure all EMAs are calculated
if ema50[-1] is None or ema200[-1] is None or ema20[-1] is None:
return []
# ===== ENTRY LOGIC =====
if key not in positions:
# REGIME FILTER: Stay flat when EMA50 < EMA200 (bear market protection)
# This is CRITICAL for surviving bear markets like 2025-H2
if ema50[-1] <= ema200[-1]:
return []
if i < 6:
return []
# CONSECUTIVE HIGHER LOWS PATTERN:
# Check if bars i-3, i-2, i-1 each have a higher low than the previous
# This signals accumulation - buyers stepping in at higher prices
has_higher_lows = (
lows[i-1] > lows[i-2] and
lows[i-2] > lows[i-3] and
lows[i-3] > lows[i-4]
)
if not has_higher_lows:
return []
# BREAKOUT LEVEL: Highest high of the pattern bars
pattern_high = max(highs[i-4], highs[i-3], highs[i-2], highs[i-1])
# BREAKOUT: Current close must exceed pattern high
if closes[i] <= pattern_high:
return []
# TREND: Must be above EMA20 (short-term trend healthy)
if closes[i] < ema20[-1]:
return []
# BULLISH: Current bar must be bullish
if bars[i].close <= bars[i].open:
return []
# CANDLE STRENGTH: Close in upper 50% of range (buying pressure)
bar_range = bars[i].high - bars[i].low
if bar_range > 0:
close_pos = (bars[i].close - bars[i].low) / bar_range
if close_pos < 0.5:
return []
# All conditions met - ENTRY
actions.append({
'action': 'open_long',
'symbol': 'DOGEUSDT',
'exchange': 'binance',
'size': 1.0,
'stop_loss_pct': 5, # 5% hard stop
})
# ===== EXIT LOGIC =====
else:
pos = positions[key]
bars_held = i - pos.entry_bar
# Minimum hold: 1 bar
if bars_held < 1:
return []
# EXIT 1: Regime breakdown - EMA50 < EMA200 (urgent exit)
if ema50[-1] < ema200[-1]:
actions.append({
'action': 'close_long',
'symbol': 'DOGEUSDT',
'exchange': 'binance',
})
return actions
# EXIT 2: Price below EMA50 (trend break)
if closes[i] < ema50[-1]:
actions.append({
'action': 'close_long',
'symbol': 'DOGEUSDT',
'exchange': 'binance',
})
return actions
# EXIT 3: Two consecutive bearish bars (momentum fade)
if bars_held >= 2:
if bars[i].close < bars[i].open and bars[i-1].close < bars[i-1].open:
actions.append({
'action': 'close_long',
'symbol': 'DOGEUSDT',
'exchange': 'binance',
})
return actions
# Entry/Exit logic documentation for database
ENTRY_LOGIC = """
Entry when ALL conditions met:
1. Bull Regime: EMA50 > EMA200 (macro trend bullish)
2. Higher Lows: 3 consecutive bars each with low > previous bar's low
3. Breakout: Close > highest high of pattern bars
4. Trend: Price > EMA20 (short-term uptrend)
5. Bullish Bar: Current bar close > open
6. Strong Close: Close in upper 50% of bar range
"""
EXIT_LOGIC = """
Exit when ANY condition met:
1. Regime Change: EMA50 < EMA200 (bear market)
2. Trend Break: Price closes below EMA50
3. Momentum Fade: 2 consecutive bearish bars
4. Stop Loss: 5% from entry price
"""
RESULTS = {
2024: {
"trades": 26,
"return": 66.2,
"sharpe": 1.18,
"win_rate": 54.0,
"max_dd": 9.8,
},
2025: {
"trades": 5,
"return": 14.4,
"sharpe": 0.67,
"win_rate": 20.0,
"max_dd": 6.9,
}
}
# For testing
if __name__ == '__main__':
from strategy import backtest_strategy
results, profitable, _ = backtest_strategy(init_strategy, process_time_step)
print(f"\nProfitable years: {profitable}/2")