Corwin-Schultz spread estimator

The Corwin-Schultz estimator infers the bid-ask spread from high and low prices. It rests on the idea, published by Shane Corwin and Paul Schultz in 2012, that the part of a high-low range due to volatility grows with the length of the period while the part due to the spread does not, so comparing one-bar and two-bar ranges separates the two.

Senzoukria · Glossary · Updated September 2026


The formula

For two consecutive bars t and t+1, compute β = [ln(H_t / L_t)]² + [ln(H_t+1 / L_t+1)]², the sum of the squared log ranges of each bar, and γ = [ln(max(H_t, H_t+1) / min(L_t, L_t+1))]², the squared log range of the two bars together. With k = 3 − 2√2, α = (√(2β) − √β) / k − √(γ / k), and the proportional spread is S = 2(e^α − 1) / (1 + e^α). The estimate is averaged over many bar pairs. The paper is Corwin and Schultz, 'A simple way to estimate bid-ask spreads from daily high and low prices', Journal of Finance, 2012.

Assumptions to keep in mind

  • The high of each bar is a trade at the ask and the low a trade at the bid.
  • Volatility scales with time, so the two-bar range should be wider than a single bar's range in a known proportion.
  • Negative pair estimates occur often through sampling noise; the authors set them to zero before averaging, which removes a downward bias and introduces an upward one.
  • A price gap between two bars with no trading inflates the two-bar range; the authors adjust the second bar's high and low by the gap.

A worked example on intraday bars

Two consecutive bars trade 4,998.00 to 5,002.00 and 4,999.00 to 5,003.00. Then β is about 1.28 × 10⁻⁶ and γ, from the combined range of 4,998.00 to 5,003.00, is about 1.00 × 10⁻⁶. The formula gives α of about 0.000317, a spread of about 3.2 basis points, roughly 1.6 index points at 5,000, some six ticks, on a market whose quoted spread is typically one tick. The two bars overlap heavily, so the two-bar range grew far less than volatility scaling predicts, and the estimator attributes the difference to the spread. On intraday futures bars, where ranges overlap for reasons unrelated to the spread, the estimate needs that caution.

In Senzoukria

Corwin-Schultz Spread is a pane indicator in the Quantitative group. 'Window (bar pairs)' is 20 by default, from 1 to 500. 'Negative pair estimates' can be floored at zero (the authors' rule and the default), excluded from the average or kept as they are. 'Adjust for no-trade gaps' is on by default, which matters on CME futures at every session boundary. 'Unit' is Basis points by default, or Proportional, Ticks or Price. A pair whose two-bar range is zero is skipped rather than counted as a zero spread, and pairs that cannot be computed do not enter the average. The app ships it next to Roll Implied Spread precisely because the two estimators rely on different data and different assumptions.

In the same section

This page in other languages

Frequently asked questions

Why does the estimator need a gap adjustment?
If the market opens a new session above the previous bar's high, the two-bar range includes the jump even though no trading happened in between. The estimator would read that jump as part of the range and overestimate the spread. The authors' adjustment shifts the second bar's high and low by the size of the gap before computing the range.
Is Corwin-Schultz better than Roll?
They answer the same question from different data. Roll uses the reversal of consecutive price changes; Corwin-Schultz uses highs and lows. Each fails in different conditions, which is why comparing both, and comparing them with the quoted spread when it is available, is more informative than trusting either alone.

Keep reading