Skip to content

Repository files navigation

Kalshi Trading Bot

Automated trading bot for Kalshi prediction markets, targeting 15-minute price movement contracts (KXBTC15M, KXETH15M). Monitors real-time price feeds from multiple exchanges plus Bybit futures (funding rates, liquidations) and Chainlink oracles, estimates settlement probability via a 16-signal heuristic model, identifies mispriced contracts, and executes trades with strict risk management.

Multi-asset · Real-time dashboard · Paper & live modes · Fee-aware Kelly sizing

Dashboard


Quick Start

Prerequisites

Requirement Notes
Python 3.11+ python3 --version
Kalshi account kalshi.com
Kalshi API key RSA key pair (see below)

Setup

# 1. Generate Kalshi API key
openssl genrsa -out kalshi_key.pem 4096
openssl rsa -in kalshi_key.pem -pubout -out kalshi_key_pub.pem
# Upload kalshi_key_pub.pem at kalshi.com account settings

# 2. Install
git clone <repo-url> && cd kalshi-btc-bot
python3 -m venv .venv && source .venv/bin/activate
pip install -e .

# 3. Environment variables
export KALSHI_API_KEY_ID="your-api-key-id"
export KALSHI_PRIVATE_KEY_PATH="/path/to/kalshi_key.pem"

# 4. Run (paper mode, safe default)
kalshi-bot --dry-run

Running Live

# Production
kalshi-bot --mode live --env prod

# With risk overrides
kalshi-bot --mode live --env prod --max-exposure 1000 --max-daily-loss 200

CLI Reference

Flag Short Description
--config PATH -c Settings YAML (default: config/settings.yaml)
--mode {paper,live} -m Trading mode
--env {demo,prod} -e Kalshi environment
--log-level LEVEL -l DEBUG / INFO / WARNING / ERROR
--max-exposure $ Max total exposure
--max-daily-loss $ Max daily loss
--dry-run Shortcut: --mode paper --env demo

How It Works

Main Loop (every ~4 seconds)

  1. Snapshot — Aggregate prices (Coinbase, Kraken), Kalshi orderbook, Bybit futures (funding rates, liquidations), Chainlink oracle
  2. Features — Compute 33 features: momentum (5 timeframes), technicals, order flow, cross-exchange signals, settlement bias, cross-asset divergence, funding rate signals, liquidation imbalance, cross-asset funding/liquidation divergence, time decay
  3. Predict — 16 weighted signals → P(YES) estimate with market-direction anchor and confidence score
  4. Edge — Compare model probability vs Kalshi implied probability, subtract fees, apply per-asset multipliers
  5. Filter — Phase gating, trend guard, edge persistence, zone filter, min price filter
  6. Risk — 9 independent safety checks with per-asset position limits
  7. Execute — Kelly-sized limit order if edge > threshold and all checks pass
  8. Monitor — Trailing take-profit, stop-loss, pre-expiry exit

Strategy Types

Strategy Assets Trigger Description
Directional BTC, ETH (BTC-beta led) net_edge > threshold for N consecutive cycles Model vs market probability mismatch
Market Making BTC, ETH (wider spread) Wide spread (5% BTC, 8% ETH) Resting limit orders to capture bid-ask spread
Settlement Ride BTC After 10 min elapsed, hold to settlement Late-window entry when implied prob is far from 0.50
Certainty Scalp BTC, ETH Last 3 min, 85%+ implied prob, spot past strike Large bet on near-certain outcome, hold to settlement
Monte Carlo BTC, ETH GBM simulation diverges from market 10K-sample simulation-based probability estimate

ETH directional is gated behind BTC beta override — requires BTC to show moderate directional momentum (|btc_beta_signal| ≥ 0.20) before ETH directional trades are allowed. Settlement rides are disabled for ETH.

Per-Asset Risk Profiles

Setting BTC ETH
Strategy Directional + MM + Settlement Ride Directional (BTC-beta led) + MM (8¢ spread)
Stop-loss 20% 20%
Max position 25 contracts 15 contracts
Max per cycle 15 contracts 10 contracts
Edge multiplier 1.0x 1.4x
Settlement ride Enabled Disabled
MM min spread

Phase-Gated Trading

Each 15-minute window is divided into 5 phases:

