AlanRex commited on
Commit
c36e155
·
verified ·
1 Parent(s): a8ab318

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -11
app.py CHANGED
@@ -590,22 +590,25 @@ app.layout = html.Div([
590
  })
591
  ])
592
 
593
- # 台指期獨立預測回調函數 (新版本)
594
  @callback(
595
- Output('taiex-prediction', 'children'),
596
- [Input('taiex-predict-button', 'n_clicks')]
 
597
  )
598
  def update_taiex_prediction(n_clicks):
599
  """
600
  這個回調函數使用新匯入的 StockPredictor 類別來執行預測。
601
- 它會自動抓取最新資料作為模型的輸入。
602
  """
603
  if not n_clicks or not stock_predictor:
604
- return html.Div("請點擊按鈕以載入預測結果。", style={'text-align': 'center', 'margin-top': '20px'})
605
-
 
606
  try:
607
- # 使用 yfinance 抓取最新的台指期 (^TWII) 資料作為預測輸入
608
- latest_data = yf.download('^TWII', period='5d', interval='1d')
 
609
 
610
  if latest_data.empty:
611
  raise ValueError("無法取得最新的台指期資料。")
@@ -614,17 +617,54 @@ def update_taiex_prediction(n_clicks):
614
  last_date = latest_data.index[-1]
615
 
616
  # 呼叫預測器物件的 predict 方法
617
- # predictor_logic.py 會自動從 historical_df 中找到此日期前一筆數據進行預測
618
  predicted_price = stock_predictor.predict(last_date.strftime('%Y-%m-%d'))
619
 
620
- return html.Div([
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  html.P("【XGBoost 模型預測】", style={'font-size': '1.5em', 'font-weight': 'bold', 'color': '#28a745'}),
622
  html.P(f"最後已知日期:{last_date.strftime('%Y-%m-%d')}", style={'font-size': '1.2em', 'font-weight': 'bold'}),
623
  html.P(f"預測隔日收盤價:{predicted_price:.2f}", style={'font-size': '1.5em', 'font-weight': 'bold', 'color': '#17a2b8'})
624
  ], style={'text-align': 'center', 'margin-top': '20px'})
625
 
 
 
626
  except (ValueError, IndexError) as e:
627
- return html.Div(f"預測失敗:{e}", style={'text-align': 'center', 'margin-top': '20px', 'color': 'red'})
628
 
629
 
630
  # --- 主要修改處:計算預測路徑 ---
 
590
  })
591
  ])
592
 
593
+ # 台指期獨立預測回調函數
594
  @callback(
595
+ [dash.dependencies.Output('taiex-prediction-results', 'children'),
596
+ dash.dependencies.Output('taiex-prediction-chart', 'figure')],
597
+ [dash.dependencies.Input('taiex-predict-button', 'n_clicks')]
598
  )
599
  def update_taiex_prediction(n_clicks):
600
  """
601
  這個回調函數使用新匯入的 StockPredictor 類別來執行預測。
602
+ 它會自動抓取最新資料作為模型的輸入,並同時生成預測結果和圖表。
603
  """
604
  if not n_clicks or not stock_predictor:
605
+ # 由於需要返回兩個值 (文字和圖表),當沒有點擊時,回傳空值或預設值
606
+ return html.Div("請點擊按鈕以載入預測結果。", style={'text-align': 'center', 'margin-top': '20px'}), go.Figure()
607
+
608
  try:
609
+ # 使用 yfinance 抓取最新的台指期 (^TWII) 資料
610
+ # 抓取 60 天的資料以提供足夠的圖表背景
611
+ latest_data = yf.download('^TWII', period='60d', interval='1d')
612
 
613
  if latest_data.empty:
614
  raise ValueError("無法取得最新的台指期資料。")
 
617
  last_date = latest_data.index[-1]
618
 
619
  # 呼叫預測器物件的 predict 方法
 
620
  predicted_price = stock_predictor.predict(last_date.strftime('%Y-%m-%d'))
621
 
622
+ # --- 繪製預測圖表 ---
623
+
624
+ # 建立一個 Plotly 圖表物件
625
+ fig = go.Figure()
626
+
627
+ # 添加歷史收盤價
628
+ fig.add_trace(go.Scatter(
629
+ x=latest_data.index,
630
+ y=latest_data['Close'],
631
+ mode='lines',
632
+ name='歷史收盤價',
633
+ line=dict(color='royalblue', width=2)
634
+ ))
635
+
636
+ # 添加預測點
637
+ fig.add_trace(go.Scatter(
638
+ x=[last_date + pd.Timedelta(days=1)],
639
+ y=[predicted_price],
640
+ mode='markers+text',
641
+ name='預測價格',
642
+ text=[f'{predicted_price:.2f}'],
643
+ textposition='top center',
644
+ marker=dict(size=10, color='red')
645
+ ))
646
+
647
+ # 更新圖表佈局
648
+ fig.update_layout(
649
+ title='台指期歷史價格與預測結果',
650
+ xaxis_title='日期',
651
+ yaxis_title='收盤價',
652
+ template='plotly_white',
653
+ hovermode='x unified'
654
+ )
655
+
656
+ # --- 準備文字結果 ---
657
+
658
+ result_div = html.Div([
659
  html.P("【XGBoost 模型預測】", style={'font-size': '1.5em', 'font-weight': 'bold', 'color': '#28a745'}),
660
  html.P(f"最後已知日期:{last_date.strftime('%Y-%m-%d')}", style={'font-size': '1.2em', 'font-weight': 'bold'}),
661
  html.P(f"預測隔日收盤價:{predicted_price:.2f}", style={'font-size': '1.5em', 'font-weight': 'bold', 'color': '#17a2b8'})
662
  ], style={'text-align': 'center', 'margin-top': '20px'})
663
 
664
+ return result_div, fig
665
+
666
  except (ValueError, IndexError) as e:
667
+ return html.Div(f"預測失敗:{e}", style={'text-align': 'center', 'margin-top': '20px', 'color': 'red'}), go.Figure()
668
 
669
 
670
  # --- 主要修改處:計算預測路徑 ---