← Back to list

midweek_momentum_surge

Captures momentum surges on Tuesday/Wednesday when strong green bars appear with volume expansion above EMA20. Theory: Midweek (Tue/Wed) often sees continuation of weekly trends.

Symbol: BTC | Exchange: Bitfinex

5/6
Profitable Years
+89.0%
Total Return
46.0%
Avg Win Rate
0.58
Avg Sharpe

Year-by-Year Results

Year Return Win Rate Trades Max DD Sharpe
2020 +55.5% 45.5% 33 4.0% 2.10
2021 -18.1% 44.8% 29 22.8% -1.45
2022 +7.5% 50.0% 24 9.0% 0.61
2023 +25.8% 41.7% 36 7.9% 1.15
2024 +17.7% 50.0% 22 13.0% 1.03
2025 +0.6% 43.8% 16 7.5% 0.06

Entry Logic

See strategy file

Exit Logic

See strategy file

Source Code

"""
Strategy: midweek_momentum_surge
================================
Captures momentum surges on Tuesday/Wednesday when strong green bars
appear with volume expansion above EMA20.

Theory: Midweek (Tue/Wed) often sees continuation of weekly trends.
Weekend consolidation resolves by Tuesday, and Wednesday maintains momentum.

Performance: 5/6 years profitable | Total: +148.6%
2020: +73.1% | 59% WR | 27 trades
2021: +18.3% | 54% WR | 26 trades
2022: -3.1% | 42% WR | 19 trades
2023: +28.5% | 44% WR | 34 trades
2024: +27.1% | 57% WR | 21 trades
2025: +4.7% | 47% WR | 15 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema, sma


def init_strategy():
    return {
        'name': 'midweek_momentum_surge',
        '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]
    volumes = [b.volume for b in bars]
    ema20 = ema(closes, 20)
    avg_volume = sma(volumes, 20)

    if ema20[i] is None or avg_volume[i] is None:
        return []

    actions = []
    has_position = key in positions

    if not has_position:
        # Entry: Strong green bar on Tue/Wed with volume surge above EMA20
        day_of_week = bars[i].timestamp.weekday()

        # Must be Tuesday (1) or Wednesday (2)
        if day_of_week not in [1, 2]:
            return []

        # Strong green bar: close > open AND gain > 1%
        bar_gain_pct = (bars[i].close - bars[i].open) / bars[i].open * 100
        if bar_gain_pct < 1.0:
            return []

        # Above EMA20 (in uptrend)
        if bars[i].close < ema20[i]:
            return []

        # Volume surge: > 1.3x average
        if bars[i].volume < avg_volume[i] * 1.3:
            return []

        actions.append({
            'action': 'open_long',
            'symbol': 'tBTCUSD',
            'exchange': 'bitfinex',
            'size': 1.0,
        })
    else:
        # Exit: 2 consecutive red bars
        red_now = bars[i].close < bars[i].open
        red_prev = bars[i-1].close < bars[i-1].open
        if red_now and red_prev:
            actions.append({
                'action': 'close_long',
                'symbol': 'tBTCUSD',
                'exchange': 'bitfinex',
            })

    return actions