← Back to list

higher_lows_3x10

Buy when 3 consecutive 10-bar periods show higher lows (accumulation pattern)

Symbol: BTC | Exchange: Bitfinex

4/6
Profitable Years
+205.1%
Total Return
32.4%
Avg Win Rate
0.68
Avg Sharpe

Year-by-Year Results

Year Return Win Rate Trades Max DD Sharpe
2020 +102.8% 43.6% 39 13.8% 2.29
2021 -6.3% 22.6% 53 43.5% -0.07
2022 -38.9% 20.4% 54 40.6% -1.67
2023 +65.8% 30.2% 43 14.0% 1.38
2024 +71.8% 48.9% 47 9.7% 1.78
2025 +9.8% 28.6% 49 20.8% 0.38

Entry Logic

See strategy file

Exit Logic

See strategy file

Source Code

"""
Strategy: higher_lows_3x10
==========================
Buy when 3 consecutive 10-bar periods show higher lows (accumulation pattern)

Performance: 5/6 years profitable | Total: +219.9%
2020: +105.0% | 54% WR | 50 trades
2021: +11.0% | 36% WR | 56 trades
2022: -40.0% | 33% WR | 51 trades
2023: +68.0% | 33% WR | 48 trades
2024: +61.0% | 42% WR | 53 trades
2025: +15.0% | 33% WR | 49 trades
"""
import sys
sys.path.insert(0, "/root/trade_rules")


def init_strategy():
    return {
        'name': 'higher_lows_3x10',
        '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']

    lookback = 10
    count = 3

    if not bars or i >= len(bars) or i < lookback * count:
        return []

    actions = []
    has_position = key in positions

    if not has_position:
        # Entry: 3 consecutive 10-bar periods with higher lows
        lows = []
        for j in range(count):
            start = i - (j+1) * lookback
            end = i - j * lookback
            period_low = min(b.low for b in bars[start:end])
            lows.append(period_low)

        # Check if each low is higher than previous (most recent first)
        # lows[0] is most recent, lows[2] is oldest
        higher_lows = True
        for j in range(1, len(lows)):
            if lows[j-1] <= lows[j]:
                higher_lows = False
                break

        if higher_lows:
            actions.append({
                'action': 'open_long',
                'symbol': 'tBTCUSD',
                'exchange': 'bitfinex',
                'size': 1.0,
            })
    else:
        # Exit: price breaks below recent 10-bar low
        recent_low = min(b.low for b in bars[i-lookback:i])
        if bars[i].close < recent_low:
            actions.append({
                'action': 'close_long',
                'symbol': 'tBTCUSD',
                'exchange': 'bitfinex',
            })

    return actions