Auto-discovered strategy
Symbol: BTC | Exchange: Bitfinex | Role: hedge
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +34.1% | 78.0% | 41 | 4.0% | 2.63 |
| 2021 | +114.4% | 70.2% | 57 | 5.3% | 5.23 |
| 2022 | +85.7% | 75.4% | 65 | 2.0% | 4.97 |
| 2023 | +45.1% | 64.5% | 62 | 1.8% | 3.17 |
| 2024 | +59.9% | 73.8% | 42 | 2.0% | 4.05 |
| 2025 | +76.2% | 66.7% | 63 | 1.6% | 4.51 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | +39.9% | OK | 2026-01→ongoing | +0.0% | PASS |
"""
Trend Fade Hedge Strategy
=========================
A hedge strategy that shorts when uptrends show signs of exhaustion
and start breaking down. Captures early trend failure by detecting
EMA rejections after short-term death crosses.
Role: hedge
Exchange: bitfinex
Symbol: tBTCUSD
Differentiation from existing volatility_spike_hedge:
- Different entry trigger: EMA rejection vs volatility spike
- Catches trend exhaustion earlier (death cross + rejection)
- Works in transition zones, not just established bear trends
- More frequent trades with smaller individual profits
Entry Conditions (all must be met):
1. EMA10 < EMA20 (short-term death cross active)
2. Price rejected from EMA20 or EMA50 (failed recovery attempt)
3. RSI in weak zone (35-50) and declining
4. EMA50 is flat or declining (momentum fading)
5. Current bar is red (bearish confirmation)
Exit Conditions (any triggers exit):
1. EMA10 crosses above EMA20 (golden cross)
2. RSI recovery above 50
3. Price closes above EMA20
4. Time stop: 15 bars
Train Performance (2024-01-01 to 2025-06-30):
- 2024: +59.9% | 42 trades | 74% WR
- 2025 (H1): +32.2% | 27 trades | 70% WR
- Total: +92.1%
- Max Drawdown: ~2%
Validation Performance (2025-07-01 to 2025-12-31):
- Return: +39.9%
- Sharpe: 3.05
- Status: PASSED
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema, rsi, atr
def init_strategy():
return {
'name': 'trend_fade_hedge',
'role': 'hedge',
'warmup': 200,
'subscriptions': [
{'symbol': 'tBTCUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {}
}
def process_time_step(ctx):
key = ('tBTCUSD', 'bitfinex')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
# Extract full price data arrays
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 indicators on full data
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)
atr_vals = atr(highs, lows, closes, 14)
# Check indicator availability at current index
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 or atr_vals[i] is None:
return []
if i < 10:
return []
actions = []
if key not in positions:
# === ENTRY CONDITIONS ===
# 1. Short-term 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 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 in weak zone (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 is flat or declining (momentum fading)
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': 'tBTCUSD',
'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': 'tBTCUSD',
'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)