Estimating Bid-Ask Spreads from Daily and Intraday Price Bars
Summary
The document discusses the Corwin–Schultz estimator, which infers bid-ask spreads from high and low prices over consecutive days. Its derivation relies on a geometric Brownian motion assumption and a relationship between one-day and two-day variance, prompting the question of whether the method transfers to shorter intervals. The responses suggest that this extension may be unreliable because intraday volatility patterns and market microstructure can affect bar highs and lows.
For intraday data, one answer proposes using nonzero gaps between the prior bar’s close and the next bar’s open as spread observations, then averaging them. It argues that this can be more informative than estimating spreads from each bar’s high and low. The document also notes that observed spreads depend on the measurement method and weighting, and that intraday estimates need validation; it offers no comparative empirical study or definitive performance evidence.
Key ideas
- The Corwin–Schultz method estimates spreads from highs and lows over two consecutive periods.
- Its derivation depends on assumptions about price variation that may not hold at intraday frequencies.
- Nonzero gaps between consecutive bars’ close and open prices can provide another spread estimate.
- Intraday market microstructure and volatility patterns may bias estimates based on bar highs and lows.
- Spread estimates can differ depending on whether observations are weighted by time or trading volume.
Tags
Full text
# Corwin-Schultz estimator of bid-ask spread
# Corwin-Schultz estimator of bid-ask spread
I am reading a paper "A Simple Way to Estimate Bid-Ask Spreads from Daily High and Low Prices" cf.A Simple Way to Estimate Bid-Ask Spreads from Daily High and Low Prices
The authors proposed the method of estimation the bid-ask spread from high and low prices of consecutive two days.
From what I can understand, there is an important assumption there that the prices follow geometric Brownian motion and, therefore, the true variance over a 2-day period is twice as large as the expectation of the variance over a single day. This property is used for the spread estimation.
Next, assume that I have more data, than just high and low prices, say, 10 min bars.
Will it improve the spread estimator if I use high and low prices of consecutive two 10 min bars instead on days? Does it contradict to the derivation for daily case?
## Answer by lehalle (score 6, accepted)
https://quant.stackexchange.com/a/60600
If you have access to intraday data, they are better ways to estimate the bid-ask spread. If you have Open, High, Low and Close price on each 5min bin $b$ (or any other interval): the Close of the previous bin and the Open of this one are consecutive. Hence $dP(b)=C(b-1)-O(b)$ allows to define an estimate $\psi(b)$ of the bid-ask spread $$\psi(b):=\min_{b:\, |dP(b)|>0} |dP(b)|.$$
It is not defined on every bin of each day (sometimes $dP(b)=0$), but often you have several of them. You can average them to obtain an estimate for the bid-ask of the day.
Of course you can add an estimate deduced from High and Low of the bin, but it is clearly worst than this $\phi$.
[EDIT following Kri's comment] There is no academic paper comparing different approaches because anyone with empirical data can compare. Moreover, under common regularity assumption:
- for the bid-ask spread: the higher frequency the better (of course it is not the same for the volatility --because of the bid-ask spread bounce at least, convicting to the well documented "signature plot" effect--),
- nevertheless there is a difference at high-frequency between the tie-weighted average spread and the traded-quantity-weighted bid-ask spread. The spread is on average smaller around the trades.
## Answer by BhaskarT (score 0)
https://quant.stackexchange.com/a/76978
I implemented and tested the Corwin Shultz method of liquidity calculation from High and low prices as follows: Paper: https://www.scielo.br/j/bar/a/DbHB3rhpfgr8f6qRFKPSMhG/?format=pdf&lang=en
```
def calculate_corwin_schultz(ohlc_df): # Code written based on Corwin & Schultz (2011) for details: https://www.scielo.br/j/bar/a/DbHB3rhpfgr8f6qRFKPSMhG/?format=pdf&lang=en
# Check for null or infinite values
if ohlc_df['High'].isnull().any() or ohlc_df['Low'].isnull().any():
print("Null values detected in 'High' or 'Low'.")
return 0
if np.isinf(ohlc_df['High']).any() or np.isinf(ohlc_df['Low']).any():
print("Infinite values detected in 'High' or 'Low'.")
return 0
epsilon = 1e-10 # Small constant to prevent division by zero
beta = (np.log(ohlc_df['High'] / (ohlc_df['Low'] + epsilon)) ** 2).dropna()
beta[beta < (np.sqrt(2) / (3 - 2 * np.sqrt(2))) ** 2] = (np.sqrt(2) / (3 - 2 * np.sqrt(2))) ** 2
gamma = (np.log(ohlc_df['High'].shift(-1) / (ohlc_df['Low'].shift(-1) + epsilon)) ** 2).dropna()
alpha_arg = 2 * beta - np.sqrt(beta) / (3 - 2 * np.sqrt(2))
alpha = (np.sqrt(alpha_arg) - np.sqrt(gamma / (3 - 2 * np.sqrt(2)))).dropna()
S = (2 * (np.exp(alpha) - 1) / (1 + np.exp(alpha))).dropna()
# If standard deviation is less than 3, return mean
print("Standard Deviation:",S.std())
if S.std() < 3:
return S.mean()
# Else, return Winsorized mean
else:
return winsorize(S, limits=[0.15, 0.15]).mean()
```
Basically, after calculating the Spread from the high-low values as described in the paper, we return the mean spread or winsozised means spread depending on the number of outliers in the data. If there are too many outlier liquidities then we winsorize them by 15% (upper and lower) and then return the winsorized spread. This addition ensures a more representative distribution. Additionally, I added a small Elipson number in the denominator ensures that there are no divide-by-zero errors.
From the above code, you can see that if you have more granular data, such as 10-minute bars, the geometric Brownian motion assumption may not hold as strongly. Market microstructure effects, such as intraday volatility patterns, order flow imbalances, and liquidity provision, can significantly impact high and low prices at intraday frequencies. These effects could introduce bias into the Corwin and Schultz estimator if applied to high-frequency data.
Moreover, the Corwin and Schultz estimator relies on the relationship between the variance of high and low prices over two consecutive days. Using 10-minute bars would change this relationship, potentially invalidating the estimator's assumptions and affecting its accuracy.
So, instead of improving the estimator, it will introduce more noise or bias, unless the estimator is adapted and validated for high-frequency data. The original derivation for the daily case may not directly extend to intraday data. It will need some modification for intraday.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.