← Back to list

crash_bounce_hedge VALIDATED PASS

Auto-discovered hedge strategy

Symbol: BTC | Exchange: Bitfinex | Role: hedge

3/6
Profitable Years
-1.8%
Total Return
56.7%
Avg Win Rate
-0.08
Avg Sharpe

Year-by-Year Results

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

Performance Chart

Loading chart...

Walk-Forward Validation PASS

1/1 Windows Profitable
+3.9% OOS Return
0.00 Median Sharpe
0.000 Score
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

AI Review Score: 45/100

overfitting complexity inconsistent concentration
## Strategy Assessment: crash_bounce_hedge ### Role Compliance (hedge) - **Val Return**: 3.9% ✓ (exceeds 0% minimum) - **Val Sharpe**: -0.08 ✗ (fails 0.3 minimum requirement) - **Trades**: Appears sufficient ✓ - **Issue**: While validation return is positive, the Sharpe ratio indicates the strategy is too volatile/risky for a hedge role ### Year-over-Year Consistency Analysis **Major Red Flag**: Highly inconsistent performance across years: - 2020-2023: Mostly negative or flat (-12.5%, -1.5%, -0.4%, +0.8%) - 2024-2025: Suddenly profitable (+4.7%, +7.3%) - Sharpe ratios swing wildly: from -0.90 to +0.61 This suggests the strategy may have accidentally captured regime-specific patterns rather than robust crash-bounce dynamics. The poor performance in 2022 (a major crash year) is particularly concerning for a "crash bounce" strategy. ### Overfitting Concerns 1. **Too Many Conditions (5 entry filters)**: - Drop percentage check - RSI oversold - Capitulation wick pattern - Volume threshold - Bar range requirement This creates a highly specific "needle in haystack" setup that may not recur reliably. 2. **Non-Standard Parameters**: - `min_drop_pct: 10` - Not a rounded standard value (should be 10, 15, 20, etc. ✓ this one is okay) - `rsi_exit: 55` - Non-standard (should be 50 or 60) - `min_wick_ratio: 0.25` - Precise ratio suggests curve-fitting - `vol_threshold: 1.3` - Should be rounded to 1.5 or 2.0 - `take_profit: 10, stop_loss: 4` - The 10:4 ratio seems optimized 3. **Complex Capitulation Detection**: The wick ratio calculation (lower_wick / bar_range > 0.25) combined with range percentage is a very specific pattern that may not generalize. ### Execution Issues - **Exit Logic Flaw**: "Two consecutive green candles" is checked within the same bar loop, creating potential same-candle execution if the current bar is the second green candle - **State Management**: The `green_count` resets to 0 on red candles, which is correct, but the consecutive green exit may trigger too quickly in choppy bounces ### Concentration Risk With only 89-103 total trades across 5+ years and highly variable year-to-year returns, there's significant risk that a small number of trades in 2024-2025 drive all the positive performance. The strategy appears to work well in some market conditions but fails in others (notably 2022's bear market). ### Strategy Concept Issues **Philosophical Problem**: A "hedge" strategy should protect during crashes, not bet on bounces AFTER crashes. By the time all 5 conditions are met (10% drop, RSI<30, capitulation wick, high volume, large range), the crash may already be priced in. True hedge strategies are often short or inverse correlation plays. The -12.5% return in 2022 suggests this isn't hedging anything—it's a tactical long-only bounce trader that only works in certain market structures. ### Positive Aspects - Proper warmup period (100 bars) - No lookahead bias detected - Reasonable stop loss / take profit structure - Attempts to capture a real phenomenon (capitulation bounces) ### Recommendation **Reject or Major Revision Required**. While the strategy passes the validation return threshold, it fails the Sharpe requirement for hedge strategies and shows concerning regime-dependency. The complexity (5+ conditions) and inconsistent year-over-year performance suggest this is curve-fit to recent market behavior rather than capturing a robust edge.
Reviewed: 2026-01-14T05:58:07.345361

Source Code

"""
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)