eagle0504 commited on
Commit
2254e31
1 Parent(s): cc0389a

Update utils/ui_helper.py

Browse files
Files changed (1) hide show
  1. utils/ui_helper.py +159 -1
utils/ui_helper.py CHANGED
@@ -5,7 +5,7 @@ import plotly.graph_objects as go
5
  import pandas as pd
6
  from utils.helper import *
7
 
8
-
9
  def main_algo_trader():
10
  # Front-end Design
11
  st.set_page_config(layout="wide")
@@ -154,6 +154,164 @@ def main_algo_trader():
154
 
155
  st.plotly_chart(fig, use_container_width=True)
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  # Download
158
  st.download_button(
159
  label="Download data as CSV",
 
5
  import pandas as pd
6
  from utils.helper import *
7
 
8
+ # english
9
  def main_algo_trader():
10
  # Front-end Design
11
  st.set_page_config(layout="wide")
 
154
 
155
  st.plotly_chart(fig, use_container_width=True)
156
 
157
+ # Download
158
+ st.download_button(
159
+ label="Download data as CSV",
160
+ data=csv,
161
+ file_name=f'history_{end_date}.csv',
162
+ mime='text/csv',
163
+ )
164
+
165
+
166
+ # chinese
167
+ def main_algo_trader_chinese():
168
+ # Front-end Design
169
+ st.set_page_config(layout="wide")
170
+ st.write("# 欢迎来到算法交易!一个快速模拟平台👋")
171
+
172
+ with st.sidebar:
173
+ with st.expander("Expand/Collapse"):
174
+ st.markdown(
175
+ r"""
176
+ 以下应用程序是成长股策略的简单演示。为简单起见,我们假设我们的研究团队交给了一些股票。在这些股票池中,我们可以做到以下几点:
177
+ - 使用 `yfinance` 库实时下载股票数据(为了速度,请从时间框架 "1mo" 开始);
178
+ - 每个周期(时间框架是一个调整参数),我们通过持有前 n 只股票(n 可以是股票的前五分之一/四分之一)来平衡我们的投资组合(等权)。
179
+ """
180
+ )
181
+
182
+ # Main inputs
183
+ tickers = st.text_input(
184
+ "使用英文键入输入股票代码(以逗号分隔):",
185
+ "MSFT, AAPL, NVDA, GOOG, AMZN, META, LLY, AVGO, TSLA, JPM, V, WMT, UNH, MA, PG, HD, JNJ, ORCL, MRK, COST, ABBV, BAC, CRM, AMD, NFLX, ACN, ADBE, DIS, TMO, WFC, MCD, CSCO, ABT, QCOM, INTC, INTU, IBM, AMAT, CMCSA, AXP, PFE, NOW, AMGN, MU",
186
+ )
187
+ start_date = st.sidebar.date_input("开始日期", pd.to_datetime("2001-01-01"))
188
+ end_date = st.sidebar.date_input("结束日期", pd.to_datetime(datetime.now().strftime("%Y-%m-%d")))
189
+ time_frame = st.sidebar.selectbox(
190
+ "选择时间框架:",
191
+ [
192
+ "1mo",
193
+ "3mo",
194
+ ],
195
+ )
196
+ top_n = st.sidebar.number_input("选择前 n 支股票", min_value=1, value=3)
197
+ height_of_graph = st.sidebar.number_input("图的高度", min_value=500, value=750)
198
+
199
+ # Process inputs
200
+ tickers_list = [ticker.strip() for ticker in tickers.split(",")]
201
+
202
+ # Run analysis on button click
203
+ if st.button("运行分析"):
204
+ with st.spinner("下载数据并计算回报..."):
205
+ stock_data = download_stock_data(
206
+ tickers_list,
207
+ start_date.strftime("%Y-%m-%d"),
208
+ end_date.strftime("%Y-%m-%d"),
209
+ w=time_frame,
210
+ )
211
+ returns_data = create_portfolio_and_calculate_returns(stock_data, top_n)
212
+ benchmark_sharpe_ratio = (
213
+ returns_data["benchmark"].mean() / returns_data["benchmark"].std()
214
+ )
215
+ portfolio_sharpe_ratio = (
216
+ returns_data["portfolio_returns"].mean()
217
+ / returns_data["portfolio_returns"].std()
218
+ )
219
+
220
+ # Data for plotting
221
+ df = returns_data[
222
+ ["rolling_benchmark", "rolling_portfolio_returns", "portfolio_history"]
223
+ ]
224
+ df.index = pd.to_datetime(df.index, unit="ms")
225
+
226
+ # Create download file
227
+ @st.cache_data
228
+ def convert_df(df):
229
+ # IMPORTANT: Cache the conversion to prevent computation on every rerun
230
+ return df.to_csv().encode('utf-8')
231
+
232
+ csv = convert_df(df)
233
+
234
+ # Create plot
235
+ fig = go.Figure()
236
+ fig.add_trace(
237
+ go.Scatter(
238
+ x=df.index,
239
+ y=df["rolling_benchmark"],
240
+ mode="lines",
241
+ name="Rolling Benchmark",
242
+ )
243
+ )
244
+ fig.add_trace(
245
+ go.Scatter(
246
+ x=df.index,
247
+ y=df["rolling_portfolio_returns"],
248
+ mode="lines",
249
+ name="Rolling Portfolio Returns",
250
+ )
251
+ )
252
+
253
+ for date, stocks in df["portfolio_history"].items():
254
+ fig.add_shape(
255
+ type="line",
256
+ x0=date,
257
+ y0=0,
258
+ x1=date,
259
+ y1=0,
260
+ line=dict(color="RoyalBlue", width=1),
261
+ )
262
+ fig.add_annotation(
263
+ x=date,
264
+ y=0.5,
265
+ text=str(stocks),
266
+ showarrow=False,
267
+ yshift=10,
268
+ textangle=-90,
269
+ font=dict(size=15), # You can adjust the size as needed
270
+ )
271
+
272
+ # Calculate means and standard deviations
273
+ benchmark_mean = returns_data["benchmark"].mean()
274
+ benchmark_std = returns_data["benchmark"].std()
275
+ portfolio_mean = returns_data["portfolio_returns"].mean()
276
+ portfolio_std = returns_data["portfolio_returns"].std()
277
+
278
+ # Update title text with additional information
279
+ if time_frame == '1mo':
280
+ some_n_based_on_time_frame = 12
281
+ in_a_year = 1000*(1+portfolio_mean)**(some_n_based_on_time_frame)
282
+ in_50_years = 1000*(1+portfolio_mean)**(some_n_based_on_time_frame*50)
283
+ else:
284
+ some_n_based_on_time_frame = 4
285
+ in_a_year = 1000*(1+portfolio_mean)**(some_n_based_on_time_frame)
286
+ in_50_years = 1000*(1+portfolio_mean)**(some_n_based_on_time_frame*50)
287
+ title_text = (
288
+ f"Performance:<br>"
289
+ f"Benchmark Sharpe Ratio = {benchmark_sharpe_ratio:.3f}, "
290
+ f"Portfolio Sharpe Ratio = {portfolio_sharpe_ratio:.3f}, "
291
+ f"based on time frame: {time_frame}<br>"
292
+ f"Benchmark => Mean: {benchmark_mean:.4f}, Std: {benchmark_std:.4f}; "
293
+ f"Portfolio => Mean: {portfolio_mean:.4f}, Std: {portfolio_std:.4f}<br>"
294
+ f"---<br>"
295
+ f"This may or may not be a small number, let's check: <br>"
296
+ f"$1,000*(1+{portfolio_mean:.4f})^({some_n_based_on_time_frame})={in_a_year}, <br>"
297
+ f"$1,000*(1+{portfolio_mean:.4f})^({some_n_based_on_time_frame}*50)={in_50_years}."
298
+ )
299
+ curr_max_num = max(
300
+ df.rolling_benchmark.max(), df.rolling_portfolio_returns.max()
301
+ )
302
+ fig.update_layout(
303
+ title=title_text,
304
+ xaxis_title="Date",
305
+ yaxis_title="Value",
306
+ yaxis=dict(range=[0, curr_max_num * 1.1]),
307
+ legend=dict(
308
+ orientation="h", x=0.5, y=-0.4, xanchor="center", yanchor="bottom"
309
+ ),
310
+ height=height_of_graph,
311
+ )
312
+
313
+ st.plotly_chart(fig, use_container_width=True)
314
+
315
  # Download
316
  st.download_button(
317
  label="Download data as CSV",