On this page5 sections
What you need before you can test anything
| Data | Where it comes from | The catch |
|---|---|---|
| Markets, outcomes, resolution dates and results | Gamma API | Resolved markets drop out of default listings; ask for them explicitly and store them |
| Price history per outcome token | CLOB prices-history endpoint | Sampled prices, not the book — you cannot see depth or the spread you would have crossed |
| Trades and positions for any wallet | Data API | Great for copy-trading research; rate-limited, paginated by cursor |
| Order-book depth over time | Nobody | You record it yourself from the WebSocket market channel, for weeks, before you can test a maker or a taker honestly |
| Your own fills | The user channel and your logs | The only data that calibrates a fill model to *your* latency and size |
| External signals with timestamps | Exchange feeds, news APIs, transcripts, forecast models | Timestamp 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
- 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.
- 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.
- 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.
- 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.
- Survivorship. Markets that were voided, delisted or resolved oddly disappear from default queries, and they are precisely the ones that would have hurt.
- 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.
- 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
- 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.
- 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.
- Replay, out of sample. Fit on one period, test on the next, walk forward. Count what you would have done net of everything.
- Paper trade live with the same fill model, for weeks, including the boring weeks.
- Go live small — a size whose total loss would annoy you — and keep the paper run going beside it as a control.
- 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.

PolyData
Platforms & ToolsAnalytics workspace and trading terminal for Polymarket. Track positions, liquidity and market flow in real time, analyze any wallet's PnL, exposure and win rate from live on-chain data, rank top traders on a leaderboard, and execute in a focused terminal — from market signal to order entry in one place.

Dome
Platforms & ToolsPrediction-market APIs and SDK for developers. One integration for Polymarket and Kalshi data — historical order books, real-time trade webhooks and WebSockets, and backtesting — via REST plus TypeScript and Python SDKs.

HashDive
Platforms & ToolsAdvanced analytics for Polymarket and Kalshi. HashDive's proprietary Smart Scores rank how consistent and profitable a trader is, alongside a market screener, wallet tracking and candlestick charts with RSI, MACD and whale-volume breakdowns.

Polymarket Analytics
Platforms & ToolsOn-chain analytics and dashboards for Polymarket. Pulls every trade, wallet and position on-chain into searchable tables, trader leaderboards ranked by win rate and PnL, live volume discovery and consolidated position tracking.
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.
