Coverage for src/jquantstats/_stats/_stats.py: 100%
34 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-23 06:13 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-23 06:13 +0000
1"""Statistical analysis tools for financial returns data.
3This module provides the `Stats` dataclass, which is the public-facing
4class that combines five mixin classes:
6- `_BasicStatsMixin` — basic statistics,
7 volatility, win/loss metrics, and risk metrics (VaR, Sharpe inputs, Kelly).
8- `_RiskStatsMixin` — Sharpe,
9 Sortino, benchmark/factor analytics (R², alpha, beta).
10- `_DrawdownMixin` — cumulative returns, drawdown series, max drawdown, and
11 per-episode drawdown details.
12- `_ReportingStatsMixin` — temporal
13 reporting, Calmar, recovery factor, capture ratios, annual breakdown, and
14 summary.
15- `_PeriodicReportingMixin` — period-bucketed tables: monthly-returns pivot,
16 distribution across calendar frequencies, benchmark comparison, worst-N periods.
17- `_RollingStatsMixin` — rolling-window
18 time-series metrics (rolling Sharpe, Sortino, and volatility).
19- `_MonteCarloStatsMixin` — block-bootstrap Monte Carlo simulation distributions
20 for total return, Sharpe, max drawdown, and CAGR.
22Module-level helpers and the ``columnwise_stat`` / ``to_frame`` decorators are
23defined in `jquantstats._stats._core` and re-exported here for backwards
24compatibility.
25"""
27from __future__ import annotations
29from typing import TYPE_CHECKING
31import polars as pl
33from ._basic import _BasicStatsMixin
34from ._core import (
35 _drawdown_series,
36 _mean,
37 _to_float,
38 columnwise_stat,
39 to_frame,
40)
41from ._drawdown import _DrawdownMixin
42from ._internals import (
43 _annualization_factor,
44 _comp_return,
45 _downside_deviation,
46 _nav_series,
47)
48from ._montecarlo import _MonteCarloStatsMixin
49from ._performance import _RiskStatsMixin
50from ._periodic import _PeriodicReportingMixin
51from ._reporting import _ReportingStatsMixin
52from ._rolling import _RollingStatsMixin
54if TYPE_CHECKING:
55 from ..data import Data
57__all__ = [
58 "Stats",
59 "_annualization_factor",
60 "_comp_return",
61 "_downside_deviation",
62 "_drawdown_series",
63 "_mean",
64 "_nav_series",
65 "_to_float",
66 "columnwise_stat",
67 "to_frame",
68]
71class Stats(
72 _BasicStatsMixin,
73 _RiskStatsMixin,
74 _DrawdownMixin,
75 _ReportingStatsMixin,
76 _PeriodicReportingMixin,
77 _RollingStatsMixin,
78 _MonteCarloStatsMixin,
79):
80 """Statistical analysis tools for financial returns data.
82 Provides a comprehensive set of methods for calculating various financial
83 metrics and statistics on returns data, including:
85 - Basic statistics (mean, skew, kurtosis)
86 - Risk metrics (volatility, value-at-risk, drawdown)
87 - Performance ratios (Sharpe, Sortino, information ratio)
88 - Win/loss metrics (win rate, profit factor, payoff ratio)
89 - Rolling calculations (rolling volatility, rolling Sharpe)
90 - Factor analysis (alpha, beta, R-squared)
91 - Concentration metrics (``hhi_positive``, ``hhi_negative``) — optional
92 Herfindahl-Hirschman Index diagnostics that quantify how concentrated
93 gains and losses are across time periods. These are public API but are
94 not included in ``summary()`` by default.
96 Metrics are organised into focused modules:
98 - `_BasicStatsMixin`
99 - `_RiskStatsMixin`
100 - `_DrawdownMixin`
101 - `_ReportingStatsMixin`
102 - `_PeriodicReportingMixin`
103 - `_RollingStatsMixin`
104 - `_MonteCarloStatsMixin`
106 Attributes:
107 all: A DataFrame combining all data (index, returns, benchmark) for
108 easy column selection.
109 """
111 def __init__(self, data: Data) -> None:
112 self._data = data
113 self.all: pl.DataFrame = data.all
115 def __repr__(self) -> str:
116 """Return a string representation of the Stats object."""
117 return f"Stats(assets={self._data.assets})"
119 @property
120 def assets(self) -> list[str]:
121 """Asset column names (excludes benchmark and date)."""
122 return self._data.assets
124 @property
125 def returns(self) -> pl.DataFrame:
126 """Returns DataFrame (asset columns only, no benchmark)."""
127 return self._data.returns
129 @property
130 def benchmark(self) -> pl.DataFrame | None:
131 """Benchmark DataFrame, or None when no benchmark was provided."""
132 return self._data.benchmark
134 @property
135 def date_col(self) -> list[str]:
136 """Date column name(s) present in the index, or empty list."""
137 return self._data.date_col
139 @property
140 def index(self) -> pl.DataFrame:
141 """Index DataFrame (date or integer range)."""
142 return self._data.index