Phase Window Behavior
1. Observation 0–7 min No directional trades; record momentum direction
2. Confirmation 7–9 min Only trade if bounce-back from Phase 1 overreaction
3. Active 9–12 min Normal trading with full edge/confidence thresholds
4. Late 12–14 min Tightened thresholds (1.3x edge, +5% confidence)
5. Final 14–15 min No new entries — contracts are unpredictable near settlement

Entry Filters

  • Edge persistence — Require 2 consecutive cycles with same-side edge before entry
  • Trend guard — Block trades against unanimous multi-timeframe momentum
  • Min entry price — No entries below $0.25 (cheap contracts lose money)
  • Zone filter — Block expensive directional trades above $0.60
  • Quality score — Combined edge + confidence must exceed minimum threshold
  • Quiet hours — No directional trading 6 PM–5 AM EST (low-volume, consistently unprofitable)
  • Volatility regime — Block entries when realized vol exceeds threshold

Edge Calculation

model_prob = heuristic_model(features)     # 16-signal weighted sum, ±0.30 range
                                           # + market-direction anchor (30% blend)
market_prob = kalshi_midpoint              # e.g., 0.55
raw_edge = |model_prob - market_prob|      # 0.07
net_edge = raw_edge - fee_drag             # ~0.04
→ Trade if net_edge > min_threshold (5%) × asset_multiplier × zone_multiplier

Exit Management

Exit Type Trigger Description
Trailing take-profit Activate at +$0.08/contract, exit on $0.05 drop from peak Let winners run
Stop-loss 20% loss from entry Cut losers early
Pre-expiry exit 90 seconds before settlement Sell if PnL ≥ -$0.03/contract
TP cooldown 15 min after take-profit Block re-entry in same window

Risk Checks (all must pass)

  1. Balance ≥ minimum
  2. Daily P&L above loss limit
  3. Per-market position < cap (per-asset limits)
  4. Total exposure < cap
  5. Concurrent positions < limit
  6. Consecutive losses < streak max
  7. Trades today < daily limit
  8. Entry cooldown (30s between fills on same market)
  9. Time to expiry > 60 seconds

Position Sizing

Fractional Kelly Criterion with adjustments:

  • Per-asset caps: different max positions for BTC vs ETH
  • Zone scaling: better risk:reward zones → larger size
  • Time scaling: reduce size as expiry approaches
  • Vol regime: tighter sizing in high volatility
  • Per-cycle cap: max contracts per single order (per-asset)
  • Minimum position size: skip tiny positions below threshold

Dashboard

Real-time browser dashboard at http://localhost:8080 via Server-Sent Events (SSE).

Summary bar — Balance, Total P&L, Trades Today, Win Rate at a glance Per-asset tabs — BTC/ETH with independent market, price, prediction, and edge panels Live data — Countdown timer, price ticker with delta, 9 signal bars, orderbook stats Positions — Color-coded YES/NO with risk stats Settlements — Compact inline badges showing recent market outcomes Trade history — Per-asset with P&L coloring Features — Collapsible 33-feature grid Decision log — Last 15 cycle decisions


Configuration

All settings in config/settings.yaml:

Setting Default Description
mode paper paper or live
kalshi.environment prod demo or prod
strategy.poll_interval_seconds 4 Main loop interval
strategy.min_edge_threshold 0.05 Minimum edge to trade (5%)
strategy.confidence_min 0.62 Minimum model confidence
strategy.asset_edge_multipliers {ETH: 1.4} Per-asset edge penalty
strategy.asset_directional_disabled [ETH] Directional disabled (BTC-beta override still allows)
strategy.asset_settlement_ride_disabled [ETH] Settlement ride disabled per asset
strategy.asset_mm_min_spread {ETH: 0.08} Per-asset MM minimum spread
strategy.btc_beta_min_signal 0.20 BTC momentum threshold for ETH directional
risk.max_position_per_market 25 Max contracts per market
risk.max_total_exposure_dollars 500 Total capital at risk
risk.max_daily_loss_dollars 300 Daily loss stop
risk.max_concurrent_positions 5 Max open positions
risk.kelly_fraction 0.20 Kelly fraction for sizing
risk.asset_max_position {ETH: 10} Per-asset position caps
risk.asset_max_per_cycle {ETH: 10} Per-asset cycle caps

