How Bandwagon reads prediction markets
Sources, de-vigging, matching, cadence, and the record against the model.
Market prices from Kalshi and Polymarket, shown for analysis. Bandwagon does not take or place wagers. How this works
What this is, and is not
Bandwagon shows and analyses prices that two prediction markets publish about sports. It does not trade, has no buy button and is not run by either market. Where a market is a Bandwagon partner, a line marked "Ad · Bandwagon earns a commission" links to it beside its prices; the prices, the gaps and the model are the same whether a market is a partner or not, and no partner pays for or changes them. "Kalshi" and "Polymarket" are the names of the markets being described. The numbers sit beside Bandwagon's own model (a rating-based probability from the results the site collects, its method) and the crowd's picks (people choosing a side in the app). Nobody is graded.
Sources
Only the operators' own public APIs: Kalshi's public market-data endpoints and Polymarket's public Gamma API. Nothing is taken from an odds aggregator or a sportsbook. Every row stores the source, the source's market id and the time it was read. Each request carries a User-Agent that names Bandwagon and a contact address, and the requests are spaced and counted (below).
| Market | API | Terms read | Status |
|---|---|---|---|
| Kalshi | https://api.elections.kalshi.com/trade-api/v2 | kalshi.com/legal/terms 2026-10-28 · Public market-data endpoints need no key (docs.kalshi.com quick start: market data). The terms page itself was not retrievable when read (HTTP 429); review before launch. | reading |
| Polymarket | https://gamma-api.polymarket.com | polymarket.com/tos 2026-10-28 · Gamma is public and unauthenticated. The Terms (s.4.2) bar scraping tools on the site and require a written agreement for market-data distributors; they do not license API data. Owner decision recorded in docs/MARKETS.md. | reading |
From a price to a probability
The price. The source's own displayed probability for "yes": the midpoint of the best bid and ask when both are quoted and within ten cents of each other, otherwise the last trade. A market with no quote and no trade has no price and is not shown.
De-vig. The prices of a game's mutually exclusive results (home and away, plus the draw in soccer) are divided by their sum so they add to 100%; the sum minus one, the overround, is stored with the number. A soccer game missing a result is not published, because normalizing a partial set would hand the missing result's share to the others. Outside soccer, a single side's price stands as it is with the other side as its complement, and the number is marked not de-vigged. Season-long markets are shown at their raw price: a field of outcomes quoted in whole cents adds to a little over 100%, and the page says so rather than hiding it.
Time. Every market number is shown with the time its price was read, US Eastern. Games show the price from the last pass before kickoff as the closing price once they are final.
Matching a market to a game or team
A market is shown only when it maps. A game market maps when both teams resolve to exactly one catalog team each, by name, short name, abbreviation, alias or a city that only one team in the league uses, and exactly one game between them starts near the time the market gives. High confidence means every name matched a catalog name and the start times agreed closely; medium means a team was found by its city alone, by the reviewed override file, or the start times were further apart. Anything else is unmapped: kept, logged once with the reason, never shown and never guessed (FCS and lower-division opponents that are not in the catalog are the common case). Fixes are lines in a reviewed file in the repository.
| Market | Kind | Mapping | Markets |
|---|---|---|---|
| Kalshi | award | high | 609 |
| Kalshi | cricket match | high | 130 |
| Kalshi | futures champion | high | 185 |
| Kalshi | futures champion | medium | 155 |
| Kalshi | futures champion | unmapped | 15 |
| Kalshi | futures win total | high | 42 |
| Kalshi | futures win total | medium | 600 |
| Kalshi | game winner | high | 162 |
| Kalshi | game winner | medium | 518 |
| Kalshi | game winner | unmapped | 388 |
| Polymarket | award | high | 889 |
| Polymarket | cricket match | high | 90 |
| Polymarket | futures champion | high | 252 |
| Polymarket | futures champion | medium | 5 |
| Polymarket | futures champion | unmapped | 15 |
| Polymarket | futures win total | high | 31 |
| Polymarket | game winner | high | 535 |
| Polymarket | game winner | medium | 210 |
| Polymarket | game winner | unmapped | 207 |
How often it is read
Games starting within 48 hours are read every ten minutes; everything else, including the season-long markets, the award markets and the check for resolved markets, hourly. A price is stored on every read; the per-game probability is stored when it moves by half a point or an hour passes. The requests each pass spends, measured from the run log over the last two days:
| Market | Pass | Runs, last 2 days | Requests per run | Most in one run |
|---|---|---|---|---|
| Kalshi | award | 29 | 8 | 13 |
| Kalshi | full | 59 | 16 | 54 |
| Kalshi | near | 245 | 8 | 37 |
| Kalshi | resolve | 48 | 0 | 1 |
| Polymarket | award | 18 | 13 | 13 |
| Polymarket | full | 48 | 17 | 32 |
| Polymarket | near | 245 | 7 | 14 |
| Polymarket | resolve | 48 | 7 | 9 |
The record: market against model
Every night each resolved game is scored. The market's number is its last de-vigged probability from the day before kickoff to kickoff; the model's is its last stored line before kickoff; both are scored on the event "the home side wins" (a draw counts as not winning), with Brier score, log loss and how often the favored side won, on the same games. Resolved season-long markets are scored on their price a week before they resolved; the model has no title probability, so those rows are the market's alone. The record is published as it stands, including where the market is better than the model.
- The model beat Kalshi's closing price in College football over 53 games (Brier 0.1665 against 0.1499, lower is better).
- The model beat Polymarket's closing price in College football over 53 games (Brier 0.165 against 0.1499, lower is better).
- Kalshi's closing price beat the model in Premier League over 10 games (Brier 0.2498 against 0.2711, lower is better).
- Polymarket's closing price beat the model in Premier League over 10 games (Brier 0.2509 against 0.2711, lower is better).
- Kalshi's closing price beat the model in NBA over 39 games (Brier 0.2015 against 0.227, lower is better).
- Polymarket's closing price beat the model in NBA over 39 games (Brier 0.2032 against 0.227, lower is better).
- Kalshi's closing price beat the model in NFL over 14 games (Brier 0.1794 against 0.1855, lower is better).
- Polymarket's closing price beat the model in NFL over 14 games (Brier 0.1786 against 0.1855, lower is better).
- Kalshi's closing price beat the model in NHL over 44 games (Brier 0.2225 against 0.2299, lower is better).
- Polymarket's closing price beat the model in NHL over 44 games (Brier 0.2235 against 0.2299, lower is better).
| League | Games | Who | n | Brier | Log loss | Straight-up |
|---|---|---|---|---|---|---|
| College football | Kalshi games | Kalshi price | 53 | 0.1665 | 0.5027 | 79% |
| College football | Kalshi games | Bandwagon model | 53 | 0.1499 | 0.4789 | 81% |
| College football | Polymarket games | Polymarket price | 53 | 0.165 | 0.4988 | 79% |
| College football | Polymarket games | Bandwagon model | 53 | 0.1499 | 0.4789 | 81% |
| Premier League | Kalshi games | Kalshi price | 10 | 0.2498 | 0.6932 | 50% |
| Premier League | Kalshi games | Bandwagon model | 10 | 0.2711 | 0.7348 | 60% |
| Premier League | Polymarket games | Polymarket price | 10 | 0.2509 | 0.695 | 50% |
| Premier League | Polymarket games | Bandwagon model | 10 | 0.2711 | 0.7348 | 60% |
| NBA | Kalshi games | Kalshi price | 39 | 0.2015 | 0.5823 | 67% |
| NBA | Kalshi games | Bandwagon model | 39 | 0.227 | 0.6406 | 62% |
| NBA | Polymarket games | Polymarket price | 39 | 0.2032 | 0.5861 | 67% |
| NBA | Polymarket games | Bandwagon model | 39 | 0.227 | 0.6406 | 62% |
| NFL | Kalshi games | Kalshi price | 14 | 0.1794 | 0.5398 | 79% |
| NFL | Kalshi games | Bandwagon model | 14 | 0.1855 | 0.5524 | 64% |
| NFL | Polymarket games | Polymarket price | 14 | 0.1786 | 0.5381 | 71% |
| NFL | Polymarket games | Bandwagon model | 14 | 0.1855 | 0.5524 | 64% |
| NHL | Kalshi games | Kalshi price | 44 | 0.2225 | 0.6353 | 58% |
| NHL | Kalshi games | Bandwagon model | 44 | 0.2299 | 0.6514 | 59% |
| NHL | Polymarket games | Polymarket price | 44 | 0.2235 | 0.6373 | 59% |
| NHL | Polymarket games | Bandwagon model | 44 | 0.2299 | 0.6514 | 59% |
The model's numbers are on the same games the market was scored on. 0.25 Brier and 0.693 log loss are a coin flip.
What it does not tell you
A market price is a crowd of traders' view with their own fees and positions; it is not a fair price, a forecast Bandwagon vouches for or a recommendation. Thin markets move on small trades; the liquidity and volume the source reports are shown where they exist. Method version 1.0; the code is in the repository (docs/MARKETS.md).
Where Bandwagon's Kalshi and Polymarket prices come from, how they are de-vigged and matched to games and teams, how often they are read, and the running record of market versus model. Market prices from Kalshi and Polymarket, shown for analysis. Bandwagon does not take or place wagers.