A four-stage path from historical tick files to a live trading bot: research on day bundles, API cross-checks, SDK backtesting, and production deployment.
A strategy that looks great in a notebook and loses money live usually did not get worse — it got measured differently. The backtest ran on cleaned candles while production sees raw ticks; the backtest filled instantly at mid while production queues at the touch; the backtest's clock was the candle close while production's is a feed with jitter. This guide describes the architecture path we recommend to close those gaps one stage at a time — using self-serve pieces where possible.
Start where iteration is cheapest: historical files. Archive days cost €1 per instrument-day (or per series-day bundle on prediction venues) and contain the full L2 order-book path plus every trade at nanosecond timestamps — enough to build queue-aware fill models and charge real spread-crossing costs instead of assuming mid-price fills. (L2 data cannot tell you your exact place in the queue; it lets you estimate it with an explicit queue model rather than ignore it.) Parse with the free Python reader or the one-click CSV/Parquet exports, and validate walk-forward (the training-data guide covers splits and label hygiene).
If your simulated fill logic never touches the order book, your backtest measures a different market than the one you will trade. A deliberately conservative baseline: fill limit orders only when the touch trades through your price, and charge takers the real spread from the file. Real fills additionally depend on traded volume ahead of you, your estimated queue position and the venue's matching rules — a queue-aware model refines this heuristic; it does not make it exact.
Before trusting your parser and aggregation code, reconcile them against numbers you did not compute. The free per-minute statistics API serves OHLC, VWAP, trade counts, turnover, spreads and book depth per minute for every instrument — computed by an independent implementation from the same recordings. The comparison validates your parser and aggregation path, not the original exchange capture, which both sides share. Aggregate your tick-level results to minutes and diff them: a persistent mismatch usually indicates a parsing, normalization or aggregation difference that should be investigated (aggressor-side mix-ups and quote-currency confusion are the classics). The live analytics give the same numbers visually for spot checks.
The subtle production killer is the programming model: research code is usually vectorized over a whole day, while live code reacts to one event at a time. Port your strategy into an event-driven harness before going live — ours is the Strategy SDK (Java): you implement callbacks for book changes, trades, order updates and timers, and the same class runs in the backtest runner and in production. The tutorial series walks from first strategy to local backtesting. Whatever SDK you use, the invariant to enforce is: one strategy artifact, two runners — never two implementations.
In production, data quality becomes latency-shaped: you care about jitter, gaps and tails. The archive you researched on was recorded from our co-located realtime feeds — going live on those feeds keeps capture and normalization identical between research and production, which removes one major source of train/live distribution shift (normalized schema, exchange timestamps, feed arbitrage against jitter; from €1,000 per API and month with a two-week free test, and the first 30 days of history included as an initial dump). Deployment placement — regions, links, how to measure your own feed delay — has its own guide: Where to run your prediction-market bot. For dedicated lines, RF routes and co-located hardware, talk to us.
An event-driven port and a careful ramp-up still leave a class of failure modes no historical file contains — the live order path itself. Budget engineering time for at least these before scaling up:
This is why the loop below starts with recording your live fills, quotes and rejects — those logs are also your incident forensics. The trading API documentation covers the live order path in detail.
This is an architecture guide, not a strategy recipe: following it makes results measurable and transferable, not profitable. Pricing facts (€1 archive days, realtime terms) are current as of August 2026 — the pricing page is authoritative. The SDK examples reference our Java stack; the staging logic applies to any event-driven framework. Nothing here is investment advice.
Usually because backtest and live differ in data (candles vs. ticks), fill assumptions (mid-price vs. queueing at the touch) or programming model (vectorized vs. event-driven). Closing those three gaps stage by stage is exactly what this path is for.
Yes — that is the design: the archive is recorded from the same co-located, normalized feeds offered in realtime, with exchange timestamps in both. A model validated on archive days sees the same schema and clocks live.
No. The invariant is framework-agnostic: one event-driven strategy artifact that both a backtest runner and production execute. Our Java SDK implements that pattern with a local backtest runner, but any framework with the same property works.
Reconcile against an independent implementation: aggregate your ticks to minutes and diff them against the free per-minute statistics API, which computes OHLC/VWAP/turnover from the same recordings. That validates your parser and aggregation, not the exchange capture both sides share — persistent mismatches usually point to a parsing, normalization or aggregation difference, not market noise.
No — ramp up. Run the strategy in shadow mode on the live feed first (orders logged, not sent), then trade minimum size while comparing fill ratio, slippage and rejects against backtest assumptions, and only then scale. Each step is a cheap chance to catch a gap the backtest could not show.