Reference / Limen research

Features

Features sit one layer above indicators. They combine, re-express, lag, or contextualize price and volume information into model-ready signals or regime flags.

Contents

This page covers feature-helper selection, input requirements, and added columns. For lower-level signal primitives, see Indicators.

Conventions

  • Feature helpers append columns and return the original frame with the extra outputs attached.
  • Helpers either operate on plain kline data or require trade-derived columns such as maker_ratio, no_of_trades, price, or quantity.
  • Not every helper is intended as a final predictor. Some are utilities used to build targets or wider feature families.
  • Regime helpers output compact categorical-style columns such as regime_ma_slope or regime_price_band.
  • find_min_d returns a scalar value instead of a frame; it searches for a stationarity-preserving fractional-differentiation order.

Configuration constraints

Features and indicators validate configuration before computing their output, including on empty input. Periods and windows require integers; Boolean values and floats (including integer-valued floats) are rejected. Periods are never silently truncated. Rolling windows are positive, with existing TA-compatible bounds retained. Causal shifts may be zero: lag helpers, momentum periods, micro_momentum, window_return, price_change_pct, and Ichimoku displacement preserve that behavior. Negative shifts are rejected.

Real coefficients must be finite, Boolean options require bool, and column names must be non-empty strings. Closed choices such as price_vs_band_regime.band reject unknown values. Period/hour sequences validate every element; calendar hours are 0..23. Missing input columns still raise native Polars schema errors.

Clip lower bounds cannot exceed their upper bounds. Breakout percentiles and momentum blend weights are in [0,1]; percentile and return thresholds are ordered. Fractional differentiation requires non-negative orders and positive truncation thresholds/steps. breakout_features.lookback is at least two because its ROC compares adjacent lags. Existing function-specific restrictions remain in force; there is no general requirement that a fast window precede a slow window.

A feature in each project

The Python project computes decimal momentum in caller-owned preparation. The same expression runs before fitting and during inference. Changing the expression changes the meaning of the model's input; retain that equality when extending it.

python · research.py
def features(bars, window):    return bars.with_columns(        (pl.col("close") / pl.col("close").shift(window) - 1).alias("momentum")    )

The Compiled project declares percent-valued roc indicators, then adds the lags and fractional feature below in its search preparation case. These projects use different units and models; their scores are not a controlled comparison.

yaml · research.yaml
    features:      - func: limen.features.lag_range        params:          col: roc_1          start: 1          end: 3          group: momentum      - func: limen.features.fractional_diff        params:          d: 0.4          cols: [close]          threshold: 0.05          group: price

The Python excerpt belongs to selection; the YAML excerpt belongs to search and preparation, with the dependencies and recorded inputs described in each project. The helper tables below describe alternatives; a listed helper is not a claim that the selection run invokes it. Trade-derived helpers require the columns named in their notes.

Kline-derived position and volatility features

These helpers work directly on bar data and require only kline-style inputs.

Function Adds by default Notes
atr_percent_sma atr_percent_sma ATR scaled by close price using SMA smoothing.
atr_sma atr_sma SMA-smoothed ATR variant.
close_position close_position Close location inside the current bar's high-low range. Accepts window; 1 preserves single-bar behavior.
close_position_rolling close_position_rolling Rolling mean of close location inside the high-low range.
close_ma_distance_atr close_ma_distance_atr Close-to-SMA distance normalized by SMA-smoothed true range.
distance_from_ma distance_from_ma Close distance from its rolling moving average.
distance_from_high distance_from_high Distance from a rolling high.
distance_from_low distance_from_low Distance from a rolling low.
gap_high gap_high Current high relative to the previous close.
kaufman_efficiency_ratio kaufman_efficiency_ratio Directional displacement divided by the rolling path length.
narrow_range narrow_range Current range divided by trailing maximum range.
price_range_position price_range_position Rolling range position over a wider window.
range_pct range_pct Current bar range as a percentage.
stochastic_k_abs stochastic_k_abs Absolute distance between stochastic %K and 0.5.
trend_strength trend_strength Fast-versus-slow trend strength summary.
volume_to_range volume_to_range Rolling mean volume per unit of high-low range.
volume_regime volume_regime Volume context over a lookback window.
vwap vwap Requires a datetime-like datetime column because VWAP resets by trading day.
wick_proportion wick_proportion Rolling mean wick share of full candle range.

Calendar and cyclical time features

These helpers derive time-of-bar context from datetime without depending on earlier indicator columns.

Function Adds by default Notes
calendar_time_features hour, minute, weekday, day_of_month, day_of_year, week_of_year, month, quarter, half_of_year, is_weekend Adds discrete calendar fields for downstream splits, filters, and rules. weekday uses ISO numbering (Monday=1 to Sunday=7), and week_of_year uses ISO week numbering.
cyclical_time_features hour_sin, hour_cos, minute_sin, minute_cos, weekday_sin, weekday_cos, day_of_month_sin, day_of_month_cos, day_of_year_sin, day_of_year_cos, week_of_year_sin, week_of_year_cos, month_sin, month_cos, quarter_sin, quarter_cos Encodes cyclical calendar fields without introducing artificial ordinal jumps. Uses the same ISO conventions as calendar_time_features; weekday cycles are phase-aligned with weekday - 1 before applying sine/cosine.
is_funding_hour is_funding_hour Parameterized funding-cadence hour indicator; default hours are 0, 8, and 16.
time_to_funding hours_to_funding Continuous hours until the next funding settlement; default cadence is every 8 hours from 0 UTC, and zero at a settlement bar.
is_us_open_hour is_us_open_hour Parameterized US open-hour indicator; default hour is 14.

Range-based volatility features

These helpers estimate volatility directly from OHLC structure instead of relying only on close-to-close returns.

Function Adds by default Notes
parkinson_volatility parkinson_volatility High-low range estimator that ignores close-to-close drift.
parkinson_vol_of_vol parkinson_vol_of_vol Rolling standard deviation of Parkinson variance.
garman_klass_volatility garman_klass_volatility OHLC estimator using open, high, low, and close information.
rogers_satchell_volatility rogers_satchell_volatility Drift-robust OHLC volatility estimator.
volatility_ratio volatility_ratio Short rolling Parkinson variance divided by long rolling Parkinson variance.
volatility_spike volatility_spike Current Parkinson variance divided by its fixed-lag value.
yang_zhang_volatility yang_zhang_volatility Combines overnight, open-close, and range information into a higher-fidelity volatility estimate. Requires window > 1.

Liquidity and impact features

These helpers translate ordinary OHLCV bars into liquidity, impact, and slippage proxies.

Function Adds by default Notes
dollar_volume dollar_volume Price-times-volume activity proxy using close and volume.
amihud_illiquidity amihud_illiquidity Absolute return per dollar of volume, a compact price-impact proxy.
volume_ratio volume_ratio Volume relative to its simple-moving-average baseline.
return_per_dollar_volume return_per_dollar_volume Signed return per dollar of volume for directional impact analysis.
range_per_dollar_volume range_per_dollar_volume Bar range scaled by dollar volume.
illiquidity_shock illiquidity_shock Current Amihud-style illiquidity relative to its own trailing mean.
liquidity_drop liquidity_drop Current LOB liquidity divided by fixed-lag LOB liquidity.
liquidity_range liquidity_range Rolling mean high-liquidity to low-liquidity ratio.
maker_liquidity_share maker_liquidity_share Maker liquidity divided by total liquidity.
maker_volume_share maker_volume_share Maker volume divided by total volume.
maker_volume_ratio maker_volume_ratio Rolling mean maker-volume share.
taker_imbalance_ratio taker_imbalance_ratio Rolling mean absolute taker imbalance as a share of volume.
trade_density trade_density Rolling mean number of trades per unit of volume.
trade_imbalance trade_imbalance Rolling maker volume divided by rolling total volume.
trade_size_ratio trade_size_ratio Short average trade size divided by long average trade size.
bulk_volume_classification bvc_buy_volume, bvc_sell_volume Splits bar volume into buy and sell by bulk-volume classification (standardized return through the normal CDF). Needs only close and volume.
order_flow_imbalance order_flow_imbalance plus bvc_buy_volume, bvc_sell_volume Rolling net BVC-classified signed flow as a share of volume; a bar-level order-flow imbalance proxy, not level-2 OFI.
vpin vpin plus bvc_buy_volume, bvc_sell_volume Volume-synchronized Probability of Informed Trading from the BVC buy/sell imbalance; a flow-toxicity gauge. Feed volume bars for canonical equal-volume buckets.

Dollar-bar crash reversal

dollar_bar_crash_reversal is the primary signal used by the bundled rule-based SFD of the same name. It requires a UTC-sorted datetime plus open, close, liquidity_sum, and maker_liquidity, and appends the Int8 column dollar_bar_crash_reversal_position.

For row t, the transform:

  1. finds the latest open at or before t - 4h by backward as-of join and computes log(close_t / reference_open) * 10_000
  2. computes maker flow as 1 - 2 * maker_liquidity / liquidity_sum only where liquidity is finite and positive
  3. standardizes flow against causal 30-day rolling medians of flow and absolute deviation, both closed on the left with at least 100 observations
  4. triggers when momentum is at or below momentum_threshold_bps and the robust flow score is above flow_z_threshold
  5. holds the trigger active for hold_minutes of wall-clock time

The structural core permits a new trigger only when the next row belongs to the same UTC date. Therefore the last row of each UTC day, including the final row in the input, cannot initiate a trigger. A position initiated earlier may remain active there until its wall-clock hold expires. This is a one-row availability boundary: the exact research trigger is not same-row causal. The built-in backtest's one-bar execution lag is an execution adaptation, not a claim that the raw trigger was knowable on row t.

The hold is time-based rather than bar-count-based. Dollar bars arrive irregularly, so the physical span represented by a 60-minute hold can exceed 60 minutes between observed execution rows.

Realized risk and tail features

These helpers describe the quality of recent movement, not just its level.

Function Adds by default Notes
realized_semivariance upside_semivariance, downside_semivariance Splits rolling squared returns into upside and downside components.
downside_volatility_ratio downside_volatility_ratio Rolling downside squared-return share of total squared returns.
realized_skewness realized_skewness Rolling skewness of close-to-close returns.
realized_kurtosis realized_kurtosis Rolling kurtosis of close-to-close returns.
jump_variation_proxy jump_variation_proxy Positive gap between realized variance and bipower variation proxy.
tail_event_intensity tail_event_intensity Share of recent bars whose absolute return exceeds a configurable threshold.
volatility_of_volatility volatility_of_volatility Rolling variability of rolling close-to-close return volatility.
return_autocorrelation return_autocorrelation Rolling correlation between returns and one-bar lagged returns.
return_volatility_correlation return_volatility_correlation Rolling correlation between returns and Parkinson variance.
volume_volatility_correlation volume_volatility_correlation Rolling correlation between volume and Parkinson variance.

Seasonality-normalized features

These helpers compare current bar behavior to the trailing mean for the same hour of the week.

Custom SFD authors must keep seasonality baselines causal. Split-wide normalization such as .mean().over(['season_weekday', 'season_hour']), or any full-split hour-of-week baseline computed in one pass, leaks future information within the split. Use trailing-only or train-fitted seasonality baselines instead. The built-in relative_volume_seasonality, relative_range_seasonality, and relative_volatility_seasonality helpers use trailing hour-of-week baselines.

Function Adds by default Notes
relative_volume_seasonality relative_volume_seasonality Current volume relative to the trailing baseline for the same hour-of-week bucket.
relative_range_seasonality relative_range_seasonality Current range percentage relative to the trailing hour-of-week baseline.
relative_volatility_seasonality relative_volatility_seasonality Current absolute return magnitude relative to the trailing hour-of-week baseline.

Candle structure and auction features

These helpers focus on how a bar moved internally, not just where it finished.

