Coverage for src/jquantstats/_stats/_stats.py: 100%

38 statements  

« prev     ^ index     » next       coverage.py v7.15.3, created at 2026-08-06 04:52 +0000

1"""Statistical analysis tools for financial returns data. 

2 

3This module provides the `Stats` dataclass, which is the public-facing 

4class that combines five mixin classes: 

5 

6- `_BasicStatsMixin` — basic statistics, 

7 volatility, win/loss metrics, and risk metrics (VaR, Sharpe inputs, Kelly). 

8- `_RiskStatsMixin` — the risk-adjusted ratio family: Sharpe, Sortino, Omega and 

9 their probabilistic / smart / adjusted variants. 

10- `_ConcentrationStatsMixin` — Herfindahl-Hirschman concentration of gains and 

11 losses (`hhi_positive`, `hhi_negative`). 

12- `_BenchmarkStatsMixin` — benchmark-relative and factor analytics (R², alpha, 

13 beta, information ratio, Treynor). 

14- `_DrawdownMixin` — cumulative returns, drawdown series, max drawdown, and 

15 per-episode drawdown details. 

16- `_ReportingStatsMixin` — temporal reporting: CAGR, expected return, RAR, 

17 Calmar, recovery factor, drawdown duration, monthly win rate. 

18- `_CaptureStatsMixin` — up- and down-market capture ratios. 

19- `_SummaryStatsMixin` — the tidy `summary` table and its `annual_breakdown`. 

20- `_PeriodicReportingMixin` — period-bucketed tables: monthly-returns pivot, 

21 distribution across calendar frequencies, benchmark comparison, worst-N periods. 

22- `_RollingStatsMixin` — rolling-window 

23 time-series metrics (rolling Sharpe, Sortino, and volatility). 

24- `_MonteCarloStatsMixin` — block-bootstrap Monte Carlo simulation distributions 

25 for total return, Sharpe, max drawdown, and CAGR. 

26 

27Module-level helpers and the ``columnwise_stat`` / ``to_frame`` decorators are 

28defined in `jquantstats._stats._core` and re-exported here for backwards 

29compatibility. 

30""" 

31 

32from __future__ import annotations 

33 

34from typing import TYPE_CHECKING 

35 

36import polars as pl 

37 

38from ._basic import _BasicStatsMixin 

39from ._benchmark import _BenchmarkStatsMixin 

40from ._capture import _CaptureStatsMixin 

41from ._concentration import _ConcentrationStatsMixin 

42from ._core import ( 

43 _drawdown_series, 

44 _mean, 

45 _to_float, 

46 columnwise_stat, 

47 to_frame, 

48) 

49from ._drawdown import _DrawdownMixin 

50from ._internals import ( 

51 _annualization_factor, 

52 _comp_return, 

53 _downside_deviation, 

54 _nav_series, 

55) 

56from ._montecarlo import _MonteCarloStatsMixin 

57from ._performance import _RiskStatsMixin 

58from ._periodic import _PeriodicReportingMixin 

59from ._reporting import _ReportingStatsMixin 

60from ._rolling import _RollingStatsMixin 

61from ._summary import _SummaryStatsMixin 

62 

63if TYPE_CHECKING: 

64 from ..data import Data 

65 

66__all__ = [ 

67 "Stats", 

68 "_annualization_factor", 

69 "_comp_return", 

70 "_downside_deviation", 

71 "_drawdown_series", 

72 "_mean", 

73 "_nav_series", 

74 "_to_float", 

75 "columnwise_stat", 

76 "to_frame", 

77] 

78 

79 

80class Stats( 

81 _BasicStatsMixin, 

82 _RiskStatsMixin, 

83 _ConcentrationStatsMixin, 

84 _BenchmarkStatsMixin, 

85 _DrawdownMixin, 

86 _ReportingStatsMixin, 

87 _CaptureStatsMixin, 

88 _SummaryStatsMixin, 

89 _PeriodicReportingMixin, 

90 _RollingStatsMixin, 

91 _MonteCarloStatsMixin, 

92): 

93 """Statistical analysis tools for financial returns data. 

94 

95 Provides a comprehensive set of methods for calculating various financial 

96 metrics and statistics on returns data, including: 

97 

98 - Basic statistics (mean, skew, kurtosis) 

99 - Risk metrics (volatility, value-at-risk, drawdown) 

100 - Performance ratios (Sharpe, Sortino, information ratio) 

101 - Win/loss metrics (win rate, profit factor, payoff ratio) 

102 - Rolling calculations (rolling volatility, rolling Sharpe) 

103 - Factor analysis (alpha, beta, R-squared) 

104 - Concentration metrics (``hhi_positive``, ``hhi_negative``) — optional 

105 Herfindahl-Hirschman Index diagnostics that quantify how concentrated 

106 gains and losses are across time periods. These are public API but are 

107 not included in ``summary()`` by default. 

108 

109 Metrics are organised into focused modules: 

110 

111 - `_BasicStatsMixin` 

112 - `_RiskStatsMixin` 

113 - `_ConcentrationStatsMixin` 

114 - `_BenchmarkStatsMixin` 

115 - `_DrawdownMixin` 

116 - `_ReportingStatsMixin` 

117 - `_CaptureStatsMixin` 

118 - `_SummaryStatsMixin` 

119 - `_PeriodicReportingMixin` 

120 - `_RollingStatsMixin` 

121 - `_MonteCarloStatsMixin` 

122 

123 Attributes: 

124 all: A DataFrame combining all data (index, returns, benchmark) for 

125 easy column selection. 

126 """ 

127 

128 def __init__(self, data: Data) -> None: 

129 self._data = data 

130 self.all: pl.DataFrame = data.all 

131 

132 def __repr__(self) -> str: 

133 """Return a string representation of the Stats object.""" 

134 return f"Stats(assets={self._data.assets})" 

135 

136 @property 

137 def assets(self) -> list[str]: 

138 """Asset column names (excludes benchmark and date).""" 

139 return self._data.assets 

140 

141 @property 

142 def returns(self) -> pl.DataFrame: 

143 """Returns DataFrame (asset columns only, no benchmark).""" 

144 return self._data.returns 

145 

146 @property 

147 def benchmark(self) -> pl.DataFrame | None: 

148 """Benchmark DataFrame, or None when no benchmark was provided.""" 

149 return self._data.benchmark 

150 

151 @property 

152 def date_col(self) -> list[str]: 

153 """Date column name(s) present in the index, or empty list.""" 

154 return self._data.date_col 

155 

156 @property 

157 def index(self) -> pl.DataFrame: 

158 """Index DataFrame (date or integer range).""" 

159 return self._data.index