聊天視窗

金融數據分析實務:從資料到洞見 - 第 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 與可解釋視覺化能提升運營效率與合規可審性。 --- > **實務建議**:在將模型投入實盤前,務必完成「沙箱」階段的多重測試(歷史回測、前向模擬、壓力測試),並確保所有回測結果能以自動化報告形式呈交合規審查。