Arte SheetsLearn. Try. Understand.

Financial Modeling

Roll’s Implied Effective Bid-Ask Spread from First-Order Price Autocovariance

Estimate hidden transaction bid-ask spreads from trade-only price tapes using Richard Roll’s (1984) microstructure formula Spread = 2 * SQRT(MAX(0, -Cov(Delta_P_t, Delta_P_{t-1}))).

How bid-ask bounce creates negative lag-1 serial covariance in trade prices

In OTC bond markets, historical daily tapes, and dark venues where Level-1 bid/ask quotes are unavailable, transaction prices P_t = M_t + (s / 2) * q_t bounce randomly between buyer-initiated prints at the ask (+s/2) and seller-initiated prints at the bid (-s/2). Even when efficient mid-quotes M_t follow a pure martingale, an uptick from bid to ask is disproportionately followed by either zero change or a downtick back to bid.

Richard Roll (1984) proved that first-order serial covariance of price changes equals Cov(Delta_P_t, Delta_P_{t-1}) = -s^2 / 4, solving directly for implied dollar spread s = 2 * SQRT(-Cov_1). In trending finite samples where positive momentum pushes empirical Cov_1 > 0, clamping MAX(0, -Cov_1) prevents imaginary square roots (#NUM!) and reports 0 implied bounce.

Microstructure MetricFormulaBounce Tape [100.25, 99.75, ...]
Price Change Delta_P_tB3 - B2[-0.50, +0.50, -0.50, +0.50, -0.50]
Lag-1 Serial CovarianceSUMPRODUCT((cur - mu_c)*(lag - mu_l)) / N-0.2500
Roll Dollar Spread (s)2 * SQRT(MAX(0, -Cov_1))1.0000 ($1.00 wide)
Proportional Spread (bps)(Roll_Spread / Mean_Price) * 10000100.0 bps (1.00%)

Lag-1 Autocovariance & Roll Dollar Spread Formula

Pair current changes C4:C7 against lagged changes C3:C6 inside LET, compute centered population covariance, and evaluate 2 * SQRT(MAX(0, -cov_lag1)).

=LET(cnt, COUNT(C4:C7), mu_cur, AVERAGE(C4:C7), mu_lag, AVERAGE(C3:C6), cov_lag, SUMPRODUCT((C4:C7 - mu_cur) * (C3:C6 - mu_lag)) / cnt, ROUND(2 * SQRT(MAX(0, -cov_lag)), 4))

Basis-Point Effective Spread Relative to Mean Trade Price

Normalize the implied dollar spread by AVERAGE(B2:B7) and multiply by 10,000 for cross-asset liquidity comparison in basis points.

=ROUND((F3 / AVERAGE(B2:B7)) * 10000, 1)

Try the example

Use the original values or change them to test your understanding.

Further reading