Trading costs

Estimating impact

structural
Reviewed 4 June 2026. As of 2026: a permanent feature of the market, not an edge that decays.

Calibrating an impact model from your own fills and public TCA data, and the traps (selection bias, regime change) that make naive estimates flatter you.

The idea

Estimating impact annotated diagramfigure
Calibrating an impact model from your own fills and public TCA data, and the traps (selection bias, regime change) that make naive estimates flatter you.

Reference figure. This concept is explained in prose and diagram; the interactive widgets live on the flagship pages it links to under Where this fits.

How do you measure impact at all?

You measure impact as price displacement: the change in a reference price (the mid) from just before your order starts to a chosen point during or after it, signed by your trade direction. Aggregate many such measurements and you can fit how displacement scales with size. But that only works if you first define your windows and your reference price carefully.

Impact is invisible on any single trade, because the price was going to move anyway: noise, plus whatever signal you traded on. It becomes visible only in aggregate, averaged over many trades, where the random moves cancel and the systematic, direction-correlated move (the impact) remains. So the whole procedure is built around three primitives: a reference price, a signed displacement, and a set of measurement windows.

The reference is the mid just before the order arrives; displacement is the signed change of the mid from that arrival point, with ε=+1\varepsilon = +1 for buys and 1-1 for sells so buy and sell impacts add rather than cancel.
d(t)=ε(m(t)m(tarr)),ε{+1,1}d(t) = \varepsilon \cdot \big(m(t) - m(t_{\text{arr}})\big), \qquad \varepsilon \in \{+1, -1\}

Sample that displacement at two windows. The during-trade window captures peak displacement: temporary plus permanent impact together. A later post-trade decay window (minutes to hours, depending on the instrument) is taken after temporary impact has largely relaxed, leaving the permanent residual. The unit of analysis is the metaorder (a parent decision worked as many child orders), not the individual fill: impact is a property of the whole order's footprint, and the square-root law on market impact is stated in metaorder terms.

Everything here depends on knowing the sign of trades. Yours are known, but to build the volume VV and the surrounding flow you usually need to classify other trades' signs (the tick rule, or Lee–Ready 1991), which imports every accuracy caveat from trade-sign inference.

Regressing displacement on signed volume

With displacements collected, you fit a functional form. Regress measured displacement on signed size to estimate the coefficient: a linear fit recovers Kyle's lambda for small orders; a fit against signed Q/V\sqrt{Q/V} recovers the square-root-law constant YY. The fit's slope is your calibrated impact coefficient, and the post-trade window's slope is your permanent coefficient.

Plot how far the price moved against how much you traded, and fit a line: straight for small orders, square-root for large ones. The linear form (Kyle 1985, small orders or the permanent component) sets displacement λ(signed order flow)\approx \lambda \cdot (\text{signed order flow}); the fitted slope λ\lambda is Kyle's lambda, cleanest for the permanent shift and marginal single-order impact. The square-root form (Gatheral; Almgren et al. 2005, large metaorders) is the one that feeds the impact model and Almgren–Chriss.

Regress measured displacement on σεQ/V\sigma\,\varepsilon\,\sqrt{Q/V}; the slope is the impact constant YY. Fit the during-trade window for total impact and the post-decay window for permanent impact; temporary is the difference.
di=YσiεiQi/Vi+noisei,Y^=ixidiixi2d_i = Y \cdot \sigma_i\,\varepsilon_i\,\sqrt{Q_i/V_i} + \text{noise}_i, \qquad \hat{Y} = \frac{\sum_i x_i d_i}{\sum_i x_i^2}

Then condition the regression. A single global YY is a starting point; the real edge is conditional impact, letting YY (or λ\lambda) depend on book depth at arrival, recent signed flow, spread, time of day and volatility regime. This is where ML earns its keep: a learned, state-dependent impact function beats a constant, letting you size more aggressively when the book is deep and back off when it is thin.

Show the estimator and its standard error optional

Stack NN metaorders with regressors xi=σiεiQi/Vix_i = \sigma_i\,\varepsilon_i\,\sqrt{Q_i/V_i} and response did_i the signed post-arrival displacement. OLS gives the slope, and its variance falls only as 1/N1/N in the count of orders.

Y^=ixidiixi2,Var(Y^)σnoise2ixi2\hat{Y} = \frac{\sum_i x_i d_i}{\sum_i x_i^2}, \qquad \operatorname{Var}(\hat{Y}) \approx \frac{\sigma_{\text{noise}}^2}{\sum_i x_i^2}

Because each did_i is dominated by price noise of size σ\approx \sigma over the window, the per-observation signal-to-noise is tiny (impact is a few basis points; window noise is tens of basis points) so the standard error on Y^\hat{Y} shrinks only as 1/N1/\sqrt{N} and you need very many metaorders for a tight estimate.

Heteroskedasticity (noise scales with σ\sigma and window length) and autocorrelation (overlapping orders in the same name) inflate naive standard errors, so cluster or block-bootstrap them. The permanent-coefficient estimate is noisier still, because it lives in the long-time tail where accumulated noise is largest.

Why estimating impact is genuinely hard

