Polymarket Backtest: Tick-Level Up/Down Books & Settlements
The canonical Polymarket backtest entry point — reconstruct L2 books, score settlements, and download free samples before you wire a full research loop.
Polymarket Up/Down markets are short-dated binaries with dense books. AymarData stores ~207.0M messages from 2025-06-01 so you can replay windows instead of guessing fills from candles.
This page owns the general “polymarket backtest” intent. Use the 15m and 5m child pages when your query is interval-specific.
Inputs
What you need to backtest Polymarket properly
What a serious backtest needs beyond candles.
Concrete window ids
List with /v1/markets, then pass slugs like btc-updown-15m-<unix> into book/trades/settlement.
Outcome-aware books
Pass outcome=up or down on every book/trades call for two-sided markets.
Realistic fills
Buy at ask, sell at bid; cap size by top-of-book; skip one-sided books.
Settlements
Terminal value comes from /v1/settlement — exclude unresolved windows from P&L.
Coverage
Live Polymarket coverage
Per-family pages under /data/polymarket/* publish weighted counts from PUBLIC_TOTALS.
Messages
~207.0M
From 2025-06-01
Avg events/day
404,297
Platform-wide
Families on site
20 crypto Up/Down
BTC ETH SOL XRP × 5 intervals
As of
2026-10-25
Code
End-to-end Polymarket backtest (REST + requests)
Screens btc-updown-15m for mid < 0.45, records ask entries, and checks settlement when present.
import os
import requests
API = "https://api.aymardata.com/v1"
KEY = os.environ["AYMARDATA_API_KEY"] # export AYMARDATA_API_KEY=ad_live_…
H = {"Authorization": f"Bearer {KEY}", "User-Agent": "aymardata-backtest/1.0"}
def list_windows(q: str, interval: str, limit: int = 40):
r = requests.get(
f"{API}/markets",
headers=H,
params={"source": "polymarket", "q": q, "interval": interval, "limit": limit},
timeout=30,
)
r.raise_for_status()
# De-dupe Up/Down rows that share the same window slug
seen, out = set(), []
for row in r.json()["data"]:
m = row["market"]
if m in seen:
continue
seen.add(m)
out.append(row)
return out
def book(market: str, outcome: str, at: str, depth: int = 5):
r = requests.get(
f"{API}/book",
headers=H,
params={
"source": "polymarket",
"market": market,
"outcome": outcome,
"at": at,
"depth": depth,
},
timeout=30,
)
r.raise_for_status()
return r.json()
def settlement(market: str):
r = requests.get(
f"{API}/settlement",
headers=H,
params={"source": "polymarket", "market": market},
timeout=30,
)
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()
def mid(snap):
bids, asks = snap.get("bids") or [], snap.get("asks") or []
if not bids or not asks:
return None
return (bids[0]["price"] + asks[0]["price"]) / 2
THRESHOLD = 0.45
rows = []
for w in list_windows("btc-updown-15m", "15m"):
market = w["market"]
hist = w.get("history_from")
if not hist:
continue
# Sample ~60s after history starts
at = hist.replace("+00:00", "Z")
if at.endswith("Z") is False and "T" in at:
at = at + ("Z" if "+" not in at else "")
snap = book(market, "up", at if "T" in at else hist)
m = mid(snap)
if m is None or m >= THRESHOLD:
continue
# Buy Up at the ask; score later against settlement when resolved
entry = (snap["asks"] or [{}])[0].get("price")
sett = settlement(market)
won = None
if sett:
outcome = str(sett.get("outcome") or sett.get("winner") or "").lower()
won = outcome in ("up", "yes", "1")
rows.append({"market": market, "mid": m, "entry": entry, "won": won})
# Counts only — label any P&L/win-rate/edge you add:
# "Illustrative output — not a real result"
print(f"signals={len(rows)} sample={rows[:3]}")
API base https://api.aymardata.com. Set AYMARDATA_API_KEY from your dashboard. Examples use requests. Any P&L, win-rate, or edge figure derived from these snippets is illustrative output — not a real result.
Free samples
Download sample CSV / Parquet
No key required — small files for schema and local smoke tests.
FAQ
Common questions
How is this different from the 15m / 5m backtest pages?
This page targets the generic “polymarket backtest” query and the overall workflow. Interval pages go deeper on 15-minute and 5-minute window structure.
Where is the longer tutorial?
See the step-by-step guide: How to backtest Polymarket Up/Down markets.
Related
Data pages and guides
Catalog leaves for schema and samples; guides for longer walkthroughs.
Run your first backtest with real ticks
Get a key, paste the snippet above, then expand to the full catalog.
Educational content, not trading or investment advice. Past data doesn't predict future results.