Polars-first risk metrics for quant hedge funds
Project description
ruin
A Polars-first risk metrics library for quant hedge funds.
Installation
pip install pyruin
# or with optional SciPy extras (reserved for future use):
pip install "pyruin[stats]"
Distributed on PyPI as
pyruin(the nameruinwas taken). The import name is unchanged:import ruin.
Quickstart
import polars as pl
import ruin
returns = pl.Series([0.01, -0.02, 0.03, -0.01, 0.02, ...]) # daily returns
sr = ruin.sharpe_ratio(returns, periods_per_year=252)
mdd = ruin.max_drawdown(returns)
df = ruin.summary(returns, periods_per_year=252)
Module Overview
| Module | What it computes |
|---|---|
ruin.returns |
from_prices, total_return, annualize_return, cagr |
ruin.volatility |
volatility, annualize_volatility, downside_deviation, semi_deviation |
ruin.drawdown |
drawdown_series, max_drawdown, average_drawdown, max_drawdown_duration, recovery_time, time_underwater, drawdown_start, drawdown_end |
ruin.ratios |
sharpe_ratio, sortino_ratio, calmar_ratio, information_ratio, treynor_ratio, omega_ratio |
ruin.tail |
value_at_risk, conditional_value_at_risk / expected_shortfall |
ruin.market |
beta, downside_beta, upside_beta, alpha, tracking_error, correlation, up_capture, down_capture |
ruin.distribution |
skewness, excess_kurtosis, jarque_bera, autocorrelation |
ruin.activity |
hit_rate, average_win, average_loss, win_loss_ratio, profit_factor, best_period, worst_period, longest_winning_streak, longest_losing_streak |
ruin.rolling |
Rolling versions of all major metrics, returning length-aligned pl.Series |
ruin.periods |
mtd, qtd, ytd, trailing, since_inception, periods_per_year_for, annual_to_periodic, periodic_to_annual |
ruin.inference |
sharpe_standard_error, sharpe_confidence_interval, bootstrap_metric |
ruin.report |
summary — the one bundled function |
Composition Principle
This library provides building blocks. If you want a bundled metric, call summary() or compose the primitives yourself. Every function returns exactly one thing. We will not add bundled convenience functions.
Composition in Polars is cheap. A custom bundle is two lines:
import polars as pl
import ruin
# Rolling Sharpe with bootstrap confidence intervals
returns = pl.Series(your_returns)
# Rolling Sharpe (returns a Series)
rs = ruin.rolling_sharpe(returns, window=60, periods_per_year=252)
# Bootstrap CI on the scalar Sharpe
point, lo, hi = ruin.bootstrap_metric(
lambda r: ruin.sharpe_ratio(r, periods_per_year=252),
returns,
n_samples=1000,
confidence=0.95,
)
print(f"Sharpe: {point:.3f} ({lo:.3f}, {hi:.3f})")
Call multiple functions and compose:
metrics = {
"sharpe": ruin.sharpe_ratio(returns, periods_per_year=252),
"sortino": ruin.sortino_ratio(returns, periods_per_year=252),
"max_dd": ruin.max_drawdown(returns),
"cvar": ruin.conditional_value_at_risk(returns),
}
What This Library Is Not
The following are explicitly out of scope. Do not open issues requesting them.
- Money-weighted returns / IRR / fee crystallization — needs cash flows; belongs in a sibling library.
- Portfolio construction — optimization, risk parity, mean-variance, Black-Litterman.
- Factor models — Fama-French, Barra-style attribution, Brinson attribution.
- Backtesting engine — trade simulation, transaction costs, execution modeling.
- Data fetching — no yfinance, no Bloomberg, no CSV readers.
- Time series hygiene — resampling, calendar alignment, gap filling, corporate actions.
- Stress testing / Monte Carlo / scenario analysis.
- Forecasting — no GARCH, EWMA, regime models, volatility prediction.
- Plotting — use Polars + Altair/Plotly/Matplotlib directly.
- Pandas support — use Polars.
pd.Series.to_numpy()converts in one call if needed. - Cornish-Fisher VaR — reserved for a future
ruin[stats]extra.
Design Principles
- Returns in, numbers out. No prices, no positions, no trades, no I/O.
- Polars-first, minimal deps. Runtime:
polars+numpyonly. - Pure functions. No side effects, no hidden state.
- One function, one metric, one return type. Scalar →
float, rolling →pl.Series. - Explicit over implicit.
periods_per_yearis always explicit.risk_freeis per-period. - NaN handling. Drop by default;
strict=Trueinsummary()raises instead.
Sign Conventions
- Drawdowns are non-positive:
-0.23means 23% drawdown. - VaR and CVaR are positive loss magnitudes (desk convention):
0.02means "lose at most 2%."
See docs/conventions.md for library-wide behaviour
(sign conventions, NaN policy, input types, alignment).
See docs/metrics.md for per-metric definitions, formulas,
assumptions, and citations.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyruin-0.1.1.tar.gz.
File metadata
- Download URL: pyruin-0.1.1.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9e0e50263087f9fe7afdbe9dab7d35f46504124078109abe04522f37d5392e3
|
|
| MD5 |
4e9902fcb0fc67e5e5b2220144850066
|
|
| BLAKE2b-256 |
fd065d49d3d0d7997975ca813280b8718bae1d95e5c60302a120d79fe90fc0be
|
Provenance
The following attestation bundles were made for pyruin-0.1.1.tar.gz:
Publisher:
publish.yml on aexsalomao/ruin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyruin-0.1.1.tar.gz -
Subject digest:
a9e0e50263087f9fe7afdbe9dab7d35f46504124078109abe04522f37d5392e3 - Sigstore transparency entry: 1328226166
- Sigstore integration time:
-
Permalink:
aexsalomao/ruin@7706b3d68779b2c4e8cc8610adf5eb88b00a8a58 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/aexsalomao
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7706b3d68779b2c4e8cc8610adf5eb88b00a8a58 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyruin-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pyruin-0.1.1-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0935ff4d99c8d94da6159de60ef63b2b10bd68e0cf46dd7e23974b5f38bf404
|
|
| MD5 |
81f7641b4218398fd337ea4de6542e46
|
|
| BLAKE2b-256 |
265d2a6f999b2faa64f7568378b41c0ca6a7c3f67df88bc4f31f0c2a1b03869b
|
Provenance
The following attestation bundles were made for pyruin-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on aexsalomao/ruin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyruin-0.1.1-py3-none-any.whl -
Subject digest:
f0935ff4d99c8d94da6159de60ef63b2b10bd68e0cf46dd7e23974b5f38bf404 - Sigstore transparency entry: 1328226192
- Sigstore integration time:
-
Permalink:
aexsalomao/ruin@7706b3d68779b2c4e8cc8610adf5eb88b00a8a58 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/aexsalomao
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7706b3d68779b2c4e8cc8610adf5eb88b00a8a58 -
Trigger Event:
release
-
Statement type: