A Real Market Maker

15th June 2026

A previous article introduced the naive market maker — place a bid at the touch, place an ask at the touch, hope both fill, take the spread. That version is doomed for two reasons. It sits at the back of the resting queue, so its fills are slow. And the moment the touch moves, one side fills and the other does not, leaving an exposure that the next tick can wipe out.

A real market maker has to answer four mathematical questions:

  1. Given the current book, what is the fair price of the asset?
  2. Given that fair price, where should the two-sided quote go — and how do you avoid quoting yourself into the middle of an empty spread?
  3. As inventory accumulates, how much should the quote lean — and at what point does one side have to go silent?
  4. Are the fills you are getting actually paying for the adverse selection you are accepting, or are you subsidising informed traders?

The rest of this article works through each of these.

Fair Value From An Imbalanced Book

The natural first guess for fair price is the midpoint of the best bid and best ask:

mid=pbb+pbl2\text{mid} = \frac{p_{bb} + p_{bl}}{2}

This is wrong whenever the two sides of the book carry different volume. A book with $5000 resting on the bid and $20 resting on the ask is not balanced at the mid — the thin ask side will be lifted long before the heavy bid side is hit, and the touch is about to walk up. The mid does not see this; the microprice does.

The microprice is a size-weighted average that pulls toward the thinner side:

micro=pbbsbl+pblsbbsbb+sbl\text{micro} = \frac{p_{bb} \cdot s_{bl} + p_{bl} \cdot s_{bb}}{s_{bb} + s_{bl}}

Note the crossed indices. The bid price is weighted by the ask size, not the bid size. This is the right asymmetry: when the ask is thin (sbls_{bl} small), the bid price gets very little weight, and the microprice sits near the ask — which is where the touch is about to go. When the two sides are balanced, the microprice collapses to the mid.

A simple two-asset example makes this concrete. Suppose pbb=100p_{bb} = 100, pbl=101p_{bl} = 101. With sbb=sbl=1000s_{bb} = s_{bl} = 1000, the microprice is 100.5100.5 — exactly the mid. With sbb=1000,sbl=50s_{bb} = 1000, s_{bl} = 50, the microprice is

10050+10110001000+50=100.952\frac{100 \cdot 50 + 101 \cdot 1000}{1000 + 50} = 100.952

— pulled almost all the way to the ask, because that is the side about to break. With the imbalance reversed, the microprice sits at 100.048100.048.

This is the right anchor, but it is too noisy to be used directly. On a thin book, one cancelled order can move it half a tick. So fair value is held in a state variable and blended toward the microprice on every update with a fixed weight α\alpha:

fairt+1=fairt+α(microtfairt)\text{fair}_{t+1} = \text{fair}_t + \alpha \cdot (\text{micro}_t - \text{fair}_t)

This is an exponential moving average with smoothing constant α\alpha. In the algorithm α=0.30\alpha = 0.30. The half-life of a microprice excursion is then ln2/ln(1α)1.94\ln 2 / -\ln(1 - \alpha) \approx 1.94 updates — fast enough to follow real moves, slow enough that a single phantom tick decays away in two updates instead of resetting the belief.

There is a second source of fair-value information that the microprice cannot see: our own fills. When one of our resting bids matches, somebody crossed the spread to sell into us. That is an aggressor revealing direction — pressure is down. When one of our resting asks matches, the aggressor was a buyer and pressure is up. Each quote fill therefore drifts fair value by a small fixed amount in the implied direction:

fairfair+sideβ\text{fair} \leftarrow \text{fair} + \text{side} \cdot \beta

with side=+1\text{side} = +1 for a bid fill (signalling sell pressure on the inverse-tick convention used by this market) and 1-1 for an ask fill, and β=0.4\beta = 0.4 ticks per fill. The microprice handles passive information; the fill drift handles active information.

The Two-Anchor Quote

With fair value in hand, the question becomes where to quote. The naive answer is "one minimum edge either side of fair":

pbid=fairh,pask=fair+hp_{\text{bid}} = \text{fair} - h, \qquad p_{\text{ask}} = \text{fair} + h

where hh is the minimum half-spread you are willing to be paid. This is wrong the moment the visible market is wider than 2h2h.

Consider a book with the bid at 100.00100.00 and the ask at 101.80101.80. Fair value sits at the mid, 100.90100.90. With h=0.10h = 0.10, the naive rule quotes 100.80/101.00100.80 / 101.00 — sitting in the middle of the spread, leading the resting queue on both sides by nearly a dollar. Both quotes would be lifted instantly by anyone willing to take the existing touch. The maker has converted itself into a taker and given the spread away.

