← Back to list

btc_consec_red_defensive VALIDATED PASS

Auto-discovered strategy

Symbol: BTC | Exchange: Binance | Role: defensive

4/6
Profitable Years
+35.0%
Total Return
42.4%
Avg Win Rate
0.40
Avg Sharpe

Year-by-Year Results

Click a year to view chart

Year Return Win Rate Trades Max DD Sharpe
2020 -10.6% 25.9% 27 26.1% -0.66
2021 +22.5% 42.9% 49 12.6% 0.88
2022 -19.4% 37.2% 78 25.6% -0.72
2023 +15.2% 59.1% 22 5.9% 1.16
2024 +18.3% 45.5% 22 6.0% 1.26
2025 +9.1% 43.6% 39 11.5% 0.45

Performance Chart

Loading chart...

Walk-Forward Validation PASS

1/1 Windows Profitable
+4.5% 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 +4.5% OK 2026-01→ongoing +0.0% PASS

AI Review

Not yet reviewed. Run: ./review_strategy.sh btc_consec_red_defensive

Source Code

"""
BTC Consecutive Red Candles Defensive Short
============================================

A defensive short strategy that profits during bear market periods by
shorting after consecutive red (down) candle patterns.

Strategy Concept:
- ONLY trades SHORT positions (profits when price falls)
- Requires bear regime (EMA50 < EMA200) to filter out bull markets
- Uses consecutive red candle pattern as entry signal
- Tight risk management with 3% stop loss and 5% take profit
- Time-based exit after 10 bars to avoid drawdowns

Why This Works:
1. In bear markets, consecutive red candles signal continuation
2. The pattern captures momentum-driven selling
3. Short time horizon (10 bar max) limits exposure
4. Tight 3% stop loss with 5% profit target gives 1.67:1 R:R
5. Volume filter avoids low-conviction entries

Entry Conditions:
1. Bear regime: EMA50 < EMA200
2. Price below EMA50 (confirmed downtrend)
3. 3+ consecutive red candles (close < open)
4. Volume not extremely low (> 50% of 20-bar average)

Exit Conditions:
1. Take profit at 5%
2. Stop loss at 3%
3. Regime change (EMA50 > EMA200)
4. Price recovery above EMA50
5. Time exit after 10 bars

Role: defensive
- Designed to profit during bear market validation period
- Must maintain positive returns (Sharpe >= 0)
- Max drawdown target < 30%

Train Performance (2024-01 to 2025-06):
  2024: +18.3% | 22 trades | 46% WR | 6.0% max DD
  2025 (partial): +4.6% | 17 trades | 41% WR | 10.3% max DD
  Total: +22.9%
"""

import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema


def init_strategy():
    return {
        'name': 'btc_consec_red_defensive',
        'role': 'defensive',
        'warmup': 200,
        'subscriptions': [
            {'symbol': 'BTCUSDT', 'exchange': 'binance', 'timeframe': '4h'},
        ],
        'parameters': {}
    }


def process_time_step(ctx):
    key = ('BTCUSDT', 'binance')
    bars = ctx['bars'][key]
    i = ctx['i']
    positions = ctx['positions']

    # Extract price series
    closes = [b.close for b in bars]
    opens = [b.open for b in bars]
    volumes = [b.volume for b in bars]

    # Calculate EMAs for regime detection
    ema50 = ema(closes, 50)
    ema200 = ema(closes, 200)

    if ema50[i] is None or ema200[i] is None:
        return []

    actions = []

    # BEAR REGIME: EMA50 < EMA200
    is_bear = ema50[i] < ema200[i]

    # PRICE BELOW EMA50 (confirmed weakness)
    below_ema50 = closes[i] < ema50[i]

    # Count consecutive red candles (close < open)
    red_count = 0
    for j in range(i, max(0, i-10), -1):
        if closes[j] < opens[j]:
            red_count += 1
        else:
            break

    # Volume filter: not extremely low volume
    avg_vol = sum(volumes[i-20:i]) / 20 if i >= 20 else volumes[i]
    vol_ok = volumes[i] > avg_vol * 0.5

    if key not in positions:
        # SHORT ENTRY:
        # Bear regime + below EMA50 + 3+ consecutive red + decent volume
        if is_bear and below_ema50 and red_count >= 3 and vol_ok:
            actions.append({
                'action': 'open_short',
                'symbol': 'BTCUSDT',
                'exchange': 'binance',
                'size': 1.0,
                'stop_loss_pct': 3.0,   # Tight 3% stop loss
                'take_profit_pct': 5.0,  # 5% take profit (1.67:1 R:R)
            })
    else:
        pos = positions[key]
        if pos.side == 'short':
            # Calculate bars held
            bars_held = i - pos.entry_bar

            # Exit conditions
            regime_change = ema50[i] > ema200[i]  # Bull regime starts
            price_recovery = closes[i] > ema50[i]  # Price reclaims EMA50
            time_exit = bars_held >= 10  # Max 10 bars hold time

            if regime_change or price_recovery or time_exit:
                actions.append({
                    'action': 'close_short',
                    'symbol': 'BTCUSDT',
                    'exchange': 'binance',
                })

    return actions


# For testing
if __name__ == '__main__':
    from strategy import backtest_strategy
    results, profitable, _ = backtest_strategy(init_strategy, process_time_step)