Function Adds by default Notes
body_to_range body_to_range Absolute candle body size divided by the full bar range.
wick_imbalance wick_imbalance Upper-wick minus lower-wick imbalance as a share of full range.
range_overlap range_overlap Overlap share between the current bar range and the previous bar range.
rejection_intensity rejection_intensity Wick-heavy rejection proxy based on total wick share and directional close location.
absorption_intensity absorption_intensity High-volume, small-body absorption proxy using a trailing shifted volume baseline.

Cross-timescale context features

These helpers summarize cross-horizon agreement or disagreement on market state.

Function Adds by default Notes
trend_coherence trend_coherence Average sign agreement across short, medium, and long return horizons.
volatility_term_structure volatility_term_structure Average ratio between short, medium, and long rolling volatility estimates.
sma_ratios <price>_sma_<period> and sma_<period>_ratio per configured period Price-to-SMA ratios across multiple horizons, keeping the SMA columns.

Breakout and regime features

These helpers provide state or structure rather than only a continuous numeric series.

Function Adds by default Notes
breakout_features lagged breakout columns plus long_roll_mean, long_roll_std, short_roll_mean, short_roll_std, roc_long_12_1, roc_short_12_1 Enriches pre-existing breakout flags.
breakout_percentile_regime price_range_position, regime_breakout_pct Uses percentile thresholds over price-range position.
hh_hl_structure_regime regime_hh_hl Captures higher-high and higher-low style structure.
ichimoku_cloud tenkan, kijun, senkou_a, senkou_b, chikou Full Ichimoku feature set.
ma_slope_regime regime_ma_slope Regime label based on moving-average slope.
price_vs_band_regime regime_price_band Uses price distance relative to a band definition.
sma_crossover crossover, signal Compact crossover-state helper.
window_return_regime ret_24, regime_window_return Return plus regime thresholding over a window.

Line-based context features

These helpers summarize how recently and how densely price interacted with detected price lines — pairs of bars at most max_duration_hours apart whose close-to-close change is at least min_height_pct (positive lines are long, negative are short; quantile lines are those at or above the quantile_threshold height quantile per direction).

The two grouped transforms below are the YAML-facing surface. Each detects lines internally from scalar params on the frame it receives — per split under the manifest pipeline, so detection cannot observe other splits — and adds its full column family in one detection pass. The composites use array geometry from limen.utils.find_price_lines; dictionary utilities remain available independently.

Function Adds by default Notes
price_lines active_lines, hours_since_big_move, line_momentum_<m>h, trending_score, reversal_potential All-line family: span count, end recency (capped at big_move_lookback_hours), and long-minus-short end counts over the trailing [t-m, t) window with their balance (trending_score, in [-1, 1]) and min/max ratio (reversal_potential, in [0, 1]).
quantile_price_lines hours_since_quantile_line, active_quantile_count, quantile_line_density_<d>h, quantile_momentum_<m>h, avg_quantile_height_<h>h, quantile_direction_bias Quantile-line family: end recency and span count, end density over density_lookback_hours, signed height sum over ends in [t-m, t], and mean height plus height-weighted direction (in [-1, 1]) over ends in [t-h, t].

active_lines and active_quantile_count count lines that span the current bar before the line's end — the event that defines it — is knowable. That within-line lookahead is inherited from the tradeline research design: treat both columns as research-only, not live-computable. The grouped transforms expose include_research_only; set it to false to omit the active-span columns. Bundled live-safe templates set include_research_only: false. The end-event columns are causal. For quantile_price_lines, each row uses the per-direction height quantile of lines completed through that row, including ties. active_quantile_count retains its retrospective whole-frame selection.

The per-column building blocks below take pre-computed line structures (list[dict] with start_idx/end_idx) and remain available for programmatic composition.

Function Adds by default Notes
active_lines active_lines Count of long and short lines active at each bar.
active_quantile_count active_quantile_count Active-line count restricted to quantile-filtered lines.
quantile_line_density quantile_line_density_<lookback>h Count of quantile-line endings within a trailing lookback_hours window.
hours_since_big_move hours_since_big_move Bars since the most recent line end, capped at lookback_hours.
hours_since_quantile_line hours_since_quantile_line Bars since the most recent quantile-line end, capped at lookback_hours.

Line calculation performance

The composite transforms keep line geometry in arrays; the standalone dictionary helpers retain their existing API. Baseline comparisons cover eager/lazy frames, research/live outputs, quantile endpoints, short histories and missing values. Quantile end features match the frozen implementation on each tested prefix's final row; their latency check compares equivalent as-of work.

Feature Rows Live wall ms, before → after Live CPU ms, before → after Peak RSS MiB, before → after
price_lines 20,000 649.1 → 62.8 548.5 → 49.1 501 → 309
price_lines 83,136 2692.9 → 236.7 2424.9 → 230.0 1360 → 498

These are local M1 Max measurements on real BTCUSDT bars, Python 3.12.12, NumPy 2.5.1 and Polars 1.42.1, with numerical-library thread limits set to one. Values are medians of three warm calls; first-call samples, research-mode results, input digests and exact schemas are in the raw measurements. Peak RSS includes imports and input loading. The raw archive also retains historical whole-frame quantile timings; those do not measure the corrected as-of calculation. Desktop contention inflated some wall samples, particularly the quantile baseline; CPU timings provide the corresponding execution cost.

Lag helpers and threshold utilities

These helpers expand existing columns or define cutoffs for target construction.

Function Adds or returns Notes
lag_column one lagged column such as close_lag_2 Requires col and lag.
lag_columns one lag per listed column Requires cols and lag.
lag_range a lag range such as close_lag_1 through close_lag_3 Requires col, start, and end.
lag_range_cols a lag range for each listed column Requires cols, start, and end.
rolling_zscore configurable *_zscore_* column Applies identity, log1p, or abs before rolling z-score standardization.
cusum_filter cusum_event Int8 flag of symmetric CUSUM events on the close log-return path (1 up, -1 down, 0 none); gates which moves are worth sampling.

Stationarity and long-memory helpers

These helpers reduce non-stationarity while preserving more long-memory structure than a first difference would.

Function Adds or returns Notes
fractional_diff one *_fracdiff column per selected input column Applies fixed-width fractional differentiation. Original columns are preserved.
find_min_d scalar d value Iterates over candidate orders and uses the Augmented Dickey-Fuller test to find the smallest stationary order.

Two practical details matter:

  • fractional_diff needs cols=['close'] and writes new columns such as close_fracdiff.
  • if one split is too short to produce the same fractional-diff column as another split, Manifest now drops that extra column during split alignment so the final data_dict stays consistent.

Trade-shape and microstructure features

These helpers need richer data than ordinary OHLCV bars.

Function Adds by default Notes
kline_imbalance imbalance Requires maker_ratio and no_of_trades from data retrieval or bar formation.
conserved_flux_renormalization synthetic OHLCV plus value_sum, vwap, flux_rel_std_mean, flux_rel_std_var, entropy_mean, entropy_var, Δflux_rms, Δentropy_rms Works on trade-level datetime, price, and quantity, then rolls those into kline-aligned diagnostics.

Dynamic-target and entry-score features

This family builds volatility-conditioned targets, stops, and regime weights, plus the microstructure entry score they combine with. The helpers compose: volatility_measure and regime_multiplier feed dynamic_target and dynamic_stop_loss, the momentum and candle-position helpers feed entry_score_microstructure, and feature_aliases snapshots the family into *_feature columns with nulls filled.

Function Adds by default Notes
close_to_extremes close_to_high, close_to_low Close position relative to bar high and low extremes.
dynamic_stop_loss dynamic_stop_loss Volatility- and regime-conditioned stop-loss level.
dynamic_target dynamic_target Volatility- and regime-conditioned target level.
ema_alignment ema, ema_alignment EMA alignment score with power transformation.
entry_score_microstructure entry_score, entry_score_base Microstructure timing score from momentum, spread, candle position, and volume spikes.
feature_aliases dynamic_target_feature, entry_score_feature, momentum_score_feature, regime_high_feature, regime_low_feature, regime_normal_feature, vol_60h_feature, vol_percentile_feature Null-filled aliases snapshotting the family for model consumption.
log_returns log_returns Logarithmic returns of the close series.
market_regime sma_20, sma_50, trend_strength, volatility_ratio, sma_48, volume_sma, volume_regime, market_favorable Trend-strength and volume-regime favorability score.
micro_momentum micro_momentum Short-horizon price momentum.
momentum_confirmation momentum_score Momentum confirmation score from recent price changes.
momentum_periods momentum_<period> per configured period Momentum over multiple horizons.
momentum_weight momentum_weight Momentum-direction weighting factor.
position_in_candle position_in_candle Close position within the bar high-low range.
position_in_range position_in_range Close position within the bar high-low range over a rolling window.
regime_multiplier regime_multiplier Volatility-regime multiplier for dynamic parameter adjustment.
returns_lags returns_lag_<lag> per configured lag Lagged simple returns.
spread spread High-low range normalized by close (same formula as range_pct, but stored in a spread column).
spread_percent spread_percent High-low range normalized by close, stored as spread_percent for microstructure scoring.
volatility_1h volatility_1h Alias of an existing volatility column at the one-hour horizon.
volatility_measure volatility_measure Combined rolling-volatility and ATR-percentage measure.
volatility_weight volatility, volatility_weight Inverse-volatility weighting factor.
volume_spike volume_spike Volume relative to a rolling-statistics baseline.
volume_trend volume_trend Short-term versus long-term volume average trend.

market_regime binds sma_20 and sma_50 to the selected short and long close averages, even for equal or swapped periods. volume_sma is the selected volume average. Fixed aliases take precedence over conflicting close sma_<period> names; close outputs take precedence over the volume sma_<lookback> output. Nonconflicting parameterized outputs remain in their existing order. Incoming sma_20, sma_50 or volume_sma columns are rejected, including repeated application. These bindings apply to this call; later transforms retain their own output behavior. SMA warmup uses NaN, while the derived regime features use null.

Choosing between indicators and features

  • Use an indicator for a direct market calculation such as RSI, ATR, or MACD.
  • Use a feature for structure around those signals, such as lags, regimes, relative position, or multi-step aggregation.
  • Use the lag helpers when the main value is temporal context rather than a new market calculation.
  • Use fractional_diff when stationarity itself is part of the design problem, not just a preprocessing afterthought.
  • Indicators for lower-level signal primitives
  • Transforms for stateless target shaping and cleanup helpers
  • Calibration for post-model probability calibration and threshold optimization
  • Experiment Manifest for how features plug into the split-first manifest pipeline
  • Utilities for the exported adf_test() helper that find_min_d builds on

Private volatility barriers

limen.features.volatility_barriers.volatility_barriers is a private backtest producer, not an ordinary primary-feature transform; see Backtest for configuration and evidence restrictions.

For simple close return r[t] = close[t]/close[t-1]-1, calculate EWMA standard deviations of r[t-1] using spans 24 and 168 by default (adjust=True, bias=False, 24 observations minimum). Require integer 2 <= min_periods <= span <= regime_span. The first min_periods+1 rows are warmup. Select regime multiplier 0.8 below fast/slow ratio 0.75, 1.2 above 1.25 and 1 otherwise, including equality and both-zero volatility. TP/SL are 10000 * fast_std * regime_multiplier * side_multiple, clipped to shared minimum/maximum (10/2000 bps). Default TP/SL multiples are 2/1. All coefficients are finite positive; clips are ordered and below 10000 bps. No future return or partition-local EWMA restart enters the calculation.

Callable contracts

These entries give the exact public signatures and the source-owned argument, return and failure contracts. Use the project examples above for the research context; a signature is reference evidence, not a claim that every option ran in the base experiment.

limen.features.absorption_intensity

