High-frequency trading engine for Kalshi prediction markets, built in Rust for low-latency real-time execution.
rust_kalshi connects to Kalshi's WebSocket feed, maintains a local order book, and runs multiple trading strategies in parallel. It detects price dislocations, momentum waves, and structural arbitrage opportunities across thousands of markets — then executes in milliseconds.
| Strategy | Description | Approach |
|---|---|---|
| Momentum Rider | Detects accelerating price moves and rides the wave | Buys in the direction of momentum while it's building |
| Surge Reversion | Identifies overreactions after momentum stalls | Fades the move once deceleration is detected |
| Sum-to-100 | Finds events where outcome prices sum below 100¢ | Buys underpriced outcomes for structural profit |
| Cross-Strike | Detects monotonicity violations across ordered strikes | Exploits adjacent strike dislocations |
| Volatility Scanner | Flags high-volatility tickers across all markets | Surfaces opportunities for other strategies |
WebSocket Feed ──→ Local Order Book (DashMap) ──→ Strategy Engine ──→ Risk Manager ──→ Executor
│ │ │ │ │
Real-time Lock-free 5 strategies Kelly sizing REST API
ticker data concurrent reads in parallel + limits or paper
- Rust 1.75+ (install via rustup)
- Kalshi API credentials (API key + RSA private key)
Copy the example environment file and fill in your credentials:
cp .env.example .envKALSHI_API_KEY_ID=your-api-key-id
KALSHI_PRIVATE_KEY_PATH=/path/to/private-key.pem
KALSHI_ENV=prodThe bot will also check ../kalshiweather/.env as a fallback.
# Build
cargo build --release
# Check your balance
cargo run --release -- balance
# Discover the most active markets
cargo run --release -- discover --min-vol 1000 --top 50
# Paper trade with $1,000 virtual balance
cargo run --release -- run --dry-run --min-vol 50 --max-markets 200 --interval 5
# Scan only (no orders, just signals)
cargo run --release -- run --scan-only --min-vol 50 --max-markets 200
# Live trading (real money)
cargo run --release -- run --min-vol 100 --max-markets 200 --interval 5| Command | Description |
|---|---|
balance |
Display account balance |
markets --series KXNBA --min-vol 100 |
List markets filtered by series and volume |
market <TICKER> |
Show market detail with order book |
discover --min-vol 1000 --top 50 |
Find the most active tradeable markets |
run [flags] |
Start the trading engine |
| Flag | Default | Description |
|---|---|---|
--scan-only |
false |
Print signals only, no orders |
--dry-run |
false |
Paper trade with $1,000 virtual balance |
--min-vol |
100 |
Minimum volume for market inclusion |
--max-markets |
500 |
Maximum markets to watch |
--interval |
5 |
Strategy evaluation interval (seconds) |
--series |
all | Comma-separated series filter (e.g., KXNBA,KXBTC) |
The bot fetches markets from a curated set of high-activity series spanning politics, sports, crypto, economics, and more. Markets are filtered by volume and price (excluding settled/boundary-priced contracts).
Connects to Kalshi's WebSocket v2 API with RSA-PSS authentication. Subscribes to ticker channels in batches of 100, handles ping/pong heartbeats, and auto-reconnects with exponential backoff on disconnection.
Every N seconds (configurable), all strategies evaluate the current order book state:
-
Momentum Rider tracks rolling price history per ticker. When a move exceeds 5¢ in 3 minutes and is accelerating (second half faster than first), it signals to buy in the direction of the move.
-
Surge Reversion uses a higher threshold (10¢ in 5 minutes) and opposite logic — signals only when momentum is decelerating, betting on mean reversion.
-
Sum-to-100 groups markets by event and checks if YES prices sum below 96¢. Only signals when it has the complete set of outcomes (prevents false positives from partial data).
-
Cross-Strike sorts markets by strike value within an event and checks for non-monotonic pricing between adjacent strikes.
- Quarter-Kelly position sizing
- Maximum 25 contracts per ticker
- Maximum 20 simultaneous positions
- $50 max total exposure
- 6-hour settlement proximity filter (skip markets expiring soon)
- Drawdown stop at 20% of balance
--dry-run mode starts with a $1,000 virtual balance and fills orders at actual book ask prices. The status line shows mark-to-market P&L every 30 seconds, with per-position breakdowns.
src/
main.rs CLI entrypoint (clap)
config.rs Environment configuration
types.rs Market, Signal, Order types
auth.rs RSA-PSS SHA-256 API authentication
client.rs REST client (markets, orders, balance, events)
websocket.rs WebSocket manager with auto-reconnect
orderbook.rs DashMap-backed concurrent order book
scanner.rs Main event loop + market discovery
state.rs Runtime position and balance tracking
risk.rs Kelly sizing and exposure limits
execution.rs Signal-to-order conversion
ticker.rs Ticker string parsing
strategies/
mod.rs Strategy trait definition
momentum.rs Momentum wave rider
surge.rs Surge reversion (mean reversion)
sum_to_100.rs Multi-outcome structural arbitrage
cross_strike.rs Adjacent strike dislocation
volatility.rs Rolling volatility scanner
Uses RSA-PSS (SHA-256) with maximum salt length for API request signing, matching Kalshi's specification. The signing message format is {timestamp_ms}{METHOD}{path} where path includes the full API prefix /trade-api/v2/....
Private. All rights reserved.
