Skip to content
Kalshi Eye

Kalshi vs Polymarket data: what differs

Kalshi and Polymarket both run binary markets on a central limit order book, but their data differs in ways that break code written for one and pointed at the other: what a market is, how the book is shaped and updated, the units, the fees, and how markets resolve.

Updated October 24, 2026. Column names are those in the archive's files.

Side by side

KalshiPolymarket
What a market isOne YES/NO contract with a ticker (KXBTC15M-26OCT121545-45), inside an event (KXBTC15M-26OCT121545) inside a series (KXBTC15M).A condition id (0x…) with two outcome tokens, each a long numeric token id with its own order book. The question, slug and outcome names are in polymarket_markets.
Order bookBids only, on YES and on NO. A NO bid at p is an offer to sell YES at 1 − p.Bids and asks on each outcome token.
Book updatesbook_l2: snapshot rows set a level, delta rows carry the signed change in size. Each day's file opens with a snapshot of every book at 00:00 UTC.polymarket_l2: a snapshot replaces the token's book, and a change carries the new absolute size at one price. Zero removes the level.
Top of bookReady made: bbo (every change), bbo_1m (minute bars), book_snap_1s (top ten levels each second), all with asks in YES terms.Rebuilt from polymarket_l2 (code below).
PricesDollars from 0 to 1. Tick bands per market in tick_structure and price_ranges: 1¢ on most, 0.1¢ on some markets or near 0 and 1.Outcome price from 0 to 1 in USDC. The minimum step is the market's tick_size, which can change while the market trades.
SizeContracts. Each YES contract pays $1 if the market settles yes.Shares. Each share of the winning outcome pays 1 USDC.
Tradestrades: YES price, size, the taker's side (yes or no) and Kalshi's trade id.polymarket_trades: the price of the token traded, size, the taker's side on that token (BUY or SELL), fee rate and transaction hash. polymarket_fills has the on-chain settlement logs.
FeesA taker fee of fee_multiplier × 0.07 × P × (1 − P) per contract, rounded up to the cent per order; some series also charge makers.The rate charged on each trade, in fee_rate_bps. Many markets charge none.
ResolutionKalshi settles each market under its rules (rules_primary) from named sources. The settlements dataset has the result, the payout and the value it settled on.An oracle resolves each market: UMA's optimistic oracle for most, Chainlink price feeds for the short crypto markets. The archive has no Polymarket outcome dataset yet; take resolutions from Polymarket's API.
FilesOne per series per UTC day, with every market of the series.One per market (condition id) per UTC day, with both tokens; fills are one file per token.
Recorded sinceOctober 12, 2026October 15, 2026

Both venues' files carry two timestamps in nanoseconds UTC: ts_recv, when the recorder received the message, and ts_venue, when the venue sent it. Order by ts_recv on both.

The order book

On Kalshi, every order is a bid: you buy YES or you buy NO. Selling YES at 60¢ is the same as bidding 40¢ for NO, so the YES ask is 1 minus the best NO bid. The archive does that conversion in bbo, bbo_1m and book_snap_1s; in book_l2 you see the raw YES and NO bid books.

On Polymarket, each outcome token is its own book with bids and asks, and both tokens of a market share one file. There is no ready-made top-of-book file, so rebuild it from the tape: a snapshot replaces a token's book, and every other row sets the size at one price.

import duckdb

rows = duckdb.sql("""
  SELECT ts_recv, ticker, is_snapshot, side, price, size
  FROM read_parquet('kalshieye-data/polymarket_l2/date=2026-10-21/series=<condition_id>/*.parquet')
  ORDER BY ts_recv
""").fetchall()

books = {}        # token id -> {"bid": {price: size}, "ask": {price: size}}
snapshot_at = {}  # token id -> ts_recv of the snapshot being applied
for ts, token, is_snapshot, side, price, size in rows:
    book = books.setdefault(token, {"bid": {}, "ask": {}})
    if is_snapshot and snapshot_at.get(token) != ts:  # a new snapshot replaces the token's book
        book["bid"].clear()
        book["ask"].clear()
        snapshot_at[token] = ts
    if size == 0:
        book[side].pop(price, None)
    else:
        book[side][price] = size
    best_bid = max(book["bid"], default=None)
    best_ask = min(book["ask"], default=None)

The same loop on Kalshi's book_l2 differs in two places: sides are yes and no (both bids), and a delta adds its size to the level instead of replacing it. The Python client's replay_book does that for you.

Tickers and outcomes

A Kalshi ticker names one contract, and its YES side is the outcome. A Polymarket trade names a token id; to know which outcome it bought, join it to the day's market list:

SELECT t.ts_recv, m.question, m.o.outcome, t.price, t.size, t.side
FROM read_parquet('kalshieye-data/polymarket_trades/date=2026-10-21/series=*/*.parquet') t
JOIN (
  SELECT ticker AS condition_id, question,
         unnest(from_json(outcomes, '[{"token_id": "VARCHAR", "outcome": "VARCHAR"}]')) AS o
  FROM read_parquet('kalshieye-data/polymarket_markets/date=2026-10-21/*.parquet')
) m ON t.series = m.condition_id AND t.ticker = m.o.token_id
ORDER BY t.ts_recv;

A BUY of the No token at 35¢ is a bet against the question at the same odds as a sell of Yes at 65¢. Turn both into one outcome's terms before you compare prices across the two venues.

Comparing the same event on both venues

  • Match on the rules, not the title. Two markets on "bitcoin above $X at 3 PM" can settle on different price sources or a different second. Kalshi names its source in rules_primary and the series' settlement_sources; Polymarket states its rules on each market's page.
  • Compare tradable prices. Use each venue's ask to buy and bid to sell, in the same outcome's terms, after each venue's fee.
  • Compare at the same instant. Join on ts_recv with an ASOF join, and drop hours either venue's recording missed (the Data coverage page has both).

Questions

Is Polymarket order book data on-chain?

No. Trades settle on Polygon, so fills are public on-chain, but orders rest in Polymarket's off-chain order book. Past books exist only where someone recorded them as they changed.

Can the same code read both venues' order books?

Not as is. Kalshi books are bids on YES and NO with signed size changes; Polymarket books have bids and asks per outcome token with absolute sizes. Convert both to bids and asks in one outcome's terms first, then the rest of the code can be shared.

Do Kalshi and Polymarket list the same markets?

Many questions overlap, crypto prices, economics, politics and sports among them, but there is no shared identifier and the rules often differ in source, timing or wording. Match markets by hand or by rules, not by title alone.

Next