Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -126,35 +126,69 @@ def advanced_xgboost_predict(data, predict_days):
|
|
| 126 |
- 呼叫模型進行預測。
|
| 127 |
- 將模型的輸出格式轉換為主程式所需的格式。
|
| 128 |
"""
|
| 129 |
-
if xgb_model is None or data.empty
|
| 130 |
return None
|
| 131 |
|
| 132 |
try:
|
| 133 |
-
# 1.
|
| 134 |
-
|
| 135 |
-
model_features = ['Open', 'High', 'Low', 'Volume']
|
| 136 |
|
| 137 |
-
#
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
-
|
| 147 |
-
|
|
|
|
| 148 |
|
| 149 |
# 2. 呼叫模型預測
|
| 150 |
-
|
|
|
|
| 151 |
|
| 152 |
# 3. 根據 predict_days 解析輸出
|
| 153 |
day_to_key_map = {
|
| 154 |
-
1: 'Close_t0_pred',
|
| 155 |
-
5: 'Close_t5_pred',
|
| 156 |
-
10: 'Close_t10_pred',
|
| 157 |
-
20: 'Close_t20_pred'
|
| 158 |
}
|
| 159 |
|
| 160 |
prediction_key = day_to_key_map.get(predict_days)
|
|
@@ -171,7 +205,7 @@ def advanced_xgboost_predict(data, predict_days):
|
|
| 171 |
return {
|
| 172 |
'predicted_price': predicted_price,
|
| 173 |
'change_pct': change_pct,
|
| 174 |
-
'confidence': 0.
|
| 175 |
}
|
| 176 |
except Exception as e:
|
| 177 |
print(f"執行 XGBoost 預測時發生錯誤: {e}")
|
|
|
|
| 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)
|
|
|
|
| 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}")
|