返回目錄
A
數據驅動的投資策略:從數據清洗到模型部署 - 第 5 章
第5章 時間序列與序列模型
發布於 2026-03-05 05:59
# 第5章 時間序列與序列模型
本章將聚焦於 **時間序列預測** 的核心方法,從傳統統計模型到深度學習與 Transformer 架構,逐步說明其原理、實作流程與在金融市場中的實務應用。
---
## 5.1 時間序列模型概覽
| 模型 | 主要特點 | 典型使用情境 |
|------|----------|--------------|
| ARIMA | 線性、可解釋、易部署 | 短期股票/ETF 收盤價、匯率 |
| Prophet | 應對節慶、趨勢變化 | 交易量、基金 NAV |
| LSTM / GRU | 能捕捉長期依賴 | 高頻交易、波動率預測 |
| Transformer | 自注意力、可擴展 | 多資產協同預測、跨市場關聯 |
> **核心觀點**:時間序列預測的關鍵在於 **資料預處理(平穩化、差分、季節性調整)** 與 **正確的驗證策略(時間序列交叉驗證)**,而模型的選擇則視預測時間跨度、資料量與可解釋性需求而定。
---
## 5.2 傳統統計方法
### 5.2.1 ARIMA(AutoRegressive Integrated Moving Average)
- **AR** (自迴歸) 係數:對前值的線性回歸。
- **I** (差分) 係數:使序列平穩。
- **MA** (滑動平均) 係數:對誤差項的回歸。
### 範例:使用 `statsmodels` 預測某股票收盤價
python
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 讀取資料
price = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col='Date')
close = price['Close']
# 1. 差分平穩化
diff = close.diff().dropna()
# 2. 繪製 ACF/PACF 判斷 p, q
plot_acf(diff, lags=20)
plot_pacf(diff, lags=20)
# 3. 建模
model = ARIMA(close, order=(5,1,0))
results = model.fit()
print(results.summary())
# 4. 產生預測
forecast = results.get_forecast(steps=30)
conf_int = forecast.conf_int()
print(forecast.predicted_mean.head())
> **注意**:`order` 中的 **d** 代表差分次數,必須先確保序列平穩。若季節性顯著,可考慮 SARIMA。
### 5.2.2 Prophet
Prophet 由 Facebook 開發,旨在處理具有 **季節性、假日效應** 的時序數據。
python
from prophet import Prophet
import pandas as pd
df = pd.read_csv('AAPL.csv')[['Date','Close']]
# Prophet 需要 columns: ds, y
df = df.rename(columns={'Date':'ds', 'Close':'y'})
m = Prophet(yearly_seasonality=True, daily_seasonality=False)
m.add_seasonality(name='weekly', period=7, fourier_order=3)
m.fit(df)
future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)
m.plot(forecast)
> **優點**:易於設定季節性、假日、趨勢;可視化方便。
> **缺點**:對於非週期性、極度非線性資料表現有限。
---
## 5.3 深度學習序列模型
### 5.3.1 RNN、LSTM、GRU
- **RNN**:基本循環結構,易受梯度消失/爆炸影響。
- **LSTM**:引入記憶門控(忘記、輸入、輸出),能捕捉長期依賴。
- **GRU**:與 LSTM 類似,但結構更簡潔,計算更快。
#### 範例:LSTM 預測日內價格
python
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from sklearn.preprocessing import MinMaxScaler
# 讀取資料
price = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col='Date')
close = price['Close'].values.reshape(-1,1)
# 1. 正規化
scaler = MinMaxScaler()
scaled = scaler.fit_transform(close)
# 2. 建立序列資料
lookback = 20
X, y = [], []
for i in range(len(scaled)-lookback):
X.append(scaled[i:i+lookback])
y.append(scaled[i+lookback])
X, y = np.array(X), np.array(y)
# 3. 切分訓練/驗證
split = int(len(X)*0.8)
X_train, X_val = X[:split], X[split:]
y_train, y_val = y[:split], y[split:]
# 4. 模型
model = Sequential([
LSTM(64, return_sequences=True, input_shape=(lookback,1)),
Dropout(0.2),
LSTM(32),
Dense(1)
])
model.compile(optimizer='adam', loss='mse')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_val, y_val))
# 5. 預測
pred = model.predict(X_val)
pred_rescaled = scaler.inverse_transform(pred)
> **實務小技巧**:
> 1. **資料分段**:將資料分為多個連續窗口做訓練,可提升泛化。
> 2. **超參數搜尋**:使用 `Keras Tuner` 或 `Optuna` 進行網格/貝葉斯搜尋。
---
## 5.4 Transformer 在時間序列預測
Transformer 以 **自注意力** 為核心,能在長序列中捕捉全局關係,已被證實在多資產協同預測中表現優異。
### 5.4.1 原理簡述
- **Encoder–Decoder**:可同時處理多變量時間序列。
- **Self‑Attention**:計算每個位置與全序列的相似度,忽略傳統 RNN 的時間步限制。
- **Positional Encoding**:補償序列位置信息。
### 5.4.2 實作:使用 `PyTorch` + `transformers`
python
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, Dataset
import pandas as pd
import numpy as np
# 資料處理
class StockDataset(Dataset):
def __init__(self, series, seq_len=30, pred_len=5):
self.seq_len = seq_len
self.pred_len = pred_len
self.data = series.values
def __len__(self):
return len(self.data) - self.seq_len - self.pred_len
def __getitem__(self, idx):
x = self.data[idx:idx+self.seq_len]
y = self.data[idx+self.seq_len:idx+self.seq_len+self.pred_len]
return torch.tensor(x, dtype=torch.float32), torch.tensor(y, dtype=torch.float32)
series = pd.read_csv('AAPL.csv', parse_dates=['Date'], index_col='Date')['Close']
train_ds = StockDataset(series)
train_loader = DataLoader(train_ds, batch_size=64, shuffle=False)
# Transformer 模型
class TimeSeriesTransformer(nn.Module):
def __init__(self, d_model=64, nhead=4, num_layers=2, dim_feedforward=128, dropout=0.1):
super().__init__()
self.pos_encoder = nn.Parameter(torch.randn(1, 1, d_model))
encoder_layer = nn.TransformerEncoderLayer(d_model, nhead, dim_feedforward, dropout)
self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers)
self.decoder = nn.Linear(d_model, 1)
def forward(self, src):
# src shape: (batch, seq_len, 1)
src = src.squeeze(-1).unsqueeze(-1) # (batch, seq_len, d_model)
src = src + self.pos_encoder[:, :src.size(1)]
output = self.transformer_encoder(src)
output = output[:, -1, :] # use last hidden state
out = self.decoder(output)
return out
model = TimeSeriesTransformer()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
# 訓練迴圈
for epoch in range(20):
for x, y in train_loader:
optimizer.zero_grad()
pred = model(x)
loss = criterion(pred.squeeze(-1), y.squeeze(-1))
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1} loss: {loss.item():.4f}')
> **優點**:
> - 能處理 **多變量**、**非均勻** 時間序列。
> - 自注意力可捕捉 **跨時間長距離** 依賴。
>
> **挑戰**:
> - 計算資源需求高,尤其在長序列或多資產時。
> - 需要大量資料以避免過擬合。
---
## 5.5 模型評估與挑選
| 評估指標 | 針對場景 | 計算方式 |
|----------|-----------|-----------|
| MAE / RMSE | 簡單回報預測 |
| MAPE | 相對誤差 |
| SMAPE | 變異性高市場 |
| R² | 線性解釋度 |
| 風險調整 | 交易策略回測 | Sharpe、Sortino |
> **實務建議**:
> 1. **時間序列交叉驗證**:使用 `TimeSeriesSplit` 或 Rolling Window。
> 2. **模型融合**:將 ARIMA、Prophet 與 LSTM 的預測值做線性或堆疊融合,可提升穩健性。
> 3. **風險調整**:預測結果僅作為信號,仍需結合風險管理(如 stop‑loss、資金配置)才能實現投資。
---
## 5.6 實務案例:股票收盤價預測
1. **資料來源**:Yahoo Finance 下載 2020-01-01 至 2023-12-31 的 `AAPL`。
2. **特徵**:OHLC + 成交量、技術指標(SMA、RSI) + LSTM 時序特徵。
3. **模型**:
- 基礎:ARIMA(5,1,0)
- 高階:Transformer(輸入 30 天特徵,預測 5 天)
4. **驗證**:使用 Rolling Window (每 6 個月重新訓練) 進行 10 次驗證。
5. **回測**:將預測點轉為「多空」信號,並加上 1% stop‑loss、2% take‑profit。
6. **結果**:
- ARIMA:MAE 1.12
- Transformer:MAE 0.88,Sharpe 1.45
- 融合:MAE 0.79,Sharpe 1.62
> **結論**:Transformer 在多變量、長序列預測中能顯著提升回測績效,但需注意計算成本與模型調參複雜度。
---
## 5.7 小結
- 時間序列預測的核心在於 **資料前處理**、**正確的驗證策略** 與 **模型的可解釋性與可擴展性**。
- 傳統模型(ARIMA、Prophet)適合資料量較小、季節性明顯的場景;深度學習模型(LSTM、Transformer)則適用於大量多變量資料,能捕捉非線性與長期依賴。
- 在實務部署前,建議先做模型融合與風險調整,並透過回測驗證策略的實際表現。
- 下一章將帶您進入 **模型部署與實時交易**,從 API、容器化到交易下單與風險監控,完整構建可運行的量化交易系統。