Mispricd
Menu
Method

No black box. This is exactly how the desk works.

Every number on this site is computed by a fixed, documented pipeline from public data: Kalshi's quotes and order books, the settlement stations' observations, Polymarket's fills, and the venues' own results. The code runs under tests, and this page is the pipeline end to end: every rule, every threshold and every database view the pages read.

Glossary

The terms the pages use, in a sentence or two.

Book
Kalshi's order book on a bracket. The robot pulls it for brackets priced between 60c and 95c, for the size within two cents of the ask, and for every dead bracket on every pass, for the queue. 01
Calls
A dated, falsifiable statement with our probability stated before the fact and the exact command that decides it. On the grading date the command is run and its tag flips to hit or miss; the calls are scored by the Brier score, where 0 is perfect and 0.25 is a coin flip. 06
Dead bracket
A bracket the station's reading has ruled out: its confirmed running high, the extreme confirmed by a second reading, has cleared the bracket's top by a full degree (on a low ladder, the confirmed running low has cleared its bottom). 02
Favorite rule
One fixed rule, tested with no discretion: the first time a bracket's midpoint sits between 65c and 90c in a regime, the rule enters Yes at the ask that was resting at that read, pays Kalshi's taker fee and holds to settlement. Each entry is scored per contract. 03
Fee
Kalshi's taker fee, from its schedule: ceil(7 · m · p · (1 − p)) cents at price p, paid on every entry of the favorite rule. The multiplier m is Kalshi's per series: 1 on the temperature ladders and on every game series here but MLB's, which Kalshi set to 0.5 from 2026-08-07 (read from Kalshi's API on 2026-10-21; until then the games page charged MLB the full fee). 03
Intervals
Day-clustered bootstrap intervals on the favorite rule's results, added offline by agents/exp_favorites.py; the scorecard does not compute them, and they decide nothing until there are weeks of settled entries. 03
Paper mirror
For each ranked wallet, a copier who saw each fill as it appeared publicly, waited sixty seconds or five minutes and paid the next ask that printed on that outcome; it measures the cost of arriving second, in cents a share. No order is placed. 07
Queue
On a dead bracket, the Yes asks resting at one cent (and at or under two cents, at or under five, and in total), recorded from the order book on every pass. 04
Refresh
Postgres (pg_cron) refreshes the views every hour at :50, about fifteen minutes after the logger's pass, so a number on the site shows the latest pass within a quarter hour of it. The board is one of those views: the latest read of every bracket in the last six hours, as of the latest refresh. A refresh that runs out of time on a slow night leaves the rest for the next hour. 05
Settlement
Kalshi settles each daily high and low market on The Weather Company's reported maximum or minimum for the station its rules name, from the markets of 2026-08-14; through 2026-08-13 it settled on the National Weather Service's Daily Climate Report for that station. The robot's markets are graded on Kalshi's own result. The dead call reads the station's public National Weather Service observations, so a disagreement between the two would show up as an observation miss. 02
01 · The robot on the ladders

Every open bracket, every hour, with no opinion.

The ladder logger (agents/kalshi_ladder_logger.py) has no forecast and no model. Once an hour it walks every daily-high and daily-low temperature ladder Kalshi lists, about forty ladders across twenty cities, and writes one row per open bracket: the best bid and ask in cents, the last trade, volume and open interest, and the contracts resting at the best bid and ask, all from Kalshi's own public market payload at the moment of the read.

The order book, the three regimes

For brackets priced between 60c and 95c it also pulls the order book, so the size within two cents of the ask is known too.

Each row is tagged with the regime it was read in, because the same price means different things at different times:

forecast
The day before settlement.The ladder is open, the station has recorded nothing yet, and the price is a forecast.
intraday
The settlement day, while the bracket is still possible.The station has recorded part of the day; the price is a forecast conditioned on it.
locked
Ruled out by the observation (section 02).The day can no longer settle this bracket Yes; what is left on it is the queue and any stale bid.

About ten thousand rows a day (9,600 to 14,800 on each full day since 2026-09-19). The row's shape is documented at the top of the logger, and DEPLOY.md lists everything that has to run.

02 · The observation and the dead call

When the day has already decided.

Each ladder settles on one station's daily maximum or minimum, the station its market's rules name: as reported by The Weather Company for the markets of 2026-08-14 on, and by the National Weather Service's Daily Climate Report through 2026-08-13.

