Auto-discovered hedge strategy
Symbol: BTC | Exchange: Bitfinex | Role: hedge
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +0.8% | 58.3% | 12 | 11.5% | 0.05 |
| 2021 | -0.4% | 50.0% | 28 | 19.2% | -0.02 |
| 2022 | -12.5% | 54.5% | 33 | 27.7% | -0.68 |
| 2023 | -1.5% | 50.0% | 6 | 2.3% | -0.90 |
| 2024 | +4.7% | 70.0% | 10 | 11.5% | 0.47 |
| 2025 | +7.2% | 57.1% | 14 | 5.8% | 0.61 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | +3.9% | OK | 2026-01→ongoing | +0.0% | PASS |
"""
Crash Bounce Hedge Strategy
============================
A hedge strategy that goes LONG after significant crashes, betting on
the inevitable short-term bounce (dead cat or real recovery).
Role: hedge
Exchange: bitfinex
Symbol: tBTCUSD
Concept:
- After significant crashes (>10% from high), there's often a bounce
- Even dead cat bounces can be 3-5%
- Enter LONG after capitulation signals appear
- Quick profit-taking on the bounce
Entry Conditions (all must be met):
1. Price dropped > 10% from 50-bar high (significant crash)
2. RSI(10) < 30 (oversold)
3. Current bar shows capitulation: lower wick > 25% of range
4. Volume > 1.3x 20-bar average (selling pressure)
5. Bar range > 1.5% (high volatility)
Exit Conditions:
1. Two consecutive green candles (take the bounce profit)
2. RSI rises above 55 (momentum recovered)
3. Time stop: 8 bars (shorter to lock in gains faster)
4. Take profit: 10%
5. Stop loss: 4% (tighter stop)
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema, rsi
def init_strategy():
return {
'name': 'crash_bounce_hedge',
'role': 'hedge',
'warmup': 100,
'subscriptions': [
{'symbol': 'tBTCUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {
# Crash detection
'high_lookback': 50,
'min_drop_pct': 10,
# RSI
'rsi_period': 10,
'rsi_oversold': 30,
'rsi_exit': 55, # Higher exit for more profit
# Capitulation detection
'min_range_pct': 1.5,
'min_wick_ratio': 0.25,
# Volume
'vol_lookback': 20,
'vol_threshold': 1.3,
# Exit settings - optimized for better risk/reward
'take_profit': 10, # More profit target
'stop_loss': 4, # Tighter stop
'time_stop': 8, # Faster exit
}
}
def process_time_step(ctx):
key = ('tBTCUSD', 'bitfinex')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
state = ctx['state']
params = ctx['parameters']
# Extract price data up to current bar
closes = [b.close for b in bars[:i+1]]
highs = [b.high for b in bars[:i+1]]
lows = [b.low for b in bars[:i+1]]
opens = [b.open for b in bars[:i+1]]
volumes = [b.volume for b in bars[:i+1]]
idx = len(closes) - 1
if idx < params['high_lookback'] + 5:
return []
# Calculate indicators
rsi_vals = rsi(closes, params['rsi_period'])
# Handle RSI indexing
if len(rsi_vals) == 0:
return []
rsi_idx = min(idx, len(rsi_vals) - 1)
current_rsi = rsi_vals[rsi_idx]
if current_rsi is None:
return []
# === CRASH DETECTION ===
start_idx = max(0, idx - params['high_lookback'])
recent_high = max(highs[start_idx:idx])
drop_pct = (recent_high - closes[idx]) / recent_high * 100
significant_crash = drop_pct > params['min_drop_pct']
# === OVERSOLD ===
oversold = current_rsi < params['rsi_oversold']
# === CAPITULATION CANDLE ===
bar_range = highs[idx] - lows[idx]
bar_range_pct = bar_range / closes[idx] * 100 if closes[idx] > 0 else 0
large_range = bar_range_pct > params['min_range_pct']
# Lower wick = min(open, close) - low
lower_wick = min(opens[idx], closes[idx]) - lows[idx]
wick_ratio = lower_wick / bar_range if bar_range > 0 else 0
capitulation_wick = wick_ratio > params['min_wick_ratio']
# === VOLUME ===
vol_start = max(0, idx - params['vol_lookback'])
avg_vol = sum(volumes[vol_start:idx]) / params['vol_lookback'] if idx > vol_start else 1
high_volume = volumes[idx] > params['vol_threshold'] * avg_vol if avg_vol > 0 else False
actions = []
if key not in positions:
# Entry: crash bounce setup
if significant_crash and oversold and large_range and capitulation_wick and high_volume:
state['green_count'] = 0
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
'take_profit_pct': params['take_profit'],
'stop_loss_pct': params['stop_loss'],
})
else:
pos = positions[key]
if pos.side != 'long':
return []
bars_held = i - pos.entry_bar
# Count green candles
if closes[idx] > opens[idx]:
state['green_count'] = state.get('green_count', 0) + 1
else:
state['green_count'] = 0
# Exit conditions
# 1. Two consecutive green (primary exit - capture the bounce)
green_exit = state.get('green_count', 0) >= 2
# 2. RSI recovery
rsi_recovered = current_rsi > params['rsi_exit']
# 3. Time stop
time_exit = bars_held >= params['time_stop']
if green_exit or rsi_recovered or time_exit:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions
# Testing
if __name__ == '__main__':
from strategy import backtest_strategy
results, profitable, _ = backtest_strategy(init_strategy, process_time_step)