← Back to list

wednesday_thursday_midweek_momentum

Buy Wednesday or Thursday when price breaks out with strong momentum in an uptrend, hold through Friday. Capitalizes on midweek momentum surges while avoiding weekend volatility. Entry Logic:

Symbol: BTC | Exchange: Bitfinex

6/6
Profitable Years
+94.7%
Total Return
60.8%
Avg Win Rate
1.23
Avg Sharpe

Year-by-Year Results

Year Return Win Rate Trades Max DD Sharpe
2020 +44.0% 57.1% 14 7.3% 1.95
2021 +9.8% 60.0% 5 3.9% 1.07
2022 +0.1% 80.0% 5 7.0% 0.01
2023 +8.5% 25.0% 8 11.1% 0.42
2024 +19.4% 80.0% 10 3.0% 2.38
2025 +13.0% 62.5% 8 4.1% 1.53

Entry Logic

See strategy file

Exit Logic

See strategy file

Source Code

"""
Strategy: wednesday_thursday_midweek_momentum
=============================================
Buy Wednesday or Thursday when price breaks out with strong momentum in an uptrend,
hold through Friday. Capitalizes on midweek momentum surges while avoiding weekend volatility.

Entry Logic:
- Wednesday or Thursday only
- Price breaks 15-bar high (at least 0.2% above)
- Above both EMA20 and EMA50 (uptrend)
- EMA20 > EMA50 (EMA alignment)
- EMA50 trending up (higher than 10 bars ago)
- Not overextended (within 5% above EMA20)
- Volume above 20-bar average (1.2x minimum)
- Strong momentum: up last 4 bars
- Bar closes in upper 60% of its range

Exit Logic:
- Exit on Saturday or later (capture midweek-to-weekend move)

Performance: 6/6 years profitable | Total: +94.7%
2020: +44.0% | 57% WR | 14 trades
2021: +9.8% | 60% WR | 5 trades
2022: +0.1% | 80% WR | 5 trades
2023: +8.5% | 25% WR | 8 trades
2024: +19.4% | 80% WR | 10 trades
2025: +13.0% | 62% WR | 8 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")
from lib import ema


def init_strategy():
    return {
        'name': 'wednesday_thursday_midweek_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 < 60:
        return []

    closes = [b.close for b in bars]
    highs = [b.high for b in bars]
    volumes = [b.volume for b in bars]

    ema20_vals = ema(closes, 20)
    ema50_vals = ema(closes, 50)

    if ema20_vals[i] is None or ema50_vals[i] is None:
        return []
    if ema50_vals[i-10] is None:
        return []

    actions = []
    has_position = key in positions

    if not has_position:
        # Entry: midweek momentum breakout
        bar = bars[i]

        # Must be Wednesday (2) or Thursday (3)
        if bar.timestamp.weekday() not in [2, 3]:
            return []

        # Uptrend: price above both EMAs
        if bar.close < ema20_vals[i] or bar.close < ema50_vals[i]:
            return []

        # EMA alignment: EMA20 > EMA50
        if ema20_vals[i] < ema50_vals[i]:
            return []

        # EMA50 trending up
        if ema50_vals[i] < ema50_vals[i-10]:
            return []

        # Not overextended (within 5% above EMA20)
        if bar.close > ema20_vals[i] * 1.05:
            return []

        # Breaking 15-bar high by at least 0.2%
        high_15 = max(highs[i-15:i])
        if bar.close < high_15 * 1.002:
            return []

        # Volume confirmation (above 20-bar average)
        avg_vol = sum(volumes[i-20:i]) / 20
        if bar.volume < avg_vol * 1.2:
            return []

        # Momentum: up last 4 bars
        if closes[i] <= closes[i-4]:
            return []

        # Strong close: upper 60% of bar range
        bar_range = bar.high - bar.low
        if bar_range > 0:
            close_pos = (bar.close - bar.low) / bar_range
            if close_pos < 0.6:
                return []

        actions.append({
            'action': 'open_long',
            'symbol': 'tBTCUSD',
            'exchange': 'bitfinex',
            'size': 1.0,
        })
    else:
        # Exit on Saturday (5) or later
        bar = bars[i]
        if bar.timestamp.weekday() >= 5:
            actions.append({
                'action': 'close_long',
                'symbol': 'tBTCUSD',
                'exchange': 'bitfinex',
            })

    return actions