Per-Asset Config

kalshi:
  assets:
    - series_ticker: "KXBTC15M"
      symbol: "BTC"
      primary_ws_url: "wss://ws-feed.exchange.coinbase.com"
      primary_symbol: "BTC-USD"
      secondary_ws_url: "wss://ws.kraken.com/v2"
      secondary_symbol: "BTC/USD"
    - series_ticker: "KXETH15M"
      symbol: "ETH"
      # ...

Project Structure

├── config/
│   └── settings.yaml              # All configurable parameters
├── src/
│   ├── bot.py                     # Main orchestrator — 5 concurrent loops
│   ├── config.py                  # Pydantic settings with validation
│   ├── data/
│   │   ├── binance_feed.py        # WS price feeds (Coinbase/Kraken)
│   │   ├── binance_futures_feed.py # Bybit futures (funding rates, liquidations)
│   │   ├── chainlink_feed.py      # Chainlink on-chain oracle prices
│   │   ├── kalshi_client.py       # Kalshi REST client (markets, orders, balance)
│   │   ├── kalshi_ws.py           # Kalshi WS (orderbook deltas, fills)
│   │   ├── kalshi_auth.py         # RSA-PSS authentication
│   │   ├── data_hub.py            # Unified aggregator → MarketSnapshot
│   │   ├── market_scanner.py      # Active market discovery
│   │   ├── time_profile.py        # Historical kline profiling
│   │   ├── database.py            # SQLite persistence (async)
│   │   └── models.py              # Data models (Tick, Snapshot, Order, etc.)
│   ├── features/
│   │   ├── feature_engine.py      # Snapshot → 33 features
│   │   └── indicators.py          # RSI, BB, MACD, ROC, VWAP
│   ├── model/
│   │   ├── predict.py             # Heuristic model (16 signals → P(YES))
│   │   ├── calibrate.py           # Probability calibration
│   │   └── train.py               # LightGBM training pipeline
│   ├── strategy/
│   │   ├── signal_combiner.py     # Signal prioritization + settlement ride + certainty scalp
│   │   ├── edge_detector.py       # Model vs market edge calculation
│   │   ├── fomo_detector.py       # Contrarian retail panic detector
│   │   ├── market_maker.py        # Spread capture strategy (per-asset min spread)
│   │   ├── mc_detector.py         # Monte Carlo simulation strategy
│   │   └── averager.py            # Asymmetric pyramiding
│   ├── risk/
│   │   ├── risk_manager.py        # 9 safety checks
│   │   ├── position_sizer.py      # Fractional Kelly sizing
│   │   └── volatility.py          # Vol regime tracking
│   ├── execution/
│   │   ├── order_manager.py       # Order lifecycle (paper + live)
│   │   └── position_tracker.py    # Position state, exits, P&L
│   └── dashboard/
│       ├── server.py              # aiohttp SSE server
│       └── page.py                # Inline HTML/CSS/JS dashboard
├── backtest/
│   ├── data_collector.py          # Historical data collection
│   ├── backtester.py              # Strategy backtesting engine
│   └── analysis.py                # Performance analysis
├── scripts/                       # Utility scripts
├── data/                          # SQLite database + candle cache
└── pyproject.toml                 # Dependencies

Database Schema

Table Purpose
trades Completed trades (order_id, ticker, side, price, fees, pnl)
predictions Model predictions with features for backtesting
outcomes Market settlement results
ticks Raw price ticks for replay
daily_summary Aggregated daily P&L

Optional Extras

pip install -e ".[ml]"        # LightGBM model training
pip install -e ".[backtest]"  # Backtesting visualization
pip install -e ".[dev]"       # pytest, mypy, ruff

Testing

pytest tests/ -v
pytest tests/ --cov=src --cov-report=term-missing

API References

  • Kalshi REST: https://api.elections.kalshi.com/trade-api/v2/
  • Kalshi Demo: https://demo-api.kalshi.co/trade-api/v2/
  • Auth: RSA-PSS signatures (SHA256)
  • Docs: trading-api.readme.io/reference

About

15 min ETH/BTC Kalshi trading bot | Use at your own risk

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages