QuantumLearner commited on
Commit
434dbc6
·
verified ·
1 Parent(s): 32ced33

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -73
app.py CHANGED
@@ -72,10 +72,10 @@ def plot_results(data, best_short_window, best_long_window, horizon_name, best_a
72
  buy_signals = data[data['positions'] == 2] # 2 indicates a Buy signal after a Sell
73
  sell_signals = data[data['positions'] == -2] # -2 indicates a Sell signal after a Buy
74
  fig.add_trace(go.Scatter(x=buy_signals.index, y=buy_signals['Close'], mode='markers',
75
- marker=dict(color='green', size=15, symbol='triangle-up'), # Increased size
76
  name=f'Buy Signal (Win Rate: {buy_accuracy:.2f})', hovertemplate='%{x|%Y-%m-%d}'))
77
  fig.add_trace(go.Scatter(x=sell_signals.index, y=sell_signals['Close'], mode='markers',
78
- marker=dict(color='red', size=15, symbol='triangle-down'), # Increased size
79
  name=f'Sell Signal (Win Rate: {sell_accuracy:.2f})', hovertemplate='%{x|%Y-%m-%d}'))
80
 
81
  # Set title and layout, including more detailed date formatting for x-axis
@@ -84,11 +84,11 @@ def plot_results(data, best_short_window, best_long_window, horizon_name, best_a
84
  xaxis_title='Date',
85
  yaxis_title='Price',
86
  xaxis=dict(
87
- tickformat="%b %Y", # Month and year format
88
- dtick="M1", # Set tick interval to every month
89
- tickangle=45, # Rotate the tick labels for better readability
90
  ),
91
- autosize=True # Enable autosizing
92
  )
93
  return fig
94
 
@@ -107,7 +107,7 @@ def plot_strategy_over_time(data, best_short_window, best_long_window):
107
  title='Strategy Accuracy Over Time',
108
  xaxis_title='Date',
109
  yaxis_title='Rolling Accuracy',
110
- autosize=True # Enable autosizing
111
  )
112
  return fig
113
 
@@ -118,9 +118,7 @@ st.set_page_config(layout="wide")
118
  with st.sidebar:
119
  st.header("Input Parameters")
120
 
121
-
122
  with st.expander("How to Use", expanded=False):
123
- #st.subheader("How to Use")
124
  st.write("""
125
  - Select the stock ticker.
126
  - Set the start and end dates.
@@ -155,7 +153,6 @@ This application optimizes a trading strategy based on the Hull Moving Average.
155
  """)
156
 
157
  with st.expander("Hull Moving Average Methodology", expanded=False):
158
-
159
  st.latex(r"""
160
  \text{HMA} = \text{WMA}(2 \times \text{WMA}(n/2) - \text{WMA}(n), \sqrt{n})
161
  """)
@@ -173,65 +170,76 @@ with st.expander("Hull Moving Average Methodology", expanded=False):
173
  st.write("""
174
  To read more about moving averages methodologies, visit [this link](https://entreprenerdly.com/top-36-moving-averages-methods-for-stock-prices-in-python/).
175
  """)
176
-
177
  # Main application logic
178
  if run_button:
179
- if 'data' not in st.session_state or st.session_state.get('ticker') != ticker or st.session_state.get('start_date') != start_date or st.session_state.get('end_date') != end_date:
180
- st.session_state['data'] = yf.download(ticker, start=start_date, end=end_date)
181
- st.session_state['ticker'] = ticker
182
- st.session_state['start_date'] = start_date
183
- st.session_state['end_date'] = end_date
184
-
185
- data = st.session_state['data']
186
-
187
- # Cache optimization results for each horizon
188
- if f'{st.session_state.horizon_page}_results' not in st.session_state:
189
- st.session_state[f'{st.session_state.horizon_page}_results'] = optimize_hma(data, selected_horizon['short_windows'], selected_horizon['long_windows'], selected_horizon['buy_threshold'], selected_horizon['sell_threshold'])
190
-
191
- # Unpack the results from the session state
192
- best_params, best_accuracy, results_df = st.session_state[f'{st.session_state.horizon_page}_results']
193
- best_short_window, best_long_window, buy_accuracy, sell_accuracy = best_params
194
-
195
- # Display results
196
- st.write(f"**{st.session_state.horizon_page} Horizon - Best Short HMA**: {best_short_window}, **Best Long HMA**: {best_long_window}, **Best Accuracy**: {best_accuracy:.2f}")
197
- st.write(f"**Buy Win Rate**: {buy_accuracy:.2f}, **Sell Win Rate**: {sell_accuracy:.2f}")
198
-
199
- # Plot results within a container to limit the height
200
- with st.container():
201
- fig = plot_results(data, best_short_window, best_long_window, st.session_state.horizon_page, best_accuracy, buy_accuracy, sell_accuracy)
202
- st.plotly_chart(fig, use_container_width=True, height=600) # Specify height here
203
-
204
- # Plot strategy performance over time within a container to limit the height
205
- st.write("Strategy Performance Over Time")
206
- with st.container():
207
- strategy_fig = plot_strategy_over_time(data, best_short_window, best_long_window)
208
- st.plotly_chart(strategy_fig, use_container_width=True, height=400) # Specify height here
209
-
210
- # Display heatmap of accuracy with annotations
211
- st.write(f"{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations")
212
- heatmap_df = results_df.pivot(index='Short_HMA', columns='Long_HMA', values='Accuracy')
213
-
214
- # Create the heatmap with annotations
215
- heatmap_fig = go.Figure(data=go.Heatmap(
216
- z=heatmap_df.values,
217
- x=heatmap_df.columns,
218
- y=heatmap_df.index,
219
- colorscale='YlGnBu',
220
- text=heatmap_df.values, # Use the values for the text inside the heatmap
221
- texttemplate="%{text:.2f}", # Format text with two decimal places
222
- hovertemplate="Short HMA: %{y}<br>Long HMA: %{x}<br>Accuracy: %{text:.2f}<extra></extra>",
223
- showscale=True
224
- ))
225
-
226
- heatmap_fig.update_layout(
227
- title=f'{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations',
228
- xaxis_title='Long HMA',
229
- yaxis_title='Short HMA',
230
- autosize=True # Enable autosizing
231
- )
232
 
233
- with st.container():
234
- st.plotly_chart(heatmap_fig, use_container_width=True, height=600) # Specify height here
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
  # Re-display the results if they exist and user switches pages without re-running
237
  else:
@@ -247,13 +255,13 @@ else:
247
  # Plot results within a container to limit the height
248
  with st.container():
249
  fig = plot_results(st.session_state['data'], best_short_window, best_long_window, st.session_state.horizon_page, best_accuracy, buy_accuracy, sell_accuracy)
250
- st.plotly_chart(fig, use_container_width=True, height=600) # Specify height here
251
 
252
  # Plot strategy performance over time within a container to limit the height
253
  st.write("Strategy Performance Over Time")
254
  with st.container():
255
  strategy_fig = plot_strategy_over_time(st.session_state['data'], best_short_window, best_long_window)
256
- st.plotly_chart(strategy_fig, use_container_width=True, height=400) # Specify height here
257
 
258
  # Display heatmap of accuracy with annotations
259
  st.write(f"{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations")
@@ -265,8 +273,8 @@ else:
265
  x=heatmap_df.columns,
266
  y=heatmap_df.index,
267
  colorscale='YlGnBu',
268
- text=heatmap_df.values, # Use the values for the text inside the heatmap
269
- texttemplate="%{text:.2f}", # Format text with two decimal places
270
  hovertemplate="Short HMA: %{y}<br>Long HMA: %{x}<br>Accuracy: %{text:.2f}<extra></extra>",
271
  showscale=True
272
  ))
@@ -275,12 +283,11 @@ else:
275
  title=f'{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations',
276
  xaxis_title='Long HMA',
277
  yaxis_title='Short HMA',
278
- autosize=True # Enable autosizing
279
  )
