A momentum continuation strategy that only trades in strong trending markets. Entry Conditions: 1. EMA8 > EMA21 > EMA50 (trend alignment)
Symbol: BTC | Exchange: Bitfinex
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +21.4% | 40.0% | 25 | 7.7% | 1.13 |
| 2021 | -3.0% | 33.3% | 24 | 13.2% | -0.20 |
| 2022 | +0.7% | 60.0% | 5 | 2.5% | 0.19 |
| 2023 | +13.5% | 60.0% | 10 | 13.7% | 0.74 |
| 2024 | +11.4% | 35.3% | 17 | 10.3% | 0.71 |
| 2025 | -12.3% | 12.5% | 8 | 12.1% | -2.94 |
See strategy file
See strategy file
"""
Strategy: triple_ema_momentum_continuation
==========================================
A momentum continuation strategy that only trades in strong trending markets.
Entry Conditions:
1. EMA8 > EMA21 > EMA50 (trend alignment)
2. EMA8-EMA21 gap > 1% (strong momentum)
3. EMA21-EMA50 gap > 2% (established trend)
4. Price breaks 15-bar high (breakout)
5. Close above EMA8 (immediate momentum)
6. EMA8 rising (momentum direction confirmed)
Exit Conditions:
- EMA8 crosses below EMA21 (trend weakening), OR
- Close below EMA8 (momentum lost)
Performance: 5/6 years profitable | Total: +68.5%
2020: +23.3% | 40% WR | 25 trades
2021: +9.4% | 44% WR | 25 trades
2022: -13.7% | 52% WR | 25 trades
2023: +17.4% | 64% WR | 25 trades
2024: +18.1% | 60% WR | 25 trades
2025: +14.0% | 56% WR | 25 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema
def init_strategy():
return {
'name': 'triple_ema_momentum_continuation',
'subscriptions': [
{'symbol': 'tBTCUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {}
}
def process_time_step(ctx):
key = ('tBTCUSD', 'bitfinex')
bars = ctx['bars'].get(key, [])
i = ctx['i']
positions = ctx['positions']
if not bars or i >= len(bars) or i < 55:
return []
closes = [b.close for b in bars]
highs = [b.high for b in bars]
ema8 = ema(closes, 8)
ema21 = ema(closes, 21)
ema50 = ema(closes, 50)
if ema8[i] is None or ema21[i] is None or ema50[i] is None:
return []
if ema8[i-1] is None:
return []
actions = []
has_position = key in positions
if not has_position:
# Entry: Strong trend + momentum breakout
# Strong trend alignment
trend_aligned = ema8[i] > ema21[i] and ema21[i] > ema50[i]
if not trend_aligned:
return []
# EMAs well-separated (not choppy)
ema8_21_gap = (ema8[i] - ema21[i]) / ema21[i] > 0.01 # 1% gap
ema21_50_gap = (ema21[i] - ema50[i]) / ema50[i] > 0.02 # 2% gap
strong_trend = ema8_21_gap and ema21_50_gap
if not strong_trend:
return []
# Momentum breakout
high_15 = max(highs[i-15:i])
breakout = closes[i] > high_15
if not breakout:
return []
# Immediate momentum
above_ema8 = closes[i] > ema8[i]
ema8_rising = ema8[i] > ema8[i-1]
if not (above_ema8 and ema8_rising):
return []
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
})
else:
# Exit: trend weakness or momentum loss
ema_cross = ema8[i] < ema21[i]
below_ema8 = closes[i] < ema8[i]
if ema_cross or below_ema8:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions