High-frequency data

Bid-ask bounce

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

The artificial up-down sawtooth in trade prices caused by trades alternating between hitting the bid and lifting the ask, with no change in fair value. Roll (1984) backs out the effective spread from exactly this serial covariance.

See it move

Bid-ask bouncedrag the spreadIX-BOUNCE
Spread0.040
Roll estimate0.040
Fair value100.000 (flat)
trade prices bounce bid↔ask · fair value never moves
Bid-ask spread0.040

What to notice. Fair value is flat, yet trade prices sawtooth up and down purely because trades alternate between hitting the bid and lifting the ask. Roll (1984) turns that spurious negative autocorrelation into an estimate of the spread itself.

What is bid-ask bounce?

Bid-ask bounce is the tendency of consecutive trades to print at the bid, then the ask, then the bid (bouncing across the spread) because buyers lift the ask and sellers hit the bid. The mid (true value) may be perfectly still, yet the transaction price oscillates by up to the full spread, manufacturing apparent price changes that are pure microstructure noise. Imagine fair value pinned at 50.005 all minute. A buyer arrives and pays the ask, 50.01; a seller arrives and hits the bid, 50.00; another buyer, 50.01. The trade tape reads 50.01, 50.00, 50.01, a one-tick "oscillation" that reflects who initiated, not any change in value.

This is the canonical example of microstructure noise: the observed transaction price is the efficient (fair) price plus a noise term equal to the signed half-spread: plus when the buyer crossed, minus when the seller did. Every other tick-data trap is a cousin of this idea. Open the explorer above with "show efficient price" on and the zero-drift preset: the latent line is flat, the prints bounce around it, and all of the measured jiggle is bounce, none of it value.

Observed price = efficient price + a noise term equal to half the spread, signed by the trade's direction. With a flat efficient price, every "move" on the trade tape is that noise: pure bounce.
pt  =  mt  +  c2qt,qt{+1,1} (buy / sell)p_t \;=\; m_t \;+\; \tfrac{c}{2}\,q_t, \qquad q_t \in \{+1,\,-1\}\ \text{(buy / sell)}

Why does the bounce inflate measured volatility?

Realised volatility is computed by summing squared returns. The bounce adds a noise term to every price, so every return picks up twice the noise: one print's noise minus the previous print's. Differencing two noisy prices doubles the noise's footprint in the return; square and sum many such returns and the noise variance does not cancel, it accumulates, adding a positive bias that grows with the number of intervals, that is, with how finely you sample. Sample every trade and you measure mostly noise; sample daily and the noise is negligible relative to true variance.

Write the observed log-price as pt=mt+utp_t = m_t + u_t: efficient price mtm_t plus i.i.d. noise utu_t with variance ω2\omega^2. The realised variance over nn intervals then has expectation roughly σ2+2nω2\sigma^2 + 2n\,\omega^2, so as nn \to \infty the noise term dominates and realised variance diverges rather than converging to σ2\sigma^2. That is the "volatility signature plot" exploding at high frequency. The practical rule: never compute short-horizon volatility from raw trade prints. Either sample coarsely enough that 2nω22n\omega^2 is small, use the mid instead of the trade price (which kills the bounce), or use a noise-robust estimator: two-scales realised volatility (Zhang–Mykland–Aït-Sahalia 2005) or realised kernels (Barndorff-Nielsen et al. 2008). Watch the "measured σ vs true σ" panel above climb as you drag the sampling-frequency slider faster.

Realised variance equals true variance plus a noise term that grows linearly with the number of sampling intervals, so faster sampling makes the estimate diverge instead of converge. The signature plot is this formula made visible.
E[RV]    σ2  +  2nω2    n    \mathbb{E}[\,\text{RV}\,] \;\approx\; \sigma^2 \;+\; 2n\,\omega^2 \;\xrightarrow[\;n\to\infty\;]{}\; \infty

What is the Roll (1984) model?

Roll (1984) turns the bounce from a nuisance into a measurement. A buy (print at the ask) tends to be followed by a return down, since the next print is equally likely at the bid, and vice versa, so successive returns are negatively correlated purely from the bounce, and the strength of that negative correlation encodes the width of the spread. Under Roll's assumptions (an efficient price that is a random walk, and i.i.d. buy/sell trade signs independent of it) the bounce induces a first-order autocovariance in transaction-price returns exactly equal to c2/4-c^2/4, where cc is the effective spread. Invert it and you recover the spread from trade prices alone, with no quote data needed, which is invaluable on historical or low-quality tapes where you only have prints.

It is the ancestor of an entire family of effective-spread estimators (Corwin–Schultz high-low, 2012; Abdi–Ranaldo, 2017) that relax Roll's strong assumptions. The autocovariance panel in the explorer above shows γ1<0\gamma_1 \lt 0 with the live 2γ12\sqrt{-\gamma_1} estimate next to the true cc.

The spread shows up as a fixed negative correlation between consecutive trade-price changes. The first-order autocovariance is c2/4-c^2/4; invert it to estimate the effective spread from prints alone.
Cov(Δpt,Δpt1)=c24c^=2γ1\mathrm{Cov}(\Delta p_t,\, \Delta p_{t-1}) = -\tfrac{c^2}{4} \quad\Longrightarrow\quad \hat{c} = 2\sqrt{-\gamma_1}
Show the derivation optional

Write the price change as the efficient innovation plus the change in the signed half-spread, with Δmt\Delta m_t mean zero, variance σm2\sigma_m^2, serially uncorrelated; qtq_t i.i.d. with P(q=+1)=P(q=1)=12P(q=+1)=P(q=-1)=\tfrac12 so E[qt]=0\mathbb{E}[q_t]=0, Var(qt)=1\mathrm{Var}(q_t)=1; and qmq \perp m.