The fix is to anchor the quote on two constraints simultaneously and let whichever demands the wider quote win each side.

Anchor 1 — the edge floor.

pbid(1)=fairh,pask(1)=fair+hp_{\text{bid}}^{(1)} = \text{fair} - h, \qquad p_{\text{ask}}^{(1)} = \text{fair} + h

Never quote closer to fair than hh. Below this, the half-spread is not large enough to cover the adverse selection embedded in any fill.

Anchor 2 — the queue bound.

pbid(2)=pblτ,pask(2)=pbb+τp_{\text{bid}}^{(2)} = p_{bl} - \tau, \qquad p_{\text{ask}}^{(2)} = p_{bb} + \tau

Where τ\tau is one tick. Never quote more aggressively than one tick inside the existing touch. Quoting tighter than this leads a resting queue that was already winning — handing free edge to whoever was about to take the existing touch.

The combined rule takes the less aggressive of the two on each side:

pbid=min(pbid(1),pbid(2)),pask=max(pask(1),pask(2))p_{\text{bid}} = \min(p_{\text{bid}}^{(1)}, p_{\text{bid}}^{(2)}), \qquad p_{\text{ask}} = \max(p_{\text{ask}}^{(1)}, p_{\text{ask}}^{(2)})

On the wide 100.00/101.80100.00 / 101.80 book the queue bound binds — the quote becomes 100.01/101.79100.01 / 101.79, one tick inside the touch on both sides. The captured round-trip is 1.781.78 instead of the 0.200.20 the naive rule would have produced, and there is no scenario where the quote ends up inside the resting touch. On a tight 100.80/101.00100.80 / 101.00 book the edge floor binds — the bid is 100.80100.80 at the touch, the ask is 101.00101.00 at the touch, and we sit behind the queue rather than cross fair for sub-edge fills.

A final passivity check guarantees we never quote through the touch:

pbidpbb,paskpblp_{\text{bid}} \leq p_{bb}, \qquad p_{\text{ask}} \geq p_{bl}

If the inequalities collapse — for instance on a one-tick market where the edge floor is already wider than the spread — the algorithm stands down on both sides until the book widens again.

Inventory As A Single Number

Two-sided market making means the only safe state is flat. The danger is not a single bad fill — it is a sequence of one-sided fills that turn a market maker into a directional bet on an asset they never wanted to be long or short.

Inventory is summarised by one signed scalar, δ\delta, defined as the difference in P&L between the two possible terminal states. For a binary-outcome contract priced at pp and a bid fill of stake ss:

δδ+sp(long the contract)\delta \leftarrow \delta + s \cdot p \qquad (\text{long the contract})

An ask fill of stake ss at price pp decreases δ\delta by the same amount. By construction, δ=0\delta = 0 is the state in which terminal P&L is independent of the outcome — the green position. (For a non-terminal asset, δ\delta collapses to signed notional and the same arithmetic applies.)

Two things happen to the quote as δ|\delta| grows.

Skew. The centre of the two-sided quote shifts proportionally to δ\delta:

centre=fair+δδmaxk\text{centre} = \text{fair} + \frac{\delta}{\delta_{\max}} \cdot k

where δmax\delta_{\max} is the hard inventory cap and kk is the maximum skew in ticks. The whole book the maker shows moves with δ\delta: when long, both quotes move up, courting sellers onto our ask and discouraging buyers onto our bid. The bid is not silenced — it is repriced. At δ=δmax/2|\delta| = \delta_{\max}/2, the centre has moved k/2k/2 ticks; at δ=δmax|\delta| = \delta_{\max}, it has moved a full kk ticks.

The cap. Past δ>δmax|\delta| > \delta_{\max}, the accumulating side stops quoting entirely. The reducing side continues. This is the only moment one side goes silent.

There is also an urgency threshold δu<δmax\delta_u < \delta_{\max} at which the reducing side gives up its queue bound and chases fair toward the touch, accepting a worse queue position in exchange for a faster rebalance. The structure of the response is therefore tiered:

State Both sides quote Skew Reducing side aggressive?
δ<δu\|\delta\| < \delta_u yes small no
δuδ<δmax\delta_u \leq \|\delta\| < \delta_{\max} yes growing yes
δδmax\|\delta\| \geq \delta_{\max} one maxed yes

