halo 的技术博客

返回

多元波动率建模里最容易踩的坑,是以为「给每个资产各装一个 GARCH,再把它们拼成协方差矩阵」就完事了。拼出来的协方差长这样:

Σt=DtRDt\Sigma_t = D_t\,R\,D_t

其中 DtD_t 是各资产条件波动率的对角阵,RR 是相关矩阵。问题在于:大多数人会顺手把 RR 写成全样本估计的常数矩阵。而相关从来不是常数——平静时两只股票相关性 0.3,暴跌时所有东西一起跳水,相关性瞬间冲到 0.85 甚至更高。用常数相关,等于在暴风雨里假设风平浪静。

结论先放这:**DCC-GARCH(Dynamic Conditional Correlation, Engle 2002)用一个两阶段结构解决了这个问题——第一阶段给每个资产各拟合一个单变量 GARCH 拿到条件波动,第二阶段用仅仅两个参数 (a,b)(a,b) 让相关矩阵 RtR_t 随时间平滑演化。它用极少参数把「相关性随时间变化」这一事实搬进组合风险,且计算量只是单变量 GARCH 的线性放大。本文从零实现,并展示 DCC 如何把危机里的相关飙升如实捕捉,而常数相关会系统性低估组合风险。

补充一句:本文用双资产把直觉讲到透,但 DCC 的方法论对 NN 资产完全一致——只是把 Qˉ\bar{Q}QtQ_t2×22\times2 换成 N×NN\times N(a,b)(a,b) 仍是那两个参数,估计量不随维度爆炸。这正是它在实盘组合风险里比「逐对相关分别建模」现实得多的根本原因。**

两资产收益与真实时变相关:危机窗口相关性从 0.30 飙升到约 0.85

一、为什么单变量 GARCH 不够#

波动率聚集是每个做量化的人都熟悉的:安静的行情能连着几周风平浪静,暴跌往往接二连三。GARCH 族把单个资产的方差建模成随时间演化的隐变量,这是对的。但当你的目标是组合——算组合方差、做风险预算、算 VaR——你需要的不是一堆 σi2\sigma_i^2,而是完整的协方差矩阵 Σt\Sigma_t

组合方差的分解很清楚(等权 w=[0.5,0.5]w=[0.5,0.5] 为例):

Var(rp)=14(σ12+σ22)+12ρσ1σ2\text{Var}(r_p) = \tfrac14(\sigma_1^2+\sigma_2^2) + \tfrac12 \rho\,\sigma_1\sigma_2

前半段是两个资产各自的波动,后半段是它们的相关耦合项。危机里 σ1,σ2\sigma_1,\sigma_2 会涨,但更致命的是 ρ\rho 从 0.3 跳到 0.85——耦合项几乎翻三倍。如果你用常数 ρ=0.387\rho=0.387(全样本平均),危机段的风险会被严重低估。这正是 2008 年很多风险模型失灵的根源。

更隐蔽的是,常数相关还会把风险贡献算错。风险预算(risk budgeting)要回答「组合波动里多大比例来自科技、多大比例来自金融」,这依赖相关结构。当真实相关在危机里趋同,风险贡献会高度集中到少数系统性因子;常数相关下的风险贡献却是平滑分散的假象,会让你在最需要降杠杆时误以为自己已经足够分散。

二、DCC 模型:相关矩阵怎么”动”起来#

DCC 的关键洞察是:先标准化掉每个资产自己的波动率,再在”标准化残差”的空间里让相关动态演化。

第一步,对每个资产拟合 GARCH(1,1),得到条件标准差 σi,t\sigma_{i,t},构造标准化残差:

εi,t=ri,tσi,t\varepsilon_{i,t} = \frac{r_{i,t}}{\sigma_{i,t}}

标准化残差近似是方差为 1、彼此相关的白噪声序列。第二步,Engle 让相关矩阵通过下面这个递归”动态”演化:

Qt=(1ab)Qˉ+a(εt1εt1)+bQt1Q_t = (1-a-b)\,\bar{Q} + a\,(\varepsilon_{t-1}\varepsilon_{t-1}^\top) + b\,Q_{t-1}

Rt=diag(Qt)1/2Qtdiag(Qt)1/2R_t = \text{diag}(Q_t)^{-1/2}\,Q_t\,\text{diag}(Q_t)^{-1/2}

  • Qˉ\bar{Q}:标准化残差的样本相关矩阵(长期中枢)
  • aa:对”昨天的相关新息” εt1εt1\varepsilon_{t-1}\varepsilon_{t-1}^\top 的敏感度
  • bb:相关性的持续度(记忆)
  • 约束 a+b<1a+b<1 保证 QtQ_t 平稳、长期收敛到 Qˉ\bar{Q}
  • 最后一步把 QtQ_t 重新缩放成单位对角的相关矩阵 RtR_t

