Coverage for src/jquantstats/_plots/_portfolio/_core.py: 100%

11 statements  

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

1"""The :class:`PortfolioPlots` facade combining the portfolio plot-family mixins.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING 

6 

7import plotly.io as pio 

8 

9from ._diagnostics import _DiagnosticPlotsMixin 

10from ._nav import _NavPlotsMixin 

11from ._rolling import _RollingPortfolioPlotsMixin 

12 

13if TYPE_CHECKING: 

14 from .._protocol import PortfolioLike 

15 

16# Ensure Plotly works with Marimo (set after imports to satisfy linters) 

17pio.renderers.default = "plotly_mimetype" 

18 

19 

20class PortfolioPlots( 

21 _NavPlotsMixin, 

22 _RollingPortfolioPlotsMixin, 

23 _DiagnosticPlotsMixin, 

24): 

25 """Facade for portfolio plots built with Plotly. 

26 

27 Provides convenience methods to visualize portfolio performance and 

28 diagnostics directly from a Portfolio instance (e.g., snapshot charts, 

29 lagged performance, smoothed holdings, and lead/lag IR). 

30 

31 Charts are organised into focused mixins: 

32 

33 - `_NavPlotsMixin` — accumulated-NAV curves: snapshot, lag sweep, 

34 smoothed holdings. 

35 - `_RollingPortfolioPlotsMixin` — rolling Sharpe/volatility and the 

36 per-year Sharpe breakdown. 

37 - `_DiagnosticPlotsMixin` — lead/lag IR, correlation heatmap, monthly 

38 returns calendar, trading-cost impact. 

39 """ 

40 

41 __slots__ = ("_portfolio",) 

42 

43 def __init__(self, portfolio: PortfolioLike) -> None: 

44 self._portfolio = portfolio