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

28 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-05-07 15:52 +0000

1"""Result container for system/experiment outputs.""" 

2 

3from dataclasses import dataclass 

4from pathlib import Path 

5 

6import polars as pl 

7 

8from .portfolio import Portfolio 

9 

10 

11@dataclass(frozen=True) 

12class Result: 

13 """Lightweight container for system outputs. 

14 

15 Attributes: 

16 portfolio: The portfolio constructed by a system/experiment. 

17 mu: Optional per-asset expected-returns surface used by some systems. 

18 """ 

19 

20 portfolio: Portfolio 

21 mu: pl.DataFrame | None = None 

22 

23 def create_reports(self, output_dir: Path) -> None: 

24 """Generate CSV exports and interactive HTML plots for this result. 

25 

26 Args: 

27 output_dir: Destination directory where two subfolders will be created: 

28 - data/: CSV exports of prices, profit, returns, positions, and signal (if mu present). 

29 - plots/: Plotly HTML reports (snapshot, lead/lag IR, lagged performance, 

30 smoothed holdings performance). 

31 """ 

32 data = output_dir / "data" 

33 plots = output_dir / "plots" 

34 

35 data.mkdir(parents=True, exist_ok=True) 

36 plots.mkdir(parents=True, exist_ok=True) 

37 

38 self.portfolio.prices.write_csv(file=data / "prices.csv") 

39 self.portfolio.profit.write_csv(file=data / "profit.csv") 

40 self.portfolio.returns.write_csv(file=data / "returns.csv") 

41 self.portfolio.tilt_timing_decomp.write_csv(file=data / "tilt_timing_decomp.csv") 

42 

43 if self.mu is not None: 

44 self.mu.write_csv(file=data / "signal.csv") 

45 

46 self.portfolio.cashposition.write_csv(file=data / "position.csv") 

47 

48 fig = self.portfolio.plots.snapshot() 

49 fig.write_html(file=plots / "snapshot.html", auto_open=False, include_plotlyjs="cdn") 

50 fig = self.portfolio.plots.lead_lag_ir_plot() 

51 fig.write_html(file=plots / "lag_ir.html", auto_open=False, include_plotlyjs="cdn") 

52 fig = self.portfolio.plots.lagged_performance_plot() 

53 fig.write_html(file=plots / "lagged_perf.html", auto_open=False, include_plotlyjs="cdn") 

54 fig = self.portfolio.plots.smoothed_holdings_performance_plot() 

55 fig.write_html(file=plots / "smooth_perf.html", auto_open=False, include_plotlyjs="cdn")