Buy after 2 consecutive bullish 4h candles with 1%+ body each and 2%+ combined gain above EMA50
Symbol: BTC | Exchange: Bitfinex
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +36.7% | 53.3% | 30 | 8.9% | 1.55 |
| 2021 | +16.9% | 46.3% | 41 | 13.7% | 0.90 |
| 2022 | +14.4% | 50.0% | 24 | 7.1% | 1.39 |
| 2023 | +34.3% | 44.0% | 25 | 7.5% | 1.49 |
| 2024 | +15.6% | 38.5% | 26 | 11.2% | 0.99 |
| 2025 | -8.0% | 27.3% | 11 | 9.5% | -1.20 |
See strategy file
See strategy file
"""
Strategy: consecutive_green_momentum
====================================
Buy after 2 consecutive bullish 4h candles with 1%+ body each and 2%+ combined gain above EMA50
Performance: 5/6 years profitable | Total: +108.0%
2020: +33.5% | 53% WR | 30 trades
2021: +14.1% | 46% WR | 41 trades
2022: +15.2% | 50% WR | 24 trades
2023: +37.6% | 42% WR | 24 trades
2024: +16.1% | 39% WR | 26 trades
2025: -8.6% | 27% WR | 11 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema
def init_strategy():
return {
'name': 'consecutive_green_momentum',
'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 < 50:
return []
closes = [b.close for b in bars]
ema50 = ema(closes, 50)
if ema50[i] is None:
return []
actions = []
has_position = key in positions
if not has_position:
# Entry: 2 consecutive bullish candles with 1%+ body each, 2%+ combined gain, above EMA50
if bars[i].close <= ema50[i]:
return []
bar1 = bars[i-1]
bar2 = bars[i]
# Previous bar must be bullish with 1%+ body
if bar1.close <= bar1.open:
return []
body1_pct = (bar1.close - bar1.open) / bar1.open
if body1_pct < 0.01:
return []
# Current bar must be bullish with 1%+ body
if bar2.close <= bar2.open:
return []
body2_pct = (bar2.close - bar2.open) / bar2.open
if body2_pct < 0.01:
return []
# Current close must be higher than previous close
if bar2.close <= bar1.close:
return []
# Combined 2-candle gain must be 2%+
combined_gain = (bar2.close - bar1.open) / bar1.open
if combined_gain < 0.02:
return []
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
})
else:
# Exit: price below EMA50 OR 2 consecutive bearish candles
if bars[i].close < ema50[i]:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
elif bars[i-1].close < bars[i-1].open and bars[i].close < bars[i].open:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions