聊天視窗

量化投資的智慧:從數據到策略 - 第 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%。 ## 小結 風險管理不再是「防呆」的程式碼,而是一套動態、可視化、可調整的機制。透過基礎度量、資產配置、尾部風險評估、動態調節、壓力測試與實時監控,我們能把策略轉化為一個在波動市場中不斷自我修正的「生命體」。在下一章,我們將進一步探討如何結合人工智慧與機器學習,為風險管理增添「預測」層面。