API
Reconstructing a Polymarket order book in Python
The archive already stores full L2 books - you are not replaying an event stream. Reconstruction means turning one snapshot's bids and asks into the derived quantities you need: the touch, the mid, cumulative depth and a fill price for a given size.
What this guide covers
- Each snapshot already carries full bids and asks ladders, best price first
- Bids descend from the best bid; asks ascend from the best ask
- Walking the ladder for a size yields an average fill price
- An empty side means the book was one-sided and the mid is undefined
From snapshot to summary
A snapshot gives you two ladders. The touch is the first entry of each. The mid is their average, when both exist. Cumulative depth is the running sum of size as you move away from the touch, and it is what tells you how much size the book can absorb at each price.
Because the ladders are stored in full and ordered, none of this requires reconstruction from trades or diffs. You read the levels directly - which is the point of archiving L2 rather than just the top of book.
Walking for a fill price
To price an order of a given size, consume the opposite ladder from the best price inward, accumulating notional until the size is filled. The average is your fill. If the ladder runs out first, the order cannot be fully filled and the remainder would rest.
This is the honest substitute for a flat slippage assumption. Because the exact levels are stored, the walk is a measurement, not an estimate, and it makes order size a real input to the backtest.
Handling one-sided books
When one side is empty the mid is undefined and any fill against that side is impossible at that instant. Represent this explicitly with nulls rather than zeros, and skip fill attempts that would consume a missing side.
Track how often this happens. A market that frequently has one-sided books is one where execution is unreliable, and a backtest that ignores that will overstate achievable fills.
Depth at a target price
A related quantity is the cumulative size available at or better than a given price. Sum the sizes of all levels at least as good as the target, which tells you how much the book can absorb before the price moves past it.
This is the number behind statements like "the book supports 5,000 contracts within one cent of the touch". It is more informative than total depth because it is anchored to a price the strategy actually cares about.
Compute it for both the current snapshot and a snapshot at settlement to see how liquidity changes as the window closes, which is exactly the regime a taker exit faces.
Code examples
def book_summary(snapshot):
bids = snapshot.get("bids") or []
asks = snapshot.get("asks") or []
best_bid = bids[0][0] if bids else None
best_ask = asks[0][0] if asks else None
mid = None
if best_bid is not None and best_ask is not None:
mid = (best_bid + best_ask) / 2
return {
"best_bid": best_bid,
"best_ask": best_ask,
"mid": mid,
"bid_depth": sum(sz for _, sz in bids),
"ask_depth": sum(sz for _, sz in asks),
}
def walk(levels, size):
remaining, cost = size, 0.0
for price, qty in levels:
take = min(remaining, qty)
cost += take * price
remaining -= take
if remaining <= 0:
return cost / size
return None # insufficient depthFree tier
The Starter plan is free, includes order books, prices, and metrics at 250ms resolution, with 3 days of history, 60 requests/min, 1,000/day, 1 free AI backtest, and 3 strategy backtests. No credit card required.
Paid data windows from $19/mo extend history to 30–120 days at higher throughput. Backtest AI add-on is +$19/mo or standalone at $29/mo.
FAQ
Do I need to replay an event stream to build the book?
No. Each archived snapshot already carries full bids and asks ladders, so reconstruction is deriving the touch, mid and depth from one snapshot, not replaying updates.
How do I get a fill price for a given size?
Walk the opposite ladder from the best price, taking size at each level until filled. The average is the fill; if depth runs out, the order cannot fully execute.
What if one side is empty?
The mid is undefined and no fill is possible against the empty side. Keep the null rather than substituting zero.
Why does order size matter so much?
Because fills walk the ladder. A size that is trivial on a deep book expensive on a thin one, so the fill price depends on both size and depth.