---
title: "Auction Mechanics and Theory"
book: "Microstructure and Execution"
subject: quant
language: en
chapter: 10
exercises: 8
source: https://one-course.com/books/quant/10/en/chapter/10-auction-mechanics-and-theory
---

# Chapter 10 — Auction Mechanics and Theory

In the minutes before a closing auction the exchange publishes an indicative price and imbalance every few seconds, and much of the auction’s volume arrives in its last seconds. Every participant watches the same numbers and decides when to show its hand. The closing auction sets the prices that index funds track and that funds are valued at, so its design, what is published, when orders are accepted and when exactly it ends, decides who can move the close and who pays for it. This chapter runs closing calls in the exchange simulator, measures how the indicative converges to the final price, prices a late order under a fixed and a [random end](#def-mx-auction-mechanics-and-theory-randomend), and replays the sniping race that [frequent batch auctions](#def-mx-auction-mechanics-and-theory-fba) were proposed to stop.

## 10.1 Uncrossing rules revisited

A call auction (One Quant Book 1, chapter 13) collects orders without matching them and clears them all at one price: the price that maximises the executed volume, then minimises the surplus, then follows the side with the surplus, then stays closest to a reference price (Book 1’s `firm.auction`). With buys of 300 shares at market, 200 at 10.02 and 400 at 10.00, and sells of 500 at 10.00, 300 at 10.01 and 200 at 10.03, the volume is 500 at 10.00, 10.01 and 10.02; the surplus is 400 to buy at 10.00 and 300 to sell at the other two, and the sell pressure picks the lower, 10.01. Madhavan (1992) compared the mechanisms: a periodic auction offers greater price efficiency and can function where continuous mechanisms fail, but traders give up continuity and bear higher information costs.

`firm.exchsim`’s engine runs the calls: orders are accepted without matching, market-on-close and limit-on-close orders (tif C) are kept aside, the engine publishes an indicative price and imbalance on a schedule (feed message I), and the uncross calls `firm.auction`. `firm.auctionsim` states a design as a policy and turns it into the simulator’s configuration.

```python
    def phases(self, open_ns: int, close_ns: int, end_ns: int) -> Phases:
        cutoff = None if self.cutoff_s is None else close_ns - int(self.cutoff_s * SEC)
        return Phases(start_ns=open_ns - SEC, open_ns=open_ns, close_ns=close_ns, end_ns=end_ns,
                      close_auction=True, close_call_ns=close_ns - int(self.call_s * SEC),
                      indicative_every_ns=int(self.indicative_s * SEC), moc_cutoff_ns=cutoff,
                      random_end_ns=int(self.random_end_s * SEC))

    def controls(self, venue: str, close_ns: int, ref_price: int, tick: int = 100) -> list:
        if not self.collar:
            return []
        lo = int(ref_price * (1 - self.collar)) // tick * tick
        hi = -(-int(ref_price * (1 + self.collar)) // tick) * tick
        return [(close_ns - int(self.call_s * SEC), venue, CTL["R"](1, ref_price, lo, hi))]
```

***Listing 10.1.** A closing auction as a policy: the call’s phases, and a collar as a price band from the start of the call. code/firm/auctionsim/firm_auctionsim.py*

## 10.2 Indicative prices and imbalance publication

The indicative is the price the auction would clear at if it ended now, and the imbalance the shares that would be left on one side. Publishing them invites the other side: a large buy imbalance at a price above value is an offer to whoever will sell. The chapter’s closing call lasts five minutes with an indicative every second. Standing limit-on-close interest of 500 shares a tick sits on each side of 100.00; random market-on-close orders of 100 to 1 000 shares arrive five times a minute until five seconds before the end; a fund sends a market-on-close buy of 10 000 shares a minute into the call. Responders read each indicative and, half the time, when the price has been pushed more than a tick from 100.00, offer the other side at 100.01 (or 99.99) in proportion to the distance, 250 shares a tick up to 3 000: they supply the imbalance at the price they believe, not at the price it has been pushed to.

```python
    def on_feed(self, ctx, m):
        if type(m).__name__ != "Feed_I" or m.direction not in "BS":
            return
        if self.rng.random() > self.prob:
            return
        side = "S" if m.direction == "B" else "B"
        away = (m.near - self.ref) if side == "S" else (self.ref - m.near)
        dev = away // 100 - self.premium // 100          # ticks beyond the premium
        if dev < 1:
            return
        px = self.ref + (self.premium if side == "S" else -self.premium)
        ctx.send(Order(side=side, qty=min(self.cap, self.per_tick * dev), price=px, tif="C"))
```

***Listing 10.2.** A responder to the published imbalance: it offers the other side at its own value plus a tick, in proportion to the push. code/microstructure/10-auction-mechanics-and-theory/python/mx_auction.py*

![The closing call. Left: the indicative price of one simulated session; the fund’s buy pushes it up, responders pull it back, and late orders set the close. Right: the distance between the last indicative and the final price, against the time left, mean over 24 sessions. Data: mx_auction.auction_study.](https://one-course.com/images/onecourse/chapters/quant-10/mx-auction-mechanics-and-theory/fig-1d619e5dcffd.svg)

***Figure 10.1.** The closing call. Left: the indicative price of one simulated session; the fund’s buy pushes it up, responders pull it back, and late orders set the close. Right: the distance between the last indicative and the final price, against the time left, mean over 24 sessions. Data: `mx_auction.auction_study`.*

Over 24 simulated sessions ([Figure 10.1](#fig-mx-auction-mechanics-and-theory-path)) the last indicative is 4.7 ticks from the final price 120 seconds before the cross, 3.5 at 60 seconds, 2.2 at 30 and 1.0 at 10; in the last five seconds, when no more orders arrive, it is the final price. Paired volume arrives earlier than price information: 76% of the final paired shares are already paired 120 seconds before the cross, 89% at 60 and 95% at 30. The volume is set early and the price late, because the price is set by the marginal orders.

**As of September 2026 — Closing-auction rules on two exchanges.**

Nasdaq publishes closing cross net order imbalance information between 3:50 and 4:00 p.m. ET; its imbalance-only close orders, which exist to offset imbalances, must be priced and execute only at or above (buy) or below (sell) the 4:00 p.m. bid or ask. On the London Stock Exchange each auction call and each extension is followed by a random period of up to 30 seconds (the exchange’s guide of March 2020).

## 10.3 Cut-offs, collars and random ends

**Definition 10.1 (Auction cut-off time).**

An *auction cut-off time* is the moment after which some orders can no longer be entered, modified or cancelled for the auction, typically market-on-close and limit-on-close orders, while orders that offset the published imbalance may still be accepted.

**Definition 10.2 (Auction collar).**

An *auction collar* is a price range around a reference price outside which the auction may not clear, or orders may not be priced; if the uncross would fall outside it, the venue extends the call or clears at the collar.

**Definition 10.3 (Random end).**

A *random end* ends an auction call at a random moment within a known window after its scheduled end, so that nobody can be sure to be the last to enter an order.

The three answer the same problem: the last order into a call can move its price and nobody can respond. A cut-off stops the orders that would create imbalances late; a collar bounds how far any order can move the price; a [random end](#def-mx-auction-mechanics-and-theory-randomend) takes away the certainty of being last. `firm.auctionsim` implements the collar as a price band from the start of the call (orders outside it are rejected, `Out_J` with reason B), the cut-off with the engine’s freeze control, and the [random end](#def-mx-auction-mechanics-and-theory-randomend) with the simulator’s uniform end time.

## 10.4 Strategic behaviour near the uncross

What is the last second worth? The experiment adds one more market-on-close buy of 3 000 shares to each session, sent 60, 10 or 1 second before the scheduled end, and measures how far it moves the closing price against the same session without it ([Figure 10.2](#fig-mx-auction-mechanics-and-theory-late)). With a fixed end, the order moves the close by 3.0 ticks (standard error 0.6) sent a minute early, 3.5 ten seconds early and 4.7 (0.4) in the last second: sent late, it walks the standing interest with no time for responders to offer. With a [random end](#def-mx-auction-mechanics-and-theory-randomend) of up to 30 seconds, the late order moves the close by 3.7 ticks (0.6): the responders get the rest of the random window. The gain from submitting last, 1.75 ticks with a fixed end, falls to 0.75 with a random one. That gain is what a participant who wants to move the close (to mark a portfolio, or to trigger something priced off it) buys by waiting; it is also the price a legitimate late order pays, which is why providers wait too.

![How far a 3 000-share market-on-close buy moves the closing price, against when it is sent, mean and standard error over 24 simulated sessions. The last second is worth most with a fixed end. Data: mx_auction.auction_study.](https://one-course.com/images/onecourse/chapters/quant-10/mx-auction-mechanics-and-theory/fig-e3bc11eb0a91.svg)

***Figure 10.2.** How far a 3 000-share market-on-close buy moves the closing price, against when it is sent, mean and standard error over 24 simulated sessions. The last second is worth most with a fixed end. Data: `mx_auction.auction_study`.*

Real closes add what the simulation leaves out: participants who choose their own timing, imbalance-only orders, and large index flows known in advance. Bogousslavsky and Muravyev (2023) study who trades at the close and what it means for [price discovery](https://one-course.com/books/quant/10/en/chapter/8-fragmentation-and-routing#def-mx-fragmentation-and-routing-discovery) and liquidity.

## 10.5 Frequent batch auctions

**Definition 10.4 (Frequent batch auction).**

A *frequent batch auction* replaces continuous matching with uniform-price call auctions held at short fixed intervals: orders arriving within an interval are treated as simultaneous and cleared together at its end.

Budish, Cramton and Shim (2015) argued that the high-frequency trading arms race is a symptom of continuous matching: when public information moves the price, a fast trader can take a quote before its owner cancels it, and whoever is fastest wins; they proposed batch auctions, for example every tenth of a second, so that time becomes discrete and a small speed advantage stops deciding who trades. The simulator runs them with `batch_interval_ns` (`firm.auctionsim.batch_venue`).

The race is easy to stage. A quoter shows one lot a tick either side of a public reference; the reference jumps two ticks 400 times; on each jump the quoter cancels and requotes after its latency, and a sniper sends an order to take the stale quote after its own. With the quoter 150 microseconds slower than the sniper, the sniper takes the stale quote on 99.75% of the jumps in the continuous market, 11.75% with batches every millisecond, 1.25% every 10 milliseconds and 0.25% every 100. With a gap of a millisecond, 99.75%, 99.75%, 11.0% and 0.75%. The share is close to the latency gap divided by the batch interval, capped at one: the sniper wins only when a batch closes between its order and the quoter’s cancel. A batch interval longer than the latency gaps that matter turns the race into an auction.

## 10.6 Tutorial: the last ten seconds

**Goal.** Run closing calls, watch the indicative converge, price the last second under two end rules, and replay the sniping race. **End state:** Figures [10.1](#fig-mx-auction-mechanics-and-theory-path) and [10.2](#fig-mx-auction-mechanics-and-theory-late) and the numbers of sections 2, 4 and 5.

1. **Design.** `firm_auctionsim.ClosingAuction(call_s, indicative_s, cutoff_s, collar, random_end_s)` , then `.phases(…)` and `.controls(…)` into `ExchangeConfig` and `Simulator.add_events` .
2. **Sessions.** `mx_auction.close_session(seed, random_end_s, extra)` ; `indicatives(res)` and `final_cross(res)` .
3. **Study.** `auction_study()` : the gap and arrival paths, and the move of the close by a late order, over 24 seeds.
4. **Race.** `snipe_race(interval_ms, quoter_us=…, sniper_us=…)` and `race_study()` ; draw with `fig_auction.py` .

**What to change next.** Add a cut-off ten seconds before the end for market-on-close orders only, and let responders keep offering; give the responders a lag of five seconds and watch the [random end](#def-mx-auction-mechanics-and-theory-randomend)’s protection shrink.

## 10.7 Build: auction policies

**Purpose.** Auction designs for the simulator: the closes of chapters 16 and 28’s benchmark algorithms, the halt reopenings of chapter 25, and Book 11’s auction strategies.

**Interface.** `ClosingAuction(call_s, indicative_s, cutoff_s, collar, random_end_s)` with `.phases`, `.controls`; `batch_venue(interval_ms)`; `indicatives(res, venue, locate)`, `final_cross(res, venue, locate)`, `gap_path(ind, final, grid_s)`.

**Rules.** The engine keeps the auction’s orders and uncrosses through Book 1’s `firm.auction`; indicatives are published only when some volume pairs; the collar is a price band from the start of the call; the [random end](#def-mx-auction-mechanics-and-theory-randomend) is uniform on its window.

**Acceptance tests.** `code/firm/auctionsim/tests/`: a scripted call whose indicatives and cross are checked by hand; a [random end](#def-mx-auction-mechanics-and-theory-randomend) inside its window; an order outside the collar rejected; a batch venue’s interval.

**Stretch.** Price-monitoring extensions when the uncross would leave the collar; imbalance-only orders; a closing call on several venues with one reference price.

Sources and further reading

- A. Madhavan, “Trading mechanisms in securities markets”, *Journal of Finance* 47(2), 1992.
- E. Budish, P. Cramton and J. Shim, “The high-frequency trading arms race: frequent batch auctions as a market design response”, *Quarterly Journal of Economics* 130(4), 2015.
- V. Bogousslavsky and D. Muravyev, “Who trades at the close? Implications for price discovery and liquidity”, *Journal of Financial Markets* 66, 2023.
- Nasdaq, *The Nasdaq Opening and Closing Crosses* , web page, 2026.
- London Stock Exchange, *Maintaining orderly markets: circuit breakers explained* , 2020.

## 10.8 Exercises

**Exercise 10.1 ★.**

Buys: 300 shares at market, 200 at 10.02, 400 at 10.00. Sells: 500 at 10.00, 300 at 10.01, 200 at 10.03. Find the uncrossing price, the volume and the surplus with Book 1’s rules.

**Solution of Exercise 10.1.**

At 10.00 demand is 900 and supply 500; at 10.01 and 10.02 demand 500 and supply 800; at 10.03 demand 300 and supply 1 000. The volume, 500, is largest at 10.00, 10.01 and 10.02; the surplus is 400 to buy at 10.00 and 300 to sell at the others, so 10.01 and 10.02 remain; the surplus is on the sell side, so the lower, 10.01: 500 shares, 300 unexecuted sell interest.

**Exercise 10.2 ★.**

The indicative shows 20 000 shares paired at 50.10 with 3 000 more to buy. What does that tell a liquidity provider, and at what price would it offer?

**Solution of Exercise 10.2.**

At 50.10 there are 3 000 more shares to buy than sellers: a seller of up to 3 000 shares would lower the price or fill at it. A provider who values the stock below 50.10 offers some of the 3 000 at its value plus a premium; if it offers at 50.10 or below, the indicative falls toward its price.

**Exercise 10.3 ★.**

A sniper is 150 microseconds faster than a quoter. Approximately how often does it take a stale quote under batch auctions every 1 and every 10 milliseconds? And with a gap of a millisecond and batches every 10?

**Solution of Exercise 10.3.**

About $0.15/1=15\%$ and $0.15/10=1.5\%$; with a one-millisecond gap and batches every 10 milliseconds, about 10%. The simulation gave 11.75%, 1.25% and 11.0%.

**Exercise 10.4 ★★.**

Standing interest is 500 shares a tick on the sell side. How many ticks does a market-on-close buy of 3 000 shares move the close if nobody responds? What did the simulation measure for a last-second order, and why is it less?

**Solution of Exercise 10.4.**

$3\,000/500=6$ ticks. The simulation measured 4.7 ticks for a last-second order: it moves the close from where the session was going to end, and part of the standing interest it walks was already paired with other orders or offset by responders earlier in the call.

**Exercise 10.5 ★★.**

Why is paired volume known long before the price in the simulated call (76% of the paired shares two minutes before the cross, with the indicative still 4.7 ticks away)?

**Solution of Exercise 10.5.**

Most paired shares come from the standing interest meeting the early market-on-close flow; later orders change the pairing little but decide which marginal order sets the price, so the indicative keeps moving while the paired volume barely changes.

**Exercise 10.6 ★★.**

Explain why a [random end](#def-mx-auction-mechanics-and-theory-randomend) reduces the gain from submitting last, and what it costs other participants.

**Solution of Exercise 10.6.**

Nobody knows whether an order sent at the scheduled end will be the last: responders may still arrive, so a late order’s effect on the price can be answered (4.7 ticks falls to 3.7 in the simulation). Participants who need to be in the auction must enter before the window and bear the uncertainty of the exact time of their fill.

**Exercise 10.7 ★★★.**

*Coding.* Rerun `snipe_race` with batches every 1, 10 and 100 milliseconds and a latency gap of 150 microseconds, and compare the sniping rate with the gap divided by the interval. Where does the approximation fail?

**Solution of Exercise 10.7.**

1 ms: 11.75% against 15%; 10 ms: 1.25% against 1.5%; 100 ms: 0.25% against 0.15%. The approximation assumes jumps fall uniformly within batches and that one batch boundary decides; with 400 jumps the rates are estimated to about a percentage point, and when the gap exceeds the interval the rate is one.

**Exercise 10.8 ★★★.**

*Find the flaw.* “The closing price is set by the whole market, so no single late order can move it much.”

**Solution of Exercise 10.8.**

The close is set by the marginal orders, and the last one in has nobody to answer it: in the simulation a 3 000-share buy in the last second of a fixed-end call moved the close by 4.7 ticks, 1.75 more than the same order a minute earlier. Cut-offs, collars and [random ends](#def-mx-auction-mechanics-and-theory-randomend) exist because single late orders can move it.

## 10.9 Problem: The Last Ten Seconds

**Problem 10.1.**

Weekend problem — the last ten seconds

An exchange asks whether to add a [random end](#def-mx-auction-mechanics-and-theory-randomend) to its closing auction and whether to replace continuous trading with [frequent batch auctions](#def-mx-auction-mechanics-and-theory-fba). Answer with the simulator.

**Part I — The call.**

1. State the uncrossing rules and apply them to exercise 1.
2. What does the engine publish during a call, and when?
3. Describe the simulated call’s participants.
4. How do the responders price their offers, and why does that matter?

**Part II — Convergence.**

5. Give the gap between the indicative and the final price at 120, 60, 30 and 10 seconds.
6. Why is it zero in the last five seconds?
7. What share of the paired volume is known two minutes and one minute before the cross?
8. What do Nasdaq and the London Stock Exchange publish or randomise?

**Part III — The last second.**

9. Define a cut-off, a collar and a [random end](#def-mx-auction-mechanics-and-theory-randomend) .
10. How far does a 3 000-share buy move the close when sent 60, 10 and 1 seconds before a fixed end?
11. And before a [random end](#def-mx-auction-mechanics-and-theory-randomend) of up to 30 seconds?
12. What is the gain from submitting last under each rule?
13. Who gains from waiting, and who pays?

**Part IV — Batches and the verdict.**

14. State Budish, Cramton and Shim’s argument.
15. Describe the sniping race and give its results for the two latency gaps.
16. Derive the approximation gap divided by interval.
17. What does a batch interval cost traders who are not racing?
18. State the *named result* : the gap between the indicative and the final price against the time to the uncross, and the gain from late submission under a fixed and a [random end](#def-mx-auction-mechanics-and-theory-randomend) .
19. Should the exchange add a [random end](#def-mx-auction-mechanics-and-theory-randomend) ? Answer in one sentence.
20. Should it switch to batches, and at what interval?

**Solution of Problem 10.1.**

**1.** Maximum volume, minimum surplus, market pressure, closeness to the reference; 10.01, 500 shares. **2.** An indicative price, paired shares and imbalance, every second in the simulated call, once some volume pairs. **3.** Standing interest of 500 shares a tick, random market-on-close orders, a fund’s 10 000-share buy, and responders. **4.** At 100.01 or 99.99, their own value plus a tick, in proportion to how far the indicative has been pushed; offering at the pushed price would lock the move in. **5.** 4.7, 3.5, 2.2 and 1.0 ticks. **6.** No more orders arrive in the last five seconds. **7.** 76% and 89%. **8.** Nasdaq: imbalance information between 3:50 and 4:00 p.m.; the LSE: a random period of up to 30 seconds after each call and extension. **9.** See the definitions. **10.** 3.0, 3.5 and 4.7 ticks. **11.** 3.0, 3.5 and 3.7 ticks. **12.** 1.75 ticks with a fixed end, 0.75 with a random one. **13.** Whoever wants to move the close gains; the other side of the auction pays the moved price. **14.** Continuous matching makes speed decide who takes stale quotes; batch auctions every fraction of a second remove the value of small speed advantages. **15.** 99.75%, 11.75%, 1.25% and 0.25% for a 150-microsecond gap at 0, 1, 10 and 100 ms; 99.75%, 99.75%, 11.0% and 0.75% for a millisecond. **16.** The sniper wins only if a batch closes between its order and the quoter’s cancel: with the jump time uniform, probability gap$/$interval. **17.** Waiting up to one interval for every execution, and less information from the continuous price. **18.** *Named result*: the indicative is 4.7 ticks from the final price two minutes before the cross, 1.0 at ten seconds and exact in the last five; submitting a 3 000-share buy in the last second rather than a minute early moves the close by 1.75 ticks more with a fixed end and by 0.75 with a [random end](#def-mx-auction-mechanics-and-theory-randomend) of up to 30 seconds. **19.** Yes: it more than halves the value of being last at the cost of an uncertain end time. **20.** Batches longer than the latency gaps that decide races, about a millisecond or more for the gaps simulated here, remove most sniping; the interval should stay short enough for traders who want immediacy.

## 10.10 Interview questions

**Interview question 10.1 ★ trader.**

How is a closing auction’s price determined, and what is an imbalance?

**Solution of Interview question 10.1.**

All orders are collected and cleared at one price that maximises executed volume (then minimises the surplus, follows its side, then the reference); the imbalance is the quantity left on one side at the indicative price.

*What the interviewer is looking for: Uniform price; the rule order; the imbalance.*

**Interview question 10.2 ★★ trader.**

You must buy 500 000 shares at the close. When do you send the order, and what do you watch?

**Solution of Interview question 10.2.**

Early enough to be inside the cut-off and to let offsetting interest respond to the published imbalance, split if the order is large relative to typical closing volume; I watch the imbalance publications, the indicative’s distance from the continuous price and the offsetting interest arriving.

*What the interviewer is looking for: Cut-offs; letting the other side respond; imbalance monitoring.*

**Interview question 10.3 ★★ researcher.**

Why do some exchanges end auctions at a random time? What would you measure to see whether it works?

**Solution of Interview question 10.3.**

To remove the certainty of being last and so the incentive to wait and move the price. Measure the share of volume and of price changes in the last seconds, and the gap between the last indicative and the final price, before and after, or against a similar market without it.

*What the interviewer is looking for: Last-mover incentive; late activity and gaps as measures.*

**Interview question 10.4 ★★ researcher.**

Explain [frequent batch auctions](#def-mx-auction-mechanics-and-theory-fba) and the problem they address.

**Solution of Interview question 10.4.**

Uniform-price auctions every short interval instead of continuous matching: orders within the interval are simultaneous, so the fastest trader no longer takes every stale quote; sniping falls to about the latency gap divided by the interval.

*What the interviewer is looking for: The race; discrete time; the gap-over-interval intuition.*

**Interview question 10.5 ★★ developer.**

Implement the indicative price of a call auction efficiently as orders arrive. What data structure do you keep?

**Solution of Interview question 10.5.**

Cumulative demand and supply by [price level](https://one-course.com/books/quant/10/en/chapter/1-the-limit-order-book#def-mx-the-limit-order-book-tick) (two sorted arrays or trees of aggregated size, with [market orders](https://one-course.com/books/quant/10/en/chapter/1-the-limit-order-book#def-mx-the-limit-order-book-orders) separate), updated in $O(\log n)$ per order; the indicative scans for the maximum of $\min(D,S)$ with the tie rules, or keeps it incrementally near the last indicative.

*What the interviewer is looking for: Aggregated depth; cumulative sums; tie-breaking.*

**Interview question 10.6 ★★★ trader, researcher.**

A competitor always enters large closing orders in the last second. How would you tell a legitimate strategy from an attempt to move the close?

**Solution of Interview question 10.6.**

Compare its orders with its positions and with instruments priced off the close (derivatives, fund valuations), measure the price impact of its late orders and whether prices revert after the close; legitimate late orders come with a reason to trade at the close and show no such pattern.

*What the interviewer is looking for: Intent evidence; reversal after the close; related positions.*
