03 / BACKTESTING

A quote becomes a strategy only after you define execution.

Use the order book to model a possible fill, then state every assumption that turns displayed liquidity into a simulated trade.

Recommended market window

For a market-internal backtest, use this baseline:

window_start_ts ≤ ts < window_end_ts

The archive can contain pre-market rows where offset_s is negative and post-market rows beyond the market duration. Keep them only when the research question needs them, and label the choice.

Fill simulation rules

ActionUseAvoid
BuyConsume the ASK side from level 1 upward.Using midpoint or BID as the buy fill.
SellConsume the BID side from level 1 downward.Using midpoint or ASK as the sell fill.
SizeApply partial fills, max depth, and a queue/size discount.Treating displayed size as guaranteed execution.
TimingAdd an explicit decision-to-order delay.Assuming the strategy trades at the observation timestamp.
CostsModel fees, slippage, and invalid or expired orders.Reporting gross returns as executable net returns.

Three scenarios worth reporting

Optimistic

Small delay, high fill ratio, shallow slippage. Useful as an upper bound, not as the main claim.

Base case

Explicit delay, partial fills, depth limit, fees, and a modest queue discount.

Conservative

Longer delay, lower fill ratio, stronger slippage, and stricter treatment of gaps and stale quotes.

Compare both sides

Report UP and DOWN separately. Their liquidity and spread can differ inside the same market window.

Minimum quality report

A useful result should show sample coverage, valid outcome markets, missing intervals, theoretical versus partial fills, depth levels, delay, fill ratio, fees, slippage, and date or holding-period slices.

The current dataset has no underlying BTC price feed, complete raw WebSocket event IDs, market-rule snapshot, or individual trade tape. Add those inputs separately if your model depends on them.