The reading, the margin, the score

The robot reads that station's hourly observations through the day and keeps the running extreme two ways: the single most extreme reading, and the extreme confirmed by a second reading, which is what the call uses. A bracket is dead once the confirmed running high has cleared its top by a full degree (or, for a low ladder, the confirmed running low has cleared its bottom). "Cleared by a full degree" is the margin that keeps the settlement report's rounding and the occasional revised observation from turning a dead call into a live one.

The call is written into the row with the readings behind it, so it can be audited later: the raw and the confirmed extreme, how many readings, how far the bracket was cleared by, and the time of the latest reading. And it is scored: a bracket called dead that settles Yes anyway is the observation feed's error, counted on the scorecard and in the record on the data page. The count is small because the margin is generous; it is never assumed to be zero.

The settlement source, read 2026-10-21. On 2026-09-29 this note said that Kalshi had announced a partnership with The Weather Company in August 2026 and that published reports disagreed about which series had moved to it and from when. Kalshi's own market data answers it. The daily high and low series now name The Weather Company as their settlement source (weather.com/kalshi), and each market's rules read, for example, "the maximum temperature recorded at New York City (CLINYC) … according to The Weather Company". The change came with the markets for 2026-08-14, listed on 2026-08-13: in the New York and Chicago high ladders and the Denver low ladder, the markets for 2026-08-13 name the National Weather Service's Daily Climate Report and those for 2026-08-14 name The Weather Company. The station is the same, and the rules still name it. The dead call still reads that station's public National Weather Service observations. The robot's markets are graded on Kalshi's own result, so a disagreement between the two shows up as an observation miss; the front page counts them.

03 · The favorite rule and the fee

Scoring the likely bracket at the price that was really there.

The favorite-longshot bias is the claim that likely outcomes are underpriced. The desk tests it with one fixed rule and no discretion: the first time a bracket's midpoint sits between 65c and 90c in a regime, the rule is scored as one Yes contract at the ask that was resting at that read, plus Kalshi's taker fee, held to settlement.

Scoring, the fee and the size

The entry is scored per contract: a winner earns one dollar less the ask and the fee, a loser loses the ask and the fee. The fee is Kalshi's schedule, ceil(7 · p · (1 − p)) cents at price p.

Capacity matters as much as sign. Every entry records the contracts that were resting at that ask, because a rule that makes six cents a contract on seventeen contracts a day is worth a dollar. The scorecard shows the median size and the dollars a week the rule could have bought at the ask; the offline scripts (agents/exp_favorites.py) add day-clustered bootstrap intervals, which the page does not compute and which decide nothing until there are weeks of settled entries.

Hypothetical results · the capacity exampleThese results are based on simulated or hypothetical performance results that have certain inherent limitations. Unlike the results shown in an actual performance record, these results do not represent actual trading. Also, because these trades have not actually been executed, these results may have under- or over-compensated for the impact, if any, of certain market factors, such as lack of liquidity. Simulated or hypothetical trading programs in general are also subject to the fact that they are designed with the benefit of hindsight. No representation is being made that any account will or is likely to achieve profits or losses similar to these being shown.
04 · The queue at one cent

Who collects the cent on a dead contract.

On a dead bracket the only trade left is a Yes seller taking a cent from a Yes bidder, or a No buyer at 99c, which is the same trade seen from the other side.

What is recorded on a dead bracket

The robot pulls the order book of every dead bracket on every pass and records the queue: the Yes asks resting at one cent, at or under two cents, at or under five, and in total; and whether any Yes bid at three cents or better is still resting on a bracket the day has ruled out, which the scorecard counts week by week. The median queue at one cent is the number on the front page, and the piece Who collects the cent on a dead contract reads the exchange's own trade tape from the moment a bracket dies to the close, with agents/backfill_tape.py.

05 · The scorecard, the board and the numbers

Computed in the database, never typed in.

views

SQL files in the desk's repository build everything the public pages show as a live number: research_views.sql (the favorite rule's entries and the logger's health), scorecard_views.sql (the weekly scorecard), board_views.sql (the live board and the site's stats), retention.sql (the all-time counts that outlive the raw rows), studies.sql (the studies' tables and views), cities_views.sql (each city's record), days_views.sql (the days' box scores), games_schema.sql (the games) and game_lines.sql (the games' margins and totals). They are views over the logger's rows and the outcomes table, readable with the public key.

