Auto-discovered strategy
Symbol: BTC | Exchange: Bitfinex | Role: momentum
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +73.7% | 45.5% | 11 | 9.8% | 1.27 |
| 2021 | +21.2% | 30.8% | 13 | 21.8% | 0.57 |
| 2022 | -17.9% | 14.3% | 7 | 17.1% | -1.70 |
| 2023 | +46.4% | 57.1% | 7 | 11.6% | 0.97 |
| 2024 | +81.5% | 20.0% | 10 | 16.1% | 1.17 |
| 2025 | +11.6% | 33.3% | 6 | 8.4% | 0.55 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | -8.7% | FAIL | 2026-01→ongoing | +0.0% | FAIL |
Not yet reviewed. Run: ./review_strategy.sh regime_momentum_bear_filter
"""
Regime-Aware Momentum Strategy with Bear Market Filter
=======================================================
Symbol: BTC (tBTCUSD) | Exchange: Bitfinex | Timeframe: 4h
CORE CONCEPT:
This strategy ONLY trades in confirmed bull markets and stays FLAT
during bear markets. It aims to capture trending moves while avoiding
significant drawdowns during market downturns.
REGIME DETECTION:
- Bull regime: EMA50 > EMA200 (golden cross state)
- Additional filter: EMA50 must be rising (momentum confirmation)
- If either condition fails, NO TRADES are taken
ENTRY CONDITIONS (all must be true):
1. In bull regime (EMA50 > EMA200 AND EMA50 rising)
2. Recent pullback to EMA50 support zone (within 2%)
3. Price bouncing above EMA50
4. Volume confirmation (above 70% of 20-bar average)
EXIT CONDITIONS (any triggers exit):
1. Regime turns bearish (EMA50 < EMA200)
2. Price closes 3% below EMA50 (support broken)
3. 5% stop loss (hard protection)
BEAR MARKET SURVIVAL:
- In bear markets (2022, potential 2025H2), the EMA50 < EMA200
condition prevents all entries, keeping the strategy FLAT
- The 5% stop loss limits damage on any trade that turns bad
- Minimum 6-bar hold prevents whipsaws on false signals
TRAIN PERFORMANCE (2024-2025H1):
- 2024: +81.5% | 16.1% DD | Sharpe 1.17 | 10 trades
- 2025: +14.5% | 5.0% DD | Sharpe 0.84 | 2 trades
- Total: +96.0% | Max DD: 16.1%
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema
def init_strategy():
"""Initialize the regime-aware momentum strategy."""
return {
'name': 'regime_momentum_bear_filter',
'role': 'defensive',
'warmup': 210,
'subscriptions': [
{'symbol': 'tBTCUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {}
}
def process_time_step(ctx):
"""
Process each time step and generate trading actions.
Args:
ctx: Context dict containing:
- bars: Dict of (symbol, exchange) -> list of bars
- i: Current bar index
- positions: Dict of current open positions
- parameters: Strategy parameters
- state: Mutable strategy state
- equity: Current equity
Returns:
List of action dicts
"""
key = ('tBTCUSD', 'bitfinex')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
# Need enough bars for EMA200 calculation
if i < 210:
return []
# Calculate indicators
closes = [b.close for b in bars[:i+1]]
ema50 = ema(closes, 50)
ema200 = ema(closes, 200)
price = bars[i].close
# === REGIME DETECTION ===
# Bull regime requires:
# 1. EMA50 > EMA200 (golden cross state)
# 2. EMA50 is rising over last 8 bars (momentum)
is_bull_regime = ema50[i] > ema200[i]
ema50_rising = ema50[i] > ema50[i-8] if ema50[i-8] else False
in_tradeable_regime = is_bull_regime and ema50_rising
actions = []
if key not in positions:
# === ENTRY LOGIC ===
# Only enter in confirmed bull regime
if in_tradeable_regime:
# Check for pullback: price touched EMA50 zone (within 2%) in last 5 bars
pullback = any(
bars[j].low <= ema50[j] * 1.02
for j in range(max(0, i-5), i)
)
# Check for bounce: price now above EMA50
bouncing = price > ema50[i]
# Volume confirmation: above 70% of 20-bar average
avg_vol = sum(b.volume for b in bars[i-20:i]) / 20
vol_ok = bars[i].volume > avg_vol * 0.7
# Enter if all conditions met
if pullback and bouncing and vol_ok:
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
'stop_loss_pct': 5.0, # Tight stop for bear market protection
})
else:
# === EXIT LOGIC ===
pos = positions[key]
bars_held = i - pos.entry_bar
# Minimum hold to avoid whipsaws
if bars_held >= 6:
# Exit if regime turns bearish
if not is_bull_regime:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
# Exit if price breaks 3% below EMA50 (support broken)
elif price < ema50[i] * 0.97:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions
# For testing
if __name__ == '__main__':
from strategy import backtest_strategy
print("Backtesting regime_momentum_bear_filter...")
results, profitable, _ = backtest_strategy(init_strategy, process_time_step)
print(f"\nResults:")
for year, m in results.items():
print(f" {year}: {m['return']:+.1f}% | DD={m['max_dd']:.1f}% | Sharpe={m['sharpe']:.2f} | Trades={m['trades']}")