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

10 statements  

« prev     ^ index     » next       coverage.py v7.13.2, created at 2026-02-03 02:21 +0000

1from __future__ import annotations 

2 

3import dataclasses 

4from typing import TYPE_CHECKING 

5 

6import polars as pl 

7 

8if TYPE_CHECKING: 

9 from ._data import Data 

10 

11 

12@dataclasses.dataclass(frozen=True) 

13class Reports: 

14 """A class for generating financial reports from Data objects. 

15 

16 This class provides methods for calculating and formatting various financial metrics 

17 into report-ready formats such as DataFrames. 

18 

19 Attributes: 

20 data (Data): The financial data object to generate reports from. 

21 

22 """ 

23 

24 data: Data 

25 

26 def metrics(self, periods: int | float | None = None) -> pl.DataFrame: 

27 """Calculate various financial metrics and return them as a DataFrame. 

28 

29 Returns: 

30 pl.DataFrame: A DataFrame containing financial metrics as rows and assets as columns. 

31 The first column is 'Metric' containing the name of each metric. 

32 

33 """ 

34 metrics: dict[str, dict[str, float]] = { 

35 "Sharpe Ratio": self.data.stats.sharpe(periods=periods), 

36 "Sortino Ratio": self.data.stats.sortino(periods=periods), 

37 # "Calmar Ratio": self.data.stats.calmar(), 

38 "Max Drawdown": self.data.stats.max_drawdown(), 

39 "Volatility": self.data.stats.volatility(periods=periods), 

40 # "CAGR": self.data.stats.cagr(), 

41 "Value at Risk (5%)": self.data.stats.value_at_risk(alpha=0.05), 

42 "Win/Loss Ratio": self.data.stats.win_loss_ratio(), 

43 # "Mean Daily Return": self.data.returns.mean(), 

44 # "Std Dev": self.data.returns.std().to_dict(), 

45 "Skew": self.data.stats.skew(), 

46 "Kurtosis": self.data.stats.kurtosis(), 

47 } 

48 

49 # convert to Polars DataFrame with metrics as rows, assets as columns 

50 return pl.DataFrame([{"Metric": name, **vals} for name, vals in metrics.items()])