Market-Maker PnL: Capture and Holding, Separated

Result

A market maker's result decomposes exactly into two lines: what it took at the moment of each fill, and what happened to the price afterwards.

Baseline run, Coinbase BTC-USD, 3 July 2026, fixed half-spread δ\delta = $4, 0.01 BTC clip, zero fees, fair price taken 10 ms before each fill:

Line Dollars
Engine PnL −331.37
Spread capture +305.43
Inventory holding −636.80
…in the first second after the fill −573.24
…after the first second −63.56
Residual mark 0.00
Disagreement with the engine 0.00

7,211 fills. Ninety per cent of the holding term is realised within one second of the fill and does not come back.

The decomposition across quoted width

Same day, same strategy, half-spread varied. This is the figure for the page: capture per fill, holding per fill and net per fill against δ\delta, with fill count on a second axis.

δ\delta, $ Fills Capture, ¢/fill Holding, ¢/fill Net, ¢/fill Day PnL, $ First second, share of holding
1 43,322 1.078 −4.644 −3.566 −1,544.65 81%
1.25 36,888 1.340 −5.116 −3.776 −1,392.89 82%
1.50 32,004 1.590 −5.537 −3.947 −1,263.21 82%
2 24,007 2.092 −6.258 −4.165 −999.97 84%
3 13,097 3.117 −7.722 −4.605 −603.11 85%
4 7,211 4.236 −8.831 −4.595 −331.37 90%
5 4,173 5.429 −9.954 −4.524 −188.79 93%
6 2,436 6.553 −10.450 −3.897 −94.93 104%
8 1,022 9.139 −9.597 −0.458 −4.68 141%
10 552 12.078 −10.904 +1.174 +6.49 144%
14 251 17.319 −12.112 +5.207 +13.07 167%
20 114 25.833 −38.614 −12.781 −14.57 72%

Capture per fill rises roughly with the quoted distance, as it must. Net per fill stays inside a one-cent band from δ\delta = $1 to δ\delta = $6 while capture rises six-fold: across that range the day's result improves entirely through taking fewer fills. The last four rows carry between 114 and 1,022 fills and are not evidence of anything. They are shown so that nobody reconstructs them from the graph and reads them as a finding.

A share above one hundred per cent in the last column means the price gives some of the move back after the first second.

What the reference price does to the split

Capture is not defined until the fair price is. Taking the mid at the fill timestamp reads the book after the trade that caused the fill has already torn it:

Mid taken before the fill Capture, ¢/fill Holding, ¢/fill Net, ¢/fill
0 ms 2.713 −7.308 −4.595
1 ms 2.975 −7.571 −4.595
5 ms 4.066 −8.661 −4.595
10 ms 4.236 −8.831 −4.595
50 ms 4.640 −9.235 −4.595
200 ms 4.982 −9.577 −4.595
1,000 ms 4.892 −9.488 −4.595

The split moves by 84%. Their sum is −4.595 ¢ at every offset. Capture reaches its plateau at about 5 ms, which is also roughly the median life of a wide-spread episode on this book; 10 ms is the offset used everywhere on this page.

What the fee costs

The runs above are priced at zero fees, which is a choice about what is being shown, not a claim about trading. On a comparable base run carrying a 1 bp maker fee and a 4 bp taker fee across three windows, fees accounted for $5,282 of a $7,567 loss: the largest single line in that ledger, larger even than the holding term.

That is a different run under a different manifest, with 5 ms latency instead of 3 ms and a calibrated Avellaneda–Stoikov quote instead of a fixed $4. It does not add to the decomposition above and must not be presented as though it did. It is here because a decomposition read without it will understate what a live book gives away.

Method and data

Data. Coinbase BTC-USD, public market data, 1–5 July 2026. Headline table and width curve are 3 July. Our own disclosure; no client data is involved in any measurement on this page.

The identity. With mim_i the fair price at fill ii, mTm_T the fair price at the end of the run, qiq_i the size, sis_i the side and pip_i the fill price:

