Never fill a gap with a zero
Four rules our market history follows: never average two venues, never fill a gap, never keep two copies, and never include a series that lies about itself.
The agent answers questions from stored history rather than by calling exchanges when you ask. That is deliberate: a backtest is only worth reading if its inputs held still while you read it, and asking the same question twice should give the same answer.
Which makes the storage the product. Four rules it follows, each of which we learned by getting it wrong.
Never fill a gap with a zero
An absent or partial series is reported as absent. It is never smoothed, interpolated or defaulted.
The reason is that a zero is a claim. An open interest of zero says nobody anywhere holds a position in that market — which is never true of a live one. A model handed that zero cannot tell it apart from a real collapse, and will happily build a conclusion on top of it.
Never average two venues
Funding rates from four venues are kept apart. Binance and Bybit correlate around 0.85 on BTC, which means they disagree often enough to matter.
Where two venues disagree, the disagreement is the reading. A mean would hide precisely the days worth knowing about — the ones where something was happening at one venue and not the other — and would replace two true numbers with one number that was never true anywhere.
Never keep two copies
There were two copies of the pool history. The agent kept its own synced copy beside the main one, on a different schedule, against an indexer that backfills.
They drifted to 39 pools against 32, with 30 in common.
There is a sharper version of the same lesson. The schedules write to a database rather than to files, because when there was a file in between, a deploy overwrote a freshly synced pool history with a stale copy from somebody’s laptop. Nothing failed. Every page rendered, every tool answered, and hedges were priced from a day ten days out of date for as long as it took somebody to notice.
Never include a series that lies about itself
Wrapped assets are absent from the price history on purpose. WBTC’s archive begins in January 2024; XAUt is missing 63 months.
A price series built from those would not describe bitcoin or gold. It would describe the wrapper’s own thin trading — and it would look like data, plot like data, and be wrong in a way no error message could catch. BTC is the reference for WBTC instead, and the wrapper’s price against the asset is an on-chain question the pool history already answers.
The same judgement runs the other way. Fees for a Uniswap pool are hard, because an indexer values a swap only if it can price both tokens, so a pool can record thousands of trades and report zero fees. Where the other side of the trade is a dollar, the fee is rebuilt exactly — and every rebuilt row is flagged, with the tools passing that flag through to the answer.
What all of this is for
It is read, not traded on. This history exists so the agent can analyse — what a range would have collected day by day, what a hedge has cost at every roll since 2021, what a perpetual pays across four venues — and none of it is a feed, a signal service, or an input to execution.
The separation is worth stating because it is unusual: the half of this system that spends money works from a closed catalogue of operations, and the half that reads works from these streams. Nothing crosses. A backtest cannot place a trade, and a plan cannot be sized from a number a survey returned.