280
 
281
  with st.container():
282
- st.plotly_chart(heatmap_fig, use_container_width=True, height=600) # Specify height here
283
-
284
 
285
  hide_streamlit_style = """
286
  <style>
 
72
  buy_signals = data[data['positions'] == 2] # 2 indicates a Buy signal after a Sell
73
  sell_signals = data[data['positions'] == -2] # -2 indicates a Sell signal after a Buy
74
  fig.add_trace(go.Scatter(x=buy_signals.index, y=buy_signals['Close'], mode='markers',
75
+ marker=dict(color='green', size=15, symbol='triangle-up'),
76
  name=f'Buy Signal (Win Rate: {buy_accuracy:.2f})', hovertemplate='%{x|%Y-%m-%d}'))
77
  fig.add_trace(go.Scatter(x=sell_signals.index, y=sell_signals['Close'], mode='markers',
78
+ marker=dict(color='red', size=15, symbol='triangle-down'),
79
  name=f'Sell Signal (Win Rate: {sell_accuracy:.2f})', hovertemplate='%{x|%Y-%m-%d}'))
80
 
81
  # Set title and layout, including more detailed date formatting for x-axis
 
84
  xaxis_title='Date',
85
  yaxis_title='Price',
86
  xaxis=dict(
87
+ tickformat="%b %Y",
88
+ dtick="M1",
89
+ tickangle=45,
90
  ),
91
+ autosize=True
92
  )
93
  return fig
94
 
 
107
  title='Strategy Accuracy Over Time',
108
  xaxis_title='Date',
109
  yaxis_title='Rolling Accuracy',
110
+ autosize=True
111
  )
112
  return fig
113
 
 
118
  with st.sidebar:
119
  st.header("Input Parameters")
120
 
 
121
  with st.expander("How to Use", expanded=False):
 
122
  st.write("""
123
  - Select the stock ticker.
124
  - Set the start and end dates.
 
153
  """)
154
 
155
  with st.expander("Hull Moving Average Methodology", expanded=False):
 
156
  st.latex(r"""
157
  \text{HMA} = \text{WMA}(2 \times \text{WMA}(n/2) - \text{WMA}(n), \sqrt{n})
158
  """)
 
170
  st.write("""