The chart below tracks one 7-minute session. The black line is δ\delta in dollars. The shaded green band is the safe range δ<δmax|\delta| < \delta_{\max}, with δmax\delta_{\max} set to $0.10. The dashed orange lines mark the urgency threshold δu\delta_u at $0.06. The purple line below is the resulting quote-centre skew in ticks.

Inventory delta over time, with quote-center skew below

Inventory swings between roughly ±\pm $0.06 for most of the session, with occasional excursions to ±\pm $0.11 — slightly past the cap. The overshoot is structural: the cap stops the next quote on the accumulating side, but the in-flight order that pushed δ|\delta| over the cap is allowed to land. Skew tracks δ\delta proportionally and inverts when δ\delta changes sign.

The principle is that a balanced two-way book consumes no directional budget at all. Bid fills and ask fills cancel in δ\delta, and the maker keeps quoting both sides indefinitely. The directional budget is paid only when fills are one-sided — exactly when it should be.

Mark-Outs And The Toxicity Filter

The deepest problem in passive market making is adverse selection. A counterparty willing to cross your quote at the touch usually knows something you do not — otherwise they would have waited. So on average, the mid moves against you immediately after a fill, and the entire economics of the strategy depend on whether the spread you charged exceeds the size of that move.

This is measurable. A mark-out compares the fill price to the market mid at some horizon HH after the fill, signed so positive means the move was in your favour:

markout=side(pfillmidt+H)\text{markout} = \text{side} \cdot (p_{\text{fill}} - \text{mid}_{t + H})

with side=+1\text{side} = +1 for a bid fill (you bought, you want the mid to go up afterwards) and 1-1 for an ask fill. In units of ticks, this is the ratio above divided by the local tick size.

The choice of HH matters. Too short and the mid has not moved enough to separate signal from noise. Too long and unrelated price movement dominates. Ten seconds is a reasonable choice for low-frequency books with many ticks of mid drift per minute.

Aggregate markouts over a rolling window of NN fills gives an estimate of the per-fill expectation:

markout=1Ni=1Nmarkouti\overline{\text{markout}} = \frac{1}{N} \sum_{i=1}^{N} \text{markout}_i

If markout0\overline{\text{markout}} \geq 0, the noise is paying the maker the spread on average — the desired state. If markout\overline{\text{markout}} becomes negative — by more than the maker's half-spread hh — fills are systematically more adverse than the edge being charged. The book is toxic.

The response to toxicity is to make the maker less attractive to informed flow while keeping it available to uninformed flow: double the half-spread and halve the quote size. The first widens what informed flow has to give up to get a fill. The second reduces the cost of being picked off when one slips through. The flag clears automatically as soon as the rolling average recovers above the threshold.

The chart below shows the markout distribution across 217 fills over 16 live sessions, with the toxic threshold (orange dashed) and the empirical mean (green) marked.

Mark-out distribution across 16 live sessions

The distribution is roughly symmetric and tightly centred. The mean is +0.19+0.19 ticks — a thin but positive expectation per fill. No heavy left tail. This is what a healthy mark-out distribution looks like: noise traders paying the spread on average, the occasional informed counterparty taking it back, but the cumulative balance favouring the maker.

Order-Flow Imbalance As A Leading Signal

Mark-outs are a trailing signal — by definition, you only know whether a fill was adverse HH seconds after it happened. A faster signal is the imbalance on the public tape, right now.

Each newly-printed trade is signed by which side of the previous touch it crossed:

