Backtesting a Polymarket strategy: where the data is, and why most backtests lie

What you need to test a Polymarket strategy honestly — market metadata, price history, order-book depth you must record yourself, your own fills — and the seven ways backtests lie: last-price fills, no fees, no spread, look-ahead, survivorship, overfitting on minute markets, and regime change. A process that survives contact with the book.

By the POLBOTS editorPublished Aug 21, 20264 min read
On this page5 sections

What you need before you can test anything

DataWhere it comes fromThe catch
Markets, outcomes, resolution dates and resultsGamma APIResolved markets drop out of default listings; ask for them explicitly and store them
Price history per outcome tokenCLOB prices-history endpointSampled prices, not the book — you cannot see depth or the spread you would have crossed
Trades and positions for any walletData APIGreat for copy-trading research; rate-limited, paginated by cursor
Order-book depth over timeNobodyYou record it yourself from the WebSocket market channel, for weeks, before you can test a maker or a taker honestly
Your own fillsThe user channel and your logsThe only data that calibrates a fill model to *your* latency and size
External signals with timestampsExchange feeds, news APIs, transcripts, forecast modelsTimestamp at *receipt*, not publication — that is when your bot would have known

Third-party platforms in the catalog — PolyData, Dome, HashDive, Polymarket Analytics — package the public parts of this into cleaner, bulk form. None of them can give you the one thing that matters most for execution: depth you were not there to record.

The seven ways backtests lie

  1. Last-price fills. The backtest buys at the last traded price. You would have paid the ask, and on a thin book the ask for your size was worse than the touch. The spread is the first cost and the most often omitted.
  2. No fees. Only takers pay, and the fee is C × rate × p × (1 − p): at a 50-cent price 1.75% of notional on crypto markets, 1.25% on sports, 1% on politics, zero on geopolitics. A taker strategy that looks like +1% per trade on a minute market is a −2.5% strategy after two crossings.
  3. Assumed fills. A maker backtest that assumes every resting order at the touch was filled has ignored queue position and size cutoffs; a taker backtest that assumes full fills has ignored depth.
  4. Look-ahead. The resolution was known when the market closed, not when you traded; the headline was published at 14:02:07 but your feed delivered it at 14:02:31; the spot print you "reacted to" was the one after the move. Every external series must be shifted to the moment your bot would actually have had it.
  5. Survivorship. Markets that were voided, delisted or resolved oddly disappear from default queries, and they are precisely the ones that would have hurt.
  6. Overfitting, especially on minute markets. Thousands of samples make it trivially easy to find a rule that worked — which is what makes the category so seductive. A strategy with eight tuned parameters fitted on last month has described last month. Hold out data; walk forward; distrust anything that only works with specific numbers.
  7. Regime change. The edge from spot leading the book was larger a year ago than today; liquidity rewards moved which books the makers sit on; fees changed the maths. A backtest across regimes averages an edge that is already gone into one that is not.

A process that survives the book

  1. Record first. Stream the books you intend to trade from the WebSocket market channel into storage — snapshots plus deltas — for weeks. Record external signals with receipt timestamps. This is the step everyone skips and the one that makes everything after it honest.
  2. Build a fill model and calibrate it. For takers: fill against recorded depth at your size, charge the spread and the fee by category. For makers: fill only when the recorded trade tape crosses your price, with a conservative assumption about your place in the queue. Then run real orders at tiny size and measure actual slippage — Uruguabot calibrates its dry-run simulator from slippage distributions measured on real fills, and that is the standard.
  3. Replay, out of sample. Fit on one period, test on the next, walk forward. Count what you would have done net of everything.
  4. Paper trade live with the same fill model, for weeks, including the boring weeks.
  5. Go live small — a size whose total loss would annoy you — and keep the paper run going beside it as a control.
  6. Scale on sample size, not on results. Hundreds of trades on minute markets before you believe an expectancy; on slow markets, accept you will be reasoning more than measuring.

The numbers that matter

Expectancy per trade after spread and fee; maximum drawdown and its duration; hit rate against average win and loss together (a 90% hit rate with one ruinous loss is how minute-market bots die); the sample size behind all of the above; and for makers, fill rate and adverse selection — how often the price moved against you right after you were filled. A Sharpe ratio on thirty trades is decoration.

What honest results look like

The most useful published record in the catalog is a net loss: Uruguabot publishes every fill from two generations of testing as raw CSVs, a 1,934-window study in which its automated signals scored at coin-flip against a human's 59%, and one default configuration at +7.3% over 25 live trades — and says in its own listing that nothing there promises future profits. Read it as a template for what you should be able to show yourself before a strategy gets real size. POLBOTS does not verify anyone's performance, including yours; that is what the process above is for.

Frequently asked questions

Where do I get historical Polymarket data?
Market metadata and resolutions from the Gamma API; price history per outcome token from the CLOB's prices-history endpoint; trades and positions for any wallet from the Data API; and third-party data platforms in the catalog for cleaned, bulk versions of the same. What nobody hands you is historical order-book depth — you record that yourself from the WebSocket feed, which is why serious testing starts weeks before it starts.
Why does my backtest make money and my bot doesn't?
Almost always one of four things: the backtest filled you at the last price when you would have crossed the spread; it forgot the taker fee (1.75% of notional at 50 cents on crypto markets); it assumed fills you would not have got at your size and queue position; or it used data — a resolution, a price, a headline — from a moment later than your bot would have had it.
How many trades before I trust a result?
More than feels necessary. On the minute markets, hundreds at a minimum; a vendor's 1,934-window study is the kind of sample at which a signal's coin-flip nature becomes visible, and a 25-trade live run — however profitable — is noise. On slower markets you will never have hundreds, which is a reason to weight reasoning over statistics there.
Is paper trading a substitute for backtesting?
It is the second half of it. A backtest tells you whether the idea ever worked; a paper run with an honest fill model tells you whether it works now, with your latency and your sizes. Do both, in that order, and treat a paper run's first profitable week as exactly that.