Auto-discovered strategy
Symbol: ETH | Exchange: Binance | Role: defensive
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | -14.3% | 27.3% | 11 | 15.1% | -1.04 |
| 2021 | +13.3% | 46.7% | 15 | 11.5% | 0.64 |
| 2022 | -8.2% | 44.1% | 34 | 21.9% | -0.33 |
| 2023 | -0.9% | 66.7% | 15 | 5.9% | -0.10 |
| 2024 | +2.1% | 52.6% | 19 | 7.2% | 0.14 |
| 2025 | +27.4% | 55.6% | 27 | 8.9% | 1.19 |
| 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 |
"""
ETH Bear Rally Fade Strategy
============================
A trend exhaustion strategy for ETHUSDT that fades rallies in bear markets.
CONCEPT:
- In bear markets (EMA50 < EMA200), counter-trend rallies eventually exhaust
- We detect exhausted rallies by looking for:
1. Bear regime (EMA50 < EMA200)
2. 3+ consecutive higher closes (rally into resistance)
3. Reversal bar (current red candle after previous green)
4. RSI above 50 and declining (momentum fading)
5. Price still below EMA200 (major resistance)
WHY IT WORKS:
- Bear market rallies are often "dead cat bounces" - temporary relief
- After 3+ consecutive up bars, late buyers are exhausted
- The first red candle signals early sellers stepping in
- RSI declining from elevated levels confirms momentum loss
- EMA200 acts as psychological resistance
PARAMETERS (all round numbers for robustness):
- Entry: 3+ consecutive higher closes + reversal bar
- RSI threshold: 50 (elevated in context of bear market)
- Stop loss: 4% (tight risk management)
- Take profit: 8% (2:1 reward-to-risk)
- Exit: RSI < 35 or 12 bars max hold
TRAIN PERFORMANCE (2024-01 to 2025-06):
- 2024: +2.1%, 19 trades, 53% WR, MaxDD=7.2%
- 2025H1: +16.2%, 14 trades, 57% WR, MaxDD=8.7%
- Total: +18.3%, Sharpe=0.79, MaxDD=12.0%
REGIME FILTER:
- SHORT ONLY in bear markets (EMA50 < EMA200)
- No longs - avoids choppy bull market conditions that hurt reversal strategies
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema, rsi
def init_strategy():
return {
'name': 'eth_bear_rally_fade',
'role': 'defensive',
'warmup': 200,
'subscriptions': [
{'symbol': 'ETHUSDT', 'exchange': 'binance', 'timeframe': '4h'},
],
'parameters': {
'ema_fast': 50,
'ema_slow': 200,
'rsi_period': 10,
'consecutive_bars': 3,
'rsi_threshold': 50,
'stop_loss_pct': 4.0,
'take_profit_pct': 8.0,
'max_hold_bars': 12,
'rsi_exit': 35,
}
}
def process_time_step(ctx):
key = ('ETHUSDT', 'binance')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
# Warmup period for EMA200 - now handled by framework via 'warmup' field
# if i < 200:
# return []
# Extract price data
closes = [b.close for b in bars]
price = closes[i]
bar = bars[i]
prev_bar = bars[i-1]
# Calculate EMAs for regime detection
ema50_vals = ema(closes[:i+1], 50)
ema200_vals = ema(closes[:i+1], 200)
e50 = ema50_vals[-1]
e200 = ema200_vals[-1]
if not all([e50, e200]):
return []
# REGIME FILTER: Only trade in bear market
# Bear = EMA50 below EMA200
bear_regime = e50 < e200
if not bear_regime:
# Exit any positions if regime changes
if key in positions and positions[key].side == 'short':
return [{
'action': 'close_short',
'symbol': 'ETHUSDT',
'exchange': 'binance',
}]
return []
# Count consecutive higher closes (rally detection)
# Look at bars BEFORE current bar to detect completed rally
consecutive_higher = 0
for j in range(i-1, max(0, i-12), -1):
if closes[j] > closes[j-1]:
consecutive_higher += 1
else:
break
# RSI for momentum analysis
rsi_vals = rsi(closes[:i+1], 10)
curr_rsi = rsi_vals[-1]
prev_rsi = rsi_vals[-2] if len(rsi_vals) > 1 else curr_rsi
if not curr_rsi:
return []
# Reversal bar detection
# Current bar is red (bearish), previous was green (bullish)
curr_red = bar.close < bar.open
prev_green = prev_bar.close > prev_bar.open
actions = []
if key not in positions:
# ENTRY: Short rallies in bear markets
# Conditions:
# 1. In bear regime (EMA50 < EMA200)
# 2. 3+ consecutive higher closes (rally)
# 3. Current bar is red after previous green (reversal)
# 4. RSI above 50 (elevated) and declining (exhaustion)
# 5. Price below EMA200 (still in downtrend)
if (consecutive_higher >= 3 and
curr_red and prev_green and
curr_rsi > 50 and curr_rsi < prev_rsi and
price < e200):
actions.append({
'action': 'open_short',
'symbol': 'ETHUSDT',
'exchange': 'binance',
'size': 1.0,
'stop_loss_pct': 4.0,
'take_profit_pct': 8.0,
})
else:
# EXIT logic for open short positions
pos = positions[key]
bars_held = i - pos.entry_bar
if pos.side == 'short':
# Exit conditions:
# 1. RSI oversold (< 35) - momentum exhausted downward
# 2. Time-based exit (12 bars = 2 days on 4h timeframe)
if curr_rsi < 35 or bars_held >= 12:
actions.append({
'action': 'close_short',
'symbol': 'ETHUSDT',
'exchange': 'binance',
})
return actions