返回目錄
A
量化投資的智慧:從數據到策略 - 第 6 章
第六章 風險管理的智慧:打造韌性投資組合
發布於 2026-02-21 18:54
# 風險管理的基石
在前一章,我們已經建立了完整的回測流程,並把交易成本、執行策略與績效指標緊密結合。今天,我們將把這些「表面」的成果,轉化為「內在」的韌性——**風險管理**。風險管理不只是把風險降到最低,更是一種平衡收益與風險、在不確定的市場中持續獲利的藝術。
## 1. 基礎風險度量
| 指標 | 公式 | 直觀意義 |
|------|------|-----------|
| 波動率 | \(\sqrt{\frac{1}{T-1}\sum_{t=1}^{T}(R_t-\bar R)^2}\) | 淨值每日波動程度 |
| 夏普比率 | \((\bar R-R_f)/\sigma\) | 風險調整後的平均報酬 |
| Sortino 比率 | \((\bar R-R_f)/\sigma_d\) | 僅考慮負面波動 |
| 最大回撤 | \(\max_{t}\{\frac{V_t - \min_{s\le t}V_s}{V_t}\}\) | 資金最大跌幅 |
> **技巧**:在 Python 里,`pandas` 的 `rolling` 可以輕鬆計算滑動波動率,`np.percentile` 能快速得到下行波動。
python
import pandas as pd
import numpy as np
# 假設 df['returns'] 為每日報酬率
window = 252 # 一個交易年
vol = df['returns'].rolling(window).std() * np.sqrt(252)
# 下行波動率
downside = df['returns'].apply(lambda r: r if r<0 else 0)
sigma_d = downside.rolling(window).std() * np.sqrt(252)
## 2. 風險偏好與資產配置
### 2.1 均值-方差最適化
- 目標:在給定風險水平下最大化預期報酬。
- 公式:\(\min_{w}\ w^T\Sigma w\) subject to \(w^T\mu = R^*\) and \(\sum w_i = 1\)。
python
import cvxpy as cp
mu = df['returns'].mean().values
Sigma = df['returns'].cov().values
n = len(mu)
w = cp.Variable(n)
R_star = 0.08 # 目標年化報酬
risk_free = 0.02
objective = cp.Minimize(cp.quad_form(w, Sigma))
constraints = [w @ mu >= R_star, cp.sum(w) == 1, w >= 0]
prob = cp.Problem(objective, constraints)
prob.solve()
weights = w.value
> **提示**:為避免過度擬合,加入「滑動」或「隨機」的風險限制,可提升實盤穩定度。
### 2.2 熱度指標(Beta)與風險貢獻
| 資產 | Beta | 風險貢獻 |
|------|------|-----------|
| A | 1.2 | 24% |
| B | 0.8 | 16% |
| C | 1.0 | 20% |
> **說明**:Beta >1 代表該資產波動大於市場,風險貢獻相對較高。可以透過調整 Beta 來控制組合整體波動。
## 3. VaR 與 CVaR
- **VaR (Value at Risk)**:在指定置信度下,未來某段時間內的最大預期損失。
- **CVaR (Conditional VaR)**:VaR 以上部位的平均損失,提供尾部風險的更完整視角。
### 3.1 歷史模擬法
python
confidence = 0.95
var = np.percentile(df['returns'].cumsum(), (1-confidence)*100)
print(f'VaR @ {confidence*100:.0f}%: {var:.2%}')
### 3.2 參數法(正態假設)
python
mu = df['returns'].mean()
std = df['returns'].std()
var_param = mu - std * scipy.stats.norm.ppf(confidence)
print(f'Parametric VaR: {var_param:.2%}')
### 3.3 Monte‑Carlo
python
n_sim = 10000
sim_returns = np.random.normal(mu, std, size=(n_sim, len(df)))
sim_cum = np.cumsum(sim_returns, axis=1)
var_mc = np.percentile(sim_cum[:, -1], (1-confidence)*100)
print(f'MC VaR: {var_mc:.2%}')
> **注意**:對於非正態資產,使用歷史模擬與 Monte‑Carlo 能更貼近實際尾部風險。
## 4. 動態風險控制
1. **止損策略**:設置固定百分比或基於 ATR 的止損點。
2. **波動率調節**:目標波動率 10%/年,若實際波動率超過,減少頭寸;低於則加碼。
3. **再平衡頻率**:月度、季度或根據市場波動率自動觸發。
python
# 波動率調節範例
target_vol = 0.10
current_vol = vol.iloc[-1]
scale = target_vol / current_vol
scaled_weights = weights * scale
scaled_weights = scaled_weights / scaled_weights.sum()
> **建議**:在實盤中加入交易閒置期與滑點模型,確保理論策略能落地。
## 5. Stress Testing & Scenario Analysis
| 事件 | 時期 | 主要影響 | 檢測方式 |
|------|------|----------|----------|
| 2008 金融危機 | 2008 | 信用市場崩潰 | 歷史回測重演 |
| 2020 新冠疫情 | 2020 | 市場大幅震盪 | 合成衝擊 (敘事情境) |
**合成衝擊示例**:將 5% 以上的市盈率下跌與 10% 的匯率變動結合,模擬極端情況。
python
# 合成衝擊
shock = df.copy()
shock['price'] *= 0.95
shock['fx'] *= 1.10
shock['returns'] = shock['price'].pct_change() + shock['fx'].pct_change()
shock_cum = shock['returns'].cumsum()
print(f'Stress cumulative loss: {shock_cum.iloc[-1]:.2%}')
## 6. 監控與報表
- **監控指標**:每日波動率、VaR、最大回撤、夏普比率。
- **Dashboard**:使用 `dash` 或 `Streamlit`,即時更新關鍵數據。
- **週報/月報**:自動化生成 PDF 或 Excel 報表,供管理層檢視。
python
# Streamlit 簡易範例
import streamlit as st
st.title('風險監控儀表板')
st.subheader('每日波動率')
st.line_chart(vol)
st.subheader('VaR 95%')
st.metric(label='VaR', value=f'{var:.2%}')
> **小結**:監控是風險管理的「眼睛」——沒有及時發現偏離,風險就會在不被察覺時累積。
---
## 7. 案例回顧:從理論到實盤
> **場景**:一個三個ETF(科技、能源、債券)組合。
> 1. 先用均值-方差最適化得到初始權重。
> 2. 設定 VaR 95% 為 5%,若實際 VaR 超過即觸發減碼。
> 3. 目標波動率 8%/年,使用 ATR 止損防止大幅下跌。
> 4. 每月再平衡一次。
> 5. 每週更新 Dashboard。
> **結果**:實盤跑 2021 年,年化報酬 12%,夏普比率 1.4,最大回撤 18%。相比純量化策略,報酬提升 3%,風險降至 4%。
## 小結
風險管理不再是「防呆」的程式碼,而是一套動態、可視化、可調整的機制。透過基礎度量、資產配置、尾部風險評估、動態調節、壓力測試與實時監控,我們能把策略轉化為一個在波動市場中不斷自我修正的「生命體」。在下一章,我們將進一步探討如何結合人工智慧與機器學習,為風險管理增添「預測」層面。