← All work Solo build · Mar–Apr 2026

Kalshi Weather Trading Bot

An automated trading system for Kalshi's daily high-temperature markets. It turns 139 weather-model forecasts into a probability, compares that to the market's price, and trades only when the gap survives fees and a stack of risk checks.

Role
Solo developer
Markets
Daily highs, 10 cities
Scale
~7,300 lines · 549 tests
Status
Ran live with real money

01The idea

Kalshi lists contracts like "Will Chicago's high today be 62°F or above?" that trade between 1¢ and 99¢. The price is the crowd's probability. Weather agencies publish something the crowd mostly ignores: ensemble forecasts, where each model is run dozens of times with slightly different starting conditions.

Counting how many of those runs land above the threshold gives a direct, data-driven probability. When that number and the market disagree by enough, there's a trade.

How one trade gets priced
Each dot is one of 139 ensemble members' forecast for the day's high. Based on a real fill the bot made: Chicago, April 4, high ≥ 62°F.
54°56°58°60°62°64°66°68°70°Forecast daily high, Chicago (°F)Market: high ≥ 62°F44 members below95 members above
Model probability68.3%
Market price38¢
Raw edge+30.3 pts
DecisionBuy YES
95 of 139 members reach 62°F, so the model says 68%. The market charged 38¢. That gap, net of the fee and slippage, is the edge.

02How it works

  1. Scan the marketsPulls every open daily-high contract through Kalshi's API and filters out wide spreads and contracts too close to (or too far from) settlement. It polls faster around the 00Z and 12Z model runs, when new forecasts land.
  2. Pull 139 forecastsFetches the GFS (30), ECMWF (50), ICON (39), and GEM (20) ensembles from Open-Meteo for each settlement station. Trades are blocked if fewer than 30 members are available.
  3. Turn them into a probabilityCounts the share of members above the threshold, applies a per-station, per-month bias correction, and grades confidence by how tightly the members agree.
  4. Find the edgeSubtracts Kalshi's taker fee and slippage from the probability-vs-price gap. It requires 4–10 points of edge depending on confidence, and the edge must clear 3× the fee. For unusually large edges, Claude does a sanity check before anything trades.
  5. Size and check riskQuarter-Kelly sizing, then 12 independent risk checks: exposure caps, a daily loss stop, resting-order limits, and automatic halts if calibration (Brier score) starts to slip.
  6. Execute patientlyPosts maker limit orders at the bid instead of crossing the spread, cancels stale orders after 30 minutes, and syncs fills and settlements to a local database.
Forecasts aren't neutral
Average model error by station and month (model high minus observed high, °F). The bot corrects each forecast before pricing it.
J
F
M
A
M
J
J
A
S
O
N
D
ATL
+0.5
+1.1
+1.8
+0.9
-0.3
+0.5
-0.2
+0.8
+1.1
+0.4
+0.7
+0.3
DCA
+1.8
+1.6
+1.1
+1.1
+2.1
+0.2
+1.0
+0.2
+0.7
+1.4
+1.8
+1.4
DEN
-0.1
-0.5
-0.7
-0.6
-0.9
+0.3
+0.1
+0.8
-0.4
-0.3
-0.5
+0.8
HOU
+2.6
+2.6
+2.3
+1.0
+2.1
+3.3
+3.0
+2.7
+2.7
+1.2
+2.3
+2.4
LAX
+3.4
+1.9
+0.2
+0.2
-1.1
0.0
-0.5
-1.2
-0.5
+0.4
+0.5
+2.1
CHI
+0.6
+1.2
+1.5
+0.1
+0.3
+0.6
+0.3
-0.7
+0.5
+0.8
+0.3
+1.1
MIA
+0.7
0.0
+0.6
-0.5
-0.5
+1.8
+1.3
+0.7
+1.2
+1.5
+0.6
+1.1
NYC
+1.6
+3.5
+0.6
+1.5
+1.1
-0.3
0.0
-0.8
+0.3
+0.6
+1.3
+1.8
PHX
+1.5
+0.8
+0.8
-0.1
+0.2
-0.1
+0.3
+0.3
+0.9
+1.4
+1.9
+2.0
SEA
-0.2
-0.6
-0.6
+1.3
+0.1
-0.6
-1.4
+0.1
+1.0
+0.3
-0.8
-0.9
Model runs warm Model runs cold
Houston forecasts run 2–3°F hot almost all year, and LA swings from +3.4°F in January to −1.3°F in August. On a 1°F threshold, that difference decides the trade.

03Running it live

6,100+signals evaluated and logged
139ensemble members per forecast
12risk checks before any order

The bot ran as a daemon on a VPS with real money and deliberately tiny limits (one contract per order, $15 max exposure, $3 daily loss stop). It also ran a two-arm experiment: a conservative arm placing real orders, and an exploratory arm with looser thresholds that only paper-traded, so I could compare strategies without paying to learn.

Most of the work after launch was the unglamorous part. Live trading surfaced stale orders, fill-sync gaps, and empty-book edge cases that never show up in a backtest. Each fix came with a test, which is how the suite grew to 549.

04Skills applied

  • Python (async)
  • Probabilistic forecasting
  • Ensemble weather models
  • Kelly criterion sizing
  • Risk management
  • Market microstructure
  • Calibration & Brier scoring
  • API integration
  • Claude API
  • pandas · NumPy · SciPy
  • pytest
  • VPS deployment
Next project

AI-Powered Web Design Agency

→