171
  To read more about moving averages methodologies, visit [this link](https://entreprenerdly.com/top-36-moving-averages-methods-for-stock-prices-in-python/).
172
  """)
173
+
174
  # Main application logic
175
  if run_button:
176
+ try:
177
+ if 'data' not in st.session_state or st.session_state.get('ticker') != ticker or st.session_state.get('start_date') != start_date or st.session_state.get('end_date') != end_date:
178
+ data = yf.download(ticker, start=start_date, end=end_date, auto_adjust=False)
179
+ if isinstance(data.columns, pd.MultiIndex):
180
+ data.columns = data.columns.get_level_values(0)
181
+ if data.empty:
182
+ raise ValueError(f"No data retrieved for {ticker}")
183
+ if len(data) < max(selected_horizon['short_windows']) + max(selected_horizon['long_windows']):
184
+ raise ValueError(f"Insufficient data points for {ticker}. Need at least {max(selected_horizon['short_windows']) + max(selected_horizon['long_windows'])} days.")
185
+ st.session_state['data'] = data
186
+ st.session_state['ticker'] = ticker
187
+ st.session_state['start_date'] = start_date
188
+ st.session_state['end_date'] = end_date
189
+
190
+ data = st.session_state['data']
191
+
192
+ # Cache optimization results for each horizon
193
+ if f'{st.session_state.horizon_page}_results' not in st.session_state:
194
+ st.session_state[f'{st.session_state.horizon_page}_results'] = optimize_hma(data, selected_horizon['short_windows'], selected_horizon['long_windows'], selected_horizon['buy_threshold'], selected_horizon['sell_threshold'])
195
+
196
+ # Unpack the results from the session state
197
+ best_params, best_accuracy, results_df = st.session_state[f'{st.session_state.horizon_page}_results']
198
+ best_short_window, best_long_window, buy_accuracy, sell_accuracy = best_params
199
+
200
+ # Display results
201
+ st.write(f"**{st.session_state.horizon_page} Horizon - Best Short HMA**: {best_short_window}, **Best Long HMA**: {best_long_window}, **Best Accuracy**: {best_accuracy:.2f}")
202
+ st.write(f"**Buy Win Rate**: {buy_accuracy:.2f}, **Sell Win Rate**: {sell_accuracy:.2f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
+ # Plot results within a container to limit the height
205
+ with st.container():
206
+ fig = plot_results(data, best_short_window, best_long_window, st.session_state.horizon_page, best_accuracy, buy_accuracy, sell_accuracy)
207
+ st.plotly_chart(fig, use_container_width=True, height=600)
208
+
209
+ # Plot strategy performance over time within a container to limit the height
210
+ st.write("Strategy Performance Over Time")
211
+ with st.container():
212
+ strategy_fig = plot_strategy_over_time(data, best_short_window, best_long_window)
213
+ st.plotly_chart(strategy_fig, use_container_width=True, height=400)
214
+
215
+ # Display heatmap of accuracy with annotations
216
+ st.write(f"{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations")
217
+ heatmap_df = results_df.pivot(index='Short_HMA', columns='Long_HMA', values='Accuracy')
218
+
219
+ # Create the heatmap with annotations
220
+ heatmap_fig = go.Figure(data=go.Heatmap(
221
+ z=heatmap_df.values,
222
+ x=heatmap_df.columns,
223
+ y=heatmap_df.index,
224
+ colorscale='YlGnBu',
225
+ text=heatmap_df.values,
226
+ texttemplate="%{text:.2f}",
227
+ hovertemplate="Short HMA: %{y}<br>Long HMA: %{x}<br>Accuracy: %{text:.2f}<extra></extra>",
228
+ showscale=True
229
+ ))
230
+
231
+ heatmap_fig.update_layout(
232
+ title=f'{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations',
233
+ xaxis_title='Long HMA',
234
+ yaxis_title='Short HMA',
235
+ autosize=True
236
+ )
237
+
238
+ with st.container():
239
+ st.plotly_chart(heatmap_fig, use_container_width=True, height=600)
240
+
241
+ except Exception as e:
242
+ st.error(f"An error occurred while running the analysis: {e}")
243
 
244
  # Re-display the results if they exist and user switches pages without re-running
245
  else:
 
255
  # Plot results within a container to limit the height
256
  with st.container():
257
  fig = plot_results(st.session_state['data'], best_short_window, best_long_window, st.session_state.horizon_page, best_accuracy, buy_accuracy, sell_accuracy)
258
+ st.plotly_chart(fig, use_container_width=True, height=600)
259
 
260
  # Plot strategy performance over time within a container to limit the height
261
  st.write("Strategy Performance Over Time")
262
  with st.container():
263
  strategy_fig = plot_strategy_over_time(st.session_state['data'], best_short_window, best_long_window)
264
+ st.plotly_chart(strategy_fig, use_container_width=True, height=400)
265
 
266
  # Display heatmap of accuracy with annotations
267
  st.write(f"{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations")
 
273
  x=heatmap_df.columns,
274
  y=heatmap_df.index,
275
  colorscale='YlGnBu',
276
+ text=heatmap_df.values,
277
+ texttemplate="%{text:.2f}",
278
  hovertemplate="Short HMA: %{y}<br>Long HMA: %{x}<br>Accuracy: %{text:.2f}<extra></extra>",
279
  showscale=True
280
  ))
 
283
  title=f'{st.session_state.horizon_page} Horizon: Accuracy Heatmap of HMA Combinations',
284
  xaxis_title='Long HMA',
285
  yaxis_title='Short HMA',
286
+ autosize=True
287
  )
288
 
289
  with st.container():
290
+ st.plotly_chart(heatmap_fig, use_container_width=True, height=600)
 
291
 
292
  hide_streamlit_style = """
293
  <style>