整个相关动态只有两个待估参数 (a,b)(a,b)——不管你有 2 个还是 200 个资产。这是 DCC 最漂亮的地方:它绕开了”N 个资产就要估 N(N-1)/2 个时变相关”的维度灾难。

三、从零实现(Python)#

下面这段代码与配图完全对应:先模拟两资产(各自 GARCH 波动 + 一个会飙升的时变真实相关),再拟合单变量 GARCH、跑 DCC,最后对比动态相关与常数相关。

四、结果:DCC 真的抓住了危机#

跑出来三个数很说明问题:DCC 拟合相关峰值 0.623,常数相关 0.387,真实峰值 0.850。DCC 把危机里的相关飙升捕捉到了,而常数相关是一条平直的线,对危机毫无反应。

DCC 拟合相关 vs 真实相关:危机飙升被追踪,常数相关全程不动

注意 DCC 峰值(0.62)低于真实峰值(0.85),这是DCC 的固有特性而非 bug:它的相关靠”昨天的相关新息”驱动,必然对瞬时跳变有平滑滞后。它擅长刻画”相关持续走高/走低”的趋势,不擅长瞬时捕捉闪崩。如果你需要即时相关,应改用基于高频实现的实时相关(realized correlation),而不是怪 DCC。

把相关矩阵在不同时点画成热图,差异更直观——平静期两只资产相关性温和,危机期几乎完全同涨同跌:

平静期 vs 危机期相关矩阵:危机里相关性被 DCC 如实抬高

落到组合风险上,区别就是”生与死”。下面把 DCC 动态协方差和常数相关协方差都代入等权组合,算每日组合波动:

等权组合风险:DCC 在危机段如实放大风险,常数相关严重低估

灰线是常数相关——危机来了它几乎纹丝不动,告诉你”一切正常”;红线(DCC)在危机段明显抬高年化波动率。用灰线做风险预算或止损,你会在最需要防守的时候以为自己很安全。

五、真实陷阱(别把 DCC 当神)#

  1. 滞后性:如上,DCC 相关是平滑的,对瞬时跳变(闪崩、流动性枯竭)反应慢。需要即时反应时用高频实现的滚动相关,或加一个”危机开关”外生变量。
  2. 维度与 Qˉ\bar{Q} 噪声:DCC 只估 (a,b)(a,b) 两个参数,但长期中枢 Qˉ\bar{Q}N×NN\times N 的。资产一多,Qˉ\bar{Q} 的样本估计噪声很大,相关矩阵可能不正定(需投影到正定锥)。高维场景应上因子 DCC(用少数因子解释相关)或收缩估计。
  3. 标准化残差的分布假设:标准 DCC 假设标准化残差近似条件正态。对肥尾资产(个股、加密货币),用 DCC-t(残差服从多元 t)能显著改善尾部相关的刻画。
  4. 非平稳与结构突变(a,b)(a,b)Qˉ\bar{Q} 用全样本估计,遇到 regime change(牛熊切换、货币政策转向)会失效。可滚动窗口估计,或上 Markov 切换 DCC。
  5. 相关 ≠ 因果:DCC 给你的是统计相关,不是”谁传染谁”的方向。要方向得用 VAR / 网络因果,别把相关飙升直接解读成风险传导路径。

结论#

DCC-GARCH 是用极少参数把”相关随时间变化”这一铁律搬进组合风险的最实用桥梁:它优于常数相关(危机里不再系统性低估),计算量只是单变量 GARCH 的线性放大,且相关矩阵自动保持正定。但它不是万能的——对瞬时跳变有平滑滞后、高维时 Qˉ\bar{Q} 噪声大、肥尾资产需换 t 分布。把它当成”相关结构的一阶近似 + 危机放大器”,而不是能瞬时捕捉闪崩的神谕,你才不会在 2008 重演的风险模型失灵里踩坑。

落地时一个省心的做法:把 DCC 当作组合风险监控的「主引擎」,同时用高频实现的滚动相关做「危机探针」——平时看 DCC 的平滑趋势,一旦探针报警就立刻切到即时相关,既不损失 DCC 的稳健,也不放过闪崩的瞬间。

DCC-GARCH 多元波动率模型:让相关矩阵随时间起舞
https://blog.halo26812.eu.org/blog/dcc-garch-multivariate
Author halo
Published at 2026年7月11日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