Coverage for src / jquantstats / _plots / _protocol.py: 100%
4 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-26 18:44 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-26 18:44 +0000
1"""Protocols describing the minimal interfaces required by the _plots subpackage."""
3from __future__ import annotations
5from typing import Protocol, runtime_checkable
7import polars as pl
9from jquantstats._cost_model import CostModel
12@runtime_checkable
13class DataLike(Protocol): # pragma: no cover
14 """Structural interface required by the :class:`~jquantstats._plots._data.DataPlots` class.
16 Any object satisfying this protocol can be passed as ``data`` without a
17 concrete dependency on :class:`~jquantstats._data.Data`.
18 """
20 @property
21 def all(self) -> pl.DataFrame:
22 """Combined DataFrame of date index and returns columns."""
23 ...
25 @property
26 def assets(self) -> list[str]:
27 """Names of the asset return columns."""
28 ...
31@runtime_checkable
32class PortfolioLike(Protocol): # pragma: no cover
33 """Structural interface required by the :class:`~jquantstats._plots._portfolio.PortfolioPlots` class.
35 Any object satisfying this protocol can be passed as ``portfolio`` without a
36 concrete dependency on :class:`~jquantstats.portfolio.Portfolio`.
37 """
39 prices: pl.DataFrame
40 aum: float
41 cost_model: CostModel
43 @property
44 def nav_accumulated(self) -> pl.DataFrame:
45 """Accumulated NAV series."""
46 ...
48 @property
49 def tilt(self) -> PortfolioLike:
50 """Tilt component portfolio."""
51 ...
53 @property
54 def timing(self) -> PortfolioLike:
55 """Timing component portfolio."""
56 ...
58 @property
59 def net_cost_nav(self) -> pl.DataFrame:
60 """Net-of-cost accumulated NAV series."""
61 ...
63 @property
64 def drawdown(self) -> pl.DataFrame:
65 """Drawdown series."""
66 ...
68 @property
69 def assets(self) -> list[str]:
70 """Asset names."""
71 ...
73 @property
74 def monthly(self) -> pl.DataFrame:
75 """Monthly returns grouped by year and month."""
76 ...
78 @property
79 def profits(self) -> pl.DataFrame:
80 """Per-period profit series."""
81 ...
83 @property
84 def stats(self) -> object:
85 """Statistics facade (rolling_sharpe, rolling_volatility, annual_breakdown, sharpe)."""
86 ...
88 def lag(self, n: int) -> PortfolioLike:
89 """Return a lagged copy of this portfolio."""
90 ...
92 def smoothed_holding(self, n: int) -> PortfolioLike:
93 """Return a smoothed-holdings copy of this portfolio."""
94 ...
96 def trading_cost_impact(self, max_bps: int = 20) -> pl.DataFrame:
97 """Return a DataFrame of Sharpe vs. one-way trading costs."""
98 ...
100 def correlation(self, frame: pl.DataFrame, name: str = "portfolio") -> pl.DataFrame:
101 """Return the correlation matrix including the portfolio profit series."""
102 ...