AlanRex commited on
Commit
e45792c
·
verified ·
1 Parent(s): a15691d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -1
app.py CHANGED
@@ -118,6 +118,100 @@ def simple_statistical_predict(data, predict_days=5):
118
  change_pct = ((predicted_price - prices[-1]) / prices[-1]) * 100
119
  return {'predicted_price': predicted_price, 'change_pct': change_pct, 'confidence': max(0.6, 1 - volatility * 2)}
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  # 【修改 4】: 建立一個新的函式來處理 XGBoost 模型的輸入和輸出
122
  # 修正後的 advanced_xgboost_predict 函數
123
  def advanced_xgboost_predict(data, predict_days):
@@ -187,7 +281,7 @@ def get_prediction(data, predict_days=5):
187
  """
188
  if USE_ADVANCED_MODEL:
189
  print(f"模式: 進階XGBoost模型 | 預測天期: {predict_days}天")
190
- # 【修改 5】: 呼叫新的 XGBoost 橋接函式
191
  prediction = advanced_xgboost_predict(data, predict_days)
192
  # 如果進階模型預測失敗,則自動降級使用簡易模型
193
  if prediction is not None:
 
118
  change_pct = ((predicted_price - prices[-1]) / prices[-1]) * 100
119
  return {'predicted_price': predicted_price, 'change_pct': change_pct, 'confidence': max(0.6, 1 - volatility * 2)}
120
 
121
+ # 【新增】: 建立一個新的函式來處理 XGBoost 模型的輸入和輸出
122
+ def advanced_xgboost_predict(data, predict_days):
123
+ """
124
+ 【進階模型橋接函式】
125
+ - 準備 XGBoost 模型所需的輸入 DataFrame。
126
+ - 呼叫模型進行預測。
127
+ - 將模型的輸出格式轉換為主程式所需的格式。
128
+ """
129
+ if xgb_model is None or data.empty:
130
+ return None
131
+
132
+ try:
133
+ # 1. 準備模型所需的特徵 (Features)
134
+ print("正在準備 XGBoost 模型輸入特徵...")
135
+
136
+ # 獲取外部市場數據
137
+ external_symbols = {'DJI': '^DJI', 'NAS': '^IXIC', 'SOX': '^SOX', 'S&P_500': '^GSPC', 'TSM_ADR': 'TSM'}
138
+ df_external = pd.DataFrame(index=data.index)
139
+ for name, ticker in external_symbols.items():
140
+ ext_data = yf.download(ticker, start=data.index.min(), end=data.index.max(), progress=False)
141
+ df_external[name] = ext_data['Close']
142
+
143
+ # 合併所有數據並向前填充缺失值
144
+ input_df = pd.concat([data, df_external], axis=1)
145
+ input_df.ffill(inplace=True)
146
+
147
+ # 載入並合併景氣燈號和 PMI
148
+ df_climate = get_business_climate_data()
149
+ df_pmi = get_pmi_data()
150
+ input_df = pd.merge(input_df.reset_index(), df_climate, on='Date', how='left', suffixes=('', '_climate')).set_index('Date')
151
+ input_df = pd.merge(input_df.reset_index(), df_pmi, on='Date', how='left', suffixes=('', '_pmi')).set_index('Date')
152
+ input_df.rename(columns={'Index': 'business_climate', 'Index_pmi': 'PMI'}, inplace=True)
153
+ input_df[['business_climate', 'PMI']] = input_df[['business_climate', 'PMI']].ffill()
154
+
155
+ # 計算技術指標
156
+ input_df = calculate_technical_indicators(input_df) # 確保計算指標
157
+
158
+ # 新增新聞情緒分數 (此處為範例,假設從 predictor 取得)
159
+ # 注意: predictor.get_news_index() 僅返回一個值,需要對齊到時間序列
160
+ news_score = predictor.get_news_index() if predictor else 0
161
+ input_df['NEWS'] = news_score if news_score is not None else 0
162
+
163
+ # 新增 'rate' 欄位 (注意:此處為佔位符,您需要提供真實數據源)
164
+ input_df['rate'] = 1.75 # 範例:假設為固定利率,請替換為真實數據
165
+
166
+ # 欄位重新命名以符合模型訓練時的名稱
167
+ input_df.rename(columns={
168
+ 'Close': 'close', 'Volume': 'volume', 'MACD_Signal': 'MACDsign',
169
+ 'MACD_Histogram': 'MACDvol'
170
+ }, inplace=True)
171
+
172
+ # 確保所有模型需要的欄位都存在
173
+ columns_to_keep = [
174
+ 'close', 'volume', 'rate', 'DJI', 'NAS', 'SOX', 'S&P_500', 'TSM_ADR', 'NEWS',
175
+ 'RSI', 'MACD', 'MACDsign', 'MACDvol', 'K', 'D', '+DI', '-DI', 'ADX',
176
+ 'business_climate', 'PMI'
177
+ ]
178
+
179
+ final_input = input_df[columns_to_keep].tail(1)
180
+
181
+ if final_input.isnull().values.any():
182
+ print("警告: 準備好的輸入數據中存在缺失值,無法進行預測。")
183
+ return None
184
+
185
+ # 2. 呼叫模型預測
186
+ print("呼叫 XGBoost 模型進行預測...")
187
+ predictions = xgb_model.predict('xgboost_model', final_input)
188
+
189
+ # 3. 根據 predict_days 解析輸出
190
+ day_to_key_map = {
191
+ 1: 'Close_t0_pred', 5: 'Close_t5_pred', 10: 'Close_t10_pred', 20: 'Close_t20_pred'
192
+ }
193
+
194
+ prediction_key = day_to_key_map.get(predict_days)
195
+
196
+ if prediction_key is None or prediction_key not in predictions:
197
+ print(f"警告: XGBoost 模型沒有提供 {predict_days} 天的預測結果。")
198
+ return None
199
+
200
+ predicted_price = predictions[prediction_key]
201
+ current_price = data['Close'].iloc[-1]
202
+ change_pct = ((predicted_price - current_price) / current_price) * 100
203
+
204
+ # 4. 包裝成主程式所需的格式
205
+ return {
206
+ 'predicted_price': predicted_price,
207
+ 'change_pct': change_pct,
208
+ 'confidence': 0.95 # XGBoost模型通常不直接提供信心度,可給定一個較高的固定值
209
+ }
210
+ except Exception as e:
211
+ print(f"執行 XGBoost 預測時發生錯誤: {e}")
212
+ return None
213
+
214
+
215
  # 【修改 4】: 建立一個新的函式來處理 XGBoost 模型的輸入和輸出
216
  # 修正後的 advanced_xgboost_predict 函數
217
  def advanced_xgboost_predict(data, predict_days):
 
281
  """
282
  if USE_ADVANCED_MODEL:
283
  print(f"模式: 進階XGBoost模型 | 預測天期: {predict_days}天")
284
+ # 【修改】: 呼叫新的 XGBoost 橋接函式
285
  prediction = advanced_xgboost_predict(data, predict_days)
286
  # 如果進階模型預測失敗,則自動降級使用簡易模型
287
  if prediction is not None: