Turn the live websocket / REST feed into a continuously valid order book, or refuse to trade against it.
Challenge we are solving
Feeds drop. Sequence numbers gap. Snapshots disagree with deltas. If you trade against an invalid book you mis-price and over-fill. The challenge is detecting the bad state fast enough to stop downstream stages.
What this stage does
Consumes the market feed, applies deltas to a local order book, validates sequence numbers, detects stale books, triggers resyncs, and emits a fresh order_book_snapshot at every tick.
Why this stage exists
Every downstream stage — signals, fair value, execution — reads from the book. The ingestion stage is the only place that knows whether the book is currently trustworthy.
Flow
WS feedpolymarket book
→
Sequence checkseq_t = seq_{t-1}+1
→
Apply deltasdepth_t = depth_{t-1}+Δ
→
Validatefresh · monotonic
→
SnapshotOrderBookSnapshot
What the backend should expose
feed_status (connected · degraded · disconnected)
last_seq, expected_seq, gap_count_60s
stale_duration_ms (since last accepted update)
book_validity (valid · stale · resyncing · invalid)
resync_jobs (last 1h)
last_snapshot_ts, last_delta_ts
Maths we expect here
Every formula below is implemented in packages/polytraders-bots/ or packages/polytraders-runner/. Treat the worked example as the unit-test sanity check you should be able to reproduce locally.
worked example\[bid=0.62,\; ask=0.64 \;\Rightarrow\; spread=0.02 \le 0.30 \;\Rightarrow\; \text{valid}\]
How a developer codes this stage
Reference TypeScript implementation lives in packages/polytraders-* at the repository root. Stage owners maintain these files — read them before writing new code.
packages/polytraders-contracts/src/OrderBookSnapshot.tsThe shape every consumer downstream receives. Includes seq, ts, bids[], asks[], hash.