返回目錄
A
投資智慧:數據驅動的投資組合管理實務 - 第 3 章
第 3 章 數據驅動的投資策略
發布於 2026-03-01 05:45
# 第 3 章 數據驅動的投資策略
本章將帶領讀者從「資料」到「策略」的完整流程,說明如何運用資料科學工具將金融市場資訊轉化為可執行的投資決策。章節結構如下:
1. 資料蒐集與儲存
2. 資料清理與前處理
3. 特徵工程與因子構造
4. 因子投資策略
5. 長短期策略設計
6. 市場時序模型
7. 風險控制與績效評估
8. 實務案例
---
## 3.1 資料蒐集與儲存
| 來源 | 資料頻率 | 主要內容 | 取得方式 |
|------|----------|----------|-----------|
| Yahoo Finance | 日頻、週頻、月頻 | 內地、海外股價、指數、ETF、期貨、ETF分紅 | `yfinance` 套件 |
| Quandl | 日頻、週頻、月頻 | 宏觀經濟、國際貿易、基金持股 | `quandl` API |
| FRED | 日頻、月頻、季頻 | 經濟指標、利率、失業率 | `fredapi` |
| CRSP/Compustat | 日頻、月頻、年頻 | 企業財報、股價、行業分類 | 付費訂閱 |
| 交易所 API | 交易日頻 | 行情、成交量、深度 | 交易所開放 API |
### 3.1.1 建議儲存方案
- **關聯式資料庫(PostgreSQL)**:適合結構化、關聯性高的資料。
- **時序資料庫(TimescaleDB)**:可自動分區、支援高頻資料。
- **雲端資料湖(AWS S3 / GCP BigQuery)**:用於大規模歷史資料備份。
- **資料管道(Airflow / Prefect)**:自動化 ETL、資料更新。
## 3.2 資料清理與前處理
資料品質直接影響因子模型的穩健性,以下為常見清理步驟:
1. **時間戳一致化**:轉換為 UTC 時間,統一時區。
2. **缺失值處理**:
- 小量缺失:前向/後向填補。
- 大量缺失:剔除該資產或使用插值(Spline、LOESS)。
3. **價格調整**:考慮拆股、配股、股息調整。
4. **滾動窗口校正**:保證每個窗口內的交易日數量足夠。
5. **去除極端離群值**:使用 3σ 限制或 IQR 方法。
6. **數據一致性檢查**:驗證相同標的在不同來源之間的報酬差異。
python
import pandas as pd
import yfinance as yf
# 下載 AAPL、MSFT
ticker = yf.download(['AAPL', 'MSFT'], start='2015-01-01', end='2024-01-01')
# 只取 Adj Close
price = ticker['Adj Close']
# 計算日報酬
ret = price.pct_change().dropna()
# 前向填補缺失值
ret.fillna(method='ffill', inplace=True)
## 3.3 特徵工程與因子構造
### 3.3.1 因子類型
| 類別 | 典型因子 | 公式(示例) |
|------|----------|--------------|
| **價值** | B/M、P/E、E/P | `bm = book / market` |
| **動量** | MOM、RSI | `mom = price_t / price_{t-12} - 1` |
| **品質** | ROE、ROA、負債比 | `roe = net_income / shareholder_equity` |
| **波動率** | σ、低波動 | `vol = price.pct_change().rolling(252).std()` |
| **市場預測** | 風險溢酬 | `beta = cov(asset, market) / var(market)` |
### 3.3.2 滾動窗口與滯後變數
- **滾動因子**:使用 60 日、120 日窗口計算因子。
- **滯後因子**:為避免前瞻性 bias,將因子值滯後 1 個交易日。
python
# 計算 12 個月動量
momentum = price.pct_change(periods=252).shift(1)
# 滾動 60 天平均價值
bm = (book / market).rolling(window=60).mean().shift(1)
### 3.3.3 標準化與多重共線性處理
- **Z-Score 標準化**:使因子分佈均值 0、標準差 1。
- **PCA**:對高度相關的因子進行主成分分析,降低維度。
- **VIF**:計算方差膨脹因子,剔除 VIF > 5 的因子。
## 3.4 因子投資策略
### 3.4.1 量化長期持有
1. **因子加權**:根據因子分數給予權重。
2. **再平衡頻率**:季度或半年調整。
3. **分散化**:同時使用多因子,避免單一因子失效。
### 3.4.2 因子組合示例
| 因子 | 權重 | 佈局方式 |
|------|------|----------|
| MOM | 30% | 先選擇前 20% 的 MOM 值,再分配權重 |
| B/M | 30% | 同上 |
| Low Vol | 20% | 選取最低 20% Vol 的股票 |
| Quality | 20% | 併入上面策略的篩選條件 |
### 3.4.3 回測框架
- **Zipline** / **Backtrader**:可快速跑因子回測。
- **Pyfolio**:生成風險回報報告。
python
import backtrader as bt
# 範例:簡單的 MOM 策略
class MOMStrategy(bt.Strategy):
params = (('period', 252),)
def __init__(self):
self.mom = bt.indicators.Momentum(self.data.close, period=self.p.period)
def next(self):
if self.mom[0] > 0:
self.buy()
elif self.mom[0] < 0:
self.sell()
## 3.5 長短期策略設計
### 3.5.1 交易對 (Pairs Trading)
- **概念**:選取相關性高的兩支股票,觀察價格差距偏離統計均值時進行多空對沖。
- **實作**:
1. 選股:使用 Pearson 相關係數挑選相關性>0.8。
2. 建立 OLS 回歸:`price_A ~ price_B`,取得殘差。
3. 計算殘差 Z-Score,若>2 賣空,< -2 多入。
python
import statsmodels.api as sm
import numpy as np
# A, B 為兩支股票回報
X = sm.add_constant(price_B)
model = sm.OLS(price_A, X).fit()
residual = price_A - model.predict(X)
zscore = (residual - residual.mean()) / residual.std()
### 3.5.2 均值回歸策略
- **工具**:Kalman Filter、EWMA。
- **風險控制**:設定止損比例,例如 3% 或 1 個標準差。
### 3.5.3 多因子長短期組合
- **Alpha 產生**:使用回歸剩餘(Alpha)作為多空判斷。
- **Beta 滾動**:保持組合 Beta 接近 0,降低市場風險。
## 3.6 市場時序模型
| 模型 | 應用場景 | 主要參數 |
|------|----------|----------|
| ARIMA | 週期預測 | p, d, q |
| GARCH | 波動率預測 | p, q |
| VAR | 多變量互動 | lags |
| Prophet | 長期趨勢 + 週期 | yearly_seasonality, weekly_seasonality |
| LSTM | 非線性長期依賴 | hidden_size, num_layers |
### 3.6.1 GARCH 範例
python
import arch
returns = price.pct_change().dropna()
model = arch.arch_model(returns, vol='Garch', p=1, q=1)
res = model.fit(update_freq=5)
print(res.summary())
### 3.6.2 LSTM 時序預測
python
import tensorflow as tf
from tensorflow.keras import layers
def build_model(input_shape):
model = tf.keras.Sequential([
layers.LSTM(64, return_sequences=True, input_shape=input_shape),
layers.LSTM(32),
layers.Dense(1)
])
model.compile(optimizer='adam', loss='mse')
return model
## 3.7 風險控制與績效評估
| 指標 | 公式 | 目標 |
|------|------|------|
| Sharpe Ratio | (Rp - Rf)/σp | > 1 良好 |
| Sortino Ratio | (Rp - Rf)/σ↓ | 低下行風險更佳 |
| Max Drawdown | max_{t} (Peak_t - Trough_t)/Peak_t | 低於 20% |
| Information Ratio | (Rp - Rb)/σα | > 1 具備 alpha |
### 3.7.1 回測報告生成
- **Pyfolio**:自動化產生 `PerformanceSummary`。
- **Zipline**:內建 `analyze` 模組。
python
import pyfolio as pf
# 計算回報與風險
pf.create_full_tear_sheet(returns)
## 3.8 實務案例:以 Python 建立 Momentum + Value 兩因子組合
| 步驟 | 說明 |
|------|------|
| 1 | 下載 200 支美股日價與市值、帳面價值資料 |
| 2 | 計算 12 月 MOM、5 月 B/M,進行 Z-Score 標準化 |
| 3 | 依 Z-Score 排序,分成 10 等分,選取前 10% |
| 4 | 給予每支股票等權重,並在每月再平衡 |
| 5 | 使用 Zipline 執行回測,產生績效指標 |
python
# 下載資料
tickers = ['AAPL','MSFT', ...] # 200 支
price = yf.download(tickers, start='2010-01-01', end='2024-01-01')['Adj Close']
# 計算 MOM
mom = price.pct_change(252).shift(1)
# 估算 B/M:假設有市值、市帳價值資料
# 進行 Z-Score
mom_z = mom.rank(axis=1, pct=True).apply(lambda x: (x-0.5)/0.5)
# 取前 10% 進行等權重
selected = mom_z.lt(0.1)
weights = selected.mean(axis=0) / selected.sum(axis=0)
### 3.8.1 主要結論
- **因子多樣化**:同時使用 MOM 與 B/M 能降低單因子失效風險。
- **再平衡頻率**:月度再平衡達到較佳績效,避免過度交易。
- **風險控制**:設定止損 2% 及止盈 5%,可進一步提升夏普比率。
---
### 3.9 進一步閱讀
- *“Quantitative Equity Portfolio Management”* by Ludwig B. Chincarini & Daehwan Kim
- *“Advances in Financial Machine Learning”* by Marcos Lopez de Prado
- *“Financial Modelling with R”* by G. R. C. (R) 作者
- Kaggle 競賽:*“Quantitative Trading”*、*“Finance Dataset”*
本章已將資料科學的核心工具與投資策略相結合,下一章將進一步探討如何將這些模型嵌入機器學習框架,以提升預測準確度與策略靈活性。