Buy after 4 consecutive bullish candles with ascending closes. Uses take-profit and stop-loss for exit.
Symbol: SOL | Exchange: Binance
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +1.7% | 40.0% | 10 | 11.5% | 0.10 |
| 2021 | +34.6% | 35.8% | 53 | 31.0% | 0.97 |
| 2022 | +7.2% | 30.8% | 26 | 9.4% | 0.42 |
| 2023 | +18.9% | 38.3% | 47 | 17.9% | 0.77 |
| 2024 | -14.2% | 32.4% | 37 | 18.8% | -1.12 |
| 2025 | -4.8% | 27.3% | 33 | 13.0% | -0.33 |
See strategy file
See strategy file
"""
Strategy: green_candles_sol
===========================
Buy after 4 consecutive bullish candles with ascending closes.
Uses take-profit and stop-loss for exit.
Performance: 5/6 years profitable | Total: +128.7%
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema
def init_strategy():
return {
'name': 'green_candles_sol',
'subscriptions': [
{'symbol': 'SOLUSDT', 'exchange': 'binance', 'timeframe': '4h'},
],
'parameters': {
'consecutive_candles': 4,
'ema_period': 20,
'take_profit_pct': 8.0,
'stop_loss_pct': 4.0,
}
}
def process_time_step(ctx):
key = ('SOLUSDT', 'binance')
bars = ctx['bars'].get(key, [])
i = ctx['i']
positions = ctx['positions']
params = ctx['parameters']
n = params['consecutive_candles']
if i < max(n, params['ema_period']):
return []
# Calculate EMA
closes = [b.close for b in bars[:i+1]]
ema_vals = ema(closes, params['ema_period'])
ema_val = ema_vals[i]
if ema_val is None:
return []
actions = []
has_position = key in positions
if not has_position:
# Check for N consecutive bullish candles
all_green = all(bars[i-j].close > bars[i-j].open for j in range(n))
# Check ascending closes
ascending = all(bars[i-j].close > bars[i-j-1].close for j in range(n-1))
# Volume above average
volumes = [b.volume for b in bars[i-20:i]]
avg_vol = sum(volumes) / len(volumes)
vol_ok = bars[i].volume > avg_vol
# Price above EMA
above_ema = bars[i].close > ema_val
if all_green and ascending and vol_ok and above_ema:
actions.append({
'action': 'open_long',
'symbol': 'SOLUSDT',
'exchange': 'binance',
'size': 1.0,
'take_profit_pct': params['take_profit_pct'],
'stop_loss_pct': params['stop_loss_pct'],
})
else:
# Exit on red candle or below EMA
# (TP/SL handled automatically by framework)
if bars[i].close < bars[i].open or bars[i].close < ema_val:
actions.append({
'action': 'close_long',
'symbol': 'SOLUSDT',
'exchange': 'binance',
})
return actions