Coverage for src/jquantstats/_plots/_data/_rolling.py: 100%
19 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 04:11 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 04:11 +0000
1"""Rolling risk/return metric line charts (Sharpe, Sortino, volatility, beta)."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, Literal, overload
7from .._render import render
8from .._specs import (
9 rolling_beta_spec,
10 rolling_sharpe_spec,
11 rolling_sortino_spec,
12 rolling_volatility_spec,
13)
15if TYPE_CHECKING:
16 from matplotlib.figure import Figure as MplFigure
17 from plotly.graph_objects import Figure as PlotlyFigure
19 from jquantstats._protocol import DataLike
21 from .._backend import Backend
22 from .._render import Figure
25class _RollingPlotsMixin:
26 """Rolling-window metric plots for :class:`DataPlots`."""
28 __slots__ = ()
30 _data: DataLike
32 @overload
33 def rolling_sharpe(
34 self,
35 rolling_period: int = ...,
36 periods_per_year: int = ...,
37 title: str = ...,
38 *,
39 backend: Literal["plotly"] | None = ...,
40 ) -> PlotlyFigure: ...
42 @overload
43 def rolling_sharpe(
44 self,
45 rolling_period: int = ...,
46 periods_per_year: int = ...,
47 title: str = ...,
48 *,
49 backend: Literal["matplotlib"],
50 ) -> MplFigure: ...
52 def rolling_sharpe(
53 self,
54 rolling_period: int = 126,
55 periods_per_year: int = 252,
56 title: str = "Rolling Sharpe Ratio",
57 *,
58 backend: Backend | None = None,
59 ) -> Figure:
60 """Rolling annualised Sharpe ratio over time.
62 Computes ``rolling_mean / rolling_std * sqrt(periods_per_year)`` with a
63 trailing window of *rolling_period* observations for every column in the
64 dataset (assets and benchmark when present).
66 Args:
67 rolling_period: Trailing window size. Defaults to 126 (6 months).
68 periods_per_year: Annualisation factor. Defaults to 252.
69 title: Chart title. Defaults to ``"Rolling Sharpe Ratio"``.
70 backend: Renderer to use. Defaults to the ambient selection.
72 Returns:
73 Figure: A line chart.
75 """
76 spec = rolling_sharpe_spec(self._data, rolling_period, periods_per_year, title)
77 return render(spec, backend)
79 @overload
80 def rolling_sortino(
81 self,
82 rolling_period: int = ...,
83 periods_per_year: int = ...,
84 title: str = ...,
85 *,
86 backend: Literal["plotly"] | None = ...,
87 ) -> PlotlyFigure: ...
89 @overload
90 def rolling_sortino(
91 self,
92 rolling_period: int = ...,
93 periods_per_year: int = ...,
94 title: str = ...,
95 *,
96 backend: Literal["matplotlib"],
97 ) -> MplFigure: ...
99 def rolling_sortino(
100 self,
101 rolling_period: int = 126,
102 periods_per_year: int = 252,
103 title: str = "Rolling Sortino Ratio",
104 *,
105 backend: Backend | None = None,
106 ) -> Figure:
107 """Rolling annualised Sortino ratio over time.
109 Computes ``rolling_mean / rolling_downside_std * sqrt(periods_per_year)``
110 where downside deviation considers only negative returns.
112 Args:
113 rolling_period: Trailing window size. Defaults to 126 (6 months).
114 periods_per_year: Annualisation factor. Defaults to 252.
115 title: Chart title. Defaults to ``"Rolling Sortino Ratio"``.
116 backend: Renderer to use. Defaults to the ambient selection.
118 Returns:
119 Figure: A line chart.
121 """
122 spec = rolling_sortino_spec(self._data, rolling_period, periods_per_year, title)
123 return render(spec, backend)
125 @overload
126 def rolling_volatility(
127 self,
128 rolling_period: int = ...,
129 periods_per_year: int = ...,
130 title: str = ...,
131 *,
132 backend: Literal["plotly"] | None = ...,
133 ) -> PlotlyFigure: ...
135 @overload
136 def rolling_volatility(
137 self,
138 rolling_period: int = ...,
139 periods_per_year: int = ...,
140 title: str = ...,
141 *,
142 backend: Literal["matplotlib"],
143 ) -> MplFigure: ...
145 def rolling_volatility(
146 self,
147 rolling_period: int = 126,
148 periods_per_year: int = 252,
149 title: str = "Rolling Volatility",
150 *,
151 backend: Backend | None = None,
152 ) -> Figure:
153 """Rolling annualised volatility over time.
155 Computes ``rolling_std * sqrt(periods_per_year)`` for every column in
156 the dataset.
158 Args:
159 rolling_period: Trailing window size. Defaults to 126 (6 months).
160 periods_per_year: Annualisation factor. Defaults to 252.
161 title: Chart title. Defaults to ``"Rolling Volatility"``.
162 backend: Renderer to use. Defaults to the ambient selection.
164 Returns:
165 Figure: A line chart.
167 """
168 spec = rolling_volatility_spec(self._data, rolling_period, periods_per_year, title)
169 return render(spec, backend)
171 @overload
172 def rolling_beta(
173 self,
174 rolling_period: int = ...,
175 rolling_period2: int | None = ...,
176 title: str = ...,
177 figsize: tuple[int, int] | None = ...,
178 *,
179 backend: Literal["plotly"] | None = ...,
180 ) -> PlotlyFigure: ...
182 @overload
183 def rolling_beta(
184 self,
185 rolling_period: int = ...,
186 rolling_period2: int | None = ...,
187 title: str = ...,
188 figsize: tuple[int, int] | None = ...,
189 *,
190 backend: Literal["matplotlib"],
191 ) -> MplFigure: ...
193 def rolling_beta(
194 self,
195 rolling_period: int = 126,
196 rolling_period2: int | None = 252,
197 title: str = "Rolling Beta",
198 figsize: tuple[int, int] | None = None,
199 *,
200 backend: Backend | None = None,
201 ) -> Figure:
202 """Rolling beta versus the benchmark.
204 Plots one line per asset per window size. Beta is estimated via the
205 standard OLS formula: ``cov(asset, bench) / var(bench)`` computed over
206 a trailing window.
208 Args:
209 rolling_period: Primary trailing window size. Defaults to 126.
210 rolling_period2: Optional second window size overlaid on the same
211 chart. Defaults to 252. Pass ``None`` to omit.
212 title: Chart title. Defaults to ``"Rolling Beta"``.
213 figsize: Optional ``(width, height)`` in pixels.
214 backend: Renderer to use. Defaults to the ambient selection.
216 Returns:
217 Figure: A line chart.
219 Raises:
220 NoBenchmarkError: If no benchmark columns are present in the data.
222 """
223 spec = rolling_beta_spec(self._data, rolling_period, rolling_period2, title, figsize)
224 return render(spec, backend)