Adverse Selection in Market Making: Every Fill Is Bad News, and We Measured How Bad

The short version, for the impatient. A plain market-making strategy captured $305.43 of spread on Coinbase BTC-USD in one day and lost $331.37 anyway, with zero fees. We ruled out bad luck, a bug and the trend one by one, and what was left is adverse selection (the average fill was underwater within one second). Quoting wider only means you get hurt less often.

The market-making strategy that can't lose

Picture a money machine. Rest a bid $4 below the fair price and an ask $4 above it, and every time someone sells to you and someone else buys from you, you pocket the gap. No view on where Bitcoin is going, no forecast, just patience.

Ours ran on Coinbase BTC-USD on 3 July 2026: 0.01 BTC a quote, re-quoted every 50 order-book events, inventory capped at five fills in one direction, a small skew leaning against whatever we held, 3 ms to the exchange, and fees switched off. Every fill is worth four cents on paper, and the machine took 7,211 of them, which comes to +$288 of paper profit for the day.

It earned every cent of the spread. It still lost $331.

Good news first: the spread came in, and we captured $305.43, a little more than the paper promised (partly because capture is measured against the mid just before each fill, and the skew moves the quotes).

The account, meanwhile, closed at −$331.37.

One day of market making: 3 July 2026Coinbase BTC-USD, quotes $4 either side of mid, 7,211 fills, zero fees
−$600−$400−$200$0$200$400+$305.43Spread captured−$636.80Lost holding inventory−$331.37Result for the dayon paper: 7,211 fills × $4 × 0.01 BTC = +$288−$600−$400−$200$0$200$400+$305.43Spreadcaptured−$636.80Lost holdinginventory−$331.37Result forthe dayon paper: 7,211 fills × $4 × 0.01 BTC= +$288

There were no fees to blame. There was no bug either: our ledger matches the engine to the cent, and we have checked that 181 times across 1–5 July 2026 with a largest disagreement of zero. The machine did exactly what it was built to do, and $619 disappeared anyway.

Where $637 went: the inventory term nobody puts on the dashboard

Every dollar of PnL lands in one of three boxes. Let mim_i be the fair price, taken as the mid, at fill ii; pip_i the price we traded at; qiq_i the size; sis_i the side, +1+1 for a buy and 1-1 for a sell; and mTm_T the fair price at the close:

PnL  =  iqi(si)(pimi)spread capture  +  iqisi(mTmi)inventory holding  +  posT(markTmT)residual \mathrm{PnL} \;=\; \underbrace{\sum_i q_i\,(-s_i)\,(p_i - m_i)}_{\text{spread capture}} \;+\; \underbrace{\sum_i q_i\,s_i\,(m_T - m_i)}_{\text{inventory holding}} \;+\; \underbrace{\mathrm{pos}_T\,(\mathrm{mark}_T - m_T)}_{\text{residual}}

Spread capture is how far from the fair price you traded, in your favour, and it is the number people brag about. Inventory holding is what the price did to each fill's position afterwards, up to the close; traders call it the markout, summed over fills it is adverse selection in dollars, and it is the one you leave off the slide. The residual marks whatever is still open at the close. We ended flat, so it is zero.

This part is plain arithmetic (it holds for any strategy on any engine), so the only interesting question is what lands in each box.

Spread capture: +$305.43. Inventory holding: −$636.80. Residual: $0.00. Total: −$331.37. The box most dashboards leave out is twice the size of the one they show.

"It was just a bad day." It wasn't.

The obvious excuse is that Bitcoin trended and we were on the wrong side. It did rise on 3 July. But a trend pays one side of the book and punishes the other, and our long and short positions lost about equally, so the loss tracked the fills rather than the day.

The most expensive second in market making

Take the average fill and slow it down. You rest a bid. Something big enough to walk through every price level in front of you arrives, and you are filled.

At t=0t = 0 you have earned 4.24 cents. One second later, 7.95 cents are gone. After ten seconds it is 8.60, after five minutes 8.85, and at the close 8.83, so you earned 4.24 and lost 8.83. Each of those is the day's total divided by 7,211, so it is an average, measured against the mid 10 ms before the fill.

The holding loss arrives in the first secondLoss on inventory counted from each fill up to the horizon, summed over the day ($4 quotes)
−$600−$400−$200$0−$573.241 second−$620.0210 seconds−$638.375 minutes−$636.80end of day90% of the final loss−$600−$400−$200$0−$573.241 second−$620.0210 seconds−$638.375 minutes−$636.80end of day90% of the final loss

Across the day, −$573.24 of the −$636.80 was gone one second after the fills. 90% of the damage, in the first second. Some of that move was already under way in the 10 ms before the fill. After five minutes the price does essentially nothing, which is why we don't read this as drift; drift builds up slowly, and this arrives all at once.

Half the loss happened in 83 minutes at the inventory limit

Half the loss is taken in 6% of the dayInventory held, in 0.01 BTC clips, against time spent there and loss taken there ($4 quotes)
0%20%40%60%15%0%0 clips29%2%1 clip24%9%2 clips16%14%3 clips10%20%4 clips6%54%5 clips(limit)share of the dayshare of the holding loss0%20%40%60%15%0%0 clips29%2%1 clip24%9%2 clips16%14%3 clips10%20%4 clips6%54%5 clips(limit)share of the dayshare of the holding loss

Fills on one side come in runs, because the traders hitting you are reacting to the same thing. Each fill pushes your inventory further in the direction the price is about to go against it. We sat at the five-fill limit for 6% of the day, about 83 minutes, and lost more than half the holding loss there. Per bitcoin held, a minute at the limit cost about twenty times what a minute holding a single fill did.

So the machine got mugged, again and again, in the same alley.

