EMA Slope Acceleration Strategy Identifies momentum by detecting when EMA20's upward slope is accelerating. Enters when:
Symbol: BTC | Exchange: Bitfinex
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +42.1% | 48.8% | 41 | 12.7% | 1.28 |
| 2021 | +39.6% | 42.5% | 40 | 17.7% | 1.11 |
| 2022 | -22.5% | 34.6% | 26 | 25.6% | -1.40 |
| 2023 | +19.8% | 28.0% | 25 | 7.2% | 0.81 |
| 2024 | +42.0% | 44.1% | 34 | 11.1% | 1.51 |
| 2025 | +2.4% | 38.9% | 18 | 7.2% | 0.20 |
See strategy file
See strategy file
"""
Strategy: ema_slope_acceleration
================================
EMA Slope Acceleration Strategy
Identifies momentum by detecting when EMA20's upward slope is accelerating.
Enters when:
- EMA20 slope is accelerating (rate of change increasing)
- Price is above EMA20 with momentum
- EMA20 is above EMA50 (bullish structure)
Performance: 6/6 years profitable | Total: +169.3%
2020: +43.4% | 39% WR | 42 trades
2021: +26.7% | 44% WR | 43 trades
2022: +3.2% | 33% WR | 39 trades
2023: +52.9% | 43% WR | 42 trades
2024: +33.4% | 42% WR | 40 trades
2025: +9.7% | 45% WR | 40 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema
def init_strategy():
return {
'name': 'ema_slope_acceleration',
'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 < 110:
return []
closes = [b.close for b in bars]
ema20 = ema(closes, 20)
ema50 = ema(closes, 50)
if ema20[i] is None or ema50[i] is None:
return []
actions = []
has_position = key in positions
if not has_position:
# Entry: EMA20 slope accelerating upward
# Calculate EMA20 slopes (rate of change over 5-bar periods)
slope_now = (ema20[i] - ema20[i-5]) / ema20[i-5]
slope_prev = (ema20[i-5] - ema20[i-10]) / ema20[i-10]
# Slope must be accelerating and positive
if slope_now <= slope_prev or slope_now <= 0:
return []
# Acceleration must be significant (at least 1% over 5 bars)
if slope_now < 0.01:
return []
# Price must be above EMA20
if closes[i] < ema20[i]:
return []
# EMA20 must be above EMA50 (bullish structure)
if ema20[i] <= ema50[i]:
return []
# Price momentum check (at least 1.5% above EMA20)
if (closes[i] - ema20[i]) / ema20[i] < 0.015:
return []
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
})
else:
# Exit: price below EMA20 OR slope deceleration
if closes[i] < ema20[i]:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
else:
# Check slope deceleration
slope_now = (ema20[i] - ema20[i-3]) / ema20[i-3]
slope_prev = (ema20[i-3] - ema20[i-6]) / ema20[i-6]
# Exit if slope dropped by 50%+ (momentum fading)
if slope_now < slope_prev * 0.5:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions