Polymarket
The venue serves no history, so its two collectors read an archive and your own raw-frame captures.
crates/vike-backfill/src/caps.rs is unambiguous about this venue: verified rather than assumed,
the bridge implements no price-history endpoint — no /prices-history, no fidelity parameter — and
no L2 book history exists to fetch, so the venue row is empty across every kind. Every Polymarket
fill comes from an archive or a capture. Two collectors do that; two research bins read the same
sources in place, with no import step at all.
pmxt_backfill — the pmxt archive
The data source is the pmxt Polymarket order-book archive, licensed CC BY 4.0, published as
Parquet by pmxt (r2v2.pmxt.dev), which is not affiliated with this project — the attribution the
module carries in its own header (crates/vike-backfill/src/pmxt/mod.rs). The bin is a default
target: no feature is needed.
pmxt_backfill --from YYYY-MM-DDTHH --to YYYY-MM-DDTHH [--tokens T1,T2,...] [--tokens-file PATH]
[--store DIR] [--dry-run] [--rate-ms N]
[--clickhouse [--ch-bin BIN] [--min-local-ts MS] [--max-local-ts MS]]From the bin header (crates/vike-backfill/src/bin/pmxt_backfill.rs): it iterates every UTC hour
in the inclusive range; for each it downloads that hour's Parquet part (a 404 means pmxt has not
published it — logged and skipped), decodes it a row group at a time (parts run 130–400 MB, so the
memory bound is the point), and appends the book, trade and quote events to the store. One bad
hour never aborts the range. --tokens and --tokens-file (one id per line, # comments allowed)
union into a filter — a real run's ~78k ids exceed the argv limit, hence the file. --dry-run
prints the hour range, the store root and each archive URL and touches nothing. The destination is
visible in crates/vike-backfill/src/pmxt/ingest.rs's ingest_file, which appends under
venue=polymarket with the token id as the symbol: kind=book (snapshots plus deltas),
kind=trade and kind=quote (the venue's own best_bid/best_ask carried on price_change
rows — prices only, and per crates/vike-backfill/src/pmxt/map.rs's l1_from_row the archive's
only complete record of the top of book, without which a delta replay is measurably wrong), the
same series shape the live feed writes, each under a pmxt:{kind}:{asset}:{hour} commit key — so
its doc can say re-runs of the same hour are a no-op. The pure mapper
(crates/vike-backfill/src/pmxt/map.rs) folds book rows to snapshots, price_change to
single-level deltas and last_trade_price to trades; tick_size_change updates per-asset state
that rides on the next book update, defaulting to 0.01 until one is seen.
The --clickhouse write path is not idempotent
--clickhouse switches the target from the hist store to the polymarket ClickHouse tables the
live L2 recorder writes, via clickhouse-client INSERTs. Unlike the hist-store path, re-running the
same hour duplicates every row — track completed ranges yourself
(crates/vike-backfill/src/pmxt/ingest.rs's ingest_file_clickhouse). --min-local-ts/
--max-local-ts exist for that reason: a recorder outage rarely starts on an hour boundary, so
pass the outage's actual [start, end] in epoch-ms and only rows inside it are written, while every
fetched hour is still decoded in full.
poly_reparse — your own raw frames
The bridge owns a raw-frame tap: RawTap/TappedStream tee verbatim WS frames plus the local
receive time to gzip files (Feeds::with_raw_capture, opt-in).
crates/bridges/polymarket/src/raw_tap.rs's header states its disposition — raw capture is
strictly insurance, losing a frame is acceptable and affecting the live feed is not — and
poly_reparse is what re-parses that perishable capture back into the store.
crates/vike-backfill/src/reparse.rs's GzFileStream replays those files as a
vike_polymarket::MarketStream, so run_session re-decodes them through the same pump as a live
session, and the captured receive time is restored as local_ts. The layout mirrors the writer:
<root>/polymarket/<token>/date=YYYY-MM-DD/frames-*.jsonl.gz (gz_files_for).
poly_reparse --raw-dir DIR --store DIR --token ID --from YYYY-MM-DD --to YYYY-MM-DD \
--mode book|quotes|trades --tick-size F--tick-size must match the value the live session used, or the book quantizes on a different
grid; the operator supplies it, because this offline tool makes no REST fetch (bin header). The bin
is built under the poly-reparse feature, which enables vike-polymarket/feeds
(crates/vike-backfill/Cargo.toml).
archive_store.rs notes the convention for whoever reconciles this store with another: it scopes a
range by ts, the venue clock, exactly as DataFusionHist does.
The archive download itself, and the events API, are on the Data API page. Running the venue live is Polymarket operations; the queue models are under backtesting and the maker models under market making.
IBKR historical
Paging IBKR historical bars through a running TWS or IB Gateway into the store as kind=bar under venue=ibkr — the offline twin of the live feed, behind the ibkr feature.
EOD, events and exec trades
Three small, unrelated collectors on one page — daily index bars from Yahoo, the data.vike.io live events API, and a venue account's own trade-history export.