python · absorption_intensity.py
def absorption_intensity(data: pl.DataFrame, window: int=20, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute high-effort low-result absorption intensity from volume and candle body share.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, close, and volume columns
window (int) Number of periods used for the trailing volume baseline
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'absorption_intensity'

limen.features.active_lines

python · active_lines.py
def active_lines(data: pl.DataFrame, long_lines: list[dict[str, float]], short_lines: list[dict[str, float]]) -> pl.DataFrame:    ...
Merged source PR · 05d3ca3ePackage signature · Limen 6.0.1 · current package validation · package source

Compute active line count per row from provided long and short line spans.

Argument Contract
data (pl.DataFrame) Klines dataset with 'datetime' and 'close' columns
long_lines (list[dict]) Long line definitions with 'start_idx' and 'end_idx'
short_lines (list[dict]) Short line definitions with 'start_idx' and 'end_idx'

Returns: pl.DataFrame: The input data with a new column 'active_lines'

limen.features.active_quantile_count

python · active_quantile_count.py
def active_quantile_count(data: pl.DataFrame, long_lines_q: list[dict[str, float]], short_lines_q: list[dict[str, float]]) -> pl.DataFrame:    ...
Merged source PR · 05d3ca3ePackage signature · Limen 6.0.1 · current package validation · package source

Compute count of active quantile-filtered lines per row.

Argument Contract
data (pl.DataFrame) Klines dataset with 'datetime' and 'close' columns
long_lines_q (list[dict]) Quantile-filtered long lines with 'start_idx' and 'end_idx'
short_lines_q (list[dict]) Quantile-filtered short lines with 'start_idx' and 'end_idx'

Returns: pl.DataFrame: The input data with a new column 'active_quantile_count'

limen.features.amihud_illiquidity

python · amihud_illiquidity.py
def amihud_illiquidity(data: pl.DataFrame, price_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute the Amihud illiquidity proxy from price changes and dollar volume.

Argument Contract
data (pl.DataFrame) Klines dataset with price and volume columns
price_col (str) Column name used for close-to-close returns
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'amihud_illiquidity'

limen.features.atr_percent_sma

python · atr_percent_sma.py
def atr_percent_sma(data: pl.DataFrame, period: int=14) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute ATR as percentage of close price using Simple Moving Average.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns
period (int) Number of periods for ATR calculation

Returns: pl.DataFrame: The input data with a new column 'atr_percent_sma'

limen.features.atr_sma

python · atr_sma.py
def atr_sma(data: pl.DataFrame, period: int=14) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Average True Range using Simple Moving Average.

NOTE: Different from standard ATR which uses Wilder's smoothing.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns
period (int) Number of periods for ATR calculation

Returns: pl.DataFrame: The input data with a new column 'atr_sma'

limen.features.body_to_range

python · body_to_range.py
def body_to_range(data: pl.DataFrame, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute candle body size relative to the full bar range.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close columns
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'body_to_range'

limen.features.breakout_features

python · breakout_features.py
def breakout_features(data: pl.DataFrame, long_col: str='breakout_long', short_col: str='breakout_short', lookback: int=12, horizon: int=12, target: str='breakout_pct') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute comprehensive breakout-related features including lags, stats, and ROC.

Argument Contract
data (pl.DataFrame) Klines dataset with breakout signal columns
long_col (str) Column name for long breakout signals
short_col (str) Column name for short breakout signals
lookback (int) Number of periods for feature calculation
horizon (int) Number of periods to shift for avoiding lookahead bias
target (str) Target column name for filtering null values

Returns: pl.DataFrame: The input data with multiple breakout feature columns added

limen.features.breakout_percentile_regime

python · breakout_percentile_regime.py
def breakout_percentile_regime(df: pl.DataFrame, period: int=24, p_hi: float=0.85, p_lo: float=0.15) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute regime classification by percentile position of 'close' within rolling [low, high].

Argument Contract
df (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns
period (int) Rolling window for high/low range
p_hi (float) Upper percentile threshold in [0, 1]
p_lo (float) Lower percentile threshold in [0, 1]

Returns: pl.DataFrame: The input data with a new column 'regime_breakout_pct'

limen.features.bulk_volume_classification

python · bulk_volume_classification.py
def bulk_volume_classification(data: pl.DataFrame, window: int=20, close_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Split each bar's volume into buy and sell volume by bulk-volume classification.

The close-to-close log return is standardized by its rolling standard

deviation and passed through the standard normal CDF to estimate the buy

fraction (Easley, Lopez de Prado, and O'Hara). Buy volume is that fraction

times total volume; sell volume is the remainder. Direction is inferred

from price action alone, so no trade-side data is required.

Argument Contract
data (pl.DataFrame) Klines dataset with close and volume columns
window (int) Rolling window for the return-volatility standardization
close_col (str) Column name used for close-to-close log returns
volume_col (str) Column name for total traded volume

Returns: pl.DataFrame: The input data with new columns 'bvc_buy_volume' and 'bvc_sell_volume'

limen.features.calendar_time_features

python · calendar_time_features.py
def calendar_time_features(df: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · b4b68096Package signature · Limen 6.0.1 · current package validation · package source

Add discrete calendar time features from the datetime column.

Argument Contract
df (pl.DataFrame) Input frame with a datetime column named datetime

Returns: pl.DataFrame: The input frame with hour, minute, weekday,

day_of_month, day_of_year, week_of_year, month,

quarter, half_of_year, and is_weekend appended. weekday uses ISO

numbering with Monday=1 through Sunday=7, and

week_of_year follows ISO week numbering

limen.features.close_ma_distance_atr

python · close_ma_distance_atr.py
def close_ma_distance_atr(data: pl.DataFrame, ma_window: int=20, atr_window: int=14, high_col: str='high', low_col: str='low', close_col: str='close', output_col: str='close_ma_distance_atr') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute close-to-SMA distance normalized by SMA-smoothed true range.

Argument Contract
data (pl.DataFrame) Klines dataset with high, low, and close columns
ma_window (int) Number of periods in the simple moving average
atr_window (int) Number of periods in the true-range moving average
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the ATR-normalized distance column appended

limen.features.close_position

python · close_position.py
def close_position(data: pl.DataFrame, window: int=1, high_col: str='high', low_col: str='low', close_col: str='close', output_col: str='close_position') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute close position within the high-low range as a unit interval fraction.

Argument Contract
data (pl.DataFrame) Klines dataset with high, low, and close columns
window (int) Rolling mean window; 1 preserves the single-bar behavior
high_col (str) High price column
low_col (str) Low price column
close_col (str) Close price column
output_col (str) Output column name

Returns: pl.DataFrame: The input data with a new close-position column

limen.features.close_position_rolling

python · close_position_rolling.py
def close_position_rolling(data: pl.DataFrame, window: int=20, high_col: str='high', low_col: str='low', close_col: str='close', output_col: str='close_position_rolling') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling mean close position inside the high-low range.

Argument Contract
data (pl.DataFrame) Klines dataset with high, low, and close columns
window (int) Number of periods in the rolling mean
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the rolling close-position column appended

limen.features.close_to_extremes

python · close_to_extremes.py
def close_to_extremes(data: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 7c385782Package signature · Limen 6.0.1 · current package validation · package source

Compute close position relative to high and low extremes.

Argument Contract
data (pl.DataFrame) Klines dataset with 'close', 'high', 'low' columns

Returns: pl.DataFrame: The input data with new columns 'close_to_high' and 'close_to_low'

limen.features.conserved_flux_renormalization

python · conserved_flux_renormalization.py
def conserved_flux_renormalization(trades_df: pl.DataFrame, *, kline_interval: str='1h', base_window_s: int=60, levels: int=6) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute multi-scale, conserved-flux features and their deviation scores

for each k-line—turning raw trade ticks into a six-value fingerprint that

flags hours where the dollar flow or trade-size entropy breaks

scale-invariant behaviour.

Argument Contract
trades_df (pl.DataFrame) The trades DataFrame.
kline_interval (str) The kline interval.
base_window_s (int) The base window size.
levels (int) The number of levels to compute.

Returns: pl.DataFrame: A klines DataFrame with the CFR features

limen.features.cusum_filter

python · cusum_filter.py
def cusum_filter(data: pl.DataFrame, threshold: float=0.01, close_col: str='close', output_col: str='cusum_event') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Flag symmetric CUSUM events on the close-price log-return path.

Running sums accumulate positive and negative log returns and reset when

either breaches threshold, emitting an event at that bar (Lopez de Prado's

symmetric CUSUM filter). The filter samples only moves whose cumulative

magnitude is meaningful, gating out micro-noise ahead of downstream sampling.

Argument Contract
data (pl.DataFrame | pl.LazyFrame) Klines dataset with a close price column
threshold (float) Cumulative log-return magnitude that triggers an event
close_col (str) Column name used for close-to-close log returns
output_col (str) Output column name

Returns: pl.DataFrame | pl.LazyFrame: The input data, matching the input frame

type, with an Int8 column: 1 for an up event, -1 for a down event,

0 otherwise

NOTE: Column access is expression-based so the feature runs on both eager

DataFrames and the LazyFrames piped by the manifest feature pipeline.

limen.features.cyclical_time_features

python · cyclical_time_features.py
def cyclical_time_features(df: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 7e64bebdPackage signature · Limen 6.0.1 · current package validation · package source

Add sine and cosine encodings for cyclical datetime fields.

Argument Contract
df (pl.DataFrame) Input frame with a datetime column named datetime

Returns: pl.DataFrame: The input frame with cyclical encodings for hour,

minute, weekday, day_of_month, day_of_year, week_of_year, month,

and quarter appended as *_sin and *_cos columns. Weekday and

week-of-year use ISO numbering, and weekday cycles are phase-

aligned with weekday - 1 before sine/cosine encoding

limen.features.distance_from_high

python · distance_from_high.py
def distance_from_high(data: pl.DataFrame, period: int=24) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute distance from rolling high as percentage.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'close' columns
period (int) Number of periods for rolling high calculation

Returns: pl.DataFrame: The input data with a new column 'distance_from_high'

limen.features.distance_from_low

python · distance_from_low.py
def distance_from_low(data: pl.DataFrame, period: int=24) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute distance from rolling low as percentage.

Argument Contract
data (pl.DataFrame) Klines dataset with 'low', 'close' columns
period (int) Number of periods for rolling low calculation

Returns: pl.DataFrame: The input data with a new column 'distance_from_low'

limen.features.distance_from_ma

python · distance_from_ma.py
def distance_from_ma(data: pl.DataFrame, window: int=20, close_col: str='close', output_col: str='distance_from_ma') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute close distance from its rolling moving average.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods in the moving average
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the moving-average distance column appended

limen.features.dollar_bar_crash_reversal

python · dollar_bar_crash_reversal.py
def dollar_bar_crash_reversal(data: pl.DataFrame | pl.LazyFrame, momentum_threshold_bps: float, flow_z_threshold: float, hold_minutes: int, *, bar_interval_seconds: int | None=None) -> pl.DataFrame | pl.LazyFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Build prior-only momentum/robust-flow crash-reversal positions.

Hold triggers for the wall-clock window; a verified interval removes the next-row day-mask dependency.

limen.features.dollar_volume

python · dollar_volume.py
def dollar_volume(data: pl.DataFrame, price_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute traded dollar volume from price and volume columns.

Argument Contract
data (pl.DataFrame) Klines dataset with price and volume columns
price_col (str) Column name used as the price proxy for traded value
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'dollar_volume'

limen.features.downside_volatility_ratio

python · downside_volatility_ratio.py
def downside_volatility_ratio(data: pl.DataFrame, window: int=20, close_col: str='close', output_col: str='downside_volatility_ratio') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling downside squared-return share of total squared returns.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods in the rolling sums
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the downside-volatility ratio appended

limen.features.dynamic_stop_loss

python · dynamic_stop_loss.py
def dynamic_stop_loss(data: pl.DataFrame, base_stop_loss: float, stop_volatility_multiplier: float, clip_lower_mult: float=0.7, clip_upper_mult: float=1.4) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute dynamic stop loss levels based on volatility conditions and regime.

Argument Contract
data (pl.DataFrame) Klines dataset with 'volatility_measure', 'regime_multiplier' columns
base_stop_loss (float) Base stop loss threshold
stop_volatility_multiplier (float) Multiplier for volatility-adjusted stops
clip_lower_mult (float) Lower bound multiplier for clipping
clip_upper_mult (float) Upper bound multiplier for clipping

Returns: pl.DataFrame: The input data with a new column 'dynamic_stop_loss'

limen.features.dynamic_target

python · dynamic_target.py
def dynamic_target(data: pl.DataFrame, base_min_breakout: float, target_volatility_multiplier: float, clip_lower_mult: float=0.6, clip_upper_mult: float=1.4) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute dynamic target levels based on volatility conditions and regime.

Argument Contract
data (pl.DataFrame) Klines dataset with 'volatility_measure', 'regime_multiplier' columns
base_min_breakout (float) Base minimum breakout threshold
target_volatility_multiplier (float) Multiplier for volatility-adjusted targets
clip_lower_mult (float) Lower bound multiplier for clipping
clip_upper_mult (float) Upper bound multiplier for clipping

Returns: pl.DataFrame: The input data with a new column 'dynamic_target'

limen.features.ema_alignment

python · ema_alignment.py
def ema_alignment(data: pl.DataFrame, ema_span: int=21, power: float=2.0) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute EMA alignment score with power transformation.

Argument Contract
data (pl.DataFrame) Klines dataset with 'close' column
ema_span (int) Span for EMA calculation
power (float) Power for alignment transformation

Returns: pl.DataFrame: The input data with new columns 'ema', 'ema_alignment'

limen.features.entry_score_microstructure

python · entry_score_microstructure.py
def entry_score_microstructure(data: pl.DataFrame, micro_momentum_period: int=3, volume_spike_period: int=20, spread_mean_period: int=48, entry_position_weight_base: float=0.25, entry_momentum_weight_base: float=0.25, entry_volume_weight_base: float=0.25, entry_spread_weight_base: float=0.25, entry_position_weight_low_vol: float=0.35, entry_momentum_weight_low_vol: float=0.15, entry_volume_weight_low_vol: float=0.15, entry_spread_weight_low_vol: float=0.35, entry_position_weight_high_vol: float=0.15, entry_momentum_weight_high_vol: float=0.35, entry_volume_weight_high_vol: float=0.35, entry_spread_weight_high_vol: float=0.15, entry_volume_spike_min: float=0.5, entry_volume_spike_max: float=1.5, entry_volume_spike_normalizer: float=1.5, entry_spread_ratio_min: float=0, entry_spread_ratio_max: float=2) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute sophisticated entry score based on microstructure timing signals.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close', 'volume', 'volatility_regime' columns
micro_momentum_period (int) Period for micro momentum calculation
volume_spike_period (int) Period for volume spike calculation
spread_mean_period (int) Period for spread normalization
entry_position_weight_base (float) Base weight for position-in-candle factor
entry_momentum_weight_base (float) Base weight for momentum factor
entry_volume_weight_base (float) Base weight for volume factor
entry_spread_weight_base (float) Base weight for spread factor
entry_position_weight_low_vol (float) Position weight in low volatility regime
entry_momentum_weight_low_vol (float) Momentum weight in low volatility regime
entry_volume_weight_low_vol (float) Volume weight in low volatility regime
entry_spread_weight_low_vol (float) Spread weight in low volatility regime
entry_position_weight_high_vol (float) Position weight in high volatility regime
entry_momentum_weight_high_vol (float) Momentum weight in high volatility regime
entry_volume_weight_high_vol (float) Volume weight in high volatility regime
entry_spread_weight_high_vol (float) Spread weight in high volatility regime
entry_volume_spike_min (float) Minimum volume spike value for clipping
entry_volume_spike_max (float) Maximum volume spike value for clipping
entry_volume_spike_normalizer (float) Normalizer for volume spike scaling
entry_spread_ratio_min (float) Minimum spread ratio for clipping
entry_spread_ratio_max (float) Maximum spread ratio for clipping

Returns: pl.DataFrame: The input data with a new column 'entry_score'

limen.features.feature_aliases

python · feature_aliases.py
def feature_aliases(df: pl.DataFrame, base_min_breakout: float=0.005, volatility_regime_enabled: bool=True) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute feature aliases with null filling for dynamic and regime features.

Argument Contract
df (pl.DataFrame) Klines dataset with dynamic features
base_min_breakout (float) Default value for dynamic_target
volatility_regime_enabled (bool) Whether to create regime feature aliases

Returns: pl.DataFrame: The input data with new columns 'dynamic_target_feature', 'entry_score_feature', 'momentum_score_feature' and optional regime columns

limen.features.find_min_d

python · fractional_diff.py
def find_min_d(data: pl.DataFrame, col: str, d_start: float=0.0, d_end: float=1.0, step: float=0.1, significance_level: float=0.05, threshold: float=1e-05) -> float:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Find the minimum fractional differentiation order achieving stationarity.

Iterates from d_start to d_end by step, applying fractional

differentiation at each d and testing with ADF. Returns the

smallest d where the series is stationary.

Argument Contract
data (pl.DataFrame) Input data containing the column to test
col (str) Column name to differentiate and test
d_start (float) Starting differentiation order
d_end (float) Maximum differentiation order
step (float) Increment between tested d values
significance_level (float) ADF test significance threshold
threshold (float) Weight truncation threshold for fractional diff

Returns: float: Smallest d achieving stationarity, or d_end if none found

limen.features.fractional_diff

python · fractional_diff.py
def fractional_diff(data: pl.DataFrame, d: float=0.0, cols: list[str] | None=None, threshold: float=1e-05) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Apply Fixed-Width Fractional Differentiation (FFD) to specified columns.

Based on Lopez de Prado's AFML Chapter 5. Achieves stationarity

while preserving memory in financial time series. Adds new columns

with suffix '_fracdiff' — original columns are preserved for

indicators that depend on raw values.

NOTE: AFML recommends applying to log-transformed prices for best results.

Argument Contract
data (pl.DataFrame) Input data
d (float) Finite, non-negative order (0 = identity copy, 1 = standard diff)
cols (list[str] | None) Columns to differentiate (required)
threshold (float) Finite, positive weight truncation threshold per AFML standard

Returns: pl.DataFrame: Data with new '{col}_fracdiff' columns added.

When d=0, the new columns are copies of the originals.

Raises: ValueError: If cols is None, empty, a string, or names missing columns,

d is non-finite or negative, threshold is non-finite or nonpositive,

or a recurrence weight is non-finite.

limen.features.gap_high

python · gap_high.py
def gap_high(data: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 3b6ff327Package signature · Limen 6.0.1 · current package validation · package source

Compute gap between current high and previous close as percentage.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high' and 'close' columns

Returns: pl.DataFrame: The input data with a new column 'gap_high'

limen.features.garman_klass_volatility

python · garman_klass_volatility.py
def garman_klass_volatility(data: pl.DataFrame, window: int=20, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Garman-Klass range-based volatility over a rolling window.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close price columns
window (int) Number of periods used for the rolling estimator
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'garman_klass_volatility'

limen.features.hh_hl_structure_regime

python · hh_hl_structure_regime.py
def hh_hl_structure_regime(df: pl.DataFrame, window: int=24, score_threshold: int=4) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute regime by higher-high / higher-low market structure within a rolling window.

Argument Contract
df (pl.DataFrame) Klines dataset with 'high', 'low' columns
window (int) Rolling window size for structure count
score_threshold (int) Absolute score threshold for Up/Down classification

Returns: pl.DataFrame: The input data with a new column 'regime_hh_hl'

limen.features.hours_since_big_move

python · hours_since_big_move.py
def hours_since_big_move(data: pl.DataFrame, long_lines: list[dict[str, float]], short_lines: list[dict[str, float]], lookback_hours: int) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute hours since the most recent line end capped by lookback_hours.

Argument Contract
data (pl.DataFrame) Klines dataset with 'datetime' and 'close' columns
long_lines (list[dict]) Long line definitions with 'start_idx' and 'end_idx'
short_lines (list[dict]) Short line definitions with 'start_idx' and 'end_idx'
lookback_hours (int) Maximum number of hours to track recency

Returns: pl.DataFrame: The input data with a new column 'hours_since_big_move'

limen.features.hours_since_quantile_line

python · hours_since_quantile_line.py
def hours_since_quantile_line(data: pl.DataFrame, long_lines_q: list[dict[str, float]], short_lines_q: list[dict[str, float]], lookback_hours: int) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute hours since the most recent quantile-filtered line end capped by lookback_hours.

Argument Contract
data (pl.DataFrame) Klines dataset with 'datetime' and 'close' columns
long_lines_q (list[dict]) Quantile-filtered long lines with 'end_idx'
short_lines_q (list[dict]) Quantile-filtered short lines with 'end_idx'
lookback_hours (int) Maximum number of hours to track recency

Returns: pl.DataFrame: The input data with a new column 'hours_since_quantile_line'

limen.features.ichimoku_cloud

python · ichimoku_cloud.py
def ichimoku_cloud(data: pl.DataFrame, tenkan_period: int=9, kijun_period: int=26, senkou_b_period: int=52, displacement: int=26) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Ichimoku Cloud components for trend and momentum analysis.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns
tenkan_period (int) Lookback period for Tenkan-sen
kijun_period (int) Lookback period for Kijun-sen
senkou_b_period (int) Lookback period for Senkou Span B
displacement (int) Non-negative shift for Senkou spans and Chikou span

Returns: pl.DataFrame: The input data with new columns:

'tenkan', 'kijun', 'senkou_a', 'senkou_b', 'chikou'

limen.features.illiquidity_shock

python · illiquidity_shock.py
def illiquidity_shock(data: pl.DataFrame, window: int=20, price_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute the current Amihud illiquidity level relative to its trailing baseline.

Argument Contract
data (pl.DataFrame) Klines dataset with price and volume columns
window (int) Number of periods used for the trailing Amihud baseline
price_col (str) Column name used for close-to-close returns
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'illiquidity_shock'

limen.features.is_funding_hour

python · is_funding_hour.py
def is_funding_hour(data: pl.DataFrame, hours: Sequence[int]=(0, 8, 16), datetime_col: str='datetime', output_col: str='is_funding_hour') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Mark rows whose hour matches a configured funding cadence.

Argument Contract
data (pl.DataFrame) Dataset with a datetime-like column
hours (Sequence[int]) Funding hours to mark
datetime_col (str) Column name for timestamps
output_col (str) Output column name

Returns: pl.DataFrame: The input data with an Int8 funding-hour flag appended

limen.features.is_us_open_hour

python · is_us_open_hour.py
def is_us_open_hour(data: pl.DataFrame, hour: int=14, datetime_col: str='datetime', output_col: str='is_us_open_hour') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Mark rows whose hour matches the configured US open hour.

Argument Contract
data (pl.DataFrame) Dataset with a datetime-like column
hour (int) Hour to mark
datetime_col (str) Column name for timestamps
output_col (str) Output column name

Returns: pl.DataFrame: The input data with an Int8 US-open-hour flag appended

limen.features.jump_variation_proxy

python · jump_variation_proxy.py
def jump_variation_proxy(data: pl.DataFrame, window: int=20, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute a rolling jump-variation proxy from realized variance and aligned bipower variation.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of returns used for the rolling jump proxy
close_col (str) Column name used for log returns

Returns: pl.DataFrame: The input data with a new column 'jump_variation_proxy'

limen.features.kaufman_efficiency_ratio

python · kaufman_efficiency_ratio.py
def kaufman_efficiency_ratio(data: pl.DataFrame, window: int=10, close_col: str='close', output_col: str='kaufman_efficiency_ratio') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Kaufman's efficiency ratio over a rolling window.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods used for displacement and path length
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the efficiency-ratio column appended

limen.features.kline_imbalance

python · kline_imbalance.py
def kline_imbalance(data: pl.DataFrame, window: int=14) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling buyer/seller imbalance over klines instead of raw trades.

Argument Contract
data (pl.DataFrame) Klines dataset with 'maker_ratio' and 'no_of_trades' columns
window (int) Number of periods for rolling window calculation

Returns: pl.DataFrame: The input data with a new column 'imbalance'

limen.features.lag_column

python · lagged_features.py
def lag_column(data: pl.DataFrame, col: str, lag: int, alias: object=None) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute a lagged version of a column.

Argument Contract
data (pl.DataFrame) Klines dataset with specified column
col (str) The column name to lag
lag (int) The number of periods to lag
alias (str, optional) New column name. If None, uses alias f"lag_{lag}"

Returns: pl.DataFrame: The input data with the lagged column appended

limen.features.lag_columns

python · lagged_features.py
def lag_columns(data: pl.DataFrame, cols: list[str], lag: int) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute lagged versions of multiple columns.

Argument Contract
data (pl.DataFrame) Klines dataset with specified columns
cols (list[str]) The list of column names to lag
lag (int) The number of periods to lag

Returns: pl.DataFrame: The input data with the lagged columns appended

limen.features.lag_range

python · lagged_features.py
def lag_range(data: pl.DataFrame, col: str, start: int, end: int) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute multiple lagged versions of a column over a range.

Argument Contract
data (pl.DataFrame) Klines dataset with specified column
col (str) The column name to lag
start (int) The start of lag range (inclusive)
end (int) The end of lag range (inclusive)

Returns: pl.DataFrame: The input data with the lagged columns appended

limen.features.lag_range_cols

python · lagged_features.py
def lag_range_cols(data: pl.DataFrame, cols: list[str], start: object, end: object) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute multiple lagged versions of multiple columns over a range.

Argument Contract
data (pl.DataFrame) Klines dataset with specified columns
cols (list[str]) The list of column names to lag
start (int) The start of lag range (inclusive)
end (int) The end of lag range (inclusive)

Returns: pl.DataFrame: The input data with the lagged columns appended

limen.features.liquidity_drop

python · liquidity_drop.py
def liquidity_drop(data: pl.DataFrame, window: int=20, liquidity_col: str='liquidity_sum', output_col: str='liquidity_drop') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute current liquidity relative to liquidity from a fixed lag.

Argument Contract
data (pl.DataFrame) Klines dataset with a total-liquidity column
window (int) Lag used as the denominator
liquidity_col (str) Column name for total liquidity
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the liquidity-drop column appended

limen.features.liquidity_range

python · liquidity_range.py
def liquidity_range(data: pl.DataFrame, window: int=20, high_liquidity_col: str='high_liquidity', low_liquidity_col: str='low_liquidity', output_col: str='liquidity_range') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling mean high-liquidity to low-liquidity ratio.

Argument Contract
data (pl.DataFrame) Klines dataset with high- and low-liquidity columns
window (int) Number of periods in the rolling mean
high_liquidity_col (str) Column name for high-side liquidity
low_liquidity_col (str) Column name for low-side liquidity
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the liquidity-range column appended

limen.features.log_returns

python · log_returns.py
def log_returns(data: pl.DataFrame, price_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute logarithmic returns for price series.

Argument Contract
data (pl.DataFrame) Dataset with price column
price_col (str) Name of the price column (default: 'close')

Returns: pl.DataFrame: The input data with a new column 'log_returns'

limen.features.ma_slope_regime

python · ma_slope_regime.py
def ma_slope_regime(df: pl.DataFrame, period: int=24, threshold: float=0.0, normalize_by_std: bool=True) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute regime using the slope of SMA(close, period) with optional normalization.

Argument Contract
df (pl.DataFrame) Klines dataset with 'close' column
period (int) SMA period for the slope
threshold (float) Slope threshold; applied after normalization when enabled
normalize_by_std (bool) Whether to divide slope by rolling std(period)

Returns: pl.DataFrame: The input data with a new column 'regime_ma_slope'

limen.features.maker_liquidity_share

python · maker_liquidity_share.py
def maker_liquidity_share(data: pl.DataFrame, maker_liquidity_col: str='maker_liquidity', liquidity_col: str='liquidity_sum', output_col: str='maker_liquidity_share') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute maker liquidity as a share of total liquidity.

Argument Contract
data (pl.DataFrame) Klines dataset with maker and total liquidity columns
maker_liquidity_col (str) Column name for maker-side liquidity
liquidity_col (str) Column name for total liquidity
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the maker-liquidity share column appended

limen.features.maker_volume_ratio

python · maker_volume_ratio.py
def maker_volume_ratio(data: pl.DataFrame, window: int=20, maker_volume_col: str='maker_volume', volume_col: str='volume', output_col: str='maker_volume_ratio') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute the rolling mean maker-volume share.

Argument Contract
data (pl.DataFrame) Klines dataset with maker volume and total volume columns
window (int) Number of periods in the rolling mean
maker_volume_col (str) Column name for maker-side traded volume
volume_col (str) Column name for total traded volume
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the rolling maker-volume ratio appended

limen.features.maker_volume_share

python · maker_volume_share.py
def maker_volume_share(data: pl.DataFrame, maker_volume_col: str='maker_volume', volume_col: str='volume', output_col: str='maker_volume_share') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute maker volume as a share of total volume.

Argument Contract
data (pl.DataFrame) Klines dataset with maker volume and total volume columns
maker_volume_col (str) Column name for maker-side traded volume
volume_col (str) Column name for total traded volume
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the maker-volume share column appended

limen.features.market_regime

python · market_regime.py
def market_regime(df: pl.DataFrame, lookback: int=48, short_sma: int=20, long_sma: int=50) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Add close-average, volume-regime and market-favorability features.

sma_20 and sma_50 bind the selected short/long close averages, including equal

or swapped periods; volume_sma binds the selected volume average. Fixed aliases

take precedence over close canonicals, which take precedence over the volume

canonical. Nonconflicting sma_ outputs retain their existing positions.

Incoming fixed aliases raise DuplicateError. SMA warmup remains NaN; derived

trend, volatility, volume-regime and favorability warmup remains null.

limen.features.micro_momentum

python · micro_momentum.py
def micro_momentum(data: pl.DataFrame, period: int=3) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute short-term price momentum over specified periods.

Argument Contract
data (pl.DataFrame) Klines dataset with 'close' column
period (int) Number of periods for momentum calculation

Returns: pl.DataFrame: The input data with a new column 'micro_momentum'

limen.features.momentum_confirmation

python · momentum_confirmation.py
def momentum_confirmation(df: pl.DataFrame, short_period: int=1, long_period: int=3, short_weight: float=0.5) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute simple momentum confirmation scores based on recent price changes.

Argument Contract
df (pl.DataFrame) Klines dataset with 'close' column
short_period (int) Number of periods for short-term momentum
long_period (int) Number of periods for long-term momentum
short_weight (float) Weight for short-term momentum in final score

Returns: pl.DataFrame: The input data with new columns 'momentum_1', 'momentum_3', 'momentum_score'

limen.features.momentum_periods

python · momentum_periods.py
def momentum_periods(data: pl.DataFrame, periods: list[int] | None=None, price_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute momentum over multiple time periods.

Argument Contract
data (pl.DataFrame) Dataset with price column
periods (list) Non-negative periods for momentum calculation
price_col (str) Name of the price column (default: 'close')

Returns: pl.DataFrame: The input data with new columns 'momentum_{period}' for each period

limen.features.momentum_weight

python · momentum_weight.py
def momentum_weight(data: pl.DataFrame, period: int=12, weight_multiplier: float=0.5, base_weight: float=0.5) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute momentum-based weighting factor from price change direction.

Argument Contract
data (pl.DataFrame) Klines dataset with 'close' column
period (int) Period for momentum calculation
weight_multiplier (float) Multiplier for positive momentum
base_weight (float) Base weight added to all observations

Returns: pl.DataFrame: The input data with a new column 'momentum_weight'

limen.features.narrow_range

python · narrow_range.py
def narrow_range(data: pl.DataFrame, window: int=20, high_col: str='high', low_col: str='low', output_col: str='narrow_range') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute current range relative to the trailing maximum range.

Argument Contract
data (pl.DataFrame) Klines dataset with high and low price columns
window (int) Number of periods in the trailing maximum
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the narrow-range column appended

limen.features.order_flow_imbalance

python · order_flow_imbalance.py
def order_flow_imbalance(data: pl.DataFrame, window: int=20, classification_window: int=20, close_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute a rolling bulk-volume order-flow imbalance from classified buy and sell volume.

Bars are split into buy and sell volume by bulk-volume classification, then

the net signed volume is summed over window and divided by the summed total

volume, giving a directional flow proxy in [-1, 1]. This is a bar-level proxy

for order-flow imbalance inferred from price; it is not the level-2 order-book

OFI of Cont, Kukanov, and Stoikov.

Argument Contract
data (pl.DataFrame) Klines dataset with close and volume columns
window (int) Rolling window over which signed flow is accumulated
classification_window (int) Rolling window for the bulk-volume classification standardization
close_col (str) Column name used for close-to-close log returns
volume_col (str) Column name for total traded volume

Returns: pl.DataFrame: The input data with classified buy/sell volume columns and a

new 'order_flow_imbalance' column

limen.features.parkinson_vol_of_vol

python · parkinson_vol_of_vol.py
def parkinson_vol_of_vol(data: pl.DataFrame, window: int=20, high_col: str='high', low_col: str='low', output_col: str='parkinson_vol_of_vol') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling standard deviation of Parkinson variance.

Argument Contract
data (pl.DataFrame) Klines dataset with high and low price columns
window (int) Number of periods in the rolling standard deviation
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the Parkinson vol-of-vol column appended

limen.features.parkinson_volatility

python · parkinson_volatility.py
def parkinson_volatility(data: pl.DataFrame, window: int=20, high_col: str='high', low_col: str='low') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Parkinson range-based volatility over a rolling window.

Argument Contract
data (pl.DataFrame) Klines dataset with high and low price columns
window (int) Number of periods used for the rolling estimator
high_col (str) Column name for high prices
low_col (str) Column name for low prices

Returns: pl.DataFrame: The input data with a new column 'parkinson_volatility'

limen.features.position_in_candle

python · position_in_candle.py
def position_in_candle(data: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 3b6ff327Package signature · Limen 6.0.1 · current package validation · package source

Compute position of close within candle high-low range.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns

Returns: pl.DataFrame: The input data with a new column 'position_in_candle'

limen.features.position_in_range

python · position_in_range.py
def position_in_range(df: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 3b6ff327Package signature · Limen 6.0.1 · current package validation · package source

Compute position of close within candle high-low range.

Uses the following calculation:

(close - low) / (high - low + 1e-10)

Argument Contract
df (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns

Returns: pl.DataFrame: The input data with a new column 'position_in_range'

limen.features.price_lines

python · price_lines.py
def price_lines(data: pl.DataFrame, max_duration_hours: int, min_height_pct: float, big_move_lookback_hours: int=DEFAULT_BIG_MOVE_LOOKBACK_HOURS, momentum_lookback_hours: int=DEFAULT_MOMENTUM_LOOKBACK_HOURS, include_research_only: object=True) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute line-based context features from internally detected price lines.

Detects lines on the frame it receives (per split under the manifest

pipeline) and adds five columns: 'active_lines' (count of lines spanning

the bar), 'hours_since_big_move' (bars since the most recent line end,

capped at big_move_lookback_hours), 'line_momentum_h' (long minus

short line ends in the trailing window [t-m, t)), 'trending_score'

(signed end-count balance in [-1, 1]), and 'reversal_potential'

(min/max end-count ratio in [0, 1]).

Argument Contract
data (pl.DataFrame | pl.LazyFrame) Klines dataset with a 'close' column
max_duration_hours (int) Exclusive upper bound on line duration in bars
min_height_pct (float) Minimum absolute line height as a fraction of start price
big_move_lookback_hours (int) Recency cap for 'hours_since_big_move'
momentum_lookback_hours (int) Trailing window for the end-count columns
include_research_only (bool) Include the non-live-computable 'active_lines' span-count column. Set False for live-safe feature surfaces.

Returns: pl.DataFrame | pl.LazyFrame: The input data, matching the input frame

type, with five new line-based columns

Raises: ValueError: If a lookback is below 1

NOTE: Column access is expression-based so the feature runs on both eager

DataFrames and the LazyFrames piped by the manifest feature pipeline.

NOTE: 'active_lines' counts lines that span the bar before the line's end

is knowable, a within-line lookahead inherited from the research design.

It is research-only and not computable live; the end-event columns are causal.

limen.features.price_range_position

python · price_range_position.py
def price_range_position(data: pl.DataFrame, period: int=24) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute price position within rolling high-low range.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns
period (int) Number of periods for rolling range calculation

Returns: pl.DataFrame: The input data with a new column 'price_range_position'

limen.features.price_vs_band_regime

python · price_vs_band_regime.py
def price_vs_band_regime(df: pl.DataFrame, period: int=24, band: Literal['std', 'dev_std']='std', k: float=0.75) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute regime by comparing 'close' to center ± k × band width over a rolling window.

Argument Contract
df (pl.DataFrame) Klines dataset with 'close' column
period (int) Rolling period for center and band width
band (Literal['std', 'dev_std']) Band width type to use
k (float) Band multiplier applied to the width

Returns: pl.DataFrame: The input data with a new column 'regime_price_band'

limen.features.quantile_line_density

python · quantile_line_density.py
def quantile_line_density(data: pl.DataFrame, long_lines_q: list[dict[str, float]], short_lines_q: list[dict[str, float]], lookback_hours: int) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute count of quantile-filtered line ends within lookback_hours window.

Argument Contract
data (pl.DataFrame) Klines dataset with 'datetime' and 'close' columns
long_lines_q (list[dict]) Quantile-filtered long lines with 'end_idx'
short_lines_q (list[dict]) Quantile-filtered short lines with 'end_idx'
lookback_hours (int) Window size in hours for density calculation

Returns: pl.DataFrame: The input data with a new column 'quantile_line_density_{lookback_hours}h'

limen.features.quantile_price_lines

python · quantile_price_lines.py
def quantile_price_lines(data: pl.DataFrame, max_duration_hours: int, min_height_pct: float, quantile_threshold: float=DEFAULT_QUANTILE_THRESHOLD, density_lookback_hours: int=DEFAULT_DENSITY_LOOKBACK_HOURS, momentum_lookback_hours: int=DEFAULT_MOMENTUM_LOOKBACK_HOURS, height_lookback_hours: int=DEFAULT_HEIGHT_LOOKBACK_HOURS, include_research_only: object=True) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute quantile-line end features from lines completed through each row.

Select heights at or above each direction's expanding quantile, with ties.

End windows include both boundaries [t-window, t]; recency caps at density_lookback_hours.

Other empty windows return zero; active_quantile_count retains retrospective whole-frame spans.

Argument Contract
data (pl.DataFrame | pl.LazyFrame) Klines with a close column
max_duration_hours (int) Exclusive upper bound on line duration in bars
min_height_pct (float) Minimum absolute height as a fraction of start price
quantile_threshold (float) Per-direction height quantile
density_lookback_hours (int) Density window and recency cap
momentum_lookback_hours (int) Signed-height window
height_lookback_hours (int) Mean-height and direction-bias window
include_research_only (bool) Add the retrospective active_quantile_count

Returns: pl.DataFrame | pl.LazyFrame: Input type with five end columns and optional span count

Raises: ValueError: If a lookback is below 1 or include_research_only is not bool

limen.features.range_overlap

python · range_overlap.py
def range_overlap(data: pl.DataFrame, high_col: str='high', low_col: str='low') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute how much the current bar overlaps the previous bar's range.

Argument Contract
data (pl.DataFrame) Klines dataset with high and low price columns
high_col (str) Column name for high prices
low_col (str) Column name for low prices

Returns: pl.DataFrame: The input data with a new column 'range_overlap'

limen.features.range_pct

python · range_pct.py
def range_pct(data: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 7c385782Package signature · Limen 6.0.1 · current package validation · package source

Compute range as percentage of close price (high-low)/close.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', and 'close' columns

Returns: pl.DataFrame: The input data with a new column 'range_pct'

limen.features.range_per_dollar_volume

python · range_per_dollar_volume.py
def range_per_dollar_volume(data: pl.DataFrame, high_col: str='high', low_col: str='low', close_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute normalized bar range per traded dollar.

Argument Contract
data (pl.DataFrame) Klines dataset with high, low, close, and volume columns
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'range_per_dollar_volume'

limen.features.realized_kurtosis

python · realized_kurtosis.py
def realized_kurtosis(data: pl.DataFrame, window: int=20, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling standardized kurtosis of close-to-close returns.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods used for the rolling kurtosis estimate
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with a new column 'realized_kurtosis'

limen.features.realized_semivariance

python · realized_semivariance.py
def realized_semivariance(data: pl.DataFrame, window: int=20, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling upside and downside semivariance from close-to-close returns.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods used for the rolling semivariance estimates
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with new columns 'upside_semivariance' and 'downside_semivariance'

limen.features.realized_skewness

python · realized_skewness.py
def realized_skewness(data: pl.DataFrame, window: int=20, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling standardized skewness of close-to-close returns.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods used for the rolling skewness estimate
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with a new column 'realized_skewness'

limen.features.regime_multiplier

python · regime_multiplier.py
def regime_multiplier(data: pl.DataFrame, regime_low_volatility_multiplier: float=0.8, regime_normal_volatility_multiplier: float=1.0, regime_high_volatility_multiplier: float=1.2) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volatility regime-based multiplier for dynamic parameter adjustment.

Argument Contract
data (pl.DataFrame) Klines dataset with 'volatility_regime' column
regime_low_volatility_multiplier (float) Multiplier for low volatility regime
regime_normal_volatility_multiplier (float) Multiplier for normal volatility regime
regime_high_volatility_multiplier (float) Multiplier for high volatility regime

Returns: pl.DataFrame: The input data with a new column 'regime_multiplier'

limen.features.rejection_intensity

python · rejection_intensity.py
def rejection_intensity(data: pl.DataFrame, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute the wick fraction that rejects movement against the candle close direction.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close columns
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'rejection_intensity'

limen.features.relative_range_seasonality

python · relative_range_seasonality.py
def relative_range_seasonality(data: pl.DataFrame, datetime_col: str='datetime', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute normalized bar range relative to the trailing mean for the same hour of the week.

Argument Contract
data (pl.DataFrame) Klines dataset with datetime, high, low, and close columns
datetime_col (str) Column name for datetimes used to derive hour-of-week buckets
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'relative_range_seasonality'

limen.features.relative_volatility_seasonality

python · relative_volatility_seasonality.py
def relative_volatility_seasonality(data: pl.DataFrame, datetime_col: str='datetime', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute absolute return magnitude relative to the trailing mean for the same hour of the week.

Argument Contract
data (pl.DataFrame) Klines dataset with datetime and close columns
datetime_col (str) Column name for datetimes used to derive hour-of-week buckets
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with a new column 'relative_volatility_seasonality'

limen.features.relative_volume_seasonality

python · relative_volume_seasonality.py
def relative_volume_seasonality(data: pl.DataFrame, datetime_col: str='datetime', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute current volume relative to the trailing mean for the same hour of the week.

Argument Contract
data (pl.DataFrame) Klines dataset with datetime and volume columns
datetime_col (str) Column name for datetimes used to derive hour-of-week buckets
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'relative_volume_seasonality'

limen.features.return_autocorrelation

python · return_autocorrelation.py
def return_autocorrelation(data: pl.DataFrame, window: int=20, close_col: str='close', output_col: str='return_autocorrelation') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling autocorrelation between returns and one-bar lagged returns.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods in the rolling correlation
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the return-autocorrelation column appended

limen.features.return_per_dollar_volume

python · return_per_dollar_volume.py
def return_per_dollar_volume(data: pl.DataFrame, price_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute signed return per traded dollar as a simple impact-efficiency proxy.

Argument Contract
data (pl.DataFrame) Klines dataset with price and volume columns
price_col (str) Column name used for close-to-close returns
volume_col (str) Column name for traded volume

Returns: pl.DataFrame: The input data with a new column 'return_per_dollar_volume'

limen.features.return_volatility_correlation

python · return_volatility_correlation.py
def return_volatility_correlation(data: pl.DataFrame, window: int=20, close_col: str='close', high_col: str='high', low_col: str='low', output_col: str='return_volatility_correlation') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling correlation between returns and Parkinson variance.

Argument Contract
data (pl.DataFrame) Klines dataset with close, high, and low columns
window (int) Number of periods in the rolling correlation
close_col (str) Column name for close prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the return-volatility correlation appended

limen.features.returns_lags

python · returns_lags.py
def returns_lags(data: pl.DataFrame, max_lag: int=24, returns_col: str='returns') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute multiple lagged returns features for time series analysis.

Argument Contract
data (pl.DataFrame) Klines dataset with returns column
max_lag (int) Maximum number of lag periods to compute
returns_col (str) Name of the returns column

Returns: pl.DataFrame: The input data with new columns 'returns_lag_1', 'returns_lag_2', etc.

limen.features.rogers_satchell_volatility

python · rogers_satchell_volatility.py
def rogers_satchell_volatility(data: pl.DataFrame, window: int=20, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Rogers-Satchell range-based volatility over a rolling window.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close price columns
window (int) Number of periods used for the rolling estimator
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'rogers_satchell_volatility'

limen.features.rolling_zscore

python · rolling_zscore.py
def rolling_zscore(data: pl.DataFrame, column: str, window: int, *, transform: ZscoreTransform='identity', output_col: str | None=None) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute a rolling z-score for a transformed input column.

Argument Contract
data (pl.DataFrame) Dataset containing the source column
column (str) Source column name
window (int) Number of periods for the rolling mean and standard deviation
transform (ZscoreTransform) Optional source transform before standardization
output_col (str | None) Output column name; defaults to {column}_zscore_{window}

Returns: pl.DataFrame: The input data with the rolling z-score column appended

limen.features.sma_crossover

python · sma_crossover.py
def sma_crossover(df: pl.DataFrame, short_window: int=10, long_window: int=30, crossover_bull: int=2, crossover_bear: int=-2) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Simple Moving Average (SMA) crossover signals.

Argument Contract
df (pl.DataFrame) Klines dataset with 'close' column
short_window (int) Number of periods for short-term SMA
long_window (int) Number of periods for long-term SMA
crossover_bull (int) Value indicating bullish crossover
crossover_bear (int) Value indicating bearish crossover

Returns: pl.DataFrame: The input data with new columns 'crossover', and 'signal'

limen.features.sma_ratios

python · sma_ratios.py
def sma_ratios(data: pl.DataFrame, periods: list[int] | None=None, price_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute price to SMA ratios for multiple time periods.

Argument Contract
data (pl.DataFrame) Klines dataset with price column
periods (list) List of SMA periods to calculate ratios for
price_col (str) Name of the price column (default: 'close')

Returns: pl.DataFrame: The input data with new columns 'sma_{period}_ratio'

limen.features.spread

python · spread.py
def spread(df: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 7c385782Package signature · Limen 6.0.1 · current package validation · package source

Compute price spread as percentage of close price.

Argument Contract
df (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns

Returns: pl.DataFrame: The input data with a new column 'spread'

limen.features.spread_percent

python · spread_percent.py
def spread_percent(data: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 7c385782Package signature · Limen 6.0.1 · current package validation · package source

Compute high-low spread as percentage of close price.

Argument Contract
data (pl.DataFrame) Klines dataset with 'high', 'low', 'close' columns

Returns: pl.DataFrame: The input data with a new column 'spread_percent'

limen.features.stochastic_k_abs

python · stochastic_k_abs.py
def stochastic_k_abs(data: pl.DataFrame, window: int=14, high_col: str='high', low_col: str='low', close_col: str='close', output_col: str='stochastic_k_abs') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute absolute distance of stochastic percent K from the center line.

Argument Contract
data (pl.DataFrame) Klines dataset with high, low, and close columns
window (int) Number of periods in the high-low channel
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the stochastic distance column appended

limen.features.tail_event_intensity

python · tail_event_intensity.py
def tail_event_intensity(data: pl.DataFrame, window: int=20, z_threshold: float=2.0, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute the trailing share of return shocks that exceed a volatility-scaled threshold.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
window (int) Number of periods used for both the volatility baseline and event share
z_threshold (float) Multiple of trailing return volatility required to count as a tail event
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with a new column 'tail_event_intensity'

limen.features.taker_imbalance_ratio

python · taker_imbalance_ratio.py
def taker_imbalance_ratio(data: pl.DataFrame, window: int=20, volume_col: str='volume', maker_ratio_col: str='maker_ratio', output_col: str='taker_imbalance_ratio') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling absolute taker imbalance as a share of volume.

Argument Contract
data (pl.DataFrame) Klines dataset with volume and maker-ratio columns
window (int) Number of periods in the rolling mean
volume_col (str) Column name for total traded volume
maker_ratio_col (str) Column name for maker-side volume ratio
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the taker-imbalance ratio column appended

limen.features.time_to_funding

python · time_to_funding.py
def time_to_funding(data: pl.DataFrame, interval_hours: int=8, offset_hour: int=0, datetime_col: str='datetime', output_col: str='hours_to_funding') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute the number of hours until the next funding settlement.

Funding settles every interval_hours from offset_hour UTC (the default

cadence is 0, 8, and 16 hours). The output is the continuous distance in hours

from each timestamp to the next settlement, and is zero at a settlement bar.

The cadence is anchored to UTC midnight, so interval_hours must divide 24.

Timezone-aware timestamps are converted to UTC; naive timestamps are assumed

to already be in UTC.

Argument Contract
data (pl.DataFrame) Dataset with a datetime column
interval_hours (int) Spacing between funding settlements in hours; must divide 24
offset_hour (int) Hour of the first daily settlement in UTC
datetime_col (str) Column name for timestamps
output_col (str) Output column name

Returns: pl.DataFrame: The input data with a new 'hours_to_funding' column

limen.features.trade_density

python · trade_density.py
def trade_density(data: pl.DataFrame, window: int=20, trades_col: str='no_of_trades', volume_col: str='volume', output_col: str='trade_density') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling mean trade count per unit of volume.

Argument Contract
data (pl.DataFrame) Klines dataset with trade-count and volume columns
window (int) Number of periods in the rolling mean
trades_col (str) Column name for number of trades
volume_col (str) Column name for total traded volume
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the trade-density column appended

limen.features.trade_imbalance

python · trade_imbalance.py
def trade_imbalance(data: pl.DataFrame, window: int=20, maker_volume_col: str='maker_volume', volume_col: str='volume', output_col: str='trade_imbalance') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling maker volume divided by rolling total volume.

Argument Contract
data (pl.DataFrame) Klines dataset with maker volume and total volume columns
window (int) Number of periods used for rolling sums
maker_volume_col (str) Column name for maker-side traded volume
volume_col (str) Column name for total traded volume
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the rolling trade-imbalance column appended

limen.features.trade_size_ratio

python · trade_size_ratio.py
def trade_size_ratio(data: pl.DataFrame, short_window: int=5, long_window: int=20, volume_col: str='volume', trades_col: str='no_of_trades', output_col: str='trade_size_ratio') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compare short and long rolling average trade sizes.

Argument Contract
data (pl.DataFrame) Klines dataset with volume and trade-count columns
short_window (int) Number of periods in the short average
long_window (int) Number of periods in the long average
volume_col (str) Column name for total traded volume
trades_col (str) Column name for number of trades
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the trade-size ratio column appended

limen.features.trend_coherence

python · trend_coherence.py
def trend_coherence(data: pl.DataFrame, short_window: int=12, medium_window: int=48, long_window: int=168, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute directional agreement across short, medium, and long return horizons.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
short_window (int) Short return horizon
medium_window (int) Medium return horizon
long_window (int) Long return horizon
close_col (str) Column name used for return calculations

Returns: pl.DataFrame: The input data with a new column 'trend_coherence'

limen.features.trend_strength

python · trend_strength.py
def trend_strength(data: pl.DataFrame, fast_period: int=20, slow_period: int=50) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute trend strength based on moving average divergence.

Argument Contract
data (pl.DataFrame) Klines dataset with 'close' column
fast_period (int) Number of periods for fast SMA calculation
slow_period (int) Number of periods for slow SMA calculation

Returns: pl.DataFrame: The input data with a new column 'trend_strength'

limen.features.volatility_1h

python · volatility_1h.py
def volatility_1h(df: pl.DataFrame, volatility_column: str='returns_volatility_12') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volatility_1h alias from existing volatility column.

Argument Contract
df (pl.DataFrame) Klines dataset with volatility column
volatility_column (str) Name of the source volatility column

Returns: pl.DataFrame: The input data with a new column 'volatility_1h'

limen.features.volatility_measure

python · volatility_measure.py
def volatility_measure(data: pl.DataFrame) -> pl.DataFrame:    ...
Merged source PR · 3b6ff327Package signature · Limen 6.0.1 · current package validation · package source

Compute combined volatility measure from rolling volatility and ATR percentage.

Argument Contract
data (pl.DataFrame) Klines dataset with 'rolling_volatility', 'atr_percent_sma' columns

Returns: pl.DataFrame: The input data with a new column 'volatility_measure'

limen.features.volatility_of_volatility

python · volatility_of_volatility.py
def volatility_of_volatility(data: pl.DataFrame, volatility_window: int=12, window: int=48, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute how unstable recent return volatility is over a second rolling horizon.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
volatility_window (int) Number of periods used for the first-stage return volatility
window (int) Number of periods used for the second-stage volatility-of-volatility estimate
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with a new column 'volatility_of_volatility'

limen.features.volatility_ratio

python · volatility_ratio.py
def volatility_ratio(data: pl.DataFrame, short_window: int=5, long_window: int=20, high_col: str='high', low_col: str='low', output_col: str='volatility_ratio') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compare short and long rolling means of Parkinson variance.

Argument Contract
data (pl.DataFrame) Klines dataset with high and low price columns
short_window (int) Number of periods in the short variance mean
long_window (int) Number of periods in the long variance mean
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the volatility-ratio column appended

limen.features.volatility_spike

python · volatility_spike.py
def volatility_spike(data: pl.DataFrame, window: int=20, high_col: str='high', low_col: str='low', output_col: str='volatility_spike') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute current Parkinson variance relative to its fixed-lag value.

Argument Contract
data (pl.DataFrame) Klines dataset with high and low price columns
window (int) Lag used as the denominator
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the volatility-spike column appended

limen.features.volatility_term_structure

python · volatility_term_structure.py
def volatility_term_structure(data: pl.DataFrame, short_window: int=12, medium_window: int=48, long_window: int=168, close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute a front-versus-back volatility term-structure ratio across three horizons.

Argument Contract
data (pl.DataFrame) Klines dataset with a close price column
short_window (int) Short volatility horizon
medium_window (int) Medium volatility horizon
long_window (int) Long volatility horizon
close_col (str) Column name used for close-to-close returns

Returns: pl.DataFrame: The input data with a new column 'volatility_term_structure'

limen.features.volatility_weight

python · volatility_weight.py
def volatility_weight(data: pl.DataFrame, period: int=20, volatility_scaling_factor: float=100, volatility_weight_min: float=0.3, volatility_weight_max: float=1.0) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volatility-based weighting factor with inverse scaling.

Argument Contract
data (pl.DataFrame) Klines dataset with 'close' column
period (int) Period for volatility calculation
volatility_scaling_factor (float) Scaling factor for volatility normalization
volatility_weight_min (float) Minimum volatility weight value
volatility_weight_max (float) Maximum volatility weight value

Returns: pl.DataFrame: The input data with new columns 'volatility', 'volatility_weight'

limen.features.volume_ratio

python · volume_ratio.py
def volume_ratio(data: pl.DataFrame, period: int=20) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volume ratio relative to simple moving average baseline.

Argument Contract
data (pl.DataFrame) Klines dataset with 'volume' column
period (int) Number of periods for SMA calculation

Returns: pl.DataFrame: The input data with a new column 'volume_ratio'

limen.features.volume_regime

python · volume_regime.py
def volume_regime(data: pl.DataFrame, lookback: int=48) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volume regime (current vs average volume).

Argument Contract
data (pl.DataFrame) Klines dataset with 'volume' column
lookback (int) Number of periods for volume average calculation

Returns: pl.DataFrame: The input data with a new column 'volume_regime'

limen.features.volume_spike

python · volume_spike.py
def volume_spike(data: pl.DataFrame, period: int=20, use_zscore: bool=False) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volume spike relative to rolling statistics baseline.

Argument Contract
data (pl.DataFrame) Klines dataset with 'volume' column
period (int) Number of periods for rolling statistics calculation
use_zscore (bool) If True, use z-score (incorporating std dev), otherwise use ratio to mean

Returns: pl.DataFrame: The input data with a new column 'volume_spike'

limen.features.volume_to_range

python · volume_to_range.py
def volume_to_range(data: pl.DataFrame, window: int=20, volume_col: str='volume', high_col: str='high', low_col: str='low', output_col: str='volume_to_range') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling mean volume per unit of high-low range.

Argument Contract
data (pl.DataFrame) Klines dataset with volume, high, and low columns
window (int) Number of periods in the rolling mean
volume_col (str) Column name for traded volume
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the volume-to-range column appended

limen.features.volume_trend

python · volume_trend.py
def volume_trend(data: pl.DataFrame, short_period: int=12, long_period: int=48) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute volume trend by comparing short-term to long-term volume averages.

Argument Contract
data (pl.DataFrame) Klines dataset with 'volume' column
short_period (int) Number of periods for short-term SMA calculation
long_period (int) Number of periods for long-term SMA calculation

Returns: pl.DataFrame: The input data with a new column 'volume_trend'

limen.features.volume_volatility_correlation

python · volume_volatility_correlation.py
def volume_volatility_correlation(data: pl.DataFrame, window: int=20, volume_col: str='volume', high_col: str='high', low_col: str='low', output_col: str='volume_volatility_correlation') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling correlation between volume and Parkinson variance.

Argument Contract
data (pl.DataFrame) Klines dataset with volume, high, and low columns
window (int) Number of periods in the rolling correlation
volume_col (str) Column name for traded volume
high_col (str) Column name for high prices
low_col (str) Column name for low prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the volume-volatility correlation appended

limen.features.vpin

python · vpin.py
def vpin(data: pl.DataFrame, window: int=50, classification_window: int=20, close_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Volume-synchronized Probability of Informed Trading (VPIN).

Bars are split into buy and sell volume by bulk-volume classification, then

VPIN is the absolute buy-minus-sell imbalance summed over window buckets

divided by the summed total volume (Easley, Lopez de Prado, and O'Hara). High

values flag one-sided, toxic-looking flow. For canonical equal-volume buckets,

supply volume bars; on time bars this is the standard bar-level approximation.

Argument Contract
data (pl.DataFrame) Klines dataset with close and volume columns
window (int) Number of buckets over which the imbalance is accumulated
classification_window (int) Rolling window for the bulk-volume classification standardization
close_col (str) Column name used for close-to-close log returns
volume_col (str) Column name for total traded volume

Returns: pl.DataFrame: The input data with classified buy/sell volume columns and a new 'vpin' column

limen.features.vwap

python · vwap.py
def vwap(data: pl.DataFrame, price_col: str='close', volume_col: str='volume') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Volume Weighted Average Price (VWAP) for each kline over its trading day.

Argument Contract
data (pl.DataFrame) Klines dataset with price and volume columns
price_col (str) Name of the price column
volume_col (str) Name of the volume column

Returns: pl.DataFrame: The input data with a new column 'vwap'

limen.features.wick_imbalance

python · wick_imbalance.py
def wick_imbalance(data: pl.DataFrame, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute upper-versus-lower wick imbalance as a fraction of total bar range.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close columns
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'wick_imbalance'

limen.features.wick_proportion

python · wick_proportion.py
def wick_proportion(data: pl.DataFrame, window: int=20, high_col: str='high', low_col: str='low', open_col: str='open', close_col: str='close', output_col: str='wick_proportion') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute rolling mean wick share of the full candle range.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close columns
window (int) Number of periods in the rolling mean
high_col (str) Column name for high prices
low_col (str) Column name for low prices
open_col (str) Column name for open prices
close_col (str) Column name for close prices
output_col (str) Output column name

Returns: pl.DataFrame: The input data with the wick-proportion column appended

limen.features.window_return_regime

python · window_return_regime.py
def window_return_regime(df: pl.DataFrame, period: int=24, r_hi: float=0.0, r_lo: float=0.0) -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute regime using windowed return close/close.shift(period) - 1.

Argument Contract
df (pl.DataFrame) Klines dataset with 'close' column
period (int) Window length for return calculation
r_hi (float) Upper threshold for Up regime
r_lo (float) Lower threshold for Down regime

Returns: pl.DataFrame: The input data with a new column 'regime_window_return'

limen.features.yang_zhang_volatility

python · yang_zhang_volatility.py
def yang_zhang_volatility(data: pl.DataFrame, window: int=20, open_col: str='open', high_col: str='high', low_col: str='low', close_col: str='close') -> pl.DataFrame:    ...
Merged source PR · d6e324c0Package signature · Limen 6.0.1 · current package validation · package source

Compute Yang-Zhang volatility over a rolling window.

Argument Contract
data (pl.DataFrame) Klines dataset with open, high, low, and close price columns
window (int) Number of periods used for the rolling estimator; must be greater than 1
open_col (str) Column name for open prices
high_col (str) Column name for high prices
low_col (str) Column name for low prices
close_col (str) Column name for close prices

Returns: pl.DataFrame: The input data with a new column 'yang_zhang_volatility'

Deterministic market regimes

classify_market_regime returns one production row per input row, with series_id and UTC datetime as join keys. It returns a narrow table; join it to the source bars before downstream preparation. Supply an explicit RegimeConfig version. MarketRegimeClassifier.update runs the same computation on chronological chunks; snapshot and from_snapshot preserve bounded JSON state across process restarts.

The seven primary labels have stable codes: INITIALIZING=0, TREND_UP=1, TREND_DOWN=2, RANGE_LOW_VOL=3, RANGE_CHOP=4, BREAKOUT_UP=5, BREAKOUT_DOWN=6. The default output has the 12 production fields below; include_audit=True adds the 20 audit and eight rank fields. Stress is the maximum of the volatility and volatility-expansion ranks, rounded to Float32 before applying its configured threshold. Its two fields are null while those ranks are unavailable.

These are configurable rule-based baseline hypotheses. Their exact thresholds have no established trading-performance or ML-optimality claim. Validate them for the intended market, sampling interval and downstream use, preserving chronological evaluation, sensitivity checks and selection-bias controls. The 2026 model-risk guidance describes testing assumptions and outcomes; backtest-overfitting research explains why selecting configurations on reported returns requires additional controls. These references support the validation discipline.

Recorded example

The Python project's helper diagnostics run this on the supplied recorded bars and retain its output. Join the returned table on series_id and datetime when adding labels to model inputs.

python · helper_cases.py
def regime_labels(raw):    from limen.features.classify_market_regime import RegimeConfig    bars = raw.with_columns(pl.lit('recorded-spot').alias('series_id'))    return features.classify_market_regime(bars, config=RegimeConfig(version='baseline-v1'), include_audit=True)

Policy and causality

Each rank compares the current feature against its last 252 finite observations in that series, excluding the current row. Ties receive half weight. The current value enters history after its rank is emitted. Audit windows are fixed at 20/60 bars; prior ranges exclude the current bar. Log ratios are evaluated as differences of logs for numerical stability; means use centered summation. The first true range uses the observed high-low range because no prior close exists. No observations or features are filled.

Candidate precedence is breakout, directional trend, low-volatility range, choppy range, then RANGE_CHOP with finite_fallback. The configuration below supplies all numerical thresholds. Trend entry requires matching score/slope signs and the corresponding signed-slope rank. Low-volatility and choppy ranges require weak absolute-trend ranks. A breakout requires a fresh crossing of its ATR threshold, its directional rank and participation rank.

After initialization, ordinary regime changes require the configured consecutive candidate count. Trend/range retention uses separate exit thresholds. Breakouts commit immediately, freeze the broken prior-range boundary, and exit when close returns inside that boundary or their TTL expires. Exit commits the underlying trend/range candidate immediately; that row cannot renew the breakout. Counters and transitions describe committed labels. Other label changes use flip; resetting to INITIALIZING uses none and its explicit fallback reason.

Input and fallback contract

Supply an eager Polars frame with String series_id, UTC Datetime datetime, and numeric open/high/low/close/volume. Keys are non-null; timestamps are unique and increasing within each series, including across chunks. Interleaved series retain independent state. Rejected keys, times or schemas leave the classifier unchanged.

OHLC must be finite and positive, high must cover open/close, low must lie below them, and volume must be finite and non-negative. An invalid observed row emits INITIALIZING with invalid_input:<column>, clears pending/breakout state and leaves an unavailable row in rolling windows. Missing history emits insufficient_history; complete windows with undefined/non-finite derived features emit invalid_input:<feature>. Feature-specific rank histories retain prior finite observations. An unavailable observation never becomes a replacement price.

Checkpoints contain only bounded observed windows, rank histories, timestamps and commitment state. Restore checks their shape, finite values, config hash and implementation hash; use checkpoints from trusted provenance. The implementation fingerprint covers the audit, ranking and state/commitment code. Configuration hashes include the threshold values, fixed windows and stable enum mapping.

classify_market_regime

python · classify_market_regime.py
def classify_market_regime(data: pl.DataFrame, *, config: RegimeConfig, include_audit: bool=False) -> pl.DataFrame:    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

MarketRegimeClassifier

python · classify_market_regime.py
class MarketRegimeClassifier:    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

MarketRegimeClassifier.__init__

python · classify_market_regime.py
def __init__(self, config: RegimeConfig) -> None:    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

MarketRegimeClassifier.snapshot

python · classify_market_regime.py
def snapshot(self) -> str:    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

MarketRegimeClassifier.from_snapshot

python · classify_market_regime.py
@classmethoddef from_snapshot(cls, config: RegimeConfig, snapshot: str) -> 'MarketRegimeClassifier':    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

MarketRegimeClassifier.update

python · classify_market_regime.py
def update(self, data: pl.DataFrame, *, include_audit: bool=False) -> pl.DataFrame:    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

RegimeConfig

python · _regime_config.py
@dataclass(frozen=True)class RegimeConfig:    version: str    trend_rank_entry: float = 0.65    trend_slope_up: float = 0.6    trend_slope_down: float = 0.4    coherence_entry: float = 0.35    trend_rank_exit: float = 0.5    coherence_exit: float = 0.2    range_vol_entry: float = 0.35    range_trend_entry: float = 0.5    range_vol_exit: float = 0.45    range_trend_exit: float = 0.6    chop_rank_entry: float = 0.65    breakout_atr: float = 0.25    breakout_rank: float = 0.95    participation_rank: float = 0.6    stress_threshold: float = 0.95    confirmation_rows: int = 2    breakout_ttl: int = 3    eps: float = 1e-12
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

RegimeConfig.config_hash

python · _regime_config.py
@propertydef config_hash(self) -> str:    ...
Merged source PR · dc1b11abPackage signature · Limen 6.0.1 · current package validation · package source

Production schema

python · _regime_contract.py
PRODUCTION: dict[str, pl.DataType | type[pl.DataType]] = {'series_id': pl.String, 'datetime': pl.Datetime('ns', 'UTC'), 'market_regime': pl.Enum(REGIMES), 'market_regime_code': pl.UInt8, 'stress_level': pl.Float32, 'is_stress': pl.Boolean, 'transition_kind': pl.Enum(TRANSITIONS), 'bars_in_regime': pl.UInt32, 'fallback_reason': pl.String, 'regime_config_version': pl.String, 'regime_config_hash': pl.String, 'regime_feature_hash': pl.String}
Merged source PR · dc1b11abPackage definition · Limen 6.0.1 · current package validation · package source

Audit schema

python · _regime_contract.py
AUDIT = ('ret_1_log', 'true_range', 'atr_20', 'atr_pct_20', 'rs_var', 'vol_rs_20', 'vol_rs_60', 'vol_expansion_20_60', 'sma_fast_20', 'sma_slow_60', 'trend_score_20_60', 'trend_slope_20', 'range_high_60_prev', 'range_low_60_prev', 'range_width_atr_60', 'range_position_60', 'breakout_up_atr', 'breakout_down_atr', 'coherence_20', 'participation_20_60')
Merged source PR · dc1b11abPackage definition · Limen 6.0.1 · current package validation · package source

Ranks schema

python · _regime_contract.py
RANKS = ('rank_abs_trend_score_252', 'rank_trend_slope_252', 'rank_vol_rs_20_252', 'rank_vol_expansion_252', 'rank_breakout_up_252', 'rank_breakout_down_252', 'rank_chop_252', 'rank_participation_252')
Merged source PR · dc1b11abPackage definition · Limen 6.0.1 · current package validation · package source

Recorded sensitivity characterization

The retained observations cover 8,784 hourly bars from 2024 and 14,496 quarter-hour bars from January–May 2025. Both periods produce all seven labels. The baseline initializes for 312 rows in each period. Fixed perturbations to trend-entry rank (0.60/0.70), breakout magnitude (0.20/0.30 ATR) and breakout TTL (2/4) change 0.17–1.52% of labels; confirmation of 1/3 rows changes 4.82–6.43%.

Reproduce with python -m tests.benchmark_regime_classifier --output observations.json. These are descriptive sensitivity observations without fitting or predictive/trading-return claims. Defaults remain hypotheses. Validate chronologically on the intended assets and intervals, monitor label stability and drift, and account for selection bias if comparing configurations against downstream returns.

Limen / Python Research and Compiled ResearchReturn to the research book
Edit this sourceSource revision · 9bc8a630
Reference / keep your place
Find a passage