Frequent batch auction

The frequent batch auction (Budish, Cramton & Shim, 2015) is a market design that discretises time. Rather than matching orders the instant they arrive, it collects every order submitted within a short interval, a fraction of a second, or one blockchain block, and clears them together at a single uniform price. Its purpose is surgical: to dismantle the high-frequency latency arms race that the continuous double auction structurally rewards, while keeping the price-discovery and liquidity-aggregation properties that make order-book trading work.

The continuous market's arms race

The continuous double auction processes events in strict serial order: an order, a cancellation, or a trade is handled the microsecond it reaches the matching engine, and ties are broken by price–time priority (best price first, then earliest arrival). Budish, Cramton & Shim observe that this creates a structural flaw. When new public information moves the fundamental value, every stale resting quote becomes mispriced at the same instant. A race then begins between two kinds of fast trader: the sniper, who wants to pick off the stale quote, and the liquidity provider, who wants to cancel it first.

Because the event is simultaneous and public, this is a race to react, not a race to predict, and someone always loses it. Liquidity providers, who know they will sometimes be sniped, widen their spreads to recover the cost. The result is a socially wasteful investment in raw speed (microwave towers, co-location, custom silicon) that buys no better price discovery, only a better position in a queue. The arms race is, in the authors' framing, a symptom of treating time as a continuous variable when the matching engine is in fact serial.

Batching: discrete time, one uniform price

The fix is to stop processing orders one at a time. Time is divided into discrete intervals of length $\tau$ (the batch interval). Orders that arrive during an interval are sealed, accumulated without execution, and at the end of the interval the whole batch is cleared at once. Demand and supply curves are built from the limit prices, and the auction picks the single price that maximises the matched volume.

Concretely, aggregate demand at a candidate price $p$ is the total quantity of bids willing to pay at least $p$, and aggregate supply is the total quantity of asks willing to sell at no more than $p$. The volume that can transact at $p$ is whichever side is shorter, and the auction maximises it:

$\displaystyle p^\star \;=\; \arg\max_{p}\; \min\bigl(\text{demand}(p),\ \text{supply}(p)\bigr).$

where $\text{demand}(p) = \sum_{i:\,b_i \ge p} q_i$ over bids $(b_i, q_i)$ and $\text{supply}(p) = \sum_{j:\,a_j \le p} q_j$ over asks $(a_j, q_j)$. Maximising $\min(\text{demand},\text{supply})$ is exactly finding where the two staircase curves cross. The clearing price can be reported as the midpoint of the executable band, the gap between the highest matched bid and the lowest matched ask, so that buyers and sellers split the surplus at the crossing.

In code: clear_uniform_price(bids, asks) in mechanisms/fba.py takes lists of (price, qty) and returns (price, quantity) by scanning every submitted limit price as a candidate and keeping the one that maximises matched volume.

Why a uniform price ends the latency race

The decisive property is that every matched order in a batch transacts at the same price $p^\star$, regardless of when it arrived inside the interval. This removes time priority entirely: there is no front of the queue to win, because there is no queue. A sniper who reacts to news one microsecond faster than a rival no longer captures a stale quote; both their orders land in the same batch and clear at one price determined by the whole crowd. Speed within an interval confers no advantage; the only thing that matters is the limit price you are willing to name.

This changes the equilibrium for liquidity providers. They are no longer systematically sniped on public-information events, so the adverse-selection premium baked into their spreads shrinks, and quoted spreads tighten. The competition that remains is the kind a market wants: competition on price, not on reaction time. On a blockchain the same argument neutralises transaction-ordering manipulation: when a block's orders all clear at one uniform price, the validator's power to reorder, insert, or sandwich transactions within the block, the substrate of much MEV, loses its value, because intra-batch position no longer determines execution price.

Relation to the continuous and the single call auction

The frequent batch auction sits between two familiar mechanisms, and is best understood as an interpolation. At one extreme, shrinking the batch interval $\tau \to 0$ recovers the continuous double auction: each order is its own batch, matching is instantaneous, and price–time priority (with its latency race) returns. At the other extreme, a single batch spanning the whole trading day is the classical call auction used at market opens and closes, maximal liquidity consolidation into one uniform-price clearing, but no continuous immediacy at all.

The FBA's contribution is to run the call-auction clearing rule frequently. It keeps the call auction's two virtues, a single fair uniform price and pooled liquidity that resists gaming, while choosing $\tau$ small enough (well under a second) that the market still feels essentially continuous to a human participant. The contrast is sharpest against the CDA: the CDA offers immediacy and pays for it with fleeting quotes and a latency race; the FBA offers near-immediacy and pays for it with a tiny, fixed delay, in exchange for eliminating that race. Where a continuous market asks who got here first, a batch auction asks only at what price the most volume can trade.

In code: BatchAuction in mechanisms/fba.py accumulates orders with submit(side, price, qty) over an interval and resolves them with clear(), which returns the uniform clearing price and matched quantity for the batch.

Try it

A batch clears at one uniform price that maximises matched volume. Against a fixed book (asks 4@98, 3@100, 5@102; bids 3@100, 2@99), vary your buy order and watch the clearing price and volume move in discrete steps.

Code: mechanisms/fba.py · Demo: examples/sim_fba.py · Related: continuous double auction · Research: perps-cda-monteprediction.md