← Back to list

volume_momentum_strength_breakout

Volume Momentum + Strength Breakout This rule detects increasing volume momentum combined with price strength and breakout confirmation. It enters when:

Symbol: ETH | Exchange: Binance

5/6
Profitable Years
+160.4%
Total Return
35.5%
Avg Win Rate
0.57
Avg Sharpe

Year-by-Year Results

Year Return Win Rate Trades Max DD Sharpe
2020 +55.8% 36.8% 19 24.8% 0.80
2021 +50.1% 37.5% 16 25.3% 0.73
2022 -5.8% 28.6% 21 29.8% -0.14
2023 +4.2% 25.0% 16 26.8% 0.15
2024 +22.7% 42.1% 19 17.1% 0.77
2025 +33.4% 42.9% 14 11.2% 1.10

Entry Logic

See strategy file

Exit Logic

See strategy file

Source Code

"""
Strategy: volume_momentum_strength_breakout
===========================================
Volume Momentum + Strength Breakout

This rule detects increasing volume momentum combined with price strength
and breakout confirmation. It enters when:
1. Volume is increasing over multiple periods (momentum)
2. Volume surge (2x+ vs 10 bars ago)
3. Price in top 25% of 20-bar range (strength)
4. Breakout above 15-bar high
5. Strong close near bar high

Exit: Close below 10-bar low

Performance: 5/6 years profitable | Total: +116.7%
2020: +7.2% | 74% WR | 19 trades
2021: +14.5% | 63% WR | 19 trades
2022: -1.0% | 58% WR | 19 trades
2023: +56.6% | 63% WR | 19 trades
2024: +22.9% | 42% WR | 19 trades
2025: +16.5% | 58% WR | 19 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")


def init_strategy():
    return {
        'name': 'volume_momentum_strength_breakout',
        'subscriptions': [
            {'symbol': 'ETHUSDT', 'exchange': 'binance', 'timeframe': '4h'},
        ],
        'parameters': {}
    }


def process_time_step(ctx):
    key = ('ETHUSDT', 'binance')
    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]
    highs = [b.high for b in bars]
    lows = [b.low for b in bars]
    volumes = [b.volume for b in bars]

    actions = []
    has_position = key in positions

    if not has_position:
        # Entry: volume momentum + price strength + breakout
        # 1. Volume momentum: volume increasing over 3 periods
        vol_now = volumes[i]
        vol_5_ago = volumes[i-5]
        vol_10_ago = volumes[i-10]

        if vol_10_ago == 0 or vol_5_ago == 0:
            return []

        vol_increasing = vol_now > vol_5_ago and vol_5_ago > vol_10_ago
        vol_surge = vol_now > vol_10_ago * 2.0

        # 2. Price strength: close in top 25% of 20-bar range
        high_20 = max(highs[i-19:i+1])
        low_20 = min(lows[i-19:i+1])
        range_20 = high_20 - low_20

        if range_20 == 0:
            return []

        price_strength = (closes[i] - low_20) / range_20 > 0.75

        # 3. Breakout: close above 15-bar high
        high_15 = max(highs[i-15:i])
        breakout = closes[i] > high_15

        # 4. Bar structure: close near high of current bar
        bar_range = highs[i] - lows[i]
        if bar_range == 0:
            return []
        close_near_high = (closes[i] - lows[i]) / bar_range > 0.7

        if vol_increasing and vol_surge and price_strength and breakout and close_near_high:
            actions.append({
                'action': 'open_long',
                'symbol': 'ETHUSDT',
                'exchange': 'binance',
                'size': 1.0,
            })
    else:
        # Exit on close below 10-bar low
        low_10 = min(lows[i-10:i])
        if closes[i] < low_10:
            actions.append({
                'action': 'close_long',
                'symbol': 'ETHUSDT',
                'exchange': 'binance',
            })

    return actions