signt={+1trade pricepbl(t1)1trade pricepbb(t1)\text{sign}_t = \begin{cases} +1 & \text{trade price} \geq p_{bl}^{(t-1)} \\ -1 & \text{trade price} \leq p_{bb}^{(t-1)} \end{cases}

A +1+1 print is a buyer aggressing into the resting ask — pressure up. A 1-1 print is a seller aggressing into the resting bid — pressure down. Over a rolling window of the last WW prints, the imbalance is

I=i=tW+1tsigni[W,W]I = \sum_{i=t-W+1}^{t} \text{sign}_i \in [-W, W]

If Iθ|I| \geq \theta for some threshold θ\theta (in the algorithm, W=10W = 10 and θ=7\theta = 7), the tape is in a run. The response has two parts.

Shift with the run. The quote centre moves one extra tick in the direction of II. In effect this front-runs the fair-value drift that the next several fills would have produced — instead of letting each individual fill push fair by β\beta ticks, the tape signal lets the quote react after a tenth of a second of imbalance rather than waiting on the mark-out window.

Widen the side being hit. The half-spread on the side that the run is aggressing into widens by one extra tick. If the tape is running buy-aggressive, sellers are being hit, so our ask widens; conversely if the tape is running sell-aggressive, our bid widens. The maker accepts a slightly worse fill price in exchange for not being run over by the side that has just announced its intent.

The combined effect is that one-way flow does not silently pick off the resting two-sided book. The maker steps out of the way before the mark-outs have time to detect the damage.

Closing The Position

For an asset with a finite horizon — a contract that settles, an instrument with a known close — there is a final problem: closing out residual inventory before the maker is forced to carry it through the settlement event.

The trivial solution is to take the touch:

hedge stake=δptouch,side={askδ>0bidδ<0\text{hedge stake} = \frac{|\delta|}{p_{\text{touch}}}, \qquad \text{side} = \begin{cases} \text{ask} & \delta > 0 \\ \text{bid} & \delta < 0 \end{cases}

This is the only moment the strategy crosses the spread on purpose, and it is necessary. A passive hedge that does not fill before the close leaves the position exposed to the settlement event — strictly worse than paying one tick of slippage for a guaranteed match.

The hedge fires when δ>ϵ|\delta| > \epsilon for a small green tolerance ϵ\epsilon. If a hedge of the minimum stake would overshoot — driving the position past flat into the opposite exposure — the algorithm carries the residual instead. There is a strict inequality the residual has to satisfy:

sminptouch<2δs_{\min} \cdot p_{\text{touch}} < 2 |\delta|

If this holds, hedging is cheaper than carrying. If it does not, the minimum-stake hedge would land the maker on the other side at greater magnitude than the current exposure, and the correct action is to stand pat.

Putting It All Together

The chart below shows the touch, the maker's resting quotes (small triangles), and the resulting fills (open circles) over a single 7-minute session. The vertical dashed line is the green-up hedge at the end.

One session: touch, quotes, and fills

The quotes track one tick inside the touch through the steady mid-session phase. When the book widens — at the start, and again toward the close — the quotes spread further apart, governed by the edge floor. Fill density follows book activity: clusters where the touch moves, gaps where it sits still. The hedge at the end takes the touch to close out a residual exposure of slightly over $0.08.

Across 16 sessions and roughly 1,900 per-side decisions, the loop fires the various gates in a stable proportion. About 89% of the time the decision is either "place a new quote" or "the existing quote is still valid". The post-fill cooldown — a deliberate pause that prevents the same fill being replaced and eaten again at the same price — fires on roughly 10% of decisions. The inventory cap binds on roughly 0.6%.

Decision breakdown across 16 sessions: placed, live, cooldown, delta-cap

The 0.6% inventory-cap share is the most informative number here. It says that the skewing-rather-than-gagging response is doing the work — the cap exists as a safety net but rarely binds because the proportional skew handles the vast majority of inventory excursions before they reach the limit.

The Mathematical Core

Stripped of implementation, every real market maker is doing six things in sequence on each book event:

  1. Form a fair price that respects book imbalance: an EMA toward the microprice.
  2. Construct a two-sided quote that respects both the edge floor and the queue bound: take the less aggressive of fair ±h\pm h and touch ±τ\pm \tau.
  3. Lean the quote against inventory: shift the centre by (δ/δmax)k(\delta / \delta_{\max}) \cdot k ticks.
  4. Hard-cap inventory only as a last resort: at δ>δmax|\delta| > \delta_{\max}, silence the accumulating side.
  5. Measure adverse selection through mark-outs; widen and shrink under toxic conditions; revert when toxicity passes.
  6. Step out of the way of one-way flow on the tape signal, before the mark-outs catch up.

Each of these is a small, local rule. None of them depends on a model of the underlying asset. The maker is a controller, not a forecaster — it does not try to predict where the price is going. It tries to be paid the spread when noise traders cross it, and to be small or absent when informed traders do.

What it cannot do is invent edge that is not there. If the spread on offer is structurally narrower than the adverse selection embedded in the flow, the mark-out filter will keep widening, the quote will keep sitting behind the touch, and the maker will earn nothing. The strategy is profitable when the realised mark-out distribution looks like the one above — symmetric, tight, slightly positive — and not otherwise.