Building a Prediction Market Bot: Lessons from 30 Days of Paper Trading
We built KalshiBot to trade NBA prediction markets autonomously. Here's what 30 days of paper trading taught us about ladder strategies, anchoring logic, and why we just went live.
Building a Prediction Market Bot: Lessons from 30 Days of Paper Trading
Thirty days ago, we pointed an autonomous trading bot at Kalshi's NBA markets and told it to make money. It was running on paper — no real dollars at risk — but the lessons were very real. Last week, we flipped the switch to live trading. Here's what we learned.
Why Prediction Markets
Prediction markets are one of the most interesting proving grounds for autonomous systems. Unlike stock markets, prediction markets have binary outcomes (did the event happen or not?), bounded prices (0-100 cents), and known expiration times. This makes them tractable for algorithmic strategies while still being complex enough to be interesting.
Kalshi, the first CFTC-regulated prediction market exchange in the US, offers markets on everything from weather to economics to sports. We chose NBA markets as our starting point for a few reasons:
- High frequency: Games almost every day during the season
- Rich data: Decades of historical statistics, real-time odds from sportsbooks
- Known resolution: Games end, scores are final, markets settle
- Liquidity: NBA markets are among Kalshi's most active
The Architecture
KalshiBot is built as a modular agent system. The core components:
Data Engine: Pulls real-time NBA data — player stats, team rankings, injury reports, historical matchups. We aggregate from multiple sources and normalize into a unified schema. The data engine runs continuously, maintaining a live picture of every upcoming game.
Probability Model: Takes the data engine's output and produces probability estimates for each market. We started with a relatively simple approach — Elo-based ratings adjusted for home court, rest days, and injuries. Nothing fancy, but grounded in signal rather than noise.
Anchoring Logic: This is where it gets interesting. We don't just use our model's probabilities. We anchor against the market's current prices and external signals (Vegas lines, other sportsbooks). The key insight: our edge isn't in having a better model than everyone else. It's in identifying when the market's price diverges from the consensus.
If our model says 65%, Vegas says 63%, and Kalshi's market is trading at 58 cents — that's a signal. Not because we're smarter than Vegas, but because Kalshi's market might be thinner, less efficient, or slower to react.
The Ladder Strategy: Rather than placing single large orders, KalshiBot uses a ladder strategy. It places multiple smaller orders at different price levels, creating a "ladder" of bids and offers. For example, if we think the fair price for "Lakers to win" is 60 cents:
Buy 10 contracts @ 55¢
Buy 8 contracts @ 56¢
Buy 5 contracts @ 57¢
Buy 3 contracts @ 58¢
The ladder serves multiple purposes:
- Better average fill price — we accumulate a position gradually
- Reduced impact — no single order moves the market against us
- Passive liquidity provision — our resting orders earn the spread when they fill
- Natural position sizing — bigger position only if the price is more favorable
Risk Manager: Enforces position limits, daily loss limits, and correlation constraints (don't bet the entire bankroll on one night's games). This component has veto power over everything else.
Execution Engine: Interfaces with Kalshi's API to place, modify, and cancel orders. Handles rate limits, error recovery, and order state tracking. Surprisingly, this was the most tedious part to build — not because Kalshi's API is bad (it's decent), but because production-grade order management is just inherently fiddly.
What 30 Days Taught Us
The Model Is Table Stakes
Our probability model's accuracy improved from ~58% to ~64% over the first two weeks as we tuned features and fixed bugs. But here's the thing — even a perfect model doesn't guarantee profit. In prediction markets, you also need:
- Liquidity to actually trade at the prices you want
- Speed to react before prices move
- Discipline to not overtrade when there's no edge
We spent more time on execution quality than model quality. Getting fills at good prices matters more than being 1% more accurate.
Spread Capture Is Real
Our best returns came not from directional bets ("I think the Celtics win") but from providing liquidity — posting bids and offers on both sides and capturing the spread. On less liquid Kalshi markets, spreads can be 5-10 cents wide. Our bot could sit in the middle, buying at 55 and selling at 60, capturing 5 cents per round trip.
This surprised us. We built a directional trading bot and accidentally discovered that the better business is market-making. We've since added dedicated market-making logic to complement the directional strategy.
Paper Trading Lies (A Little)
Paper trading was invaluable for testing logic, catching bugs, and building confidence. But it lies about three things:
- Fills: In paper trading, your limit order always fills when price touches your level. In real markets, you might be behind 50 other orders in the queue.
- Impact: Your orders don't move the market in paper mode. In reality, placing a 100-contract order on a thin book absolutely moves the price.
- Psychology: Losing fake money feels nothing like losing real money. We knew this intellectually but still felt the difference viscerally when we went live.
The 3 AM Problem
NBA games on the West Coast tip off at 10 PM Eastern and can run past midnight. Our bot needs to be awake, monitoring, and executing during these hours. "Just run it on a server" sounds easy until you're debugging a stuck order at 3 AM because Kalshi's WebSocket disconnected during a game.
We learned to build robust reconnection logic, stale-data detection, and a dead man's switch that flattens all positions if the bot loses connectivity for more than 5 minutes. Autonomous systems that handle real money need to fail safe, not fail open.
Edge Decays Fast
The most profitable setup we found — anchoring against stale Kalshi prices when injury news breaks — works beautifully... for about 10 minutes. Then other participants reprice the market, and the edge evaporates. This means our execution speed matters enormously. Not HFT-level microseconds, but "react within a minute of news breaking" matters.
We built a news ingestion pipeline that monitors Twitter/X, team feeds, and injury report APIs. When a star player is ruled out, our bot reproices every affected market within seconds and aggressively takes mispriced contracts before the rest of the market catches up.
Going Live
Last Tuesday, we deployed KalshiBot with real capital. Starting small — $500 bankroll, strict daily loss limit of $50. The first three days:
- Day 1: +$12.40 (mostly spread capture on Nuggets/Clippers)
- Day 2: -$8.20 (directional bet on Bucks went wrong)
- Day 3: +$23.10 (caught a stale price after Embiid was listed as questionable)
Small numbers, but the system works. The bot placed 47 orders across 12 markets, with a fill rate of 68% and an average holding period of 3.2 hours. We're watching closely, ready to pull the plug if something breaks.
What's Next
The immediate roadmap:
- Expand to other sports — NHL markets are next, similar data availability
- Improve the anchoring model — incorporate more external signals
- Scale the market-making — this is where the consistent returns are
- Build a monitoring dashboard — right now we're tailing logs like cavemen
The bigger vision: KalshiBot is a proving ground for our approach to autonomous systems. The same architecture — data engine, probability model, decision logic, risk management, execution — applies to any domain where an agent needs to make decisions under uncertainty. Prediction markets just happen to be the domain where you get the clearest, fastest feedback on whether your agent is any good.
The Autonomous Edge is published by AnteMass. We build autonomous systems that operate in the real world. Follow us on X/Twitter for updates.