Δpt  =  Δmt  +  c2(qtqt1)\Delta p_t \;=\; \Delta m_t \;+\; \tfrac{c}{2}\,(q_t - q_{t-1})

Form the first-order autocovariance. The Δm\Delta m terms drop out (efficient innovations are serially uncorrelated and independent of the signs) leaving only the sign term:

Cov(Δpt,Δpt1)=(c2)2E[(qtqt1)(qt1qt2)]\mathrm{Cov}(\Delta p_t, \Delta p_{t-1}) = \left(\tfrac{c}{2}\right)^2 \mathbb{E}\big[(q_t - q_{t-1})(q_{t-1} - q_{t-2})\big]

Expand the expectation using E[qtqs]=0\mathbb{E}[q_t q_s] = 0 for tst \neq s and E[qt2]=1\mathbb{E}[q_t^2] = 1: only the E[qt12]-\mathbb{E}[q_{t-1}^2] term survives, giving 1-1.

E[(qtqt1)(qt1qt2)]=001+0=1\mathbb{E}\big[(q_t - q_{t-1})(q_{t-1} - q_{t-2})\big] = 0 - 0 - 1 + 0 = -1

Therefore γ1=(c2)2(1)=c24\gamma_1 = \left(\tfrac{c}{2}\right)^2 (-1) = -\tfrac{c^2}{4}, and inverting gives c^=2γ1\hat{c} = 2\sqrt{-\gamma_1}. The estimator is only real when γ1<0\gamma_1 \lt 0; positive sample autocovariances (from drift, autocorrelated order flow, or thin sampling) make Roll's estimate undefined, a known failure mode this page flags below.

Where does the Roll model break, and what replaces it?

Roll assumes i.i.d. trade signs and a pure random-walk efficient price; real markets honour neither. Trade signs are strongly positively autocorrelated (order splitting, herding), a stylised fact in its own right, and that positive autocorrelation works against the negative bounce-induced autocovariance, so the measured γ1\gamma_1 is biased toward zero or positive and Roll under-estimates the spread or returns no estimate at all. Adverse selection muddies it further: when informed flow moves the efficient price with the trade direction, part of what looks like "spread" is permanent impact, not bounce: the Glosten–Milgrom / Stoll decomposition splits the spread into order-processing, inventory and adverse-selection components, only some of which Roll captures.

The replacements keep Roll's core insight (the spread hides in the serial dependence of prices) while relaxing his assumptions: Hasbrouck's Bayesian Gibbs-sampler version, the Corwin–Schultz (2012) high-low estimator, and the Abdi–Ranaldo (2017) close-high-low estimator. Roll is the foundational idea, not the production estimator: know it because everything after it is "Roll, but robust to X". This is the spread the bounce encodes, a real trading implicit cost, and the quantity the spread vs adverse selection decomposition pulls apart. Crank the trade-sign autocorrelation control in the explorer above and watch Roll's estimate degrade.

Positive order-flow autocorrelation pushes the measured autocovariance up toward (or past) zero, so Roll under-states the spread or fails entirely. Modern estimators relax the i.i.d.-sign assumption that breaks here.
Corr(qt,qt1)>0    γ1    c^=2γ1 biased low or undefined\text{Corr}(q_t, q_{t-1}) \gt 0 \;\Rightarrow\; \gamma_1 \uparrow \;\Rightarrow\; \hat{c} = 2\sqrt{-\gamma_1}\ \text{biased low or undefined}

Worked example

A synthetic Roll-model tape, as of 2026. Reproduce it in the explorer above. Set the efficient price flat at 50.005 (true σ over the window ≈ 0, for clarity), an effective spread c=0.02c = 0.02 (two ticks of 0.01), i.i.d. fair-coin trade signs, and generate 10,000 prints. With mid 50.005 and c=0.02c = 0.02, the bid is 49.995 and the ask 50.015, so every print lands on one of those two: the price "moves" 0.02 on roughly half the steps. Compute per-trade returns and annualise and the measured σ is large and entirely spurious: the true efficient σ was zero, so all of it is bounce.

Now run Roll. The sample first-order return autocovariance comes out γ1c2/4=(0.02)2/4=0.0001\gamma_1 \approx -c^2/4 = -(0.02)^2/4 = -0.0001, and inverting recovers the true two-tick spread from prices alone.

From a flat efficient price and a known 2-tick spread, Roll recovers c^=0.02\hat{c}=0.02 from the trade prints alone, with no quotes used. The negative autocovariance is the spread.
c^=2γ1=20.0001=2×0.01=0.02\hat{c} = 2\sqrt{-\gamma_1} = 2\sqrt{0.0001} = 2 \times 0.01 = 0.02

Then break it: turn on a small efficient-price drift and positive sign autocorrelation. γ1\gamma_1 shrinks toward zero (and can go positive) so Roll's estimate drops below 0.02 or becomes undefined, demonstrating exactly the failure mode the replacements were built for. These figures are illustrative and synthetic; the explorer lets you set cc, true σ and the sign-autocorrelation and watch both the bias and the Roll estimate respond. Real effective spreads vary by instrument, venue and time of day (as of 2026). The bounce is the first of four statistical traps in tick data; the others (fat tails, irregular time and trade-sign inference) each break a naive assumption the same way. The over-stated volatility this trap produces is exactly what fakes mean-reversion signals in statistical arbitrage and corrupts the volatility input to market making.

Where this fits

Common questions

What is bid-ask bounce?
Bid-ask bounce is the artificial up-down sawtooth in transaction prices caused by trades alternating between hitting the bid and lifting the ask, with no change in the underlying fair value. It inflates measured volatility and creates spurious negative autocorrelation in returns. Roll’s 1984 model uses exactly this serial covariance to back out the effective spread from trade prices alone.