Markout: why your liquidity provider looks fine until you measure it
Fill rate and average spread say almost nothing about execution quality. The number that matters is where the market went after you traded, and most brokers have never calculated it.
Every broker monitors fill rate and average spread, because both arrive free in a provider report. Neither tells you what a liquidity provider costs you. The measurement that does is markout, and it is almost never on the dashboard because it requires you to keep asking a question after the trade is already done.
What markout actually measures
Markout is the difference between the price you were filled at and the market mid some fixed interval later, signed so that a positive number means the market moved against the party who provided the liquidity. Measure it across every fill with one provider and you have the cleanest available estimate of what that relationship is worth.
markout_t = side × (mid(T + t) − fill_price) × 10⁴ / mid(T)The interval matters more than the formula. At 100 milliseconds you are mostly measuring latency and quote staleness. At 30 seconds you are measuring whether the flow itself carries information. Running several horizons at once is what separates a provider who is slow from a provider who is selecting against you.
Why spread hides it
A provider competing for flow can quote inside everyone else and recover the difference in how it handles what it wins. Three mechanisms do this, and all of them are invisible in a spread comparison:
- Last look. The provider holds your order for a short window and decides whether to fill. Rejects cluster precisely where the market has moved against it, so your realised fills are a biased sample of the orders you sent.
- Asymmetric slippage. Price improvement is passed on rarely; adverse movement is passed on consistently. The average slippage figure nets to something small and unremarkable while the distribution is badly skewed.
- Internalisation and recycling. Your order is matched against other flow, and only the residual, the part the provider does not want, reaches the market. What it keeps is what it expects to profit from.
A provider can win every spread comparison you run and still be the most expensive relationship on the desk.
Rejects are data, not noise
The standard mistake is measuring markout on fills only. Rejected orders are where last-look behaviour is visible, and excluding them removes exactly the evidence you need. Compute markout on the intended order at the intended time, whether or not it filled, and compare the two populations.
- 01Order sentT + 0ms, at quoted price
- 02Hold windowT + 5 to 80ms, provider observing
- 03Market movesagainst the provider
- 04Reject returnedT + 85ms
- 05Re-quote, wideryou pay the difference
| LP B | LP D | |
|---|---|---|
| Average spread quoted | 0.42 pips | 0.31 pips |
| Fill rate | 97.1% | 94.8% |
| Reject rate in moving markets | 1.2% | 7.4% |
| Markout at 5s | +0.04 | −0.42 |
| Effective cost per $1M | $46 | $104 |
Illustrative figures, chosen to show the mechanism. Your own numbers will differ.
Running it continuously
What you need
A timestamped record of every order sent, not every order filled, with the provider, the intended price, the outcome, and an independent mid-price series for the same symbol at millisecond resolution. The independent series is the part most brokers lack; using the provider’s own quote stream as the reference makes the measurement circular.
What to watch for
- Markout drifting at one horizon but not others, usually a latency or staleness issue rather than selection.
- Markout degrading only in specific sessions, which points at how the provider is covering rather than at your flow.
- A sudden improvement after you raise it with them, followed by decay over six to eight weeks.
None of this is complicated arithmetic. It is a data-joining problem: order intent, order outcome and an independent price series have to sit in the same place, aligned to the millisecond, and stay joined as providers and symbols change. That is the work.