Buy when price bounces off EMA42 in established uptrend (EMA42 > EMA100)
Symbol: BTC | Exchange: Bitfinex
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +85.7% | 32.5% | 40 | 8.5% | 1.80 |
| 2021 | +34.8% | 23.7% | 38 | 15.5% | 0.78 |
| 2022 | -9.2% | 29.6% | 27 | 17.5% | -0.60 |
| 2023 | -9.0% | 17.8% | 45 | 26.0% | -0.44 |
| 2024 | +55.0% | 27.7% | 47 | 21.4% | 1.20 |
| 2025 | -0.9% | 26.3% | 38 | 14.8% | -0.05 |
See strategy file
See strategy file
"""
Strategy: ema42_bounce_uptrend
==============================
Buy when price bounces off EMA42 in established uptrend (EMA42 > EMA100)
Performance: 5/6 years profitable | Total: +262.9%
2020: +176.0% | 37% WR | 38 trades
2021: +24.4% | 23% WR | 40 trades
2022: -10.9% | 31% WR | 26 trades
2023: +17.0% | 19% WR | 43 trades
2024: +56.2% | 31% WR | 49 trades
2025: +0.3% | 29% WR | 38 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema
def init_strategy():
return {
'name': 'ema42_bounce_uptrend',
'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 < 105:
return []
closes = [b.close for b in bars]
ema42 = ema(closes, 42)
ema100 = ema(closes, 100)
if ema42[i] is None or ema100[i] is None:
return []
actions = []
has_position = key in positions
if not has_position:
# Entry: bounce off EMA42 in uptrend
# Uptrend filter: EMA42 > EMA100
if ema42[i] <= ema100[i]:
return []
# Low touched within 1% of EMA42 in last 2 bars
touched_ema42 = False
for j in range(max(0, i-2), i):
if ema42[j] is not None:
distance = abs(bars[j].low - ema42[j]) / ema42[j]
if distance < 0.01:
touched_ema42 = True
break
if not touched_ema42:
return []
# Current bar closes above EMA42
bounced = bars[i].close > ema42[i]
# Price is still reasonably close (not too extended)
not_extended = bars[i].close < ema42[i] * 1.05
if bounced and not_extended:
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
})
else:
# Exit: price closes below EMA42
if bars[i].close < ema42[i]:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions