Title: | Efficient Estimation of Bid-Ask Spreads from Open, High, Low, and Close Prices |
---|---|
Description: | Implements the efficient estimator of bid-ask spreads from open, high, low, and close prices described in Ardia, Guidotti, & Kroencke (JFE, 2024) <doi:10.1016/j.jfineco.2024.103916>. It also provides an implementation of the estimators described in Roll (JF, 1984) <doi:10.1111/j.1540-6261.1984.tb03897.x>, Corwin & Schultz (JF, 2012) <doi:10.1111/j.1540-6261.2012.01729.x>, and Abdi & Ranaldo (RFS, 2017) <doi:10.1093/rfs/hhx084>. |
Authors: | Emanuele Guidotti [aut, cre] |
Maintainer: | Emanuele Guidotti <[email protected]> |
License: | MIT + file LICENSE |
Version: | 2.1.2 |
Built: | 2025-02-14 19:18:04 UTC |
Source: | https://github.com/eguidotti/bidask |
Implements the efficient estimator of bid-ask spreads from open, high, low, and close prices described in Ardia, Guidotti, & Kroencke (JFE, 2024): doi:10.1016/j.jfineco.2024.103916
edge(open, high, low, close, sign = FALSE)
edge(open, high, low, close, sign = FALSE)
open |
numeric vector of open prices. |
high |
numeric vector of high prices. |
low |
numeric vector of low prices. |
close |
numeric vector of close prices. |
sign |
whether to return signed estimates. |
Prices must be sorted in ascending order of the timestamp.
The spread estimate. A value of 0.01 corresponds to a spread of 1%.
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
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread edge(x$Open, x$High, x$Low, x$Close)
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread edge(x$Open, x$High, x$Low, x$Close)
Implements an expanding window calculation of the efficient estimator of bid-ask spreads from open, high, low, and close prices described in Ardia, Guidotti, & Kroencke (JFE, 2024): doi:10.1016/j.jfineco.2024.103916.
edge_expanding(open, high, low, close, sign = FALSE, na.rm = TRUE)
edge_expanding(open, high, low, close, sign = FALSE, na.rm = TRUE)
open |
numeric vector of open prices. |
high |
numeric vector of high prices. |
low |
numeric vector of low prices. |
close |
numeric vector of close prices. |
sign |
whether to return signed estimates. |
na.rm |
whether to ignore missing values. |
Prices must be sorted in ascending order of the timestamp.
Vector of spread estimates. A value of 0.01 corresponds to a spread of 1%. This function always returns a result of the same length as the input prices.
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
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread using an expanding window s <- edge_expanding(x$Open, x$High, x$Low, x$Close) tail(s) # equivalent to s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 1:nrow(x), na.rm = TRUE) tail(s)
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread using an expanding window s <- edge_expanding(x$Open, x$High, x$Low, x$Close) tail(s) # equivalent to s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 1:nrow(x), na.rm = TRUE) tail(s)
Implements a rolling window calculation of the efficient estimator of bid-ask spreads from open, high, low, and close prices described in Ardia, Guidotti, & Kroencke (JFE, 2024): doi:10.1016/j.jfineco.2024.103916.
edge_rolling(open, high, low, close, width, sign = FALSE, na.rm = FALSE)
edge_rolling(open, high, low, close, width, sign = FALSE, na.rm = FALSE)
open |
numeric vector of open prices. |
high |
numeric vector of high prices. |
low |
numeric vector of low prices. |
close |
numeric vector of close prices. |
width |
if an integer, the width of the rolling window. If a vector with the same length of the input prices, the width of the window corresponding to each observation. Otherwise, a vector of endpoints. See examples. |
sign |
whether to return signed estimates. |
na.rm |
whether to ignore missing values. |
Prices must be sorted in ascending order of the timestamp.
Vector of spread estimates. A value of 0.01 corresponds to a spread of 1%. This function always returns a result of the same length as the input prices.
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
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread using a rolling window s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 21) tail(s) # estimate the spread using custom endpoints ep <- c(3, 35, 100) s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = ep) s[c(35, 100)] # equivalent to edge(x$Open[3:35], x$High[3:35], x$Low[3:35], x$Close[3:35]) edge(x$Open[35:100], x$High[35:100], x$Low[35:100], x$Close[35:100]) # estimate the spread using an expanding window s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 1:nrow(x)) tail(s) # equivalent to s <- edge_expanding(x$Open, x$High, x$Low, x$Close, na.rm = FALSE) tail(s)
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread using a rolling window s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 21) tail(s) # estimate the spread using custom endpoints ep <- c(3, 35, 100) s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = ep) s[c(35, 100)] # equivalent to edge(x$Open[3:35], x$High[3:35], x$Low[3:35], x$Close[3:35]) edge(x$Open[35:100], x$High[35:100], x$Low[35:100], x$Close[35:100]) # estimate the spread using an expanding window s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 1:nrow(x)) tail(s) # equivalent to s <- edge_expanding(x$Open, x$High, x$Low, x$Close, na.rm = FALSE) tail(s)
This function performs simulations consisting of n
periods and where each period consists of a given number of trades
.
For each trade, the actual price is simulated as
, where
is the standard deviation per trade and
is a random draw from a unit normal distribution.
The standard deviation per trade equals the
volatility
divided by the square root of the number of trades
.
Trades are assumed to be observed with a given probability
.
The bid (ask) for each trade is defined as multiplied by one minus (plus) half the
spread
and we assume a 50% chance that a bid (ask) is observed.
High and low prices equal the highest and lowest prices observed during the period.
Open and Close prices equal the first and the last price observed in the period.
If no trade is observed for a period, then the previous Close is used as the Open, High, Low, and Close prices for that period.
sim( n = 10000, trades = 390, prob = 1, spread = 0.01, volatility = 0.03, overnight = 0, drift = 0, units = 1, sign = FALSE )
sim( n = 10000, trades = 390, prob = 1, spread = 0.01, volatility = 0.03, overnight = 0, drift = 0, units = 1, sign = FALSE )
n |
the number of periods to simulate. |
trades |
the number of trades per period. |
prob |
the probability to observe a trade. |
spread |
the bid-ask spread. |
volatility |
the open-to-close volatility. |
overnight |
the close-to-open volatility. |
drift |
the expected return per period. |
units |
the units of the time period. One of: |
sign |
whether to return positive prices for buys and negative prices for sells. |
A data.frame of open, high, low, and close prices if units=1
(default).
Otherwise, an xts
object is returned (requires the xts
package to be installed).
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
# simulate 10 open, high, low, and close prices with spread 1% sim(n = 10, spread = 0.01)
# simulate 10 open, high, low, and close prices with spread 1% sim(n = 10, spread = 0.01)
This function implements several methods to estimate bid-ask spreads from open, high, low, and close prices and it is optimized for fast calculations over rolling and expanding windows.
spread(x, width = nrow(x), method = "EDGE", sign = FALSE, na.rm = FALSE)
spread(x, width = nrow(x), method = "EDGE", sign = FALSE, na.rm = FALSE)
x |
tabular data with columns named |
width |
if an integer, the width of the rolling window. If a vector with the same length of the input prices, the width of the window corresponding to each observation. Otherwise, a vector of endpoints. By default, the full sample is used to compute a single spread estimate. See examples. |
method |
the estimators to use. See details. |
sign |
whether to return signed estimates. |
na.rm |
whether to ignore missing values. |
The method EDGE
implements the Efficient Discrete Generalized Estimator described in Ardia, Guidotti, & Kroencke (JFE, 2024).
The methods OHL
, OHLC
, CHL
, CHLO
implement the generalized estimators described in Ardia, Guidotti, & Kroencke (JFE, 2024).
They can be combined by concatenating their identifiers, e.g., OHLC.CHLO
uses an average of the OHLC
and CHLO
estimators.
The method AR
implements the estimator described in Abdi & Ranaldo (RFS, 2017). AR2
implements their 2-period version.
The method CS
implements the estimator described in Corwin & Schultz (JF, 2012). CS2
implements their 2-period version. Both versions are adjusted for overnight (close-to-open) returns as described in the paper.
The method ROLL
implements the estimator described in Roll (JF, 1984).
A data.frame of spread estimates, or an xts
object if x
is of class xts
.
A value of 0.01 corresponds to a spread of 1%.
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
Abdi, F., & Ranaldo, A. (2017). A simple estimation of bid-ask spreads from daily close, high, and low prices. Review of Financial Studies, 30 (12), 4437-4480. doi:10.1093/rfs/hhx084
Corwin, S. A., & Schultz, P. (2012). A simple way to estimate bid-ask spreads from daily high and low prices. Journal of Finance, 67 (2), 719-760. doi:10.1111/j.1540-6261.2012.01729.x
Roll, R. (1984). A simple implicit measure of the effective bid-ask spread in an efficient market. Journal of Finance, 39 (4), 1127-1139. doi:10.1111/j.1540-6261.1984.tb03897.x
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread spread(x) # equivalent to edge(x$Open, x$High, x$Low, x$Close) # estimate the spread using a rolling window of 21 periods s <- spread(x, width = 21) tail(s) # equivalent to s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 21) tail(s) # estimate the spread using an expanding window s <- spread(x, width = 1:nrow(x)) tail(s) # equivalent to s <- edge_expanding(x$Open, x$High, x$Low, x$Close, na.rm = FALSE) tail(s) # estimate the spread using custom endpoints ep <- c(3, 35, 100) spread(x, width = ep) # equivalent to edge(x$Open[3:35], x$High[3:35], x$Low[3:35], x$Close[3:35]) edge(x$Open[35:100], x$High[35:100], x$Low[35:100], x$Close[35:100]) # use multiple estimators spread(x, method = c("EDGE", "AR", "CS", "ROLL", "OHLC", "OHL.CHL"))
# simulate open, high, low, and close prices with spread 1% x <- sim(n = 1000, spread = 0.01) # estimate the spread spread(x) # equivalent to edge(x$Open, x$High, x$Low, x$Close) # estimate the spread using a rolling window of 21 periods s <- spread(x, width = 21) tail(s) # equivalent to s <- edge_rolling(x$Open, x$High, x$Low, x$Close, width = 21) tail(s) # estimate the spread using an expanding window s <- spread(x, width = 1:nrow(x)) tail(s) # equivalent to s <- edge_expanding(x$Open, x$High, x$Low, x$Close, na.rm = FALSE) tail(s) # estimate the spread using custom endpoints ep <- c(3, 35, 100) spread(x, width = ep) # equivalent to edge(x$Open[3:35], x$High[3:35], x$Low[3:35], x$Close[3:35]) edge(x$Open[35:100], x$High[35:100], x$Low[35:100], x$Close[35:100]) # use multiple estimators spread(x, method = c("EDGE", "AR", "CS", "ROLL", "OHLC", "OHL.CHL"))