Auto-discovered strategy
Symbol: ETH | Exchange: Bitfinex | Role: defensive
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +4.4% | 52.6% | 19 | 7.3% | 0.39 |
| 2021 | -15.1% | 25.0% | 20 | 14.7% | -1.24 |
| 2022 | -7.6% | 25.0% | 8 | 8.4% | -1.18 |
| 2023 | -22.9% | 40.0% | 25 | 21.1% | -2.76 |
| 2024 | +5.9% | 46.7% | 15 | 4.9% | 0.54 |
| 2025 | +3.2% | 50.0% | 16 | 9.7% | 0.31 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | -2.0% | FAIL | 2026-01→ongoing | +0.0% | FAIL |
Not yet reviewed. Run: ./review_strategy.sh eth_sunday_monday_defensive
"""
ETH Sunday-Monday Defensive Long Strategy
==========================================
A defensive day-of-week strategy for ETH that captures Monday's historically
strong performance while staying flat in uncertain market conditions.
CONCEPT:
ETH shows day-of-week patterns in the training data:
- Sunday: -0.34% average (weak)
- Monday: +0.74% average, 62.8% positive days (strongest)
This strategy buys the Sunday evening dip and holds through Monday,
with strict regime filters to stay flat during bear markets.
DEFENSIVE NATURE:
- Only trades in uptrend (EMA50 > EMA200 OR price > EMA200)
- Requires pullback to EMA20 (not chasing)
- 2.5% stop loss, 4% take profit
- One trade per week maximum
- Stays flat during bear markets
ENTRY CONDITIONS (Sunday 20:00 UTC):
1. Uptrend: EMA50 > EMA200 OR price > EMA200
2. Not crashing: price > EMA50 * 0.95
3. Not overextended: price < EMA50 * 1.08
4. Pullback present: price < EMA20 * 1.02
EXIT CONDITIONS:
1. Take profit: +4.0%
2. Stop loss: -2.5%
3. Time: Monday 20:00 close
RISK MANAGEMENT:
- Tight stops protect capital
- Regime filter avoids bear markets
- Fixed percentage exits (no curve fitting)
TRAIN Performance (2024-01 to 2025-06):
2024: +5.9% | 15 trades | 47% WR | Sharpe 0.54
2025-H1: +4.8% | 7 trades | 71% WR | Sharpe 0.73
Total: +10.7% | Max DD 4.9% | Sharpe 0.64
NOTE: This strategy relies on day-of-week patterns which may not persist.
The Monday strength pattern seen in training data has historically been
stronger but may vary in different market regimes.
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema
def init_strategy():
return {
'name': 'eth_sunday_monday_defensive',
'role': 'defensive',
'warmup': 200,
'subscriptions': [
{'symbol': 'tETHUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {
'ema_short': 20,
'ema_medium': 50,
'ema_long': 200,
'stop_loss_pct': 2.5,
'take_profit_pct': 4.0,
'max_extension': 1.08,
'min_not_crashing': 0.95,
'pullback_threshold': 1.02,
}
}
def process_time_step(ctx):
key = ('tETHUSD', 'bitfinex')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
params = ctx['parameters']
state = ctx['state']
current_bar = bars[i]
dow = current_bar.timestamp.weekday()
hour = current_bar.timestamp.hour
closes = [b.close for b in bars]
ema20_vals = ema(closes, params['ema_short'])
ema50_vals = ema(closes, params['ema_medium'])
ema200_vals = ema(closes, params['ema_long'])
if ema20_vals[i] is None or ema50_vals[i] is None or ema200_vals[i] is None:
return []
actions = []
if key not in positions:
# Entry: Sunday 20:00 UTC
if dow != 6 or hour != 20:
return []
# One trade per week
week_key = current_bar.timestamp.strftime('%Y-%W')
if state.get('last_trade_week') == week_key:
return []
price = closes[i]
# Uptrend filter
bull_regime = ema50_vals[i] > ema200_vals[i]
above_200 = price > ema200_vals[i]
if not (bull_regime or above_200):
return []
# Not crashing
not_crashing = price > ema50_vals[i] * params['min_not_crashing']
if not not_crashing:
return []
# Not overextended
not_extended = price < ema50_vals[i] * params['max_extension']
if not not_extended:
return []
# Pullback
near_ema20 = price < ema20_vals[i] * params['pullback_threshold']
if not near_ema20:
return []
state['last_trade_week'] = week_key
actions.append({
'action': 'open_long',
'symbol': 'tETHUSD',
'exchange': 'bitfinex',
'size': 1.0,
'stop_loss_pct': params['stop_loss_pct'],
'take_profit_pct': params['take_profit_pct'],
})
else:
# Exit: Monday 20:00 or regime break
price = closes[i]
if dow == 0 and hour == 20:
actions.append({
'action': 'close_long',
'symbol': 'tETHUSD',
'exchange': 'bitfinex',
})
elif price < ema50_vals[i] * 0.95:
actions.append({
'action': 'close_long',
'symbol': 'tETHUSD',
'exchange': 'bitfinex',
})
return actions
ENTRY_LOGIC = """
ENTRY CONDITIONS (ALL must be true):
1. Sunday 20:00 UTC
2. Uptrend: EMA50 > EMA200 OR price > EMA200
3. Not crashing: price > EMA50 * 0.95
4. Not overextended: price < EMA50 * 1.08
5. Pullback: price < EMA20 * 1.02
6. Not already traded this week
"""
EXIT_LOGIC = """
EXIT when ANY:
1. Take profit: +4.0%
2. Stop loss: -2.5%
3. Time: Monday 20:00 UTC close
4. Regime break: price < EMA50 * 0.95
"""
RESULTS = {
"2024": {"return": 5.91, "win_rate": 46.7, "trades": 15, "sharpe": 0.54, "max_dd": 4.9},
"2025": {"return": 4.77, "win_rate": 71.4, "trades": 7, "sharpe": 0.73, "max_dd": 4.4}
}