Refresh, retention, settlement
refresh

Postgres (pg_cron) refreshes them every hour at :50, about fifteen minutes after the logger's pass, so a number on the site shows the latest pass within a quarter hour of it; a refresh that runs out of time on a slow night leaves the rest for the next hour. The board is one of those views: it shows the latest read of every bracket in the last six hours, as of the latest refresh; if the robot stops, the board empties and the front page's chip says how long it has been quiet, from the heartbeat row the logger writes after every pass.

retention

Raw reads are kept for twenty-eight days (thirty-five until 2026-12-03: the first calls were graded from one complete export, and call C-013 is graded on 2026-12-02 from an export of the raw reads back to 2026-11-01); a month of them is about what the free database holds. Before a row ages out, everything the site scores from it has been copied into permanent tables (retention.sql): the favorite rule's entries with their results, one row per bracket the robot read (first and last read, whether the observation ever ruled it out and the first read that did, the first read whose midpoint was 90% or more while both a bid and an ask were resting, and the station's confirmed running extreme at its last read, with the reading's time), one row per day of reads, and each week of the scorecard, frozen once its rows are gone. The scorecard, the receipts and the front page's all-time counts read those tables, so the record outlives the rows it came from.

settlement

Kalshi's own result settles every market, recorded once per ticker and day. The scorecard's weeks are ISO weeks of the market date. Only settled entries carry a P&L; open ones are counted, not scored.

