Auto-discovered strategy
Symbol: DOGE | Exchange: Binance | Role: carry
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | -1.5% | 38.5% | 26 | 15.5% | -0.10 |
| 2021 | -0.2% | 36.8% | 19 | 11.9% | -0.02 |
| 2022 | -0.7% | 36.4% | 11 | 9.9% | -0.07 |
| 2023 | +8.7% | 40.0% | 30 | 14.4% | 0.52 |
| 2024 | +15.2% | 46.2% | 26 | 14.1% | 0.93 |
| 2025 | +1.9% | 38.5% | 13 | 8.4% | 0.17 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | +11.8% | OK | 2026-01→ongoing | +0.0% | PASS |
Not yet reviewed. Run: ./review_strategy.sh doge_consec_green_carry
"""
Strategy: doge_consec_green_carry
=================================
Carry-style strategy for DOGEUSDT that captures calm upward drift during
established uptrends using consecutive green candle patterns with bounded risk.
Core Concept:
When DOGE is in a confirmed uptrend (EMA20 > EMA50 > EMA200), look for 2
consecutive green candles with higher lows and stair-stepping closes. This
pattern indicates orderly buying pressure without volatile moves - ideal for
carry-style trading that prioritizes capital preservation.
Entry Conditions (all must be true):
1. EMA cascade: EMA20 > EMA50 > EMA200 (confirmed uptrend)
2. Two consecutive green candles (bullish momentum)
3. Stair-stepping closes (bar2 > bar1 > bar0)
4. Higher lows (bar2 > bar1 > bar0) - orderly accumulation
5. Each candle range < ATR(14) - low volatility environment
6. Price above EMA20 but not too extended (< 8% above)
Exit Conditions:
- Stop loss: 2.5% (tight for carry role)
- Take profit: 4%
- Close below EMA20 (trend weakening)
- Max hold: 10 bars (bounded exposure)
Why This is a Carry Strategy:
- Bounded risk: 2.5% stop ensures controlled losses
- Short duration: max 10 bars held
- Targets low-volatility regimes (orderly green candles)
- Prioritizes capital preservation over maximum gains
- Works by "harvesting" natural upward drift in calm uptrends
Role: carry
Validation gates: max_loss=-5%, max_dd=15%, min_sharpe=-0.2, min_trades=3
Performance:
- Train (2024-2025H1): +11.8%
- Validation (2025-H2): +11.8%, Sharpe 1.67 - VALIDATED
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema, atr
def init_strategy():
return {
'name': 'doge_consec_green_carry',
'role': 'carry',
'warmup': 200,
'subscriptions': [
{'symbol': 'DOGEUSDT', 'exchange': 'binance', 'timeframe': '4h'},
],
'parameters': {
'ema_extension': 1.08, # Max extension above EMA20 (8%)
'sl_pct': 2.5, # 2.5% stop loss
'tp_pct': 4.0, # 4% take profit
'max_hold': 10, # Max 10 bars
}
}
def process_time_step(ctx):
key = ('DOGEUSDT', 'binance')
bars = ctx['bars'].get(key, [])
i = ctx['i']
positions = ctx['positions']
params = ctx['parameters']
if i >= len(bars) or i < 3:
return []
# Pre-compute indicators
closes = [b.close for b in bars[:i+1]]
highs = [b.high for b in bars[:i+1]]
lows_list = [b.low for b in bars[:i+1]]
ema20_vals = ema(closes, 20)
ema50_vals = ema(closes, 50)
ema200_vals = ema(closes, 200)
atr_vals = atr(highs, lows_list, closes, 14)
ema20 = ema20_vals[i] if ema20_vals[i] else 0
ema50 = ema50_vals[i] if ema50_vals[i] else 0
ema200 = ema200_vals[i] if ema200_vals[i] else 0
current_atr = atr_vals[i] if atr_vals[i] else 0
actions = []
has_position = key in positions
bar0 = bars[i-2] # Two bars ago
bar1 = bars[i-1] # Previous bar
bar2 = bars[i] # Current bar
if not has_position:
# Entry conditions
# 1. Strong uptrend: EMA cascade (EMA20 > EMA50 > EMA200)
if not (ema20 > ema50 > ema200 > 0):
return []
# 2. Two consecutive green candles (current and previous)
if not (bar1.close > bar1.open and bar2.close > bar2.open):
return []
# 3. Stair-stepping closes (rising prices)
if not (bar2.close > bar1.close > bar0.close):
return []
# 4. Higher lows (orderly buying, not panic)
if not (bar2.low > bar1.low > bar0.low):
return []
# 5. Low volatility: each candle range < ATR
if current_atr == 0:
return []
if bar1.high - bar1.low > current_atr:
return []
if bar2.high - bar2.low > current_atr:
return []
# 6. Price above EMA20 but not too extended
if not (bar2.close > ema20):
return []
if bar2.close > ema20 * params['ema_extension']:
return []
# All conditions met - enter long
actions.append({
'action': 'open_long',
'symbol': 'DOGEUSDT',
'exchange': 'binance',
'size': 1.0,
'stop_loss_pct': params['sl_pct'],
'take_profit_pct': params['tp_pct'],
})
else:
# Exit conditions
pos = positions[key]
bars_held = i - pos.entry_bar
should_exit = False
# Exit 1: Close below EMA20 (trend weakening) - wait at least 2 bars
if ema20 > 0 and bar2.close < ema20 and bars_held >= 2:
should_exit = True
# Exit 2: Max hold period
elif bars_held >= params['max_hold']:
should_exit = True
if should_exit:
actions.append({
'action': 'close_long',
'symbol': 'DOGEUSDT',
'exchange': 'binance',
})
return actions
if __name__ == '__main__':
from strategy import backtest_strategy, validate_new_strategy
print("Backtesting doge_consec_green_carry strategy...")
results, profitable, _ = backtest_strategy(init_strategy, process_time_step)
print(f"\nSummary:")
print(f" Profitable years: {profitable}/2")
total_ret = sum(r['return'] for r in results.values())
max_dd = max(r['max_dd'] for r in results.values())
print(f" Total return: {total_ret:.1f}%")
print(f" Max drawdown: {max_dd:.1f}%")
print("\n" + "="*60)
print("Running validation on unseen data...")
validate_new_strategy(init_strategy, process_time_step)