polyorderbooks/polymarket-btc-5min-historical-l2
Polymarket BTC 5-Minute Historical L2 Order Books Full level-2 order book snapshots captured at 1-second resolution for one resolved Polymarket BTC 5-minute up/down market — every resting bid and ask, not just top-of-book. One row per (timestamp, outcome). 600 rows covering 300 seconds across both outcomes. from datasets import load_dataset ds = load_dataset("polyorderbooks/polymarket-btc-5min-historical-l2", split="train") row = ds[0] print(row["timestamp"], row["outcome"])… See the full description on the dataset page: https://huggingface.co/datasets/polyorderbooks/polymarket-btc-5min-historical-l2.
Polymarket BTC 5-Minute Historical L2 Order Books
Full level-2 order book snapshots captured at 1-second resolution for one resolved Polymarket BTC 5-minute up/down market — every resting bid and ask, not just top-of-book.
One row per (timestamp, outcome). 600 rows covering 300 seconds across both outcomes.
from datasets import load_dataset
ds = load_dataset("polyorderbooks/polymarket-btc-5min-historical-l2", split="train")
row = ds[0]
print(row["timestamp"], row["outcome"])
print("best bid", row["best_bid"], "best ask", row["best_ask"])
print("depth", len(row["bids"]), "bid levels /", len(row["asks"]), "ask levels")Why this dataset exists
Most publicly available Polymarket data is midpoints or daily candles. That is enough to plot a price line and not enough to answer the question that matters for execution research: what would this trade actually have cost?
A midpoint says the market was at 0.195. The ladder says only 13.6 was available at the best ask, and filling 100 units would have averaged 0.2086 — 4.3% worse than top of book. That difference is invisible in candle data and is the reason backtests built on midpoints overstate returns.
Coverage
Schema
Prices are probabilities in [0, 1]. Sizes are fractional, not integer share counts.
Working with the ladders
def simulate_buy(row, target_size):
"""What it would actually have cost to buy target_size."""
filled = cost = 0.0
for level in row["asks"]:
take = min(level["size"], target_size - filled)
cost += take * level["price"]
filled += take
if filled >= target_size:
break
if filled < target_size:
return None # ladder exhausted — not fillable
return {"avg_price": cost / filled, "slippage": cost / filled - row["asks"][0]["price"]}Two properties of this data are worth knowing before you model with it:
- The two outcomes are complementary.
Yes_bid + No_ask == 1andYes_ask + No_bid == 1, structurally. Useful as an integrity check on your own pipeline. - Depth varies per snapshot and per side. Between 1 and 74 levels here. Code that assumes a fixed number of levels will silently truncate.
Use cases
Execution-aware backtesting · slippage and fill modelling · spread and depth regime analysis · market microstructure research on short-horizon prediction markets · validating an order book reconstruction pipeline against a known-good reference.
Source and methodology
Captured from the Polymarket CLOB by PolyOrderbooks, a historical Polymarket data API covering prices, liquidity metrics, and L2 order books.
Snapshots are recorded as observed, at 1-second cadence, with no synthetic interpolation. A repeated ladder across consecutive seconds means the book did not change, or no new capture landed in that second — the data does not distinguish the two, which matters if you are computing update frequency or realised volatility from it.
- Sample page and CSV download: polyorderbooks.com/datasets/polymarket-btc-5min-orderbook-sample
- Working with L2 data: docs.polyorderbooks.com/historical/order-books
- API quickstart: docs.polyorderbooks.com/quickstart
Larger coverage
This is a single market. The full archive covers Polymarket crypto markets continuously at 1-second capture, available through the REST API and Python SDK:
pip install polyorderbooksLicense
Creative Commons Attribution 4.0 (CC BY 4.0).
About PolyOrderbooks
We capture Polymarket order book depth at 1-second resolution and serve it over a REST API. Polymarket archives no order book history of its own — its /book endpoint returns the current state and nothing stores it — so this data exists only because it was recorded while the markets traded.
The citable release
For a paper, cite the DOI-carrying release rather than this repository — 897,192 snapshots across 805 resolved markets and three contract lengths, same schema, same licence:
PolyOrderbooks. (2026). Polymarket Crypto Up/Down Order Books: 1-Second L2 Depth Across Three Contract Lengths [Dataset]. Zenodo. https://doi.org/10.5281/zenodo.22084114
Questions
Open a discussion on this dataset for anything about the data itself.
For the API — a window these files do not reach, a coverage question, a plan — email contact@polyorderbooks.com. Corrections to the data are welcome and taken seriously; if you find something wrong here we would rather know.
Not affiliated with, endorsed by, or connected to Polymarket.
