openquant.microstructural
Compiled from Rust (crates/pyopenquant). Signatures and types are from the shipped .pyi stubs; descriptions are the functions’ own docstrings, as help() shows them. All Python modules.
Functions
encode_array
encode_array(array: Sequence[float], encoding: Sequence[tuple[float, str]]) -> strEncode each value as the letter of the nearest codebook value (AFML §18.5).
Ties go to the first codebook entry. The message has exactly one letter per value.
Parameters
array: list[float]Values to encode.
encoding: list[tuple[float, str]]Codebook from
quantile_mappingorsigma_mapping; each letter must be a one-character string.
Returns
- str
The encoded message, as long as
array.
Raises
- ValueError
If
arraycontainsNaN, or the codebook is empty or has aNaNvalue.
encode_tick_rule_array
encode_tick_rule_array(arr: Sequence[int]) -> strEncode tick signs as a string: 1 -> "a", -1 -> "b", 0 -> "c" (AFML §18.5).
Parameters
arr: list[int]Tick-rule signs, each
1,-1or0.
Returns
- str
One letter per sign, for the entropy functions.
Raises
- ValueError
If a value is not
1,-1or0.
get_avg_tick_size
get_avg_tick_size(tick_sizes: Sequence[float]) -> floatArithmetic mean of trade sizes (the mean trade size of a bar).
Parameters
tick_sizes: list[float]Size of each trade.
Returns
- float
The mean, or
NaNfor an empty list.
get_bar_based_amihud_lambda
get_bar_based_amihud_lambda(
close: Sequence[float],
dollar_volume: Sequence[float],
window: int,
) -> list[float]Bar-based Amihud's lambda: rolling mean of |r_t| / DV_t over window bars.
AFML §19.4.2. r_t is the close-to-close log return and DV_t the bar's dollar volume. A bar with zero dollar volume contributes 0 to the sum but still counts in the window divisor.
Parameters
close: list[float]Close prices, oldest first.
dollar_volume: list[float]Dollar volume of each bar, aligned with
close.window: intNumber of bars in the rolling mean.
Returns
- list[float]
One value per bar;
NaNbefore indexwindowand for any window containing a zero previous close or aNaNdollar volume.
Raises
- ValueError
If
dollar_volumeandclosediffer in length.
get_bar_based_hasbrouck_lambda
get_bar_based_hasbrouck_lambda(
close: Sequence[float],
dollar_volume: Sequence[float],
window: int,
) -> list[float]Bar-based Hasbrouck's lambda: rolling mean of r_t / (b_t * sqrt(DV_t)) over window bars.
AFML §19.4.3. r_t is the close-to-close log return, DV_t the bar's dollar volume and b_t the sign of r_t, carried forward over unchanged bars, so each ratio equals |r_t| / sqrt(DV_t). A bar with zero dollar volume contributes 0 but still counts in the window divisor.
Parameters
close: list[float]Close prices, oldest first.
dollar_volume: list[float]Dollar volume of each bar, aligned with
close.window: intNumber of bars in the rolling mean.
Returns
- list[float]
One value per bar;
NaNbefore indexwindowand for any window containing a zero previous close or a negative dollar volume.
Raises
- ValueError
If
dollar_volumeandclosediffer in length.
get_bar_based_kyle_lambda
get_bar_based_kyle_lambda(
close: Sequence[float],
volume: Sequence[float],
window: int,
) -> list[float]Bar-based Kyle's lambda: rolling mean of dp_t / (V_t * b_t) over window bars.
AFML §19.4.1. dp_t is the close-to-close change, V_t the bar's volume and b_t the sign of dp_t, carried forward over unchanged bars. Because the sign comes from the same price change, each ratio equals |dp_t| / V_t and the result is never negative. It is a mean of ratios, not a regression, so one bar with tiny volume can dominate a window.
Parameters
close: list[float]Close prices, oldest first.
volume: list[float]Volume of each bar, aligned with
close.window: intNumber of bars in the rolling mean.
Returns
- list[float]
One value per bar;
NaNbefore indexwindowand for any window containing a zero-volume bar.
Raises
- ValueError
If
volumeandclosediffer in length.
get_bekker_parkinson_vol
get_bekker_parkinson_vol(
high: Sequence[float],
low: Sequence[float],
window: int,
) -> list[float]Bekker-Parkinson volatility: high-low volatility net of the Corwin-Schultz spread.
AFML §19.3.4, Snippet 19.2. Uses the same beta and gamma as get_corwin_schultz_estimator: sigma = (2^(-1/2) - 1) sqrt(beta) / (k2 (3 - 2 sqrt(2))) + sqrt(gamma / (k2^2 (3 - 2 sqrt(2)))) with k2 = sqrt(8 / pi), floored at zero. It is a per-bar volatility of log prices, not annualised.
Parameters
high: list[float]Bar highs, oldest first.
low: list[float]Bar lows, aligned with
high.window: intNumber of bars in the rolling mean of
beta.
Returns
- list[float]
One volatility per bar;
NaNbefore indexwindowand wherever a low is zero.
Raises
- ValueError
If
highandlowdiffer in length.
get_bvc_buy_volume
get_bvc_buy_volume(
close: Sequence[float],
volume: Sequence[float],
window: int,
) -> list[float]Bulk volume classification: estimated buy volume of each bar.
AFML §19.5.2 (Easley, López de Prado and O'Hara, 2012). Each bar's buy volume is V_t * Phi(dp_t / sigma), where dp_t is the close-to-close change, sigma the sample standard deviation of the last window changes (including the current one, floored at 1e-12) and Phi the standard normal CDF.
Parameters
close: list[float]Close prices, oldest first.
volume: list[float]Total volume of each bar, aligned with
close.window: intNumber of price changes in the rolling standard deviation; at least 2.
Returns
- list[float]
Estimated buy volume per bar;
NaNbefore indexwindow.
Raises
- ValueError
If
volumeandclosediffer in length, orwindow < 2.
get_corwin_schultz_estimator
get_corwin_schultz_estimator(
high: Sequence[float],
low: Sequence[float],
window: int,
) -> list[float]Corwin and Schultz's (2012) relative bid-ask spread from bar highs and lows.
AFML §19.3.4, Snippet 19.1. With beta the window-bar rolling mean of ln(H_t/L_t)^2 + ln(H_{t-1}/L_{t-1})^2 and gamma the squared log range of the two-bar high and low, alpha = (sqrt(2 beta) - sqrt(beta)) / (3 - 2 sqrt(2)) - sqrt(gamma / (3 - 2 sqrt(2))) is floored at zero and the spread is 2 (exp(alpha) - 1) / (1 + exp(alpha)). The result is a fraction of price, not price units. Individual values are floored at exactly zero whenever volatility swamps the spread, so average over many bars rather than reading single values.
Parameters
high: list[float]Bar highs, oldest first.
low: list[float]Bar lows, aligned with
high.window: intNumber of bars in the rolling mean of
beta.
Returns
- list[float]
One relative spread per bar;
NaNbefore indexwindowand wherever a low is zero.
Raises
- ValueError
If
highandlowdiffer in length.
get_konto_entropy
get_konto_entropy(message: str, window: int) -> floatKontoyiannis' entropy-rate estimator from longest-match lengths, in bits per symbol.
AFML §18.4, Snippets 18.3-18.4. For each point i, L_i is one plus the length of the longest substring starting at i that also starts within the preceding look-back window; the estimate is the mean of log2(n + 1) / L_i. With window == 0 the window expands (n = i, points 1..=len/2); otherwise the window is clamped to w = min(window, len // 2) as in Snippet 18.4, and w sets the points (w to len - w), the look-back and the log2(w + 1) numerator. Quadratic or worse in the message length.
Parameters
message: strEncoded message.
window: intLook-back window in characters; 0 for an expanding window.
Returns
- float
Entropy rate in bits per symbol; 0 for messages shorter than 2 characters.
get_lempel_ziv_entropy
get_lempel_ziv_entropy(message: str) -> floatLempel-Ziv complexity: LZ dictionary size divided by message length.
AFML §18.4, Snippet 18.2. Lower values mean more repetition. Works on characters, not bytes. The estimate is erratic on short messages and quadratic or worse in length.
Parameters
message: strEncoded message.
Returns
- float
The complexity in
(0, 1], or 0 for an empty message.
get_plug_in_entropy
get_plug_in_entropy(message: str, word_length: int) -> floatPlug-in (maximum-likelihood) entropy rate, in bits per symbol.
AFML §18.3, Snippet 18.1. The Shannon entropy of overlapping words of word_length characters, divided by word_length. As in Snippet 18.1, the words are those ending before the last character, so there are len(message) - word_length of them and word_length == len(message) returns (negative) zero. Biased downward for long words on short messages.
Parameters
message: strEncoded message.
word_length: intWord length in characters, between 1 and
len(message).
Returns
- float
Entropy rate in bits per symbol.
Raises
- ValueError
If
word_lengthis 0 or exceeds the message length in characters.
get_roll_impact
get_roll_impact(
close: Sequence[float],
dollar_volume: Sequence[float],
window: int,
) -> list[float]Roll measure per unit of dollar volume, a spread cost scaled by traded value.
Element-wise get_roll_measure(close, window) / dollar_volume (AFML §19.3.2).
Parameters
close: list[float]Close prices, oldest first.
dollar_volume: list[float]Dollar volume of each bar, aligned with
close.window: intNumber of bars in the rolling Roll covariance.
Returns
- list[float]
One value per bar;
NaNwhere the Roll measure isNaNor the dollar volume is zero.
Raises
- ValueError
If
dollar_volumeandclosediffer in length.
get_roll_measure
get_roll_measure(close: Sequence[float], window: int) -> list[float]Roll's (1984) effective bid-ask spread over a rolling window of close prices.
Computes 2 * sqrt(|cov(dp_t, dp_{t-1})|), where the covariance is the sample (n - 1) covariance of close-to-close price changes with their first lag over the last window bars (AFML §19.3.2). The result is in price units. Roll's formula needs a negative autocovariance; following mlfinlab the absolute value is taken, so a trending series with positive autocovariance also reports a "spread". Check the sign yourself on anything that is not a liquid, mean-reverting tick series.
Parameters
close: list[float]Close prices, oldest first.
window: intNumber of bars in the rolling covariance.
Returns
- list[float]
One value per bar.
NaNbefore indexwindow + 1, and everywhere whenwindow < 2or fewer than two prices are given.
get_shannon_entropy
get_shannon_entropy(message: str) -> floatShannon entropy of a message's characters, -sum(p * log2(p)), in bits per symbol.
AFML §18.2. It ignores order entirely: "abababab" scores 1 bit, the same as a fair coin. An empty message returns (negative) zero.
Parameters
message: strEncoded message, e.g. from
encode_tick_rule_arrayorencode_array.
Returns
- float
Entropy in bits per symbol.
get_trades_based_amihud_lambda
get_trades_based_amihud_lambda(
log_ret: Sequence[float],
dollar_volume: Sequence[float],
) -> floatTrades-based Amihud's lambda over one bar's trades.
AFML §19.4.2. The regression through the origin of per-trade absolute log returns on dollar volume, sum(DV * |r|) / sum(DV^2).
Parameters
log_ret: list[float]Each trade's log return from the previous trade.
dollar_volume: list[float]Each trade's dollar volume, aligned with
log_ret.
Returns
- float
The lambda estimate, or
NaNif every dollar volume is zero.
Raises
- ValueError
If
dollar_volumeandlog_retdiffer in length.
get_trades_based_hasbrouck_lambda
get_trades_based_hasbrouck_lambda(
log_ret: Sequence[float],
dollar_volume: Sequence[float],
aggressor_flags: Sequence[float],
) -> floatTrades-based Hasbrouck's lambda over one bar's trades.
AFML §19.4.3. The regression through the origin of per-trade log returns on signed root dollar volume, sum(r * a * sqrt(DV)) / sum((a * sqrt(DV))^2). The signed return is regressed, as in AFML; results from versions before issue #105 was fixed (which used the absolute return) are not comparable.
Parameters
log_ret: list[float]Each trade's log return from the previous trade.
dollar_volume: list[float]Each trade's dollar volume, aligned with
log_ret.aggressor_flags: list[float]Each trade's side:
+1buy,-1sell.
Returns
- float
The lambda estimate;
NaNif every signed root dollar volume is zero or any dollar volume is negative.
Raises
- ValueError
If
dollar_volumeoraggressor_flagsis not as long aslog_ret.
get_trades_based_kyle_lambda
get_trades_based_kyle_lambda(
price_diff: Sequence[float],
volume: Sequence[float],
aggressor_flags: Sequence[float],
) -> floatTrades-based Kyle's lambda over one bar's trades.
AFML §19.4.1. The regression through the origin of per-trade price changes on signed volume, sum(dp * v * a) / sum((v * a)^2). Transaction price changes include bid-ask bounce, so the estimate is impact plus bounce; regress mid-price changes if quotes are available.
Parameters
price_diff: list[float]Each trade's price change from the previous trade.
volume: list[float]Each trade's size, aligned with
price_diff.aggressor_flags: list[float]Each trade's side:
+1buy,-1sell (0drops the trade from the regression).
Returns
- float
The lambda estimate, or
NaNif every signed volume is zero.
Raises
- ValueError
If
volumeoraggressor_flagsis not as long asprice_diff.
get_vpin
get_vpin(
volume: Sequence[float],
buy_volume: Sequence[float],
window: int,
) -> list[float]Volume-synchronised probability of informed trading (VPIN).
Easley, López de Prado and O'Hara (2012); AFML §19.5.2. The rolling mean over window bars of |V_buy - V_sell|, with V_sell = volume - buy_volume, divided by the **current** bar's volume. Dividing by the current bar's volume rather than the window's makes this the published measure only on volume bars, where every bar has the same volume; on time bars a quiet bar inflates it and a busy bar deflates it.
Parameters
volume: list[float]Total volume of each bar, oldest first.
buy_volume: list[float]Buy-initiated volume of each bar (e.g. from
get_bvc_buy_volume), aligned withvolume.window: intNumber of bars in the rolling mean.
Returns
- list[float]
One value per bar;
NaNfor the firstwindow - 1bars and where the current volume is zero.
Raises
- ValueError
If
buy_volumeandvolumediffer in length.
quantile_mapping
quantile_mapping(array: Sequence[float], num_letters: int) -> list[tuple[float, str]]Build a quantile codebook for encode_array (AFML §18.5).
Returns num_letters pairs (value, letter), one per quantile. The quantiles are evenly spaced from 0.01 to 1.0 (just 0.01 when num_letters == 1); each value is the order statistic at round(q * (n - 1)), so bins are roughly equally populated. Letters are characters chr(0), chr(1), ..., starting with control characters such as NUL: fine for the entropy functions, not for printing. Duplicate values can appear when the data has ties.
Parameters
array: list[float]Values to build the codebook from.
num_letters: intAlphabet size, between 1 and 256.
Returns
- list[tuple[float, str]]
(value, letter)pairs in increasing quantile order; each letter is a one-character string.
Raises
- ValueError
If
num_lettersis 0 or above 256,arrayis empty, orarraycontainsNaN.
sigma_mapping
sigma_mapping(array: Sequence[float], step: float) -> list[tuple[float, str]]Build a fixed-width codebook for encode_array (AFML §18.5).
The codebook values are min, min + step, ..., strictly below max(array), lettered chr(0), chr(1), ... (control characters first). An array whose values are all equal gives the one entry (min, chr(0)); the codebook is never empty.
Parameters
array: list[float]Values to build the codebook from.
step: floatWidth of each bin, e.g. a fraction of the standard deviation of
array.
Returns
- list[tuple[float, str]]
(value, letter)pairs in increasing value order; each letter is a one-character string.
Raises
- ValueError
If
stepis not a positive finite number,arrayis empty or containsNaN, or more than 256 letters would be needed.
vwap
vwap(dollar_volume: Sequence[float], volume: Sequence[float]) -> floatVolume-weighted average price, sum(dollar_volume) / sum(volume).
Parameters
dollar_volume: list[float]Dollar volume (price times size) of each trade.
volume: list[float]Size of each trade, aligned with
dollar_volume.
Returns
- float
The VWAP, or
NaNif the volumes sum to zero.
Raises
- ValueError
If
volumeanddollar_volumediffer in length.