Impact estimation is hard because impact is small relative to price noise, and because of an identification problem: the price often moves with your trade for reasons your trade did not cause, because you traded on a signal others also acted on. Disentangling impact-you-caused from drift-you-predicted is the central difficulty, and naive regressions over-attribute drift to impact.

Signal/impact confounding, the big one. If you buy because you forecast the price will rise, the price rises partly because you were right, not because you traded. A regression of displacement on your signed volume then over-states impact, charging your cost model for moves your alpha produced. Mitigations: measure on uninformed flow where available (execution-only orders with no alpha), include the signal as a control, or use the post-decay permanent residual, which better isolates the information your order leaked from the broader move.

Tiny signal, huge noise. Impact is a few basis points; the mid wanders tens of basis points over any decay window. The estimator works only in aggregate and converges as 1/N1/\sqrt{N}, so small desks simply lack the trade count for a tight YY, itself a reason the data is valuable. Endogeneity of size and timing. Smart traders trade more when liquidity is deep, so size correlates with the very conditions that reduce impact, biasing a naive fit toward lower impact than you will actually pay when forced to trade in bad conditions.

Trade-sign error from Lee–Ready or the tick rule (a few percent of trades) propagates into the regressors; see trade-sign inference. Regime dependence: YY and λ\lambda drift with volatility regime, tick-size changes and venue structure, so a coefficient fit on last year's data can be wrong today; date your calibration and refit. And cross-impact: in correlated instruments, trading one moves others; a single-name model misses it, and the cross-impact matrix is far harder to estimate (more parameters, the same noisy data).

What data you need to do this

To estimate impact you need your own fills time-stamped and aligned to the book state at execution, the trade-and-quote stream around each order to compute displacement and the reference mid, and enough metaorders for the 1/N1/\sqrt{N} estimator to converge. Clean, reconstructable order-book data with reliable trade signs is the binding constraint, and the resource most people cannot get cleanly.

The minimum viable dataset is: your fills, each with venue timestamp, side, size and price, aligned to the mid at arrival and at each decay window; TAQ / L2 quotes around every order to reconstruct the reference mid and the post-trade decay path (ideally L3/MBO to control for book depth, the best conditioning feature); signed volume for VV, meaning a trade-sign classifier and its error budget unless you have native sign data; and a clean volatility σ\sigma per instrument per window, mindful that the bid-ask bounce inflates naive σ\sigma.

This is exactly where the cost guides meet the HF-data guides: how the stream is recorded lives there. The honest 2026 note: this is the step where good data is a durable advantage. The model is public; the calibration is private, and the private calibration is only as good as the aligned data behind it. Most public or retail data cannot recover the book state at your fill, which is why this estimation is so hard to do well outside a desk.

Worked example

A back-of-envelope calibration, illustrative and as of 2026, to show the shape of the procedure, not a real fit. Collect 2,000 of your own buy/sell metaorders in one liquid name with daily volume V=5,000,000V = 5{,}000{,}000 shares, daily volatility σ=150\sigma = 150 bps and price \$50. For each, record signed Q/V\sqrt{Q/V} and the signed mid displacement from arrival, sampled at +5 minutes (peak, temporary plus permanent) and +2 hours (the permanent residual).

Fit total impact on the +5-minute window. Suppose the slope comes out Y^0.6\hat{Y} \approx 0.6. Sanity-check against market impact: a 1%-of-volume order has 0.01=0.10\sqrt{0.01} = 0.10, so it costs about 0.6×150×0.10=90.6 \times 150 \times 0.10 = 9 bps, in the right ballpark.

Calibrated total impact, and the permanent split from the +2-hour residual: about a third of the 9 bps is permanent (the market kept it); the rest was temporary and relaxed.
I0.6σQ/V=9 bps;Y^perm0.2    3 bps perm,  6 bps temp\mathcal{I} \approx 0.6\,\sigma\,\sqrt{Q/V} = 9\ \text{bps}; \quad \hat{Y}_{\text{perm}} \approx 0.2 \;\Rightarrow\; 3\ \text{bps perm}, \; 6\ \text{bps temp}

Now the standard-error reality check. Per-order window noise is about σ\sigma over 5 minutes, 5/390×15017\sqrt{5/390}\times 150 \approx 17 bps, against a true signal of about 9 bps: a per-observation signal-to-noise of roughly 0.5. Over N=2,000N = 2{,}000 orders the standard error on Y^\hat{Y} is roughly 17/(x2000)17 / (\overline{|x|}\,\sqrt{2000}), wide enough that you should report a confidence interval on YY, not a point estimate, and refit as more orders accrue.

The honest conclusion: your calibrated cost model is I(bps)0.6σQ/V\mathcal{I}(\text{bps}) \approx 0.6\,\sigma\,\sqrt{Q/V} with about a third permanent, but with a fat error bar, conditional on this regime, and only as trustworthy as your alignment of fills to the book and your control for the alpha that motivated the trades. A sharper impact estimate is, directly, a higher safe capacity. Numbers are synthetic; the procedure (windows, then signed-\sqrt{}-volume regression, then split temporary from permanent, then bound the error, then condition on book state) is the transferable part.

Where this fits