← Back to list

volume_breakout_eth

Volume-confirmed breakout strategy for ETH. Entry: - Price breaks above 30-bar high

Symbol: ETH | Exchange: Binance

6/6
Profitable Years
+274.1%
Total Return
54.5%
Avg Win Rate
1.59
Avg Sharpe

Year-by-Year Results

Year Return Win Rate Trades Max DD Sharpe
2020 +135.1% 70.4% 27 5.0% 4.45
2021 +28.9% 52.0% 25 16.1% 0.92
2022 +12.3% 46.7% 15 7.3% 0.59
2023 +9.0% 41.2% 17 8.4% 0.60
2024 +42.2% 66.7% 18 18.8% 1.68
2025 +46.6% 50.0% 18 12.5% 1.30

Entry Logic

See strategy file

Exit Logic

See strategy file

Source Code

"""
Strategy: volume_breakout_eth
=============================
Volume-confirmed breakout strategy for ETH.

Entry:
- Price breaks above 30-bar high
- Volume above 75th percentile
- Positive momentum (10-bar ROC > 5%)

Exit:
- Hold max 15 bars
- Or momentum reverses (ROC < 0)

Performance: 6/6 years profitable | Total: +262.7%
"""
import sys
sys.path.insert(0, '/root/trade_rules')
import numpy as np


def init_strategy():
    return {
        'name': 'volume_breakout_eth',
        'subscriptions': [
            {'symbol': 'ETHUSDT', 'exchange': 'binance', 'timeframe': '4h'},
        ],
        'parameters': {
            'breakout_period': 30,
            'roc_period': 10,
            'roc_threshold': 5.0,
            'volume_percentile': 75,
            'max_hold_bars': 15,
        }
    }


def process_time_step(ctx):
    key = ('ETHUSDT', 'binance')
    bars = ctx['bars'].get(key, [])
    i = ctx['i']
    positions = ctx['positions']
    params = ctx['parameters']

    if i < 50:
        return []

    # Calculate indicators
    closes = np.array([b.close for b in bars[:i+1]])
    highs = np.array([b.high for b in bars[:i+1]])
    volumes = np.array([b.volume for b in bars[:i+1]])

    # Rate of change (momentum)
    roc = (closes[i] - closes[i - params['roc_period']]) / closes[i - params['roc_period']] * 100

    # Breakout level
    high_n = np.max(highs[i - params['breakout_period']:i])

    # Volume threshold
    vol_threshold = np.percentile(volumes[i-50:i], params['volume_percentile'])

    actions = []
    has_position = key in positions

    if not has_position:
        # Entry: breakout + volume + momentum
        if (closes[i] > high_n and
            volumes[i] > vol_threshold and
            roc > params['roc_threshold']):
            actions.append({
                'action': 'open_long',
                'symbol': 'ETHUSDT',
                'exchange': 'binance',
                'size': 1.0,
            })
    else:
        # Exit: max hold or momentum reversal
        pos = positions[key]
        bars_held = i - pos.entry_bar

        if bars_held >= params['max_hold_bars'] or roc < 0:
            actions.append({
                'action': 'close_long',
                'symbol': 'ETHUSDT',
                'exchange': 'binance',
            })

    return actions