Simulator Fill Engine
// walk_book · slippage_fallback · halt_handling · limits
Tapeboard's paper-trading simulator fills orders through one of two paths: an L2 walk-book when a Level 2 snapshot is cached for the symbol, or a size-vs-volume slippage model when no L2 is available. Halted symbols refuse all fills until they resume.
How Tapeboard fills paper orders
Tapeboard's paper-trading simulator fills orders through one of two paths: an L2 walk-book when a Level 2 snapshot is cached for the symbol, or a size-vs-volume slippage model when no L2 is available. Halted symbols refuse all fills until they resume. Each path is described below with the exact source function it lives in.
Path 1: Level 2 walk-book (primary)
When the symbol has a cached Level 2 snapshot in the order-book store, the engine walks the book in price order. Market orders consume best-bid (sells) or best-ask (buys) outward, level by level, until the requested share count is satisfied. Limit orders consume levels until either the share count is satisfied or the next level would cross the limit price — at which point the remainder rests as an open limit.
The L2 cache is populated by any panel that has subscribed to the symbol's level2 stream — typically the Order Book panel, the Time and Sales tape, or the Montage panel. If no panel has subscribed, the L2 store is empty for that symbol and the engine falls back to the slippage model (§02).
Walk-book pseudo-code
function walkBook(side, wantedShares, book):
levels = (side == BUY) ? book.asks : book.bids // price-sorted
filled = 0
weightedPrice = 0
for (price, size) in levels:
take = min(size, wantedShares - filled)
weightedPrice += take * price
filled += take
if filled >= wantedShares: break
return {
filledShares: filled,
avgFillPrice: weightedPrice / filled,
partial: filled < wantedShares,
}
Partial fills occur when the cumulative book depth on the consuming side is thinner than the requested size. Tapeboard returns the partial fill with the actual filled share count rather than silently topping up at the last seen price — this is the behavior a live broker would return on a thin name.
Path 2: Slippage model (fallback)
When no L2 book is cached for the symbol, the engine uses a size-vs-volume slippage model implemented in slippageFillPrice. The model computes:
rawImpactPct = (wantedShares / baselineVolume) * 0.02 impactPct = clamp(rawImpactPct, 0, 0.005) // capped at 0.5% signedImpact = (side == BUY) ? +impactPct : -impactPct fillPrice = referencePrice * (1 + signedImpact)
Constants: the impact multiplier is 0.02, the cap is 0.5% (so even a 25%-of-volume order pays no more than 50 bps in modeled slippage), and the default baseline volume when none is supplied is 10,000 shares. The reference price is the last seen mid for the symbol.
This fallback is deliberately conservative. The 0.5% cap means thin penny stocks may not get a fully realistic fill in the slippage model — for the most accurate paper trading on those names, open the Order Book panel first to populate the L2 cache and the engine will route through the walk-book path.
Halt handling: SSR and LULD reject fills, not just throttle them
When a symbol is halted (the halted flag is set from a security_status Level 1 message, or a LULD halt is derived intraday from the symbol's rolling VWAP and tier-specific band), the engine refuses all fills for that symbol. Market orders return a halt-reject error code; limit orders sit as resting orders until the halt clears.
The full LULD and SSR enforcement logic is documented separately at /methodology/ssr-luld.
What this model doesn't do
No queue-position modeling. The walk-book consumes levels in price order, but it does not model your queue position within a single price level. A limit order at the best bid sees all of the displayed size at that level as available — in practice you'd be at the back of the queue and could miss fills as the level is depleted.
No exchange-specific routing. The book is presented as a consolidated view of the venues the Schwab feed exposes. Real routing decisions (NYSE vs ARCA vs IEX vs dark pools) are not simulated. For most retail traders this is fine; for HFT-adjacent workflows it is not.
Top-of-book only on retail Schwab feed. Schwab's retail Level 1 + Level 2 feed publishes top-of-book depth only — ARCA and EDGX depth are not in the feed. The walk-book can only consume what the feed publishes. On thin small-caps this is a real limitation; on liquid large-caps top-of-book is usually all that fills before a market order completes anyway.
Source: frontend/src/stores/useOrderBookStore.ts (walkBook + slippageFillPrice). See also: /methodology (full methodology index) and /paper-trading-simulator (feature page). Last reviewed 2026-05-11.