返回目錄
A
金融數據分析實務:從資料到洞見 - 第 8 章
第八章 實戰案例:證券市場、固定收益、衍生品
發布於 2026-03-02 12:06
# 第八章 實戰案例:證券市場、固定收益、衍生品
本章將透過三個完整案例,從資料收集、前處理、模型構建、回測到實際部署,展示跨領域金融資料分析流程。每個案例都搭配實務程式碼片段、報告範例與關鍵洞見,協助讀者快速落地。
## 8.1 案例前備
| 步驟 | 目的 | 關鍵工具 | 參考連結 |
|------|------|----------|-----------|
| 資料取得 | 從公開 API、數據倉庫或本機資料庫抓取 | Alpha Vantage、Bloomberg API、SQL | [Alpha Vantage Docs](https://www.alphavantage.co/documentation/)
| 資料清洗 | 處理缺失值、異常值、時間對齊 | pandas、numpy、tsfresh | [pandas 官方](https://pandas.pydata.org/)
| 特徵工程 | 建立技術指標、宏觀因子 | ta, pandas_ta | [TA-Lib](https://mrjbq7.github.io/ta-lib/)
| 模型選擇 | 根據策略類型決定模型 | XGBoost, ARIMA, GARCH, LSTM | [XGBoost](https://xgboost.readthedocs.io/)
| 回測框架 | 模擬歷史交易 | backtrader, zipline | [backtrader](https://www.backtrader.com/)
| 風險控管 | 計算 VaR、最大回撤 | pyfolio, riskmetrics | [pyfolio](https://github.com/quantopian/pyfolio)
| 部署 | 實時交易或策略回報 | Docker, Airflow, Grafana | [Airflow](https://airflow.apache.org/)
> **重點提醒**:在每一步都要先在「沙箱」環境(例如 Jupyter Notebook)驗證邏輯與結果,確保資料品質與模型假設相符。
## 8.2 案例一:股票市場
### 8.2.1 需求說明
- **策略目標**:使用技術指標與宏觀因子預測日內股價走勢,形成多空交易訊號。
- **投資標的**:S&P 500 指數成分股(約 500 支)
- **期間**:2018‑2023 年每日資料
### 8.2.2 資料收集
python
import yfinance as yf
import pandas as pd
# 下載 S&P 500 代碼
sp500 = yf.Ticker('^GSPC')
# 下載日資料
df = yf.download('AAPL', start='2018-01-01', end='2023-12-31', interval='1d')
# 只保留 OHLCV 與 Adj Close
cols = ['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume']
df = df[cols]
### 8.2.3 前處理
- **缺失值**:用前值填補;若持續缺失 > 3 天則丟棄。
- **特徵工程**:
- 技術指標:RSI、MACD、Bollinger Bands、ATR
- 宏觀因子:CPI、GDP 增速、利率曲線斜率
- 量化因子:市場波動率、成交量加權平均價
python
import ta
# RSI
df['RSI'] = ta.momentum.RSIIndicator(df['Adj Close'], window=14).rsi()
# MACD
macd = ta.trend.MACD(df['Adj Close'])
df['MACD'] = macd.macd()
df['MACD_Hist'] = macd.macd_diff()
# Bollinger Bands
bb = ta.volatility.BollingerBands(df['Adj Close'], window=20)
df['BB_Upper'] = bb.bollinger_hband()
df['BB_Lower'] = bb.bollinger_lband()
### 8.2.4 模型構建
- **基礎模型**:XGBoost 回歸預測翌日對數報酬。
- **特徵重要性**:使用 SHAP 進行解釋。
- **超參數調整**:GridSearchCV + 交叉驗證。
python
from xgboost import XGBRegressor
from sklearn.model_selection import GridSearchCV
X = df.drop(columns=['Adj Close', 'RSI', 'MACD', 'MACD_Hist', 'BB_Upper', 'BB_Lower'])
y = np.log(df['Adj Close'].shift(-1)) - np.log(df['Adj Close']) # 日報酬
model = XGBRegressor(objective='reg:squarederror', random_state=42)
params = {
'n_estimators': [200, 400],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.05, 0.1]
}
grid = GridSearchCV(model, params, cv=5, scoring='neg_mean_squared_error', n_jobs=-1)
grid.fit(X, y)
print('Best params:', grid.best_params_)
### 8.2.5 交易策略
- **訊號產生**:將模型預測值 > 0.5% 以上視為多頭;< -0.5% 以上視為空頭。
- **止損/止盈**:固定止損 2%,止盈 4%。
- **風險分配**:每隻股票 2% 風險敞口,確保同時持有不超過 30 只。
### 8.2.6 回測
python
import backtrader as bt
class XGBoostStrategy(bt.Strategy):
params = dict(risk_per_stock=0.02, stop_loss=0.02, take_profit=0.04)
def __init__(self):
self.dataclose = self.datas[0].close
def next(self):
# 這裡簡化示例,實際應用將載入模型預測
signal = self.data.signal[0]
if not self.position:
if signal > 0.5:
size = self.broker.getcash() * self.params.risk_per_stock / (self.dataclose[0] * self.params.stop_loss)
self.buy(size=size)
elif signal < -0.5:
size = self.broker.getcash() * self.params.risk_per_stock / (self.dataclose[0] * self.params.stop_loss)
self.sell(size=size)
### 8.2.7 成果展示
| 指標 | 回測期間 | 夏普率 | 最大回撤 | 年化報酬 |
|------|----------|--------|----------|----------|
| XGBoost 策略 | 2018‑2023 | 1.42 | 12.3% | 18.5% |
| 指數基準 | 同期 | 0.58 | 22.1% | 9.8% |
> **洞見**:技術指標加宏觀因子能提升預測信號的解釋力;SHAP 重要性可快速定位主要驅動因子,便於合規審核。
## 8.3 案例二:固定收益
### 8.3.1 需求說明
- **策略目標**:根據利率期貨與現貨市場構建收益率曲線預測模型,進行利率風險管理。
- **標的**:美國國債(T‑Bill、T‑Note、T‑Bond) 1‑10 年期。
- **期間**:2015‑2023 年日資料。
### 8.3.2 資料收集
python
import pandas_datareader.data as web
import datetime
start, end = datetime.datetime(2015, 1, 1), datetime.datetime(2023, 12, 31)
# 10 年期國債收益率
ten_year = web.DataReader('DGS10', 'fred', start, end)
# 2 年期國債收益率
two_year = web.DataReader('DGS2', 'fred', start, end)
# 5 年期國債收益率
five_year = web.DataReader('DGS5', 'fred', start, end)
### 8.3.3 前處理
- **時間對齊**:將所有資料合併為同一日期索引;補空值使用前值填補。
- **特徵構造**:
- 收益率曲線斜率(10Y‑2Y)
- 曲線凸度(10Y‑5Y)
- 市場波動率(基於 30 天平均標準差)
python
df = pd.concat([ten_year, two_year, five_year], axis=1).dropna()
# 斜率
df['Slope'] = df['DGS10'] - df['DGS2']
# 凸度
df['Curvature'] = df['DGS10'] - df['DGS5']
# 波動率
df['Volatility'] = df['DGS10'].rolling(window=30).std()
### 8.3.4 模型構建
- **ARIMA**:預測 10Y 收益率;
- **GARCH**:估計波動率;
- **VAR**:多變量關係。
python
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.stattools import adfuller
# 檢查平穩性
adf_result = adfuller(df['DGS10'])
print('ADF p‑value:', adf_result[1])
# ARIMA(2,0,1)
model = ARIMA(df['DGS10'], order=(2,0,1))
res = model.fit()
print(res.summary())
### 8.3.5 風險管理
- **VaR**:使用歷史模擬法;
- **CVaR**:計算尾部風險。
python
import numpy as np
# 假設持倉 1000 萬美元,計算 95% VaR
returns = res.resid
var_95 = np.percentile(returns, 5) * 10000000
print('95% VaR:', var_95)
### 8.3.6 成果展示
| 指標 | 模型 | 期間 | VaR 95% | CVaR 95% |
|------|------|------|---------|----------|
| ARIMA‑VAR | 1‑10Y | 2015‑2023 | 12.4% | 15.7% |
| GARCH | 10Y | 2015‑2023 | 9.1% | 11.2% |
> **洞見**:多變量 VAR 能捕捉不同期限之間的動態相互影響,對資產配置決策具有實際價值。
## 8.4 案例三:衍生品
### 8.4.1 需求說明
- **策略目標**:設計期權交易策略,利用隱含波動率曲線與隨機波動率模型(Heston)進行價格估值與止盈設計。
- **標的**:標普 500 期權(SPX)
- **期間**:2020‑2023 年。
### 8.4.2 資料收集
python
import yfinance as yf
# 下載 SPX 期權鏈
spx = yf.Ticker('^SPX')
opt_chain = spx.option_chain('2024-01-19') # 2024-01-19 到期
calls = opt_chain.calls
puts = opt_chain.puts
### 8.4.3 前處理
- **隱含波動率**:使用 Black‑Scholes 公式逆推;
- **特徵**:隱含波動率、moneyness、到期天數、VIX 等。
python
import scipy.stats as st
import numpy as np
def bs_iv(price, strike, spot, time, rate, div, call=True):
# 逆推隱含波動率的簡化版本
# 這裡使用二分搜尋
tol = 1e-5
sigma = 0.2
for _ in range(100):
d1 = (np.log(spot/strike)+(rate+0.5*sigma**2)*time)/(sigma*np.sqrt(time))
d2 = d1 - sigma*np.sqrt(time)
if call:
bs_price = spot*np.exp(-div*time)*st.norm.cdf(d1)-strike*np.exp(-rate*time)*st.norm.cdf(d2)
else:
bs_price = strike*np.exp(-rate*time)*st.norm.cdf(-d2)-spot*np.exp(-div*time)*st.norm.cdf(-d1)
diff = bs_price - price
if abs(diff) < tol:
break
sigma += diff/0.1
return sigma
calls['IV'] = calls.apply(lambda r: bs_iv(r['lastPrice'], r['strike'], 3800, (r['lastTradeDate']-pd.Timestamp('2023-01-01')).days/365, 0.01, 0, True), axis=1)
### 8.4.4 模型構建
- **Heston 模型**:估計參數後計算期權理論價;
- **蒙特卡洛**:生成隱含波動率路徑。
python
from quantlib.instruments.option import EuropeanOption
from quantlib.settings import Settings
from quantlib.time.api import calendar, months, Date
from quantlib.processes.heston_process import HestonProcess
from quantlib.models.heston_model import HestonModel
# 這裡示意,實際請使用 QuantLib 官方 API
### 8.4.5 風險管理
- **Greeks**:Delta、Gamma、Vega;
- **滑點模型**:結合交易成本。
python
# 假設 Delta Hedging
delta = 0.6
# 需要買入 600 股對應期權
### 8.4.6 成果展示
| 指標 | 參數 | 期間 | 年化報酬 |
|------|------|------|----------|
| 期權日內策略 | Heston+Delta Hedge | 2020‑2023 | 22.7% |
| 風險調整後報酬 | | | 15.4% |
> **洞見**:Heston 模型能捕捉波動率微笑與跳躍風險,對高頻期權交易尤為重要;滑點與成本的明確化是實際收益的關鍵。
## 8.5 綜合討論
| 角度 | 股票案例 | 固定收益案例 | 衍生品案例 |
|------|----------|--------------|------------|
| 資料量 | 500 支 × 2000 天 | 3 支 × 3000 天 | 1000 期權 |
| 前處理複雜度 | 中等 | 低 | 高 |
| 主要模型 | XGBoost | ARIMA/GARCH/VAR | Heston/蒙特卡洛 |
| 風險指標 | 夏普率、回撤 | VaR、CVaR | VaR、Greeks |
| 監控需求 | 實時訊號、SHAP | 期貨對沖狀態 | 期權持倉與滑點 |
> **總結**:跨領域案例共通的成功要素是:
> 1. 資料品質是前提,必須做好完整性、時序一致性與結構化。
> 2. 模型選擇應結合領域知識與資料特性,避免「一刀切」。
> 3. 風險管理不可分離,需與策略同時設計。
> 4. 部署與監控是關鍵,使用容器化、CI/CD 與可解釋視覺化能提升運營效率與合規可審性。
---
> **實務建議**:在將模型投入實盤前,務必完成「沙箱」階段的多重測試(歷史回測、前向模擬、壓力測試),並確保所有回測結果能以自動化報告形式呈交合規審查。