Coverage for src/jquantstats/_plots/_data/_montecarlo.py: 100%

12 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-23 04:11 +0000

1"""Monte Carlo simulation charts (fan chart and metric distribution).""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, Literal, overload 

6 

7from .._render import render 

8from .._specs import montecarlo_distribution_spec, montecarlo_spec 

9 

10if TYPE_CHECKING: 

11 from matplotlib.figure import Figure as MplFigure 

12 from plotly.graph_objects import Figure as PlotlyFigure 

13 

14 from jquantstats._protocol import DataLike 

15 

16 from .._backend import Backend 

17 from .._render import Figure 

18 

19 

20class _MonteCarloPlotsMixin: 

21 """Monte Carlo simulation plots for :class:`DataPlots`.""" 

22 

23 __slots__ = () 

24 

25 _data: DataLike 

26 

27 @overload 

28 def montecarlo( 

29 self, 

30 n: int = ..., 

31 period: int = ..., 

32 title: str = ..., 

33 figsize: tuple[int, int] | None = ..., 

34 *, 

35 backend: Literal["plotly"] | None = ..., 

36 ) -> PlotlyFigure: ... 

37 

38 @overload 

39 def montecarlo( 

40 self, 

41 n: int = ..., 

42 period: int = ..., 

43 title: str = ..., 

44 figsize: tuple[int, int] | None = ..., 

45 *, 

46 backend: Literal["matplotlib"], 

47 ) -> MplFigure: ... 

48 

49 def montecarlo( 

50 self, 

51 n: int = 100, 

52 period: int = 252, 

53 title: str = "Monte Carlo Simulation", 

54 figsize: tuple[int, int] | None = None, 

55 *, 

56 backend: Backend | None = None, 

57 ) -> Figure: 

58 """Fan chart of Monte Carlo simulated cumulative return paths. 

59 

60 For each asset column, draws ``n`` bootstrapped paths sampled with 

61 replacement from historical returns and overlays the observed path for 

62 the trailing *period* observations. 

63 

64 Args: 

65 n: Number of simulated paths per asset. Defaults to 100. 

66 period: Number of observations per path. Defaults to 252. 

67 title: Chart title. Defaults to ``"Monte Carlo Simulation"``. 

68 figsize: Optional figure ``(width, height)`` in pixels. 

69 backend: Renderer to use. Defaults to the ambient selection. 

70 

71 Returns: 

72 Figure: A fan chart. 

73 

74 Raises: 

75 ValueError: If ``n`` or ``period`` is not a positive integer. 

76 

77 """ 

78 return render(montecarlo_spec(self._data, n, period, title, figsize), backend) 

79 

80 @overload 

81 def montecarlo_distribution( 

82 self, 

83 n: int = ..., 

84 period: int = ..., 

85 metric: str = ..., 

86 title: str = ..., 

87 figsize: tuple[int, int] | None = ..., 

88 *, 

89 backend: Literal["plotly"] | None = ..., 

90 ) -> PlotlyFigure: ... 

91 

92 @overload 

93 def montecarlo_distribution( 

94 self, 

95 n: int = ..., 

96 period: int = ..., 

97 metric: str = ..., 

98 title: str = ..., 

99 figsize: tuple[int, int] | None = ..., 

100 *, 

101 backend: Literal["matplotlib"], 

102 ) -> MplFigure: ... 

103 

104 def montecarlo_distribution( 

105 self, 

106 n: int = 1000, 

107 period: int = 252, 

108 metric: str = "sharpe", 

109 title: str = "Monte Carlo Distribution", 

110 figsize: tuple[int, int] | None = None, 

111 *, 

112 backend: Backend | None = None, 

113 ) -> Figure: 

114 """Distribution of Monte Carlo simulation metrics. 

115 

116 Computes one metric per simulated path and shows the resulting 

117 distribution as a histogram with the observed trailing-period value 

118 overlaid as a vertical reference line. 

119 

120 Supported metrics: 

121 - ``"sharpe"`` (annualized, 252 periods/year) 

122 - ``"drawdown"`` (maximum drawdown, negative value) 

123 - ``"cagr"`` (annualized geometric return) 

124 

125 Args: 

126 n: Number of simulations per asset. Defaults to 1000. 

127 period: Number of observations in each simulation. Defaults to 252. 

128 metric: Metric to evaluate. One of ``"sharpe"``, ``"drawdown"``, 

129 or ``"cagr"``. 

130 title: Chart title. Defaults to ``"Monte Carlo Distribution"``. 

131 figsize: Optional figure ``(width, height)`` in pixels. 

132 backend: Renderer to use. Defaults to the ambient selection. 

133 

134 Returns: 

135 Figure: A histogram figure. 

136 

137 Raises: 

138 ValueError: If ``n`` or ``period`` is not a positive integer, or 

139 ``metric`` is not one of the supported names. 

140 

141 """ 

142 spec = montecarlo_distribution_spec(self._data, n, period, metric, title, figsize) 

143 return render(spec, backend)