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

16 statements  

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

1"""Periodic-return bar charts and the monthly-return heatmap.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, Literal, overload 

6 

7from .._render import render 

8from .._specs import ( 

9 daily_returns_spec, 

10 monthly_heatmap_spec, 

11 monthly_returns_spec, 

12 yearly_returns_spec, 

13) 

14 

15if TYPE_CHECKING: 

16 from matplotlib.figure import Figure as MplFigure 

17 from plotly.graph_objects import Figure as PlotlyFigure 

18 

19 from jquantstats._protocol import DataLike 

20 

21 from .._backend import Backend 

22 from .._render import Figure 

23 

24 

25class _PeriodicPlotsMixin: 

26 """Daily/monthly/yearly bar charts and the monthly heatmap for :class:`DataPlots`.""" 

27 

28 __slots__ = () 

29 

30 _data: DataLike 

31 

32 @overload 

33 def daily_returns(self, title: str = ..., *, backend: Literal["plotly"] | None = ...) -> PlotlyFigure: ... 

34 

35 @overload 

36 def daily_returns(self, title: str = ..., *, backend: Literal["matplotlib"]) -> MplFigure: ... 

37 

38 def daily_returns(self, title: str = "Daily Returns", *, backend: Backend | None = None) -> Figure: 

39 """Daily returns as a bar chart. 

40 

41 Each bar is coloured green for positive returns and red for negative 

42 returns. When multiple assets are present each asset gets its own 

43 trace in the palette colour with opacity used for positive/negative 

44 differentiation. 

45 

46 Args: 

47 title: Chart title. Defaults to ``"Daily Returns"``. 

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

49 

50 Returns: 

51 Figure: A bar chart. 

52 

53 """ 

54 return render(daily_returns_spec(self._data, title=title), backend) 

55 

56 @overload 

57 def yearly_returns( 

58 self, title: str = ..., compounded: bool = ..., *, backend: Literal["plotly"] | None = ... 

59 ) -> PlotlyFigure: ... 

60 

61 @overload 

62 def yearly_returns( 

63 self, title: str = ..., compounded: bool = ..., *, backend: Literal["matplotlib"] 

64 ) -> MplFigure: ... 

65 

66 def yearly_returns( 

67 self, 

68 title: str = "Yearly Returns", 

69 compounded: bool = True, 

70 *, 

71 backend: Backend | None = None, 

72 ) -> Figure: 

73 """Annual compounded (or summed) returns as a grouped bar chart. 

74 

75 Args: 

76 title: Chart title. Defaults to ``"Yearly Returns"``. 

77 compounded: Compound returns within each year. Defaults to True. 

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

79 

80 Returns: 

81 Figure: A grouped bar chart. 

82 

83 """ 

84 return render(yearly_returns_spec(self._data, title=title, compounded=compounded), backend) 

85 

86 @overload 

87 def monthly_returns( 

88 self, title: str = ..., compounded: bool = ..., *, backend: Literal["plotly"] | None = ... 

89 ) -> PlotlyFigure: ... 

90 

91 @overload 

92 def monthly_returns( 

93 self, title: str = ..., compounded: bool = ..., *, backend: Literal["matplotlib"] 

94 ) -> MplFigure: ... 

95 

96 def monthly_returns( 

97 self, 

98 title: str = "Monthly Returns", 

99 compounded: bool = True, 

100 *, 

101 backend: Backend | None = None, 

102 ) -> Figure: 

103 """Monthly compounded (or summed) returns as a bar chart. 

104 

105 Args: 

106 title: Chart title. Defaults to ``"Monthly Returns"``. 

107 compounded: Compound returns within each month. Defaults to True. 

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

109 

110 Returns: 

111 Figure: A bar chart. 

112 

113 """ 

114 return render(monthly_returns_spec(self._data, title=title, compounded=compounded), backend) 

115 

116 @overload 

117 def monthly_heatmap( 

118 self, 

119 title: str = ..., 

120 compounded: bool = ..., 

121 asset: str | None = ..., 

122 *, 

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

124 ) -> PlotlyFigure: ... 

125 

126 @overload 

127 def monthly_heatmap( 

128 self, 

129 title: str = ..., 

130 compounded: bool = ..., 

131 asset: str | None = ..., 

132 *, 

133 backend: Literal["matplotlib"], 

134 ) -> MplFigure: ... 

135 

136 def monthly_heatmap( 

137 self, 

138 title: str = "Monthly Returns Heatmap", 

139 compounded: bool = True, 

140 asset: str | None = None, 

141 *, 

142 backend: Backend | None = None, 

143 ) -> Figure: 

144 """Monthly returns calendar heatmap (year x month). 

145 

146 One heatmap is produced per call for a single asset. Green cells 

147 indicate positive months; red cells indicate negative months. 

148 

149 Args: 

150 title: Chart title. Defaults to ``"Monthly Returns Heatmap"``. 

151 compounded: Compound intra-month returns. Defaults to True. 

152 asset: Asset column name to display. Defaults to the first 

153 non-date column in the dataset. 

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

155 

156 Returns: 

157 Figure: A calendar heatmap. 

158 

159 """ 

160 spec = monthly_heatmap_spec(self._data, title=title, compounded=compounded, asset=asset) 

161 return render(spec, backend)