tickfoundry
capture livesign inget the data →
§ research · note 004

150 million rows of the 2026 World Cup, free

2026-09-01world cup 2026free datasetcalibration

We have published every Polymarket market attached to the 2026 FIFA World Cup as a free dataset: 1,085 events, 39,497 markets, 77,378 outcome tokens, about 150 million rows. It is on Kaggle, and it is the archive rather than a summary of it. Minute bars built from the top of the book, every fill off the market-data socket, the chain-settled fills with the wallet that settled them, and the full 25-level order book for a final that went to penalties.

candles_1m_mid104.5M rows1-minute mid bars with a time-weighted spread, 2026-02-21 to 2026-08-27
trades16.4M rowsevery fill off the market-data socket, exchange and receive timestamps
trades_onchain19.6M rowschain-settled fills carrying the settling wallet
candles_1m_tape5.9M rows1-minute traded bars: OHLC, VWAP, volume, taker-buy share
depth_final_…_l23.1M rowsthe full 25-level book for the final, decided on penalties
outcomes.csv39,497 rowsthe official resolved result for every market
sports_state6,544 rowslive game state for 68 fixtures: score, period, in-play flag

Why a tournament makes a good dataset

Most public prediction-market data is a daily closing price, which is enough to draw a chart and not much else. A completed tournament is different, because every price series in it terminates in a known answer. The dataset ships the official resolution for 39,441 of its 39,497 markets, so the classic question — did the 70% favourite win 70% of the time — is a group-by rather than a research project. Bucket the prices, count the winners, and the reliability curve falls out.

There is also the live game-state feed for 68 of the tournament's fixtures — score, period, whether the ball was in play — which is the file that turns a price series into an event study. You can see the price move; that tells you the goal that moved it. It joins to everything else on ts_recv_ns, the same clock the order book is stamped on. Two honest limits: our recording of it starts 2026-06-21, so the opening ten days of group stage are absent and cannot be backfilled from anywhere, and no key links a fixture to its markets — the upstream field that would have done it is null on every row, so you match on team names and time.

The other two things you cannot do with snapshots: the minute bars carry a time-weighted spread rather than a sampled one, so you can measure how liquidity behaved through goals and red cards instead of at whatever instant a snapshot happened to land; and the on-chain fills carry the settling wallet, so flow is attributable across markets and across time. Quotes on this venue are anonymous and always will be. Fills are not.

The build was mostly about a seam

Our own continuous capture starts 2026-05-11. The World Cup's outright markets were pricing months before that, so the pre-tournament window comes from the pmxt public archive, which is CC BY 4.0. Two archives, one dataset, and the joining is where the work was.

The first attempt spliced them at the moment our capture began, 09:37 UTC on 05-11. That is the obvious thing to do and it is wrong twice over. It puts a handover in the middle of a trading session, and it ships our own 05-11 — which is about 55% of a day, because that is when we started recording — as though it were whole. The fix was to take the other archive's complete 05-11 and discard our partial one. The seam is now a date boundary: everything up to and including 2026-05-11 is one archive, everything from 2026-05-12 is the other, and no date is served by both or by half a capture.

Every row says which archive it came from, in a source column. That is not decoration: it is also the licence boundary, since the pmxt rows carry CC BY 4.0 and ours carry CC BY-NC 4.0. If you would rather work with one capture, WHERE source = 'tickfoundry' is the whole filter.

Two things we found by checking rather than assuming

A naive read of "every partition for these markets" silently mixed the two archives inside what we were about to label our own socket capture — 535,476 fills, 3% of the file. The tell was a range check: the earliest fill was dated mid-April, and our capture does not start until May. Labelling third-party observations as your own is the kind of error that survives every schema validation ever written, because the shape is perfect and only the provenance is wrong.

The second was cosmetic and more embarrassing. Tick sizes came out of the database as 0.001000000000000000208…, mid prices as 0.5650000000000001, spreads as 0.010000000000000009. None of that is precision; it is a float64 round-trip made visible. It is fixed in the published files, and the fix shrank the dataset by 150 MB, because values with a long random tail do not compress. We mention it because if you have ever pulled prediction-market numbers through a database and a float, they probably look like this too.

What it is not

It is one tournament, three months, and a sports vertical. There is no raw feed in it, no nanosecond-stamped socket messages, and only one day of full-depth book — the final — rather than the whole tournament. Those exist, and they are the paid product; this is a slice cut wide enough to be genuinely useful on its own. If it is useful and you need a different tournament, a longer history, deeper book, or the raw feed, that is what we do.

Get the dataset on Kaggle →Free sample bundleSports catalogue