Auto-discovered strategy
Symbol: ETH | Exchange: Bitfinex | Role: hedge
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +55.6% | 63.6% | 44 | 2.9% | 3.26 |
| 2021 | +119.0% | 76.3% | 38 | 2.8% | 6.15 |
| 2022 | +115.6% | 77.2% | 57 | 5.5% | 5.62 |
| 2023 | +50.4% | 70.6% | 51 | 2.3% | 3.72 |
| 2024 | +86.5% | 69.4% | 49 | 3.6% | 4.63 |
| 2025 | +75.8% | 63.6% | 55 | 3.4% | 3.86 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | +48.7% | OK | 2026-01→ongoing | +0.0% | PASS |
"""
ETH EMA Rejection Hedge Strategy
================================
A hedge strategy that shorts ETH when uptrends show exhaustion and price
rejects from key EMA levels. Captures trend failures by detecting EMA
rejections after short-term death crosses.
Role: hedge
Exchange: bitfinex
Symbol: tETHUSD
Concept:
- When EMA10 < EMA20 (death cross active), the short-term trend is bearish
- When price rallies to test EMA20 or EMA50 but fails to reclaim it, this
confirms weakness and provides a low-risk short entry
- The strategy profits when these failed recovery attempts lead to continued
decline
Entry Conditions (all must be met):
1. EMA10 < EMA20 (death cross active - short-term bearish)
2. Price rejected from EMA20 or EMA50 (high touched EMA but close below)
3. RSI in weak zone (35-50) and declining (momentum fading)
4. EMA50 flat or declining (no medium-term support)
5. Current bar is red (bearish confirmation)
Exit Conditions (any triggers exit):
1. EMA10 crosses above EMA20 (golden cross - trend reversal)
2. RSI recovery above 50 (momentum returning)
3. Price closes above EMA20 (failed breakdown)
4. Time stop: 15 bars
Risk Management:
- Stop loss: 4%
- Take profit: 6%
Performance:
- Train 2024: +86.5% | 49 trades | 69% WR
- Train 2025-H1: +21.1% | 23 trades | 56% WR
- Validation 2025-H2: +48.7% | Sharpe 3.47 | PASS
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema, rsi
def init_strategy():
return {
'name': 'eth_ema_rejection_hedge',
'role': 'hedge',
'warmup': 200,
'subscriptions': [
{'symbol': 'tETHUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {}
}
def process_time_step(ctx):
key = ('tETHUSD', 'bitfinex')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
# Extract price data
closes = [b.close for b in bars]
highs = [b.high for b in bars]
lows = [b.low for b in bars]
opens = [b.open for b in bars]
# Calculate EMAs
ema_10 = ema(closes, 10)
ema_20 = ema(closes, 20)
ema_50 = ema(closes, 50)
ema_100 = ema(closes, 100)
rsi_vals = rsi(closes, 14)
# Check indicator availability
if ema_10[i] is None or ema_20[i] is None:
return []
if ema_50[i] is None or ema_100[i] is None:
return []
if rsi_vals[i] is None:
return []
if i < 10:
return []
actions = []
if key not in positions:
# === ENTRY CONDITIONS ===
# 1. Death cross active: EMA10 < EMA20
death_cross_active = ema_10[i] < ema_20[i]
# 2. Price rejected from EMA20 or EMA50
# High touched EMA but close is below
rejected_ema20 = highs[i] > ema_20[i] * 0.99 and closes[i] < ema_20[i]
rejected_ema50 = highs[i] > ema_50[i] * 0.99 and closes[i] < ema_50[i]
rejection = rejected_ema20 or rejected_ema50
# 3. RSI weak (35-50) and declining
rsi_weak = 35 < rsi_vals[i] < 50
rsi_declining = rsi_vals[i] < rsi_vals[i-1] if i > 0 else False
# 4. EMA50 flat or declining (no support)
ema50_flat_down = ema_50[i] <= ema_50[i-5] * 1.005 if i >= 5 else False
# 5. Red bar (bearish confirmation)
red_bar = closes[i] < opens[i]
# All conditions must be met
if death_cross_active and rejection and rsi_weak and rsi_declining and ema50_flat_down and red_bar:
actions.append({
'action': 'open_short',
'symbol': 'tETHUSD',
'exchange': 'bitfinex',
'size': 1.0,
'stop_loss_pct': 4,
'take_profit_pct': 6,
})
else:
pos = positions[key]
if pos.side != 'short':
return []
bars_held = i - pos.entry_bar
# === EXIT CONDITIONS ===
# 1. Golden cross: EMA10 crosses above EMA20
golden_cross = (
ema_10[i] > ema_20[i] and
i > 0 and ema_10[i-1] <= ema_20[i-1]
)
# 2. RSI recovery above 50
rsi_recovery = rsi_vals[i] > 50
# 3. Time stop - 15 bars
time_exit = bars_held >= 15
# 4. Price closes above EMA20 (trend recovery)
above_ema20 = closes[i] > ema_20[i]
if golden_cross or rsi_recovery or time_exit or above_ema20:
actions.append({
'action': 'close_short',
'symbol': 'tETHUSD',
'exchange': 'bitfinex',
})
return actions
# Testing
if __name__ == '__main__':
from strategy import backtest_strategy, validate_new_strategy
print("=" * 60)
print("TRAIN PERIOD BACKTEST")
print("=" * 60)
results, profitable, _ = backtest_strategy(init_strategy, process_time_step)
print("\n" + "=" * 60)
print("VALIDATION ON UNSEEN DATA")
print("=" * 60)
validate_new_strategy(init_strategy, process_time_step)