Implements the efficient estimator of bid-ask spreads from open, high, low, and close prices described in Ardia, Guidotti, & Kroencke (JFE, 2024): https://doi.org/10.1016/j.jfineco.2024.103916
pip install bidaskThere are three functions in this package. The function edge computes a single bid-ask spread estimate from vectors of open, high, low, and close prices. The functions edge_rolling and edge_expanding are optimized for fast calculations over rolling and expanding windows, respectively.
from bidask import edge, edge_rolling, edge_expandingThe input prices must be sorted in ascending order of the timestamp. The output value is the spread estimate. A value of 0.01 corresponds to a spread of 1%.
edge(open, high, low, close, sign=False)| field | description |
|---|---|
open |
Array-like vector of open prices. |
high |
Array-like vector of high prices. |
low |
Array-like vector of low prices. |
close |
Array-like vector of close prices. |
sign |
Whether to return signed estimates. |
Implements a rolling window calculation of edge. The input is a pandas data frame. The output is a pandas series of rolling spread estimates. A value of 0.01 corresponds to a spread of 1%.
edge_rolling(df, window, sign=False, **kwargs)| field | description |
|---|---|
df |
Data frame with columns 'open', 'high', 'low', 'close' (case-insensitive). |
window |
Size of the moving window. For more information about this parameter, see here. |
sign |
Whether to return signed estimates. |
**kwargs |
Additional keyword arguments to pass to the pandas rolling function. For more information about the rolling parameters, see here. |
Implements an expanding window calculation of edge. The input is a pandas data frame. The output is a pandas series of expanding spread estimates. A value of 0.01 corresponds to a spread of 1%.
edge_expanding(df, min_periods=1, sign=False)| field | description |
|---|---|
df |
Data frame with columns 'open', 'high', 'low', 'close' (case-insensitive). |
min_periods |
Minimum number of observations in window required to have a value; otherwise, result is np.nan. |
sign |
Whether to return signed estimates. |
Load the test data.
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/eguidotti/bidask/main/pseudocode/ohlc.csv")Compute the spread estimate using all the observations.
from bidask import edge
edge(df.Open, df.High, df.Low, df.Close)Compute rolling estimates using a window of 21 observations.
from bidask import edge_rolling
edge_rolling(df=df, window=21)Compute expanding estimates starting with a minimum of 21 observations.
from bidask import edge_expanding
edge_expanding(df=df, min_periods=21)The rolling estimates:
rolling_estimates = edge_rolling(df=df, window=window, step=step, sign=sign)are equivalent to, but much faster than:
expected_estimates = []
for t in range(0, len(df), step):
t1 = t + 1
t0 = t1 - window
expected_estimates.append(edge(
df.Open.values[t0:t1],
df.High.values[t0:t1],
df.Low.values[t0:t1],
df.Close.values[t0:t1],
sign=sign
) if t0 >= 0 else np.nan)The expanding estimates:
expanding_estimates = edge_expanding(df=df, min_periods=min_periods, sign=sign)are equivalent to, but much faster than:
expected_estimates = []
for t in range(0, len(df)):
t1 = t + 1
expected_estimates.append(edge(
df.Open.values[0:t1],
df.High.values[0:t1],
df.Low.values[0:t1],
df.Close.values[0:t1],
sign=sign
) if t1 >= min_periods else np.nan)Ardia, D., Guidotti, E., Kroencke, T.A. (2024). Efficient Estimation of Bid-Ask Spreads from Open, High, Low, and Close Prices. Journal of Financial Economics, 161, 103916. doi: 10.1016/j.jfineco.2024.103916
A BibTex entry for LaTeX users is:
@article{edge,
title = {Efficient estimation of bid–ask spreads from open, high, low, and close prices},
journal = {Journal of Financial Economics},
volume = {161},
pages = {103916},
year = {2024},
doi = {https://doi.org/10.1016/j.jfineco.2024.103916},
author = {David Ardia and Emanuele Guidotti and Tim A. Kroencke},
}