PnL  =  iqi(si)(pimi)  +  iqi(+si)(mTmi)  +  posT(markTmT) \mathrm{PnL} \;=\; \sum_i q_i(-s_i)(p_i - m_i) \;+\; \sum_i q_i(+s_i)(m_T - m_i) \;+\; \mathrm{pos}_T(\mathrm{mark}_T - m_T)

The second term is per-fill markout carried to the end of the run, multiplied by size and summed. Cutting it at a horizon HH leaves the identity exact, because intermediate marks cancel: qs(m(t+H)mi)\sum q s\,(m(t+H) - m_i) plus everything after HH is the same total. The horizon is therefore a reading choice.

Units. Per-fill figures are cents. At a 0.01 BTC clip a cent per fill is a dollar of price displacement per unit, so 4.24 ¢ of capture is $4.24 per unit, a little over the nominal $4: capture is taken against the mid 10 ms before the fill rather than the mid the quote was set against, and the inventory skew moves quotes too. A resting limit order fills at its own price. Multiplying a per-unit displacement by the fill count without the size overstates the total by two orders of magnitude.

Execution model. power_prob(3) queue from hftbacktest; the model places each 0.01 BTC order at the back of the queue at its price (a median 0.033 BTC rests at the best price); 3 ms round-trip order latency; 100 ms decision grid; position limit 0.05 BTC; mark convention bid/ask; fees zero.

Reconciliation. 181 separate decompositions of runs from that week were checked against the engine's own PnL, and the largest disagreement any of them showed was $0.00.

Sensitivity we ran. At δ\delta = $4 three queue models (power_prob(3), log_prob and a risk-adverse variant) produced an identical fill set, byte for byte, and the same −$331.37. At δ\delta = $1 the queue model does change the result, by $2.32 out of −$1,544.65. Against the book, 78.7% of quotes at δ\delta = $4 rested deeper than the fifth level, with a median book depth of $2.42 and a 90th percentile of $4.62. Orders placed per fill: 4.4 at δ\delta = $1, 26.5 at $4, 171 at $8.

Baseline for the markout. The unconditional one-second move of the mid over this period has mean zero and a standard deviation of $4.9. Measured one-second displacement at δ\delta = $4 is $7.95 per unit, or about 1.6 standard deviations conditional on being filled.

Known trap. Integrating the holding term from the equity series does not work. A fill and the price move that caused it both fit between two rows of the decision grid, and the correlation being measured falls into that gap: the integral gives −$291 against an exact −$636.80. Compute the term per fill instead.

What would disprove this

The identity fails if, on a run with non-zero fees or a different mark convention, the three terms disagree with the engine's PnL by more than a cent. Fees have no separate line in it yet, and it has only been checked at zero.

Front-loading fails as a claim if one-second markout comes in below half the holding term. That would mean the displacement is recovered rather than permanent, and the decomposition would be measuring inventory drift rather than selection.

Width ceases to be the lever described here if, on another venue, pair or period, net per fill moves materially with quoted width rather than staying flat. That is the claim on this page most likely to be venue-specific.

Our queue finding does not carry to anyone quoting at the touch: we have shown the queue model inert at δ\delta = $4 and slightly active at δ\delta = $1, and we have not measured a maker sitting at the front of the queue. Nothing here should be read as covering that case.

Two conditions this measurement has not been separated from: every day measured had a rising mid, and every run used our own execution model. A falling market and a different queue model are the two repeats worth doing first.

A number this page does not report. An earlier internal note quoted a ratio of holding to capture of "15–20 times". That figure is withdrawn. It runs 4.3 at δ\delta = $1, 2.1 at δ\delta = $4, and about twelve on a tightly quoting calibrated baseline: it is a property of the quoted width, not of the market, and reporting one number for it would be reporting the run we happened to pick.

Related measurements

  • Adverse Selection in Market Making: Every Fill Is Bad News. What this decomposition means for a strategy that is already running.
  • Coinbase BTC-USD Spread Distribution, in Ticks. The book this was measured against.
  • Is Avellaneda–Stoikov's k Defined by the Data?. The assumption the holding term contradicts.