API¶
finance-calcs exposes calculation functions at the top level and through the
.fcalcs namespace on both polars.Expr and polars.Series. Most functions
return pl.Expr so they compose naturally inside select, with_columns, and
lazy pipelines. A small number of statistical and post-trade helpers take
concrete pl.Series or pl.DataFrame inputs because they compute sample-level
summaries, extract round trips, or fit extreme-value routines outside the Polars
expression engine.
Use this page as the complete public API map. Function signatures below are shown in a compact form; the reference blocks at the end of each section are rendered by yardang/Sphinx from the live docstrings.
Namespace and Windowing¶
Every expression function can be called directly:
import polars as pl
import finance_calcs as fc
out = df.select(fc.sharpe(pl.col("ret")).alias("sharpe"))
or through the namespace:
out = df.select(pl.col("ret").fcalcs.sharpe().alias("sharpe"))
The same namespace exists on pl.Series for eager one-off checks:
value = returns.fcalcs.sharpe()
Across return, risk, alpha, factor, and tail metrics, window= means a rolling
row-count window. period= means bucketed calculations over a calendar or
custom period. period= accepts:
finance_enums.Frequency, such asFrequency.Monthaliases accepted by
finance_enums.to_frequency(), such as"monthly"Polars
dt.truncate()duration strings, such as"1q"or"2w"a precomputed bucket expression, such as
pl.col("fiscal_period")
When period is a frequency or duration string, pass date=pl.col("date") so
finance-calcs can build the bucket expression.
Returns and Periods¶
Return functions turn prices into returns, compound return paths, or terminal period returns. They are the base layer for most risk and factor metrics.
Function |
Use it for |
Notes |
|---|---|---|
|
Build a reusable period bucket from dates |
Accepts |
|
Arithmetic price returns |
Computes |
|
Log price returns |
Computes |
|
Compounded return path |
Resets inside each rolling window or period bucket |
|
Terminal compounded return |
Produces the final compound return for the sample, window, or bucket |
|
Alias-style aggregate return |
Same aggregation as |
|
Calendar/custom period compound return |
Convenience wrapper around |
|
Annualized geometric return |
Uses compound return and observation count |
|
Annualized standard deviation |
|
- finance_calcs.period_bucket(date: Expr, period: Frequency | str | Expr) Expr[source]¶
Return a period bucket expression for
date.periodaccepts afinance_enums.Frequency, any alias understood byfinance_enums.to_frequency(), any Polars duration string accepted bydt.truncate(), or a precomputed bucket expression.
- finance_calcs.simple_returns(price: Expr) Expr[source]¶
Per-period simple return \(p_t / p_{t-1} - 1\).
- finance_calcs.cum_returns(returns: Expr, starting_value: float = 0.0, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Cumulative compounded return.
With
window=Nonereturns the cumulative path(1 + r).cumprod() - 1. Withwindow=Nreturns the compounded return over each trailingN-bar window. Withperiod=..., the cumulative path resets inside each period bucket.
- finance_calcs.cum_returns_final(returns: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Total compounded return.
window=None→ scalar terminal compounded return.window=N→ rolling compounded return over each trailingN-bar window.period=...→ terminal compounded return for each period bucket.
- finance_calcs.returns(returns: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Compound return over a trailing window or full sample.
window=None, period=Nonereturns the full-sample compound return.window=Nreturns trailing compounded returns overNrows.period=...returns the compounded return for each period bucket.
- finance_calcs.aggregate_returns(returns: Expr, date: Expr, period: Frequency | str | Expr) Expr[source]¶
Compound returns by a calendar or custom period bucket.
- finance_calcs.annualized_return(returns: Expr, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised geometric return (CAGR).
window=None→ scalar lifetime CAGR.window=N→ rolling CAGR annualised byperiods_per_year / window.period=...→ CAGR for each period bucket.
- finance_calcs.annualized_volatility(returns: Expr, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised standard deviation of returns.
window=None→ scalar lifetime volatility;window=N→ rolling annualised volatility;period=...→ volatility for each period bucket.
Risk and Drawdown¶
Risk metrics operate on return expressions. Scalar risk_free inputs are annual
rates and are converted to per-period rates where appropriate; expression
risk_free inputs are treated as already per-period.
Function |
Use it for |
Notes |
|---|---|---|
|
Annualized volatility |
Alias for |
|
Annualized Sharpe ratio |
Supports scalar annual risk-free rates or per-period expressions |
|
Annualized Sortino ratio |
Uses downside deviation below |
|
Annualized return / abs(max drawdown) |
Uses the same sample/window/period controls |
|
Annualized semi-deviation |
Squares only observations below the threshold |
|
Naming alias for downside deviation |
Same arguments and result as |
|
Running drawdown path |
Equity curve divided by running peak minus one |
|
Drawdown path alias |
Same result as |
|
Most negative drawdown |
Supports lifetime, rolling, or period-bucketed drawdown |
|
Historical VaR quantile |
Returns the lower-tail return quantile |
|
Expected shortfall |
Mean return of observations at or below VaR |
|
Gaussian VaR |
Supports common cutoffs from the built-in z-score table |
- finance_calcs.volatility(returns: Expr, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised volatility alias for
annualized_volatility().
- finance_calcs.sharpe(returns: Expr, risk_free: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised Sharpe ratio.
\(\sqrt{\mathrm{ppy}}\,\mathrm{mean}(r - r_f) / \mathrm{std}(r - r_f)\).
risk_freemay be a scalar annual rate (converted to per-period geometrically) or apl.Exprper-period rate column for a time-varying risk-free rate.window=None→ scalar lifetime Sharpe;window=N→ rolling;period=...→ per-bucket.
- finance_calcs.sortino(returns: Expr, required_return: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised Sortino ratio.
required_returnmay be a scalar per-period threshold or apl.Exprper-period column.window=None→ scalar;window=N→ rolling;period=...→ per-bucket.
- finance_calcs.calmar(returns: Expr, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised return divided by the absolute max drawdown.
window=None→ scalar;window=N→ rolling;period=...→ per-bucket.
- finance_calcs.downside_deviation(returns: Expr, required_return: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised semi-deviation below
required_return.required_returnmay be a scalar per-period threshold or apl.Exprper-period column for a time-varying threshold.window=None→ scalar;window=N→ rolling;period=...→ per-bucket.
- finance_calcs.downside_risk(returns: Expr, required_return: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised downside-risk alias for
downside_deviation().
- finance_calcs.drawdown_series(returns: Expr, *, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Per-period drawdown series
equity / running_peak - 1.
- finance_calcs.underwater_series(returns: Expr, *, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Alias of
drawdown_series().
- finance_calcs.max_drawdown(returns: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Maximum (most negative) drawdown.
window=None→ lifetime;window=N→ rolling minimum of the drawdown series over each trailingN-bar window.period=...→ maximum drawdown inside each period bucket.
- finance_calcs.value_at_risk(returns: Expr, cutoff: float = 0.05, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Historical Value-at-Risk.
window=None→ scalar lower-tail quantile;window=N→ rolling historical VaR.period=...→ per-bucket VaR.
- finance_calcs.conditional_value_at_risk(returns: Expr, cutoff: float = 0.05, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Historical CVaR / Expected Shortfall.
window=None→ scalar;window=N→ rolling mean of returns at or below the rolling VaR.period=...→ per-bucket CVaR.
Overlap and Price Channels¶
Overlap studies smooth prices or build price channels from high/low/close data.
The period argument in this section is an indicator lookback length, not a
calendar bucket.
Function |
Use it for |
Notes |
|---|---|---|
|
Simple moving average |
Rolling mean |
|
Exponential moving average |
Uses Polars EWM mean with |
|
Weighted moving average |
Recent observations receive larger linear weights |
|
Double EMA |
|
|
Triple EMA |
|
|
Midpoint of rolling high/low close |
Uses close-only rolling max/min |
|
Midpoint of high/low channel |
Uses rolling high max and low min |
|
Bollinger upper band |
Middle plus standard-deviation multiple |
|
Bollinger middle band |
SMA |
|
Bollinger lower band |
Middle minus standard-deviation multiple |
|
Donchian upper channel |
Rolling high maximum |
|
Donchian lower channel |
Rolling low minimum |
|
Donchian midline |
Average of upper and lower channels |
- finance_calcs.sma(close: Expr, period: int = 20) Expr[source]¶
Simple moving average over
periodobservations.- Parameters:
close – Price (or any series) to average.
period – Window length.
- Returns:
Rolling mean expression.
- finance_calcs.ema(close: Expr, period: int = 20) Expr[source]¶
Exponential moving average with
span = period.- Parameters:
close – Series to smooth.
period – Span. The smoothing factor is
2 / (period + 1).
- Returns:
EWMA expression.
- finance_calcs.wma(close: Expr, period: int = 20) Expr[source]¶
Linearly-weighted moving average.
- Parameters:
close – Series to smooth.
period – Window length.
- Returns:
Expression yielding the WMA. Recent observations have higher weight: weight
i=i + 1fori in 0..period-1.
- finance_calcs.dema(close: Expr, period: int = 20) Expr[source]¶
Double exponential moving average:
2 * EMA - EMA(EMA).- Parameters:
close – Series to smooth.
period – Span.
- Returns:
DEMA expression.
- finance_calcs.tema(close: Expr, period: int = 20) Expr[source]¶
Triple exponential moving average
3*EMA - 3*EMA(EMA) + EMA(EMA(EMA)).- Parameters:
close – Series to smooth.
period – Span.
- Returns:
TEMA expression.
- finance_calcs.midpoint(close: Expr, period: int = 14) Expr[source]¶
(rolling_max(close) + rolling_min(close)) / 2.- Parameters:
close – Price series.
period – Window length.
- Returns:
Midpoint expression.
- finance_calcs.midprice(high: Expr, low: Expr, period: int = 14) Expr[source]¶
(rolling_max(high) + rolling_min(low)) / 2.- Parameters:
high – Bar high.
low – Bar low.
period – Window length.
- Returns:
Midprice expression.
- finance_calcs.bbands_upper(close: Expr, period: int = 20, nbdev_up: float = 2.0) Expr[source]¶
Bollinger upper band
SMA + nbdev_up * std.- Parameters:
close – Price series.
period – Window length.
nbdev_up – Number of standard deviations above the SMA.
- Returns:
Upper-band expression.
- finance_calcs.bbands_middle(close: Expr, period: int = 20) Expr[source]¶
Bollinger middle band — SMA of close.
- Parameters:
close – Price series.
period – Window length.
- Returns:
Rolling mean expression.
- finance_calcs.bbands_lower(close: Expr, period: int = 20, nbdev_dn: float = 2.0) Expr[source]¶
Bollinger lower band
SMA - nbdev_dn * std.- Parameters:
close – Price series.
period – Window length.
nbdev_dn – Number of standard deviations below the SMA.
- Returns:
Lower-band expression.
- finance_calcs.donchian_upper(high: Expr, period: int = 20) Expr[source]¶
Donchian upper channel — rolling maximum of
high.- Parameters:
high – Bar high.
period – Window length.
- Returns:
Rolling max expression.
Momentum¶
Momentum functions consume close or OHLC expressions and return oscillator,
rate-of-change, or directional-movement expressions. The period argument is an
indicator lookback length.
Function |
Use it for |
Notes |
|---|---|---|
|
Relative Strength Index |
Wilder smoothing |
|
MACD line |
Fast EMA minus slow EMA |
|
MACD signal line |
EMA of |
|
MACD histogram |
MACD line minus signal line |
|
Price momentum |
Difference from |
|
Percent rate of change |
|
|
Decimal rate of change |
|
|
Price ratio |
|
|
Price ratio scaled by 100 |
|
|
Williams %R |
Close location within rolling high/low range |
|
Fast stochastic %K |
Range-normalized close |
|
Stochastic %D |
SMA of |
|
Commodity Channel Index |
Typical-price deviation oscillator |
|
Chande Momentum Oscillator |
Up/down movement balance |
|
TRIX |
One-bar ROC of triple-smoothed log price |
|
Raw +DM |
Wilder directional movement |
|
Raw -DM |
Wilder directional movement |
|
+DI |
Smoothed +DM divided by true range |
|
-DI |
Smoothed -DM divided by true range |
|
Average Directional Index |
Trend-strength measure from +DI and -DI |
- finance_calcs.rsi(close: Expr, period: int = 14) Expr[source]¶
Relative Strength Index (Wilder).
- Parameters:
close – Price series.
period – Smoothing period.
- Returns:
Expression yielding RSI in
[0, 100].
- finance_calcs.macd_line(close: Expr, fast: int = 12, slow: int = 26) Expr[source]¶
MACD line —
EMA(fast) - EMA(slow).- Parameters:
close – Price series.
fast – Fast EMA span.
slow – Slow EMA span.
- Returns:
Expression yielding the MACD line.
- finance_calcs.macd_signal(close: Expr, fast: int = 12, slow: int = 26, signal: int = 9) Expr[source]¶
MACD signal line — EMA of
macd_line().- Parameters:
close – Price series.
fast – Fast EMA span.
slow – Slow EMA span.
signal – Signal EMA span.
- Returns:
Expression yielding the MACD signal line.
- finance_calcs.macd_hist(close: Expr, fast: int = 12, slow: int = 26, signal: int = 9) Expr[source]¶
MACD histogram —
MACD - signal.- Parameters:
close – Price series.
fast – Fast EMA span.
slow – Slow EMA span.
signal – Signal EMA span.
- Returns:
Expression yielding the MACD histogram.
- finance_calcs.mom(close: Expr, period: int = 10) Expr[source]¶
Momentum —
close - close[period].- Parameters:
close – Price series.
period – Look-back length.
- Returns:
Difference expression.
- finance_calcs.roc(close: Expr, period: int = 10) Expr[source]¶
Rate-of-change in percent —
100 * (close / close[period] - 1).- Parameters:
close – Price series.
period – Look-back length.
- Returns:
ROC expression.
- finance_calcs.rocp(close: Expr, period: int = 10) Expr[source]¶
ROC percentage (TA-Lib):
(close - close[period]) / close[period].- Parameters:
close – Price series.
period – Look-back length.
- Returns:
ROCP expression.
- finance_calcs.rocr(close: Expr, period: int = 10) Expr[source]¶
ROC ratio:
close / close[period].- Parameters:
close – Price series.
period – Look-back length.
- Returns:
ROCR expression.
- finance_calcs.rocr100(close: Expr, period: int = 10) Expr[source]¶
ROC ratio scaled by 100.
- Parameters:
close – Price series.
period – Look-back length.
- Returns:
ROCR100 expression.
- finance_calcs.willr(high: Expr, low: Expr, close: Expr, period: int = 14) Expr[source]¶
Williams %R.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – Window length.
- Returns:
Expression in
[-100, 0].
- finance_calcs.stoch_k(high: Expr, low: Expr, close: Expr, period: int = 14) Expr[source]¶
Fast stochastic %K.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – Window length.
- Returns:
Expression in
[0, 100].
- finance_calcs.stoch_d(high: Expr, low: Expr, close: Expr, period: int = 14, d_period: int = 3) Expr[source]¶
Stochastic %D — SMA of
stoch_k().- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – %K window length.
d_period – Smoothing window for %D.
- Returns:
Expression yielding %D.
- finance_calcs.cci(high: Expr, low: Expr, close: Expr, period: int = 20) Expr[source]¶
Commodity Channel Index.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – Window length.
- Returns:
CCI expression. Uses mean absolute deviation in the denominator.
- finance_calcs.cmo(close: Expr, period: int = 14) Expr[source]¶
Chande Momentum Oscillator.
- Parameters:
close – Price series.
period – Window length.
- Returns:
CMO expression in
[-100, 100].
- finance_calcs.trix(close: Expr, period: int = 15) Expr[source]¶
TRIX — 1-day ROC of triple-smoothed log price.
- Parameters:
close – Price series.
period – EMA span.
- Returns:
TRIX expression in percent.
- finance_calcs.plus_dm(high: Expr, low: Expr) Expr[source]¶
Wilder’s +DM raw (un-smoothed).
- Parameters:
high – Bar high.
low – Bar low.
- Returns:
Per-bar +DM expression. Zero when down-move dominates.
- finance_calcs.minus_dm(high: Expr, low: Expr) Expr[source]¶
Wilder’s -DM raw (un-smoothed).
- Parameters:
high – Bar high.
low – Bar low.
- Returns:
Per-bar -DM expression. Zero when up-move dominates.
- finance_calcs.plus_di(high: Expr, low: Expr, close: Expr, period: int = 14) Expr[source]¶
Wilder’s +DI.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – Smoothing period.
- Returns:
+DI expression in percent.
Volatility Indicators¶
These functions estimate realized or range-based volatility from returns or
OHLC bars. The period argument is an indicator lookback length.
Function |
Use it for |
Notes |
|---|---|---|
|
Wilder true range |
Max of high-low, high-prior-close, low-prior-close |
|
Average True Range |
Wilder-smoothed true range |
|
Normalized ATR |
|
|
High-low volatility |
Range-based estimator |
|
OHLC volatility |
Uses open/high/low/close within each bar |
|
Drift-independent OHLC volatility |
Works better when drift is nonzero |
|
Overnight + open-close + range volatility |
Combines several OHLC variance components |
|
Exponentially weighted volatility |
EWM standard deviation |
|
Rolling realized volatility |
Rolling sample standard deviation |
- finance_calcs.true_range(high: Expr, low: Expr, close: Expr) Expr[source]¶
Wilder’s true range.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
- Returns:
Per-bar TR expression
max(H-L, |H - C[-1]|, |L - C[-1]|).
- finance_calcs.atr(high: Expr, low: Expr, close: Expr, period: int = 14) Expr[source]¶
Average True Range using Wilder smoothing.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – Smoothing period.
- Returns:
ATR expression.
- finance_calcs.natr(high: Expr, low: Expr, close: Expr, period: int = 14) Expr[source]¶
Normalised ATR —
100 * ATR / close.- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
period – Smoothing period.
- Returns:
NATR expression in percent.
- finance_calcs.parkinson_vol(high: Expr, low: Expr, period: int = 20) Expr[source]¶
Parkinson high-low range volatility estimator.
\[\begin{split}\\hat{\\sigma}^2 = \\frac{1}{4 \\ln 2} \\cdot \\overline{\\left(\\ln(H/L)\\right)^2}\end{split}\]- Parameters:
high – Bar high.
low – Bar low.
period – Window length.
- Returns:
Per-period volatility expression (rolling).
- finance_calcs.garman_klass_vol(open_: Expr, high: Expr, low: Expr, close: Expr, period: int = 20) Expr[source]¶
Garman-Klass OHLC volatility estimator.
\[\begin{split}\\hat{\\sigma}^2 = \\overline{\\tfrac{1}{2}(\\ln H/L)^2 - (2\\ln 2 - 1)(\\ln C/O)^2}\end{split}\]- Parameters:
open – Bar open.
high – Bar high.
low – Bar low.
close – Bar close.
period – Window length.
- Returns:
Per-period GK volatility expression (rolling).
- finance_calcs.rogers_satchell_vol(open_: Expr, high: Expr, low: Expr, close: Expr, period: int = 20) Expr[source]¶
Rogers-Satchell drift-independent volatility.
\[\begin{split}\\hat{\\sigma}^2 = \\overline{\\ln(H/C)\\ln(H/O) + \\ln(L/C)\\ln(L/O)}\end{split}\]- Parameters:
open – Bar open.
high – Bar high.
low – Bar low.
close – Bar close.
period – Window length.
- Returns:
RS volatility expression (rolling).
- finance_calcs.yang_zhang_vol(open_: Expr, high: Expr, low: Expr, close: Expr, period: int = 20, k: float | None = None) Expr[source]¶
Yang-Zhang volatility — minimum-variance combination of overnight, open-to-close, and Rogers-Satchell drift-independent components.
- Parameters:
open – Bar open.
high – Bar high.
low – Bar low.
close – Bar close.
period – Window length.
k – Weight on open-to-close variance. Defaults to
0.34 / (1.34 + (period+1)/(period-1)).
- Returns:
YZ volatility expression (rolling).
Volume Indicators¶
Volume indicators combine close movement, intrabar range, and volume into flow or accumulation measures.
Function |
Use it for |
Notes |
|---|---|---|
|
On-Balance Volume |
Cumulative signed volume based on close direction |
|
Chaikin Accumulation/Distribution line |
Cumulative money-flow volume |
|
Chaikin A/D Oscillator |
Fast EMA of AD minus slow EMA of AD |
- finance_calcs.obv(close: Expr, volume: Expr) Expr[source]¶
On-Balance Volume.
- Parameters:
close – Price series.
volume – Volume series.
- Returns:
Running cumulative signed volume. The first bar contributes zero because the prior close is unknown.
- finance_calcs.ad(high: Expr, low: Expr, close: Expr, volume: Expr) Expr[source]¶
Chaikin Accumulation/Distribution line.
- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
volume – Bar volume.
- Returns:
Running A/D line. Bars with zero range contribute zero flow.
- finance_calcs.adosc(high: Expr, low: Expr, close: Expr, volume: Expr, fast: int = 3, slow: int = 10) Expr[source]¶
Chaikin A/D Oscillator —
EMA(AD, fast) - EMA(AD, slow).- Parameters:
high – Bar high.
low – Bar low.
close – Bar close.
volume – Bar volume.
fast – Fast EMA span.
slow – Slow EMA span.
- Returns:
ADOSC expression.
Alpha and Information Coefficient¶
Alpha helpers are designed for cross-sectional signal panels. Compute forward
returns, per-date IC values, and IC summary statistics from generated or real
date, symbol, signal, fwd_returns data.
Function |
Use it for |
Notes |
|---|---|---|
|
Future simple returns |
|
|
Linear information coefficient |
Pearson correlation |
|
Rank information coefficient |
Spearman correlation through ranks |
|
Default IC alias |
Alias for |
|
Conditional IC |
Correlation after filtering observations by a condition |
|
One-horizon IC |
IC against one forward-return horizon |
|
IC decay expressions |
Builds one aliased IC expression per horizon |
|
IC information ratio |
Mean IC divided by IC standard deviation |
|
Directional hit rate |
Fraction where signal and forward return signs agree |
|
Series-level IC summary |
Returns count, mean, std, IR, t-stat, and positive-IC share |
- finance_calcs.forward_returns(price: Expr, periods: int = 1) Expr[source]¶
Forward simple return over
periodsbars.- Parameters:
price – Price series.
periods – Look-ahead horizon in bars.
- Returns:
Expression yielding
price.shift(-periods) / price - 1.
- finance_calcs.pearson_ic(signal: Expr, fwd: Expr) Expr[source]¶
Pearson information coefficient.
- Parameters:
signal – Signal / alpha series.
fwd – Forward-return series of the same length.
- Returns:
Scalar correlation expression.
- finance_calcs.spearman_ic(signal: Expr, fwd: Expr) Expr[source]¶
Spearman rank information coefficient.
- Parameters:
signal – Signal / alpha series.
fwd – Forward-return series of the same length.
- Returns:
Scalar rank-correlation expression.
- finance_calcs.information_coefficient(signal: Expr, fwd: Expr) Expr¶
Spearman rank information coefficient.
- Parameters:
signal – Signal / alpha series.
fwd – Forward-return series of the same length.
- Returns:
Scalar rank-correlation expression.
- finance_calcs.conditional_ic(signal: Expr, fwd: Expr, condition: Expr, *, method: str = 'spearman') Expr[source]¶
Information coefficient on observations matching
condition.
- finance_calcs.horizon_ic(signal: Expr, fwd: Expr, *, method: str = 'spearman') Expr[source]¶
Information coefficient for one forward-return horizon.
- finance_calcs.ic_decay(signal: Expr, forward_returns_by_horizon: Mapping[int, Expr], *, method: str = 'spearman', prefix: str = 'ic_') list[Expr][source]¶
Build one horizon IC expression per forward-return horizon.
- finance_calcs.ic_ir(ic: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
IC information ratio —
mean(ic) / std(ic).window=None→ scalar;window=N→ rolling IR over each trailingN-observation window;period=...→ per-bucket IR.
Quantile and Signal Transforms¶
These functions prepare cross-sectional signals for portfolio construction or quantile spread analytics.
Function |
Use it for |
Notes |
|---|---|---|
|
Cross-sectional quantile labels |
Produces integer labels |
|
Rank-normalized signal |
Scales ranks to |
|
Cross-sectional z-score |
Centers and scales by sample standard deviation |
|
Outlier clipping |
Clips to |
|
Quantile spread return |
Mean return of upper quantile minus lower quantile |
|
Quantile return expressions |
Builds one mean-return expression per quantile |
|
Turnover signal |
True when quantile label changed from previous row |
|
Quantile turnover |
Mean of quantile-change flags |
- finance_calcs.assign_quantile(signal: Expr, n_quantiles: int = 5) Expr[source]¶
Assign integer quantile labels
0..n_quantiles-1tosignal.- Parameters:
signal – Signal series. Nulls produce null labels.
n_quantiles – Number of quantile buckets.
- Returns:
Integer expression in
[0, n_quantiles - 1]. Higher signal values map to higher labels.
- finance_calcs.rank_normalize(signal: Expr) Expr[source]¶
Cross-sectional rank scaled to
[-0.5, 0.5].- Parameters:
signal – Signal series.
- Returns:
Expression with mean zero and bounded support.
- finance_calcs.zscore(signal: Expr) Expr[source]¶
Cross-sectional z-score:
(x - mean) / std.- Parameters:
signal – Signal series.
- Returns:
Z-score expression.
- finance_calcs.winsorize(signal: Expr, cutoff: float = 3.0) Expr[source]¶
Clip values to
mean ± cutoff * std.- Parameters:
signal – Signal series.
cutoff – Number of standard deviations. Must be positive.
- Returns:
Clipped expression.
- finance_calcs.long_short_spread(returns: Expr, quantile: Expr, upper: int, lower: int) Expr[source]¶
Top-quantile mean return minus bottom-quantile mean return.
Use inside
group_by("date").agg(...):df.group_by("date").agg( long_short_spread(pl.col("ret"), pl.col("q"), upper=4, lower=0) .alias("ls"), )
- Parameters:
returns – Forward return series.
quantile – Integer quantile label series.
upper – Long quantile label.
lower – Short quantile label.
- Returns:
Scalar expression.
- finance_calcs.mean_return_by_quantile(returns: Expr, quantile: Expr, *, n_quantiles: int = 5, prefix: str = 'q') list[Expr][source]¶
Build mean-return expressions for quantile labels
0..n-1.
- finance_calcs.quantile_changed(quantile: Expr) Expr[source]¶
Boolean expression:
quantile != quantile.shift(1).Use inside
... .over("asset")to compute per-asset turnover flags. Aggregate by date to get the fraction of names that changed quantile.- Parameters:
quantile – Integer quantile label series.
- Returns:
Boolean expression. The first observation is null/false.
Factor and Benchmark Metrics¶
Factor metrics compare strategy returns against a benchmark return series.
They support lifetime, rolling, and period-bucketed calculations where the
signature includes window, period, and date.
Function |
Use it for |
Notes |
|---|---|---|
|
Annualized Jensen alpha |
Return unexplained by benchmark beta |
|
Market beta |
|
|
Alpha in up markets |
Restricts observations to |
|
Alpha in down markets |
Restricts observations to |
|
Beta in up markets |
Restricts observations to |
|
Beta in down markets |
Restricts observations to |
|
Up-market capture |
Mean strategy return divided by mean benchmark return when benchmark is positive |
|
Down-market capture |
Mean strategy return divided by mean benchmark return when benchmark is negative |
|
Capture balance |
Up capture divided by down capture |
|
Fraction of outperformance observations |
|
|
Annualized active risk |
Standard deviation of active return |
|
Annualized active return per active risk |
Mean active return divided by active standard deviation, scaled |
- finance_calcs.alpha(returns: Expr, benchmark: Expr, risk_free: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised Jensen’s alpha.
risk_freemay be a scalar annual rate (divided to per-period) or apl.Exprper-period rate column for a time-varying risk-free rate.window=None→ scalar;window=N→ rolling annualised alpha;period=...→ per-bucket alpha.
- finance_calcs.beta(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
OLS market beta —
cov(r, b) / var(b).window=None→ scalar;window=N→ rolling beta;period=...→ per-bucket beta.
- finance_calcs.up_alpha(returns: Expr, benchmark: Expr, risk_free: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised alpha on up-market bars only.
- finance_calcs.down_alpha(returns: Expr, benchmark: Expr, risk_free: float | Expr = 0.0, periods_per_year: int = 252, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Annualised alpha on down-market bars only.
- finance_calcs.up_beta(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Beta restricted to bars where
benchmark > 0.
- finance_calcs.down_beta(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Beta restricted to bars where
benchmark < 0.
- finance_calcs.up_capture(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Mean asset return / mean benchmark return on up-market bars.
- finance_calcs.down_capture(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Mean asset return / mean benchmark return on down-market bars.
- finance_calcs.up_down_capture(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
up_capture / down_capture.
- finance_calcs.batting_average(returns: Expr, benchmark: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Fraction of periods where
returns > benchmark.
Distribution and Sharpe Statistics¶
The first five functions are expression metrics. The Sharpe significance and
confidence-interval helpers consume a concrete pl.Series because they perform
sample-level statistical calculations outside the Polars expression engine.
Function |
Use it for |
Notes |
|---|---|---|
|
Sample skewness |
Expression metric |
|
Excess kurtosis |
Fisher definition |
|
Bundled skew/kurt struct |
Returns a Polars struct expression |
|
Trend stability of cumulative log returns |
R-squared of cumulative log returns vs time |
|
Tail-ratio-adjusted total return sanity check |
|
|
Probability Sharpe exceeds benchmark |
Lopez de Prado PSR |
|
Multiple-testing-adjusted Sharpe probability |
Bailey and Lopez de Prado DSR |
|
Required sample length |
Observations needed for Sharpe confidence |
|
Bootstrap Sharpe CI |
Returns point estimate, lower, upper |
|
HAC-style Sharpe CI |
Returns point estimate, lower, upper |
- finance_calcs.skewness(returns: Expr) Expr[source]¶
Sample skewness of
returns.- Parameters:
returns – Returns expression.
- Returns:
Scalar skewness.
- finance_calcs.kurtosis(returns: Expr) Expr[source]¶
Excess kurtosis of
returns(Fisher definition).- Parameters:
returns – Returns expression.
- Returns:
Scalar excess kurtosis.
- finance_calcs.higher_moments(returns: Expr) Expr[source]¶
Bundled struct of
{skew, kurt}forreturns.- Parameters:
returns – Returns expression.
- Returns:
Struct expression with fields
skewandkurt.
- finance_calcs.stability_of_timeseries(returns: Expr) Expr[source]¶
Coefficient of determination of cumulative log returns vs time.
Implements pyfolio’s
stability_of_timeseries— fit \(y_t = a + b \cdot t\) to the log-equity curve and returnR^2. Closer to 1 means more linear (steady) growth.- Parameters:
returns – Periodic returns (not log).
- Returns:
Scalar
R^2expression.
- finance_calcs.common_sense_ratio(returns: Expr) Expr[source]¶
tail_ratio * (1 + cumulative_return)— sanity sniff test.- Parameters:
returns – Periodic returns expression.
- Returns:
Scalar expression.
- finance_calcs.probabilistic_sharpe(returns: Series, benchmark_sr: float = 0.0, periods_per_year: int = 252) float[source]¶
Lopez de Prado probabilistic Sharpe ratio.
Probability that the observed Sharpe is greater than
benchmark_sr, accounting for sample skew and kurtosis.- Parameters:
returns – Periodic returns.
benchmark_sr – Annualised threshold Sharpe.
periods_per_year – Periods per year.
- Returns:
Pr(SR_true > benchmark_sr)in[0, 1].
- finance_calcs.deflated_sharpe(returns: Series, n_trials: int, sr_variance: float | None = None, periods_per_year: int = 252) float[source]¶
Deflated Sharpe ratio (Bailey & Lopez de Prado).
Adjusts the probabilistic Sharpe for multiple-testing across
n_trialscandidate strategies.- Parameters:
returns – Periodic returns.
n_trials – Number of independent strategies tried.
sr_variance – Variance of the trial Sharpes. If
Nonea conservative default of1.0is used (worst case).periods_per_year – Periods per year.
- Returns:
Pr(SR_true > expected_max_SR_under_null)in[0, 1].
- finance_calcs.minimum_track_record_length(returns: Series, benchmark_sr: float = 0.0, alpha: float = 0.05, periods_per_year: int = 252) float[source]¶
Minimum number of observations for
SR > benchmark_srat confidence1-alpha.- Parameters:
returns – Periodic returns.
benchmark_sr – Annualised threshold Sharpe.
alpha – Significance level (
0.05→ 95% confidence).periods_per_year – Periods per year.
- Returns:
Minimum number of observations (float; round up in practice).
- finance_calcs.sharpe_ci_bootstrap(returns: Series, n_bootstrap: int = 1000, confidence: float = 0.95, periods_per_year: int = 252, seed: int | None = None) Tuple[float, float, float][source]¶
Bootstrap confidence interval for the Sharpe ratio.
- Parameters:
returns – Periodic returns.
n_bootstrap – Number of bootstrap resamples.
confidence – Two-sided confidence level.
periods_per_year – Periods per year.
seed – RNG seed.
- Returns:
Tuple
(sharpe, lower, upper).
- finance_calcs.sharpe_with_ci(returns: Series, risk_free: float | Series | ndarray = 0.0, periods_per_year: int = 252, confidence: float = 0.95) Tuple[float, float, float][source]¶
Sharpe with HAC-style asymptotic confidence interval.
- Parameters:
returns – Periodic returns.
risk_free – Annual risk-free rate (subtracted period-wise) as a scalar, or a per-period rate series (
pl.Series/np.ndarray) aligned toreturnsfor a time-varying risk-free rate.periods_per_year – Periods per year.
confidence – Two-sided confidence level.
- Returns:
Tuple
(sharpe, lower, upper)where the bounds are derived from the Mertens (2002) asymptotic variance of the Sharpe.
Tail Risk¶
Tail-risk expression metrics support lifetime, rolling, and period-bucketed
calculations. The GPD helpers consume pl.Series and fit a Peaks-over-Threshold
model to tail losses.
Function |
Use it for |
Notes |
|---|---|---|
|
Right-tail / left-tail balance |
|
|
Drawdown depth persistence |
RMS of drawdown sequence |
|
Gain/loss balance around threshold |
Sum gains divided by absolute sum losses |
|
Extreme VaR from GPD fit |
Returns positive loss magnitude |
|
Extreme CVaR from GPD fit |
Expected shortfall beyond |
- finance_calcs.tail_ratio(returns: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Right tail / left tail ratio —
|p95| / |p05|.window=None→ scalar;window=N→ rolling;period=...→ per-bucket.
- finance_calcs.ulcer_index(returns: Expr, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
RMS of the drawdown sequence.
UI = sqrt(mean(dd_t^2))wheredd_tis the percentage drawdown at timet.window=None→ scalar;window=N→ rolling RMS over each trailingN-bar window.period=...→ per-bucket RMS drawdown.
- finance_calcs.omega_ratio(returns: Expr, required_return: float | Expr = 0.0, *, window: int | None = None, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Omega ratio — gain/loss probability-weighted ratio.
required_returnmay be a scalar per-period threshold or apl.Exprper-period column for a time-varying threshold.
- finance_calcs.gpd_var(returns: Series, var_p: float = 0.01, threshold_p: float = 0.1) float[source]¶
GPD-fitted extreme VaR (positive number, magnitude of loss).
Fits a Generalized Pareto Distribution to the excess of losses over a threshold (peak-over-threshold) and inverts to obtain the
var_pquantile.- Closed form:
\(VaR_p = u + \frac{\beta}{\xi}\left(\left(\frac{n}{n_u} p\right)^{-\xi} - 1\right)\)
- Parameters:
returns – Periodic returns (
pl.Series).var_p – Tail probability (
0.01→ 1% VaR).threshold_p – Probability mass beyond the threshold
uused for the GPD fit (0.10→ top-10% of losses).
- Returns:
VaR magnitude as a positive float.
- finance_calcs.gpd_cvar(returns: Series, var_p: float = 0.01, threshold_p: float = 0.1) float[source]¶
GPD-fitted extreme CVaR (expected shortfall beyond
var_p).- Closed form for the GPD tail (xi < 1):
\(CVaR_p = \frac{VaR_p}{1 - \xi} + \frac{\beta - \xi u}{1 - \xi}\)
- Parameters:
returns – Periodic returns.
var_p – Tail probability.
threshold_p – Mass beyond the threshold used for the fit.
- Returns:
CVaR magnitude as a positive float.
Portfolio¶
Portfolio metrics aggregate position weights. They are most useful inside a
group_by("date") aggregation over a long-form position panel.
Function |
Use it for |
Notes |
|---|---|---|
|
Total absolute exposure |
Sum of absolute weights |
|
Long plus short notional |
Alias for |
|
Signed net exposure |
Sum of weights |
|
Long exposure |
Sum of positive weights |
|
Short exposure |
Sum of negative weights, returned as negative |
|
Herfindahl concentration |
Sum of squared normalized absolute weights |
|
Top-name exposure share |
Gross exposure held by top |
|
Active share vs benchmark |
|
- finance_calcs.gross_leverage(weights: Expr) Expr[source]¶
Sum of absolute weights — total notional / equity.
- Parameters:
weights – Position weight expression.
- Returns:
Scalar gross-leverage expression.
- finance_calcs.gross_exposure(weights: Expr) Expr[source]¶
Alias for
gross_leverage— long + short notional.- Parameters:
weights – Position weight expression.
- Returns:
Scalar gross-exposure expression.
- finance_calcs.net_exposure(weights: Expr) Expr[source]¶
Long minus short notional — signed sum of weights.
- Parameters:
weights – Position weight expression.
- Returns:
Scalar net-exposure expression.
- finance_calcs.long_exposure(weights: Expr) Expr[source]¶
Sum of positive weights.
- Parameters:
weights – Position weight expression.
- Returns:
Scalar long-exposure expression.
- finance_calcs.short_exposure(weights: Expr) Expr[source]¶
Sum of negative weights (returned as a negative number).
- Parameters:
weights – Position weight expression.
- Returns:
Scalar short-exposure expression.
- finance_calcs.concentration(weights: Expr) Expr[source]¶
Herfindahl-Hirschman index of normalised absolute weights.
Computed on absolute weights normalised to sum to 1 — yields
1/Nfor an equal-weight portfolio ofNnames and1.0for a single-name portfolio.- Parameters:
weights – Position weight expression.
- Returns:
Scalar HHI expression in
(0, 1].
- finance_calcs.top_n_concentration(weights: Expr, n: int = 10) Expr[source]¶
Fraction of gross exposure held by the top
nabsolute weights.- Parameters:
weights – Position weight expression.
n – Number of top positions.
- Returns:
Scalar expression in
[0, 1].
Active share —
0.5 * sum(|w - b|).- Parameters:
weights – Portfolio weight expression.
benchmark_weights – Benchmark weight expression aligned to
weights.
- Returns:
Scalar active-share expression in
[0, 1].
Post-Trade¶
Post-trade utilities consume transaction, round-trip, or execution data. Cost,
slippage, turnover, and trade-quality metrics are expression kernels. Round-trip
extraction and summary helpers take concrete pl.DataFrame inputs because they
need ordered trade sequences.
Function |
Use it for |
Notes |
|---|---|---|
|
Absolute traded notional |
|
|
Explicit plus basis-point costs |
Adds commission, fees, and bps cost on notional |
|
Traded notional volume |
Sums notional over the full sample or period bucket |
|
Execution slippage |
Side-aware when a side expression is provided |
|
Decision-price slippage |
Side-aware implementation shortfall in bps |
|
VWAP slippage |
Side-aware execution vs. VWAP in bps |
|
Position-weight turnover |
Absolute weight change; optional rolling sum |
|
Per-trade cost alias |
Same calculation as |
|
Cost decomposition |
Returns component totals and percentages |
|
FIFO round-trip extraction |
Builds entry/exit trade rows from signed quantities |
|
Trade-quality summary |
Count, win rate, average PnL, total PnL, PF, payoff |
|
Long/short trade summary |
Aggregates round trips by side |
|
Sector trade summary |
Aggregates round trips by mapped sector |
|
Profitable-trade fraction |
Expression metric |
|
Gross profit / gross loss |
Expression metric |
|
Average win / average loss |
Expression metric |
|
Mean trade PnL |
Expression metric |
|
Holding-period summary |
Returns mean, median, and max duration |
|
Maximum adverse/favorable move |
Adds |
|
Win/loss streaks |
Returns max consecutive wins and losses |
|
PnL by exit reason |
Groups counts and PnL by exit-reason label |
|
Size/return relationship |
Correlation of absolute trade size with trade return |
- finance_calcs.transaction_notional(quantity: Expr, price: Expr) Expr[source]¶
Absolute traded notional,
abs(quantity) * price.
- finance_calcs.transaction_cost(quantity: Expr, price: Expr, *, commission: float | Expr = 0.0, fees: float | Expr = 0.0, bps: float | Expr = 0.0) Expr[source]¶
Per-trade cost from explicit charges plus basis-point slippage.
bpsis applied to absolute traded notional.commissionandfeesmay be scalars or expressions aligned to the transaction rows.
- finance_calcs.transaction_volume(quantity: Expr, price: Expr, *, period: Frequency | str | Expr | None = None, date: Expr | None = None) Expr[source]¶
Absolute traded notional, summed over the full sample or period.
- finance_calcs.slippage_bps(execution_price: Expr, benchmark_price: Expr, *, side: Expr | None = None) Expr[source]¶
Execution slippage in basis points.
Without
side, the result is signed price difference versus the benchmark. Withside, positive values mean adverse execution cost for buy/cover and sell/short transactions.
- finance_calcs.implementation_shortfall(execution_price: Expr, decision_price: Expr, *, side: Expr | None = None) Expr[source]¶
Side-aware execution slippage versus the decision price.
- finance_calcs.vwap_slippage(execution_price: Expr, vwap: Expr, *, side: Expr | None = None) Expr[source]¶
Side-aware execution slippage versus VWAP.
- finance_calcs.turnover(weights: Expr, *, window: int | None = None) Expr[source]¶
Portfolio turnover contribution from position-weight changes.
Apply over a symbol/security partition, then aggregate by rebalance date. The contribution is
0.5 * abs(weight - prior_weight).
- finance_calcs.cost_per_trade(quantity: Expr, price: Expr, *, commission: float | Expr = 0.0, fees: float | Expr = 0.0, bps: float | Expr = 0.0) Expr[source]¶
Alias for per-trade transaction cost.
- finance_calcs.cost_attribution(transactions: DataFrame, *, quantity_col: str = 'amount', price_col: str = 'price', commission_col: str = 'commission', fees_col: str = 'fees', bps_col: str = 'bps', spread_bps_col: str = 'spread_bps', market_impact_bps_col: str = 'market_impact_bps', slippage_component: str = 'slippage') DataFrame[source]¶
Summarize transaction costs by component.
- finance_calcs.extract_round_trips(transactions: DataFrame, *, timestamp_col: str = 'timestamp', symbol_col: str = 'symbol', quantity_col: str = 'amount', price_col: str = 'price') DataFrame[source]¶
Extract FIFO round trips from signed transaction quantities.
- finance_calcs.round_trip_stats(round_trips: DataFrame, *, pnl_col: str = 'pnl') dict[str, float | int][source]¶
Summary statistics for extracted round trips.
- finance_calcs.long_short_round_trip_stats(round_trips: DataFrame, *, side_col: str = 'side', pnl_col: str = 'pnl') DataFrame[source]¶
Round-trip statistics split by long and short trades.
- finance_calcs.sector_round_trip_stats(round_trips: DataFrame, sector_map: Mapping[str, str], *, symbol_col: str = 'symbol', pnl_col: str = 'pnl') DataFrame[source]¶
Round-trip statistics by sector.
- finance_calcs.payoff_ratio(pnl: Expr) Expr[source]¶
Average winning trade divided by absolute average losing trade.
- finance_calcs.trade_duration_stats(duration: Iterable[Any]) dict[str, float][source]¶
Mean, median, and maximum holding duration.
- finance_calcs.mae_mfe(trades: DataFrame, prices: DataFrame, *, timestamp_col: str = 'timestamp', symbol_col: str = 'symbol', price_col: str = 'price') DataFrame[source]¶
Attach maximum adverse and favorable excursion to round trips.
- finance_calcs.consecutive_wins_losses(pnl: Iterable[Any]) dict[str, int][source]¶
Maximum consecutive winning and losing trade counts.