The fix everyone tries: quote a wider spread

Stand further away, charge more per fill, and the dangerous traders will go bother someone else. We re-ran the same day at twelve widths, from $1 to $20 either side of the mid, and at first it looks like it works.

From $1 to $6, capture per fill rose six-fold, while the daily loss shrank from $1,545 at $1 to $95 at $6. That is a sixteen-times smaller loss from turning one knob.

We found a profitable spread width

Keep turning the knob, and at $10 the day finishes +$6.49. At $14 it finishes +$13.07.

A market maker that makes money, and all it took was one parameter. The knob works.

Then we counted the fills

At $14 the strategy traded 251 times all day; at $10, 552. The uncertainty on those days is wider than the profit itself, and at $20 the day is back in the red. Call that an edge and you would have to call a few hundred coin flips an edge too.

Now look per fill.

Wider quotes: capture ×6, net per fill barely movesCents per fill, 3 July 2026, one strategy re-run at seven quote widths
−12¢−8¢−4¢capturedlost holdingnet$1$1.5$2$3$4$5$6quote distance from mid (half-spread)−12¢−8¢−4¢capturedlost holdingnet$1$2$3$4$5$6quote distance from mid (half-spread)

Across $1 to $6, where there are thousands of fills behind every point, the holding loss per fill grew right alongside the capture, and the net per fill barely moved: between −3.6 and −4.6 cents at every width.

What widening actually buys: fewer fillsFills per day and the day's result at each quote width, 3 July 2026
0k15k30k45k43,322$1−$1,54532,004$1.5−$1,26324,007$2−$1,00013,097$3−$6037,211$4−$3314,173$5−$1892,436$6−$95quote:day:0k15k30k45k43,322$1−$1,54532,004$1.5−$1,26324,007$2−$1,00013,097$3−$6037,211$4−$3314,173$5−$1892,436$6−$95quote:day:

The whole sixteen-fold improvement came from fewer fills (43,322 at $1, 2,436 at $6). Wider quotes get you the same counterparties, just fewer of them. The leak is still there; you are simply running less water through it.

Getting filled is the bad news: that is adverse selection

If you keep one section of this article, keep this one.

At $4, 78.7% of our quotes sat beyond the fifth price level, which itself sat a median $2.42 behind the best price. Routine flow never gets that far. A trade that reaches you out there has swept everything in front of you, and a trade that big is rarely noise. It may be someone who has decided the price is wrong, or a forced seller clearing a position. Either way, the fact that it reached you is information about the next second, and the next second goes against you.

The further out you stand, the stronger the filter. Our strategy placed 4.4 orders per fill at $1, 26.5 at $4 and 171 at $8, and every extra dollar of width selects your fills more tightly from the violent end of the tape.

Which is adverse selection in one line. Whoever trades against you picks your fills for you, so they are never a random sample of the market, and the pick has a direction.

Your spread-capture number is a choice

One more uncomfortable fact. The capture figures above take the mid 10 ms before each fill. Take it at the fill timestamp and capture drops to 2.71 cents, because the trade that filled you has already torn up the book. Take it a second earlier and it rises to 4.89 cents. The net is −4.60 cents at every reference point we tried.

So if someone shows you a spread-capture figure without saying where they took the mid, they have shown you a choice, and probably a flattering one. The same goes for any "adverse selection costs N times your spread" rule of thumb: holding over capture is 4.3 at a $1 half-spread and 2.1 at $4. We had such a figure in an internal note and withdrew it, because the ratio moves with the quote width you picked and tells you nothing fixed about the market.

What actually works against adverse selection

So much for knobs. This is the conclusion we stand behind.

Put adverse selection in the model before you calibrate anything. The plain Avellaneda–Stoikov setup most people start from assumes every fill earns exactly the half-spread and the people trading with you know nothing. Here the holding term is twice the capture at $4. An optimum found inside that assumption belongs to a different market, and refitting kk will not move it.

Use width to set exposure. It changes how many fills you take and leaves their quality alone, and you pay for it with an order-to-trade ratio that rose from 4.4 at $1 to 171 at $8.

The real work is deciding whether you are in the book when the informed trade arrives: skew against inventory before the book fills up, gate quotes on toxicity, pull a quote, and hold queue position early enough that your fills aren't only the ones that swept past everyone else. We work on these in strategy design and risk controls.

What this does not show

  • One venue, one pair, one day for the curves: Coinbase BTC-USD, 3 July 2026. The identity was checked across 1–5 July 2026. The price rose on every day we measured, and we have not repeated this in a falling market.
  • The slow-motion fill is an average, the day's totals divided by 7,211, and no single fill looked exactly like it.
  • The day's result has an uncertainty band. At $4 it runs from −$396 to −$268 at 95%, and the loss is significant at every width up to $6.
  • No fees. On a run that did carry them (a three-window run with a 1 bp maker fee), fees were the largest line, $5,282 of a $7,567 loss. That run had a different setup and must not be added to the figures above.
  • Our execution model is ours. It places each 0.01 BTC order at the back of the queue at its price, where the best price held a median 0.033 BTC. At $4 it doesn't matter: three different queue models produced the same fills byte for byte and the same −$331.37. At $1 the choice moves the day by $2.32 out of −$1,544.65. For someone quoting at the touch it would matter far more, and we have not measured that case.
  • Order latency is 3 ms. A run at 5 ms is a different measurement, and we do not mix the two.

So, why does your market maker lose money?

The spread is priced fine; ours earned every cent of it. It loses because being filled is itself a signal, the price answers within a second, and the standard model assumes that signal isn't there. Fix the model first, and keep the width for what it is, an exposure dial.

Full method, data and what would falsify the decomposition: Market-Maker PnL: Capture and Holding, Separated.