Sources: page, view, SQL, job
Each public page, the view it reads with the public key, the SQL file that defines it, and what fills it
PageView it readsDefined inFilled by
Board, Data, Home, Deskboard_public (each bracket's latest read in the last six hours), scorecard_site_statsboard_views.sqlthe ladder logger (agents/kalshi_ladder_logger.py), hourly; board_public is a plain view over the hourly snapshot; the views refresh every hour at :50 (pg_cron)
Data, Home, Deskheartbeatsheartbeat_migration.sqlthe worker (agents/logger_main.py), after every pass
Scorecard, Receipts, Data, Homesite_totalsretention.sqlpersist_scorecard(), at every refresh: the permanent tables the view adds up
Scorecard, Receipts, Data, Homescorecard_weeksretention.sqlpersist_scorecard(), from the favorite rule's entries and the weekly view in scorecard_views.sql
Calibrationcalibration_bins, calibration_daysretention.sqlpersist_scorecard(), which keeps one read per market 24, 12, 6 and 1 hours before its day ends (calib_reads)
Calibration, Receipts, Data, Homecalibration_scoresretention.sqlthe same reads (calib_reads), scored against the outcomes
Citiescity_days, calibration_city_days, leader_city, timing_by_city: counts, sums over a ladder and times, by citycities_views.sqlthe permanent tables persist_scorecard() fills (each bracket once, with its first 90% read and first ruled-out read; the calibration reads); calibration_city_days is refreshed with the other views
Daysday_totals, day_ladders: each settled market day and each of its laddersdays_views.sqlplain views over the permanent tables persist_scorecard() fills, plus the outcomes
Studiesstudy_clock, study_nickels, study_nickel_misses, study_ladder_sums, study_leaderstudies.sqlpersist_studies(), inside persist_scorecard()
Games, Calibration, Data, Homegames_publicpublication_hardening.sql, a view over game_numbers (games_schema.sql)agents/game_numbers.py, every pass
Gamesgame_lines_public (margins and totals)game_lines.sqlagents/game_lines.py, every pass; the finals from Kalshi's live data
Gamesgame_days_public, games_open_vs_linegames_record.sqlpersist_game_days(), inside persist_scorecard() and after the worker settles a game: one permanent row per series and market day
Whale finder, Studies, Data, Homepoly_wallets, published rows onlywhales_schema.sqlagents/whale_finder.py, weekly
Deskdesk_events_public (the last 30 days of the desks' events, counts and kinds only)desks_schema.sqlagents/desk_events.py, at the end of every pass and as each desk works
Callsno view: calls.js, a file in the site—by hand: a call's result is pasted in on its grading date

The refresh is refresh_research_views(), run by pg_cron every hour at :50; the logger can run it too (RESEARCH_REFRESH), and by default does not. research_views.sql builds the favorite rule's entries, which persist_scorecard() copies into favorites_entries; its own views are read only on the owner's sign-in pages.

06 · The calls

A probability, a rule, a date. Then the result.

A call is a dated, falsifiable statement about what the data will show, with our probability stated before the fact and the exact command that decides it.

Grading, studies, the Brier score

On the grading date the command is run on a fresh export of the database, or on the permanent tables it reads, the result is pasted into the call, and its tag flips to hit or miss. From C-007 on, each call is one of the studies: a question posted before its window opened, graded only on the markets after the posting, with what was measured before shown beside it and never pooled. A call is never edited after it is posted; if a rule turns out to be ambiguous it is graded against us. The score is the Brier score over graded calls, the mean of (probability − outcome)², where 0 is perfect and 0.25 is a coin flip. The calls page keeps them all, misses included.

07 · The whales

Decoded from their own fills, not from a leaderboard.

A Polymarket wallet's fills are public. The desk pulls every one (agents/wallet_trades.py), resolves every market it traded against the venue's own result, and scores each fill: what was paid, what it settled at, how long it was held.

The whale finder, the paper mirror

That is enough to say what the strategy actually is, where it wins and where it loses, without reading a single post about it. The first piece, The boring strategy that printed, decoded, is 9,030 fills read this way; its hold times, not its entry prices, are what identify it as an observation bot. The same method applies to any public wallet, and the desk's calls include one about that wallet's next month.

The whale finder applies it to every wallet at once: each week it lists every temperature event on Polymarket over the last two weeks, pulls every taker fill of every market, groups them by wallet, scores each with the same first-in first-out rule and labels it from its fills alone (an observation bot buys on the market's day and sells within the hour; a tail seller is long No on the tails and holds; the thresholds are printed on the page). For the wallets that rank it runs the paper mirror: a copier who saw each fill on the public feed, waited sixty seconds or five minutes, and paid the next ask that printed on that outcome, holding to resolution or copying the exit. No order is placed. The mirror measures the cost of arriving second, in cents a share, on the wallet's own buys. One wallet contributes too few buys to decide anything, so the figures that count are pooled by profile, every wallet of a kind added together.

08 · The desk that started this

A forecast desk, scored against the price, closed.

From July 24 to September 8, 2026, the site was a forecast desk: NWS guidance fitted into a probability for every Kalshi temperature contract, compared with the price, published when they disagreed, and scored after settlement head to head with the price on the same markets. Seven weeks and 11,427 settled markets later the price had won on every cut, and a closing research note tested every NWS resource the desk had not used; none beat the price either.

When it closed, and its record

The desk was closed on September 17, 2026, and its record is on the receipts page. The logger that had been reading the ladders beside it, with no model, is the robot this site runs on now.

09 · What this is not

Descriptive, never prescriptive.

Mispricd is an information publication. It measures prediction markets and publishes what it finds with the sources and the timestamps, and most of what it finds is that an edge belongs to someone else: a market maker's queue, a bot's observation feed, a spread that eats the signal. It does not recommend trades, size positions, manage risk, execute orders or hold funds, and it never tells you what to bet. What you do with a measurement is entirely your call.

10 · Corrections

What we got wrong, and when it was fixed.

A figure that was wrong is corrected where it stands and listed here with the date. A posted call is never edited; a call's own record is on the calls page.

  • 2026-10-21 · The settlement source. Kalshi settles its daily high and low markets on The Weather Company's reported maximum or minimum for the station its rules name, from the markets of 2026-08-14; through 2026-08-13 it settled on the National Weather Service's Daily Climate Report. The receipts page said the forecast desk was scored against the same climate report the market settles on, which held only through 2026-08-13: the desk was scored on the National Weather Service's report throughout, so from 2026-08-14 to 2026-09-08 its record is graded on the government's report for the same station, not on Kalshi's source. The research page said the favorite rule's entries settle when the National Weather Service's climate report lands; they settle when Kalshi settles them. Section 02 had said only that some series might have moved. All three now say what Kalshi's own data shows. The pieces stand as published and use the desk's grading for those weeks: Piece 01's Kalshi table has Miami's low on September 1 "settled 75", Piece 02 has two dead brackets that "settled Yes" (New York's high on August 27, Boston's on August 30) and a $1,423 loss on Boston's inside its net of $608 a day, and the scorecard and the research page give the favorite rule's 47 days of history as +6.1c a contract. Against Kalshi's own results, read on 2026-10-21, Miami (75) and New York (77) agree and Boston does not: Kalshi settled that high at 86, the running reading the piece cites, not the report's 83, so the 82–83° bracket settled No and the $1,423 loss comes from the report, not from Kalshi; the other dead brackets and favorite-rule entries from 2026-08-14 to 2026-09-08 were not re-graded market by market.
  • 2026-10-13 · Games graded on a price read during play. The games record grades the line and the pick at the desk's last hourly read before a game's start. Until this correction the start it used was an estimate: the ticker's own time where the ticker carries one (baseball), else three hours before Kalshi's occurrence time, else the end of the game day, and none of the three is certain. Kalshi publishes its own schedule for the games it lists, and against it the desk's line for 27 of the 573 games settled with a winner from 2026-09-26 to 2026-10-12 was read at or after the game began (22 in college football, 4 in baseball and 1 in the NFL; 23 of the 27 had a usable line and 22 a pick). Kalshi lists CHI at GB on Oct 11 for 1 pm ET, where the desk's start was 4:25 pm, and LAD at MIL on Oct 12 for 5 pm ET, where the ticker said 8 pm; in the baseball games Kalshi's own hourly trading confirms play had begun before the read. Those 27 games now show as "not graded: the start used was late" and count in no tally, and every day of the record from 2026-09-26 was recomputed. From now on the start is the one Kalshi lists, and every game is checked as it settles; a game Kalshi lists no start for is not graded when Kalshi closed its market less than 2.5 hours after the start used in football, 2 in the NBA and the NHL or 1.5 elsewhere. Measured on 2026-10-13, before the correction and after it: the favourite at the line won 319 of 495 and 301 of 472; the pick was right 316 of 487 and 299 of 465; the numbers were right 318 of 573 and 304 of 546.
  • 2026-10-06 · The 90% clock on a one-sided book. The time a ladder's winning bracket first had a midpoint of 90% or more (the cities page's "when the day is decided") counted every read, and on a book with no ask the midpoint averages the bid with 100: a bid of 80 and nothing offered read as 90%, a price nobody could pay. The clock now counts a read only while both a bid and an ask were resting, the rule the calibration page already used, and every bracket whose reads were still kept was recomputed under it (measured on 2026-10-06: 145 of the 701 times then kept moved later or cleared).
  • 2026-10-03 · The tail brackets' labels. Each ladder's two tail brackets were labelled into their neighbours. The board printed a bottom tail such as T61 as "≤61°" and a top tail such as T71 as "≥71°", and the front page's tape printed every tail as "≥". Kalshi titles them "<61°" (60° or below; the bracket above it starts at 61°) and ">71°" (72° or above), and that is how they read now. Piece 02's chart of the one-cent queue labelled its ruled-out tails "≤" too: the high ones, such as Phoenix "≤91", are bottom tails ("<91°"), and the low ones, such as Denver "≤57", are top tails (">57°"), because a day's running low can only rule out the brackets above it. Only the labels were wrong: the counts, and the ruled-out verdicts, always used the right bounds.
  • 2026-09-29 · The front page's all-time counts. The permanent rollup that outlives the raw rows added up counts made one day at a time. A bracket's reads span two or three days, so ladders and ruled-out brackets were counted more than once, and a bracket was counted as ruled out and settled only when a read from its first day of reads was already ruled out, which was true of 52. The tile read "0 of 52 dead brackets settled"; counted once per bracket it is 0 of 553. No ruled-out bracket settled Yes under either count. The rollup now keeps one row per bracket.
  • 2026-09-29 · "The code is in the open." The front page and this page said the code was public. The desk's repository is private. They now say what is true: the code runs under tests, and this page sets out every rule.
  • 2026-09-29 · Polymarket and US persons. Piece 03 said US persons cannot trade Polymarket. That holds for the international exchange the piece measured, but Polymarket has since opened a separate, CFTC-regulated exchange for US customers. The piece now says so.
  • 2026-09-29 · An open call's interim figure. The symbols page quoted an interim result for call C-001, which is graded on 17 October. It now points to the live figure instead.