@@ -53,27 +53,27 @@ def create_bar_chart_figure(
5353) -> go .Figure :
5454 """Bar chart of average % return over different RPUR levels."""
5555 sorted_results = sorted (results .items (), key = lambda x : np .mean (x [1 ]))
56- averages = [np .mean (data ) for _ , data in sorted_results ]
56+ averages = [float ( np .mean (data ) ) for _ , data in sorted_results ]
5757 colors = _viridis_colors (averages )
58+ x_labels = [f"RPR { rpur :.2f} " for rpur , _ in sorted_results ]
5859
5960 min_result , max_result = min (averages ), max (averages )
6061 y_range = max_result - min_result
6162 y_tick_interval = y_range / 10 if y_range != 0 else 1
6263 y_ticks = np .arange (min_result , max_result + y_tick_interval , y_tick_interval )
6364
64- fig = go .Figure ()
65- for i , (rpur , data ) in enumerate (sorted_results ):
66- avg = averages [i ]
67- fig .add_trace (go .Bar (
68- x = [f"RPR { rpur :.2f} " ],
69- y = [avg ],
70- marker_color = colors [i ],
71- hoverinfo = "text" ,
72- hovertext = f"RPUR: { rpur :.2f} <br>Avg Return: { avg :.2f} %" ,
73- text = [f"{ avg :.2f} %" ],
74- textposition = "outside" ,
75- textfont = dict (size = 12 , color = "black" ),
76- ))
65+ # Single trace with per-bar colors so categorical axis works correctly
66+ fig = go .Figure (go .Bar (
67+ x = x_labels ,
68+ y = averages ,
69+ marker_color = colors ,
70+ hoverinfo = "text" ,
71+ hovertext = [f"RPUR: { rpur :.2f} <br>Avg Return: { avg :.2f} %"
72+ for (rpur , _ ), avg in zip (sorted_results , averages )],
73+ text = [f"{ avg :.2f} %" for avg in averages ],
74+ textposition = "outside" ,
75+ textfont = dict (size = 12 , color = "black" ),
76+ ))
7777
7878 fig .update_layout (
7979 title = "Average Percentage Return Over Different Levels of Return Per Unit Risk" ,
@@ -90,7 +90,7 @@ def create_bar_chart_figure(
9090 )
9191 fig .add_hline (y = 0 , line_dash = "dash" , line_color = "gray" )
9292
93- avg_return_for_annotation = np .mean (results [return_per_unit_risk_value ])
93+ avg_return_for_annotation = float ( np .mean (results [return_per_unit_risk_value ]) )
9494 _add_expected_return_annotation (
9595 fig ,
9696 x_label = f"RPR { return_per_unit_risk_value :.2f} " ,
@@ -121,6 +121,7 @@ def create_win_rate_vs_return_chart(
121121 avg_returns .append (float (np .mean (pct_returns )))
122122
123123 colors = _viridis_colors (avg_returns )
124+ x_labels = [f"WR { r :.0f} " for r in win_rates ]
124125 min_return , max_return = min (avg_returns ), max (avg_returns )
125126 y_range = max_return - min_return
126127 y_ticks = np .arange (
@@ -129,25 +130,25 @@ def create_win_rate_vs_return_chart(
129130 10 ,
130131 )
131132
132- fig = go . Figure ()
133- for i , ( rate , ret ) in enumerate ( zip ( win_rates , avg_returns )):
134- fig . add_trace ( go . Bar (
135- x = [ f" { rate } %" ] ,
136- y = [ ret ],
137- text = [ f" { ret :.2f } %" ],
138- textposition = "inside" if ret < 0 else "outside" ,
139- marker_color = colors [ i ] ,
140- textfont = dict ( color = "white" if ret < 0 else "black" , size = 12 ) ,
141- hoverinfo = "text" ,
142- hovertext = f"Win Rate: { rate } %<br>Return: { ret :.2f } %" ,
143- ))
133+ # Single trace with per-bar colors so categorical axis works correctly
134+ fig = go . Figure ( go . Bar (
135+ x = x_labels ,
136+ y = avg_returns ,
137+ text = [ f" { r :.2f } %" for r in avg_returns ],
138+ textposition = [ "inside" if r < 0 else "outside" for r in avg_returns ],
139+ marker_color = colors ,
140+ textfont = dict ( size = 12 ) ,
141+ hoverinfo = "text" ,
142+ hovertext = [ f"Win Rate: { wr :.0f } %<br>Return: { r :.2f } %"
143+ for wr , r in zip ( win_rates , avg_returns )] ,
144+ ))
144145
145146 fig .update_layout (
146147 title = "Average Percentage Return vs. Win Rate" ,
147148 xaxis = dict (
148149 title = "Win Rate (%)" ,
149- tickvals = win_rates ,
150- ticktext = [ f" { t } %" for t in win_rates ] ,
150+ tickangle = - 45 ,
151+ automargin = True ,
151152 ),
152153 yaxis = dict (
153154 title = "Average Percentage Return (%)" ,
@@ -166,7 +167,7 @@ def create_win_rate_vs_return_chart(
166167 avg_for_annotation = float (np .interp (win_rate_value , win_rates , avg_returns ))
167168 _add_expected_return_annotation (
168169 fig ,
169- x_label = f"{ win_rate_value } % " ,
170+ x_label = f"WR { win_rate_value :.0f } " ,
170171 y_value = avg_for_annotation ,
171172 y_range = y_range ,
172173 )
0 commit comments