返回目錄
A
數據驅動投資分析:從基礎到量化交易 - 第 5 章
第5章 量化策略設計與回測
發布於 2026-03-04 18:46
# 第5章 量化策略設計與回測
## 5.1 何為「策略」
在數據驅動投資的語境下,\*策略\*不是一個靜態的規則集合,而是**可執行、可測量、可改進**的交易機制。它需要:
1. **訊號產生** – 從前面建立的模型或統計指標得到買賣訊號。
2. **風險控制** – 以止損、倉位限制或多因子分散等方式降低非預期損失。
3. **執行機制** – 考慮滑點、手續費、執行速度等實務條件。
4. **績效評估** – 使用 Sharpe、Sortino、最大回撤等指標來量化回報與風險。
本章將把這四個模塊串連起來,並示範如何在 Python 環境下實作、回測與優化。
## 5.2 策略設計流程
1. **定義投資目標**:\*高頻量化、日內套利、長期機會發掘\* 等。
2. **選擇市場與資產**:如 US Equities、ETF、外匯或期貨。
3. **建立訊號來源**:
- *技術指標*(如 MACD、RSI)
- *機器學習預測*(如 XGBoost 方向預測)
- *經濟事件*(利率公告、GDP 增速)
4. **設計風險管理規則**:
- 風險敞口上限(10% 個別、30% 風險因子)
- 止損、止盈、風險/報酬比率
5. **模擬執行(回測)**:結合歷史行情、滑點模型與手續費。
6. **績效評估與改進**:使用多指標、Walk‑Forward Validation、交叉驗證。
以下示範以 *日內均線交叉* 為簡單訊號,並加入 XGBoost 方向預測以提升訊號信噪比。
## 5.3 技術架構
| 模組 | 主要工具 | 說明 |
|------|----------|------|
| 數據獲取 | `yfinance`, `pandas-datareader` | 下載歷史行情、成交量 |
| 特徵工程 | `ta-lib`, `pandas` | 計算技術指標 |
| 訊號預測 | `xgboost` | 方向預測 |
| 回測引擎 | `backtrader`, `zipline` | 模擬交易、滑點 |
| 評估工具 | `pyfolio`, `quantstats` | 生成報表 |
## 5.4 範例:日內均線交叉 + XGBoost 預測
```python
import pandas as pd
import numpy as np
import yfinance as yf
from ta.trend import EMAIndicator
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import backtrader as bt
# 1. 下載資料
symbol = "AAPL"
start = "2020-01-01"
end = "2023-12-31"
price = yf.download(symbol, start=start, end=end, interval="1h")
# 2. 特徵工程
price['ema_20'] = EMAIndicator(price['Close'], window=20).ema_indicator()
price['ema_50'] = EMAIndicator(price['Close'], window=50).ema_indicator()
price['macd'] = price['ema_20'] - price['ema_50']
price['rsi'] = price['Close'].rolling(14).apply(lambda x: 100 - 100/(1+((x[-1]-x.mean())/x.std())))
# 3. 方向標籤(下個時間段收盤價相對於本期)
price['future_ret'] = price['Close'].shift(-1) - price['Close']
price['label'] = (price['future_ret'] > 0).astype(int)
# 4. XGBoost 訓練
features = ['ema_20','ema_50','macd','rsi']
X = price[features].fillna(0)
y = price['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, shuffle=False)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
model = XGBClassifier(n_estimators=200, learning_rate=0.05, max_depth=3)
model.fit(X_train, y_train)
price['pred'] = model.predict(scaler.transform(X))
# 5. 策略定義(Backtrader)
class MomentumStrategy(bt.Strategy):
params = dict(risk_per_trade=0.01)
def __init__(self):
self.dataclose = self.datas[0].close
self.ema20 = bt.indicators.ExponentialMovingAverage(self.datas[0], period=20)
self.ema50 = bt.indicators.ExponentialMovingAverage(self.datas[0], period=50)
self.pred = [] # 從 DataFrame 取預測訊號
def next(self):
i = len(self.datas[0]) - 1
if self.ema20[i] > self.ema50[i] and self.pred[i] == 1:
if not self.position:
size = (self.broker.getcash() * self.params.risk_per_trade) / self.dataclose[0]
self.buy(size=size)
elif self.ema20[i] < self.ema50[i] and self.pred[i] == 0:
if self.position:
self.close()
# 6. 初始化 Backtrader
cerebro = bt.Cerebro()
data = bt.feeds.PandasData(dataname=price, fromdate=pd.Timestamp(start), todate=pd.Timestamp(end))
cerebro.adddata(data)
cerebro.addstrategy(MomentumStrategy)
cerebro.broker.set_cash(100000)
cerebro.broker.setcommission(commission=0.001)
# 7. 回測
results = cerebro.run()
cerebro.plot()
```
> **注意**:上述示範僅為概念驗證,實務中需加入滑點模型、執行延遲測試以及多策略併發。
## 5.5 回測的七大陷阱
1. **前瞻性偏差(Look‑ahead bias)**:使用未來資訊進行特徵或訊號。解法:確保所有特徵都在「時間戳」之前。
2. **過度擬合(Over‑fitting)**:模型在訓練集表現極佳,但在測試集失敗。做法:使用 Walk‑Forward、交叉驗證、正則化。
3. **交易成本忽略**:滑點、手續費若未納入,績效高估。加上實際交易成本。
4. **資料稀疏**:低頻資料對高頻策略不適。確保資料頻率與策略匹配。
5. **市場微結構失真**:如深度資料缺失,影響滑點估算。使用 Level‑2 資料或第三方數據。
6. **風險模型不精確**:單純使用每日波動率無法捕捉波動聚集。考慮 GARCH、EWMA 等。
7. **策略穩定性**:不同時期、不同市場條件可能導致策略失效。進行多市場、不同時間段的驗證。
## 5.6 進階優化
### 5.6.1 超參數調整
利用 **Optuna** 或 **Ray Tune** 進行大規模超參數搜索,結合多目標(收益率、夏普比率、最大回撤)。
```python
import optuna
def objective(trial):
max_depth = trial.suggest_int('max_depth', 3, 10)
learning_rate = trial.suggest_loguniform('learning_rate', 0.001, 0.1)
n_estimators = trial.suggest_int('n_estimators', 100, 500)
# 重新訓練並評估回測績效
model = XGBClassifier(max_depth=max_depth, learning_rate=learning_rate, n_estimators=n_estimators)
# ...
return -sharpe # 目標最小化
study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=50)
```
### 5.6.2 風險平衡
採用 **Kelly** 或 **Equal‑Risk** 分配,將每筆交易的風險量化為「可接受最大虧損」而非固定倉位。
### 5.6.3 多策略組合
使用 **Markowitz Portfolio Optimization** 或 **Black‑Litterman** 把多個子策略的期望報酬與共變量組合,實現分散與風險控制。
## 5.7 真實環境部署
1. **執行平台**:雲端(AWS、GCP)或自建 EC2,使用 Docker 容器化。
2. **資料來源**:訂閱實時行情 API(如 IEX Cloud、Polygon)。
3. **滑點模擬**:使用 **VWAP**、**TWAP** 或實際委託書深度。
4. **監控**:實時寫入 **Prometheus**,用 Grafana 做 Dashboard;設定警報(失敗率、滑點異常)。
5. **自動化回測**:CI/CD pipeline,持續整合每次模型更新。
## 5.8 小結
- **策略不是模型**:模型僅產生訊號,完整策略還需風險管理、執行機制與績效評估。
- **回測是檢驗**:一套策略必須經過嚴謹的回測與現實成本模擬,才能確定其可行性。
- **迭代是關鍵**:市場在變,策略也須持續調整。建立「策略迭代週期」是長期成功的關鍵。
> **提示**:下章將深入探討如何把已驗證的策略實際部署到高頻交易環境,並介紹實時風險監控與自動化交易的架構設計。