Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -126,69 +126,35 @@ 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 |
-
|
| 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 |
-
#
|
| 159 |
-
|
| 160 |
-
|
| 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 |
-
|
| 187 |
-
predictions = xgb_model.predict('xgboost_model', final_input)
|
| 188 |
|
| 189 |
# 3. 根據 predict_days 解析輸出
|
| 190 |
day_to_key_map = {
|
| 191 |
-
1: 'Close_t0_pred',
|
|
|
|
|
|
|
|
|
|
| 192 |
}
|
| 193 |
|
| 194 |
prediction_key = day_to_key_map.get(predict_days)
|
|
@@ -205,7 +171,7 @@ def advanced_xgboost_predict(data, predict_days):
|
|
| 205 |
return {
|
| 206 |
'predicted_price': predicted_price,
|
| 207 |
'change_pct': change_pct,
|
| 208 |
-
'confidence': 0.
|
| 209 |
}
|
| 210 |
except Exception as e:
|
| 211 |
print(f"執行 XGBoost 預測時發生錯誤: {e}")
|
|
|
|
| 126 |
- 呼叫模型進行預測。
|
| 127 |
- 將模型的輸出格式轉換為主程式所需的格式。
|
| 128 |
"""
|
| 129 |
+
if xgb_model is None or data.empty or len(data) < 1:
|
| 130 |
return None
|
| 131 |
|
| 132 |
try:
|
| 133 |
+
# 1. 準備模型實際需要的特徵
|
| 134 |
+
# 根據錯誤訊息,模型只需要 'Open', 'High', 'Low', 'Volume'
|
| 135 |
+
model_features = ['Open', 'High', 'Low', 'Volume']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
+
# 檢查 yfinance 回傳的資料中是否存在這些欄位
|
| 138 |
+
if not all(feature in data.columns for feature in model_features):
|
| 139 |
+
print(f"錯誤: 輸入資料缺少必要欄位。需要 {model_features},但只找到 {list(data.columns)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
return None
|
| 141 |
|
| 142 |
+
# 選取最新一筆資料,並只保留模型需要的欄位
|
| 143 |
+
# yfinance 預設的欄位名稱 ('Open', 'High', etc.) 已符合模型需求
|
| 144 |
+
input_df = data[model_features].tail(1)
|
| 145 |
+
|
| 146 |
+
print(f"準備好的特徵欄位: {list(input_df.columns)}")
|
| 147 |
+
print(f"輸入模型的資料:\n{input_df}")
|
| 148 |
+
|
| 149 |
# 2. 呼叫模型預測
|
| 150 |
+
predictions = xgb_model.predict('xgboost_model', input_df)
|
|
|
|
| 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 |
return {
|
| 172 |
'predicted_price': predicted_price,
|
| 173 |
'change_pct': change_pct,
|
| 174 |
+
'confidence': 0.90 # 給定一個固定信心度
|
| 175 |
}
|
| 176 |
except Exception as e:
|
| 177 |
print(f"執行 XGBoost 預測時發生錯誤: {e}")
|