Skip to main content
The MOMENTUM strategy trades based on the actual direction of Bitcoin’s spot price over the last 60 seconds. Unlike PREVIOUS which relies on past market outcomes, MOMENTUM looks directly at BTC price changes from Coinbase to predict the next 15-minute move.

Strategy Logic

The hypothesis: recent short-term price momentum (60 seconds) indicates the likely direction for the next 15-minute market window.
  • If BTC price increased over the last 60 seconds → Bet YES (price will go up)
  • If BTC price decreased over the last 60 seconds → Bet NO (price will go down)

Signal Generation

1

Collect Price History

Bot continuously polls Coinbase API every 5 seconds and stores BTC prices in a time-series buffer.
2

Detect Market Rollover

When a new KXBTC15M market opens, activate MOMENTUM signal generation.
3

Compare Prices

Look back 60 seconds in the price buffer and compare old price vs. current price.
4

Execute Trade

  • If current > old → Buy YES
  • If current ≤ old → Buy NO

Implementation

BTC Price Collection

The bot maintains a rolling window of BTC prices:
# bot.py:34-41
def get_btc_price():
    """Get current BTC price from Coinbase."""
    resp = requests.get(
        "https://api.coinbase.com/v2/prices/BTC-USD/spot",
        timeout=10
    )
    resp.raise_for_status()
    return float(resp.json()["data"]["amount"])
Prices are stored with timestamps:
# bot.py:288-294
try:
    btc_price = get_btc_price()
    btc_prices.append((now, btc_price))  # deque of (timestamp, price)
except Exception as e:
    btc_price = None
    print(f"  [BTC price error: {e}]")

Momentum Calculation

Here’s the core MOMENTUM strategy from bot.py:
# bot.py:416-462
if (
    pending_previous
    and ("MOMENTUM", ticker) not in traded_keys
    and len(btc_prices) >= 2
):
    # Get price from ~60 seconds ago
    cutoff = now - timedelta(seconds=MOMENTUM_WINDOW_SECONDS)
    old_prices = [(t, p) for t, p in btc_prices if t <= cutoff]
    
    if old_prices:
        _, old_price = old_prices[-1]
        _, current_price = btc_prices[-1]
        
        if current_price > old_price:
            side = "yes"  # Price rising, bet UP
        else:
            side = "no"   # Price falling, bet DOWN
        
        # Record signal
        signals[ticker]["MOMENTUM"] = side
        
        price = yes_ask if side == "yes" else no_ask
        contracts = STAKE_USD / price if price > 0 else 0
        pct_change = ((current_price - old_price) / old_price) * 100
        
        trade = {
            "time": now.isoformat(),
            "strategy": "MOMENTUM",
            "previous_ticker": pending_previous,
            "previous_result": f"BTC {pct_change:+.3f}%",
            "buy_ticker": ticker,
            "buy_side": side,
            "stake_usd": STAKE_USD,
            "price_usd": round(price, 4),
            "contracts": round(contracts, 4),
            "outcome": "",
            "payout_usd": "",
            "profit_usd": "",
        }
        trades.append(trade)
        save_trades(trades)
        traded_keys.add(("MOMENTUM", ticker))
        
        direction = "UP" if side == "yes" else "DOWN"
        print(f"  -> [MOMENTUM] BTC {pct_change:+.3f}% -> BUY {side} ({direction}) ${STAKE_USD} @ ${price:.4f}")

Configuration

ParameterDefaultDescription
MOMENTUM_WINDOW_SECONDS60Lookback period for price comparison
STAKE_USD5.0Fixed amount to bet
POLL_SECONDS5Price polling frequency
The btc_prices deque has maxlen=btc_history_len (calculated based on the longest momentum window needed). Older prices are automatically evicted.

Risk Characteristics

Advantages

Real-time data: Uses actual BTC price, not lagging market outcomes Short lookback: 60-second window captures recent momentum Independent signal: Doesn’t depend on previous market settlement

Limitations

Noise sensitivity: 60 seconds may capture random fluctuations rather than true trends No mean reversion awareness: Doesn’t account for overbought/oversold conditions Fixed stake: No position sizing or risk management

When to Use

MOMENTUM performs best during:
  • High volatility periods: When BTC is making rapid directional moves
  • News-driven markets: Immediate reaction to announcements or events
  • Intraday trending: When short-term momentum persists across 15-minute windows
MOMENTUM can struggle during:
  • Choppy/ranging markets: Frequent direction changes cause whipsaws
  • Low volatility: Small 60-second moves may not predict 15-minute outcomes
  • Execution delays: If price changes significantly between signal and execution

MOMENTUM_15 Variant

The MOMENTUM_15 strategy extends the lookback to the full 15-minute window:
# From momentum_15.py:406-420
cutoff = now - timedelta(seconds=MOMENTUM_15_WINDOW_SECONDS)  # 900 seconds
old_prices = [(t, p) for t, p in btc_prices if t <= cutoff]

if not old_prices:
    print(
        f"  Waiting for full {MOMENTUM_15_WINDOW_SECONDS}s BTC history "
        f"before trading {ticker}"
    )
    time.sleep(POLL_SECONDS)
    continue

_, old_price = old_prices[-1]
_, current_price = btc_prices[-1]
side = "yes" if current_price > old_price else "no"
pct_change = ((current_price - old_price) / old_price) * 100
MOMENTUM_15 uses MOMENTUM_15_WINDOW_SECONDS = 15 * 60 = 900 seconds (from bot.py:19). This aligns the signal lookback with the actual market duration.

MOMENTUM vs MOMENTUM_15

AspectMOMENTUMMOMENTUM_15
Lookback60 seconds900 seconds (15 min)
LatencyLow (data usually ready)Higher (needs 15min history)
Signal typeShort-term momentumTrend alignment
Best forQuick reversalsSustained trends

Example Trade Flow

1

Price collection

At 12:00:00, BTC = 95,000At12:01:00,BTC=95,000 At 12:01:00, BTC = 95,450 (+0.47%)
2

New market opens

KXBTC15M-B opens at 12:01:05
3

MOMENTUM signal generation

Compare current (95,450)vs60sago(95,450) vs 60s ago (95,000)
  • Price increased → Signal = YES
4

Execute trade

Buy YES at ask price $0.48
  • Stake: $5.00
  • Contracts: 10.42 (= 5.00/5.00 / 0.48)
5

Market settles

If BTC continues up and settles YES:
  • Payout: $10.42
  • Profit: $5.42

Performance Monitoring

Bot console output shows MOMENTUM P&L:
[12:34:56] KXBTC15M-24MAR05-T1245 (180s) | yes=$0.52 no=$0.48 | BTC=95,234 | 
           P:$+2.50 M:$-1.20 C:$+3.75 M15:$+4.10 ...
Where:
  • M:$-1.20 = MOMENTUM strategy cumulative P&L
  • M15:$+4.10 = MOMENTUM_15 strategy cumulative P&L
Detailed trade log:
-> [MOMENTUM] BTC +0.245% -> BUY yes (UP) $5.00 @ $0.4800
** [MOMENTUM] SETTLED KXBTC15M-24MAR05-T1230: WIN $+5.42

Standalone Bot

MOMENTUM_15 has its own standalone implementation in momentum_15.py for isolated testing:
# momentum_15.py:266-273
print("=" * 60)
print("MOMENTUM_15 STRATEGY BOT - REAL TRADING")
print("=" * 60)
print(f"Series: {SERIES_TICKER}")
print(f"Stake: ${STAKE_USD} per trade")
print(f"Momentum window: {MOMENTUM_15_WINDOW_SECONDS}s")
print(f"Poll interval: {POLL_SECONDS}s")
print(f"DRY RUN: {dry_run}")
Use momentum_15.py with DRY_RUN=true to backtest the 15-minute momentum signal without risking capital.

PREVIOUS Strategy

Compare market-outcome signals vs. price-based signals

CONSENSUS Strategy

Combines MOMENTUM with PREVIOUS for confirmation

Build docs developers (and LLMs) love