股價趨勢預測:用 Prophet 預測未來股價
技術指標和回測告訴我們「過去的表現」,但我們更想知道的是「未來會怎麼走」。這時候,我們需要時間序列預測來輔助判斷。
Prophet 股價預測實戰
import yfinance as yf
import pandas as pd
from prophet import Prophet
import matplotlib.pyplot as plt
# 下載資料(使用更多歷史資料)
df = yf.download("2330.TW", start="2018-01-01", end="2024-12-31")
close = df['Close']
# 準備 Prophet 資料格式
prophet_df = pd.DataFrame({
'ds': df.index,
'y': close.values
})
# 建立並訓練模型
model = Prophet(
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False,
changepoint_prior_scale=0.05,
seasonality_prior_scale=10.0
)
model.add_country_holidays(country_name='TW')
model.fit(prophet_df)
# 預測未來 90 天
future = model.make_future_dataframe(periods=90)
forecast = model.predict(future)
# 畫出預測
fig = model.plot(forecast)
plt.title('台積電 2330 股價預測(未來 90 天)')
plt.xlabel('日期')
plt.ylabel('股價')
plt.show()
# 趨勢分解
fig2 = model.plot_components(forecast)
plt.show()
只看未來預測部分
# 只顯示未來預測的部分
future_forecast = forecast[forecast['ds'] > df.index[-1]]
print("=== 未來 90 天股價預測 ===")
print(future_forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].head(10))
# 尋找預測中的最高點與最低點
max_price_idx = future_forecast['yhat'].idxmax()
min_price_idx = future_forecast['yhat'].idxmin()
print(f"\n預測最高點:{future_forecast.loc[max_price_idx, 'ds'].date()}")
print(f"預測最高價:{future_forecast.loc[max_price_idx, 'yhat']:.2f}")
print(f"預測最低點:{future_forecast.loc[min_price_idx, 'ds'].date()}")
print(f"預測最低價:{future_forecast.loc[min_price_idx, 'yhat']:.2f}")
預測漲跌方向準確度
預測「精確價格」很難,但預測「明天是漲還是跌」相對可行:
# 建立一個簡單的漲跌方向預測評估
prophet_df['direction'] = prophet_df['y'].diff().shift(-1).apply(
lambda x: 1 if x > 0 else 0
)
# 使用 Prophet 預測方向的邏輯
# 比較今天預測的 yhat 與昨天的 yhat
forecast['direction_pred'] = forecast['yhat'].diff().apply(
lambda x: 1 if x > 0 else 0
)
# 合併歷史資料
result = prophet_df.join(
forecast[['yhat', 'direction_pred']],
how='inner'
).dropna()
# 計算方向預測準確率
accuracy = (result['direction'] == result['direction_pred']).mean()
print(f"漲跌方向預測準確率: {accuracy*100:.1f}%")
實戰:多檔股票掃描儀
想同時監控多檔股票嗎?讓我們建立一個股票掃描儀:
# === 多股掃描儀 ===
watchlist = ["2330.TW", "2317.TW", "2454.TW", "TSLA", "AAPL", "MSFT"]
scan_results = []
for ticker in watchlist:
try:
# 下載資料
data = yf.download(ticker, start="2023-01-01", end="2024-12-31")
close = data['Close']
# 計算技術指標
ma5 = close.rolling(5).mean()
ma20 = close.rolling(20).mean()
current_price = close.iloc[-1]
current_ma5 = ma5.iloc[-1]
current_ma20 = ma20.iloc[-1]
# 判斷趨勢
trend = "上升" if current_ma5 > current_ma20 else "下降"
# 計算近期漲跌幅
return_1m = (close.iloc[-1] / close.iloc[-22] - 1) * 100
return_3m = (close.iloc[-1] / close.iloc[-66] - 1) * 100
scan_results.append({
'股票': ticker,
'收盤價': current_price,
'MA5': current_ma5,
'MA20': current_ma20,
'趨勢': trend,
'1個月漲跌': f"{return_1m:+.1f}%",
'3個月漲跌': f"{return_3m:+.1f}%"
})
except Exception as e:
print(f"{ticker}: 讀取失敗 - {e}")
# 顯示結果
result_df = pd.DataFrame(scan_results)
print("\n=== 股票掃描儀結果 ===")
print(result_df.to_string(index=False))
# 篩選出上升趨勢的股票
uptrend_stocks = result_df[result_df['趨勢'] == '上升']
print(f"\n上升趨勢股票: {len(uptrend_stocks)} 檔")
print(uptrend_stocks[['股票', '收盤價', '1個月漲跌']].to_string(index=False))
使用 Vibe Coding 建立掃描儀
🔥 【股票掃描儀詠唱範例】
「請幫我建立一個股票掃描儀:1. 讀取一個 watchlist.csv(包含股票代號清單)。2. 對每檔股票計算 MA10、MA30、MACD、RSI。3. 篩選出同時滿足以下條件的股票:MA10 > MA30(黃金交叉)、RSI 在 40-60 之間(未過熱)、MACD 柱狀圖翻正。4. 輸出一個表格:股票代號、價格、信號強度評分。5. 將結果儲存為 scan_result.csv。6. 畫出所有符合條件股票的價格走勢圖。」
本日總結
在本章中,你學到了:
- ✅ Prophet 股價預測:用時間序列模型預測股價趨勢
- ✅ 預測區間解讀:理解 yhat、yhat_lower、yhat_upper 的意義
- ✅ 漲跌方向預測:評估模型的判斷能力
- ✅ 股票掃描儀:一次掃描多檔股票的技術指標狀態
- ✅ 趨勢篩選:自動找出處於上升趨勢的股票
下一章,我們將學習風險管理——交易中最重要的一件事!
預測股價:可行但不要當成明牌
用 ML 預測股價是量化交易中最吸引人的話題,但也最容易誤解。沒有任何模型可以精準預測明天的股價——如果有的話,發明者早就默默發財而不是公開論文了。
Prophet 能預測什麼?
| 成分 | 說明 | 股價適用性 | |:----|:----|:---------| | 趨勢 | 長期上漲或下跌 | ✅ 部分可以(大盤長期向上) | | 季節性 | 固定週期波動 | ❌ 股價沒有明顯季節性 | | 假日效應 | 特定日期的影響 | ⚠️ 聖誕行情可能有效 |
Prophet 真正的強項是具有明顯趨勢和季節性的資料——例如銷售量、網站流量、溫度。
那量化交易用 ML 做什麼?
與其預測股價,ML 在量化交易中更務實的應用是:
| 應用 | 做法 | |:----|:----| | 情緒分析 | 分析新聞和社群媒體的情緒分數 | | 波動率預測 | 預測未來波動度來調整選擇權策略 | | 異常偵測 | 找出異常的交易行為或市場操縱 | | 特徵重要性 | 分析哪些因子對報酬最有預測力 |
下一章預告:風險管理
預測終究只是預測。下一章的風險管理才是交易中最重要的課題——確保你在預測錯誤時不會受傷。