markowitz.backtest.stats¶
markowitz.backtest.stats
¶
Performance statistics for backtest return series.
All functions accept a pandas.Series of per-period simple returns and
return a scalar. Annualization is controlled by the ann argument (12 for
monthly, 252 for daily, etc.).
calmar(r: pd.Series, ann: int = 12) -> float
¶
Calmar ratio: annualized arithmetic mean / |max drawdown|.
Returns 0.0 when the drawdown is zero.
Source code in src/markowitz/backtest/stats.py
ceq(r: pd.Series, gamma: float) -> float
¶
Per-period certainty-equivalent return under quadratic utility.
CEQ = mu - 0.5 * gamma * sigma^2.
Source code in src/markowitz/backtest/stats.py
jobson_korkie_memmel(r_i: pd.Series, r_n: pd.Series) -> tuple[float, float]
¶
Jobson-Korkie test with the Memmel (2003) correction.
Tests :math:H_0: Sharpe(:math:r_i) = Sharpe(:math:r_n) against a
two-sided alternative. Returns (z, p_value).
Identical input series yield z == 0 and p_value == 1.
Source code in src/markowitz/backtest/stats.py
ledoit_wolf_bootstrap_pvalue(r_i: pd.Series, r_n: pd.Series, *, B: int = 999, block_length: int = 5, seed: int = 0) -> float
¶
Stationary-block-bootstrap p-value for the Sharpe-difference test.
Uses Politis-Romano fixed-block sampling under the null that the two
Sharpe ratios are equal. Returns a two-sided p-value in [0, 1].
Source code in src/markowitz/backtest/stats.py
max_drawdown(r: pd.Series) -> float
¶
Maximum drawdown of the wealth path implied by r.
Returns a non-positive number (0.0 if the path is monotonically
non-decreasing).
Source code in src/markowitz/backtest/stats.py
sharpe_ratio(r: pd.Series, rf: pd.Series | float = 0.0, ann: int = 12) -> float
¶
Annualized Sharpe ratio of an excess-return series.
Returns 0.0 if the standard deviation is exactly zero (degenerate case).
Source code in src/markowitz/backtest/stats.py
sortino_ratio(r: pd.Series, rf: pd.Series | float = 0.0, ann: int = 12) -> float
¶
Annualized Sortino ratio using downside semi-deviation (target = 0).