第 3 章 · 03 HRP 层次风险平价(对应 QS022) 速查摘要:本节精读 HRP(Hierarchical Risk Parity,层次风险平价)——Marcos López de Prado 提出的"避开协方差求逆"的稳健组合优化法。脚本很短:25 只行业 ETF(XLE/XLF/XLU/...), 先画系统树图看清聚类结构,然后 一步出权重,最后 看分配、 看风险贡献。HRP 的哲学是:先用相关性把"相似的"资产聚成一组,再在组与组之间做朴素等权分配——完全不碰矩阵求逆,因此对小样本和高度共线资产稳健得多。 涉及脚本:原项目 (约 90 行) ⚠️ 注意:HRP 与 QS011 的风险平价、QS014 的马科维茨都不同。
速查摘要:本节精读 HRP(Hierarchical Risk Parity,层次风险平价)——Marcos López de Prado 提出的"避开协方差求逆"的稳健组合优化法。脚本很短:25 只行业 ETF(XLE/XLF/XLU/...),
plot_dendrogram(codependence='pearson', linkage='single')先画系统树图看清聚类结构,然后HCPortfolio(returns).optimization(model='HRP', codependence='pearson', linkage='single', max_k=10)一步出权重,最后plot_pie看分配、plot_risk_con看风险贡献。HRP 的哲学是:先用相关性把"相似的"资产聚成一组,再在组与组之间做朴素等权分配——完全不碰矩阵求逆,因此对小样本和高度共线资产稳健得多。
涉及脚本:原项目
QS022-hrp/01_hrp.py(约 90 行)
⚠️ 注意:HRP 与 QS011 的风险平价、QS014 的马科维茨都不同。马科维茨和风险平价都要对协方差矩阵做求逆(或解二次规划),当资产数接近样本数、或资产高度相关时,协方差矩阵病态、求逆爆炸,权重会剧烈震荡。HRP 用聚类 + 递归二分完全绕开求逆,这是它的核心创新。理解这一点,才能理解为什么 Marcos López de Prado 在《Advances in Financial Machine Learning》里把 HRP 列为"实用机器学习组合优化"的代表。
阅读完本节,你应当能够:
codependence='pearson' 之外的度量(gerber1/tan)做稳健性切换。马科维茨均值方差优化要解:
min w'Σw s.t. w'μ = target, w'1 = 1
里头隐含对 Σ(协方差矩阵)的求逆。当资产数 n 接近样本数 T 时,样本协方差矩阵的估计噪声被放大,逆矩阵剧烈震荡——典型的"权重在一两个资产上跳到极大正值、另一些跳到极大负值"。这就是为什么教科书里漂亮的马科维茨,落地实战一塌糊涂。
Marcos López de Prado(2016,《Building Diversified Portfolios that Outperform Out-of-Sample》)提出的 HRP 完全规避求逆,分两步:
第一步:层次聚类。把资产按相关性距离聚类——相似的资产(相关高)聚到同一簇。距离矩阵 d = sqrt(0.5·(1 - corr)),用单链接(single linkage)做凝聚聚类,得到一棵系统树。树的结构反映"哪些资产可以互相替代"。
第二步:递归二分(Recursive Bisection)。从树根(全部资产)开始,自顶向下递归地把每个簇一分为二;在每一层,两个子簇之间按"逆方差"分配权重(w ∝ 1/σ²,但只在簇级别,不是单个资产级别);一直递归到叶子(单资产)。最终每个资产拿到的权重 = 它所在路径上所有分裂点的逆方差权重之积。
关键洞察:HRP 只用到相关性结构(决定聚类树)和单资产方差(决定簇内分配),全程不需要协方差矩阵的逆。这就是它稳健的根源——协方差矩阵估计得再烂,只要相关性排序大致正确,聚类树就稳定,权重就稳定。
codependence 的选择riskfolio 的 codependence 参数控制"用什么度量资产间的相关性",决定聚类树形状:
'pearson':皮尔逊线性相关,默认。但对极端值敏感。'spearman':秩相关,抗异常值。'gerber1'/'gerber2':Gerber 统计量(2021),专门为金融收益设计,只统计"同向显著波动"对,对噪声鲁棒。'tan':基于 t-Copula 的尾部相关性,捕捉"危机时一起跌"的现象。如果资产间相关性不稳定(典型如危机期),把 pearson 换成 gerber1 或 tan,HRP 权重会更稳健。
assets = [ "XLE","XLF","XLU","XLI","GDX", "XLK","XLV","XLY","XLP","XLB", "XOP","IYR","XHB","ITB","VNQ", "GDXJ","IYE","OIH","XME","XRT", "SMH","IBB","KBE","KRE","XTL", ] data = yf.download(assets)["Adj Close"] returns = data.pct_change().dropna()
这是精心挑选的"行业 ETF 全家桶":能源(XLE/XOP/OIH/XLE)、金融(XLF/KBE/KRE)、公用事业(XLU)、工业(XLI)、黄金矿业(GDX/GDXJ)、科技(XLK/SMH)、医疗(XLV/XHB)、消费(XLY/XLP/XRT)、材料(XLB/XME)、生物科技(IBB)、地产(IYR/ITB/VNQ)、电信(XTL/原 T)、电信(T)等。这些 ETF 之间有强聚类结构(比如黄金类 GDX/GDXJ/OIH 高度相关),正好展示 HRP 的优势——把高相关资产聚到一组、不重复配置。
ax = rp.plot_dendrogram( returns=returns, codependence="pearson", linkage="single", k=None, max_k=10, leaf_order=True, ax=None, )
plot_dendrogram 是 HRP 流程最重要的诊断图。横轴是单个资产(叶子),纵轴是"合并距离"——两条线在哪高度合并,就反映它们的相关性距离(sqrt(0.5·(1-corr)))。合并点越低,两资产越相关。
典型结果:GDX 和 GDXJ(都是黄金矿业)会在很低的位置合并,XLE 和 XOP(都是能源)、KBE 和 KRE(都是区域银行)同理。这些低距离合并对就是 HRP 要"识别并去重"的相似资产。max_k=10 限制最多分 10 个簇(用于上色),leaf_order=True 让叶子按相似度重排,树图更可读。
读图口诀:先看哪些资产在底部早早合并(高度低)——它们是"高度可替代的",HRP 会把它们当一个整体分配一份权重,避免重复押注。
port = rp.HCPortfolio(returns=returns) w = port.optimization( model="HRP", codependence="pearson", rm="MV", rf=0.05, linkage="single", max_k=10, leaf_order=True, )
HCPortfolio 是 riskfolio 的层次聚类组合对象,跟 Portfolio(QS014)平行。model="HRP":用 HRP 算法(还有 'HERC' 另一种层次聚类变体)。codependence/linkage/max_k/leaf_order 必须跟 plot_dendrogram 完全一致——否则你画的树图和实际优化用的不是同一棵树,诊断图就失去意义。rm="MV":簇内分配时用方差风险度量(MV 之外的度量如 CVaR 也可,但 HRP 论文原版用 MV)。rf=0.05:无风险利率,本算法用不上,但参数留着。ax = rp.plot_pie(w=w, title="HRP Naive Risk Parity", others=0.05, nrow=25, cmap="tab20", height=8, width=10) ax = rp.plot_risk_con(w=w, cov=returns.cov(), returns=returns, rm="MV", rf=0, alpha=0.05, color="tab:blue", height=6, width=10, t_factor=252)
others=0.05:权重小于 5% 的资产合并成"Others"显示,避免饼图碎成 25 片看不清。plot_risk_con 画每只资产对组合方差风险的贡献。HRP 不是严格风险平价,所以贡献图不会完全平——但会比马科维茨均衡得多(不会一两只资产占掉 50% 风险)。这是 HRP"软风险平价"特性的直观体现。HRP 不需要预估预期收益。整个算法只用协方差结构(聚类)和单资产方差(簇内分配),完全不用 μ。这避开了"预测收益"这个金融里最难的问题,也是它实战稳健的核心原因之一。
codependence/linkage/max_k 必须三处一致。plot_dendrogram 和 optimization 这三个参数要对得上,否则你诊断的树和优化用的树不是一棵。一个常见 bug 是画图用 linkage='ward'、优化用 linkage='single',然后困惑为什么树和权重对不上。
single linkage vs ward/complete。HRP 原论文用 single(单链接,取两簇最近两点距离),它对"链式聚类"敏感,适合发现细长聚类结构。换成 ward(离差平方和)会更均衡、但可能合并本应分开的簇。López de Prado 推荐 single。
gerber1/tan 比 pearson 更稳健。Pearson 相关对极端值敏感、且只度量线性关系。危机期资产相关性普遍飙升(都跟着跌),Pearson 会"过度聚类",把本不相似的资产当成一类。Gerber 只统计显著同向波动、t-Copula 捕捉尾部相关,都是为金融非正态收益设计的稳健度量。实战里建议跑两版对比。
HRP 是"软风险平价"。它不追求严格的 RC_i = RC_j,而是让"相似的资产合计贡献一份风险"。所以风险贡献图不是直线,但会比马科维茨均衡——这正是设计意图。
样本量小于资产数时选 HRP。当 T < n(比如 100 天数据、200 只股票),马科维茨的协方差矩阵奇异、风险平价的二次规划无解,但 HRP 照样跑——这是它最大的实用价值。
💡 速查要点:HRP 两步走——
plot_dendrogram(codependence, linkage)画树诊断 +HCPortfolio.optimization(model='HRP', codependence, linkage, max_k)出权重。全程不求逆、不预测收益,只靠相关性聚类 + 逆方差分配,小样本和高度共线场景下比马科维茨/风险平价稳健得多。三个聚类参数务必画图与优化一致。
codependence 可切:pearson(默认)→ gerber1/tan(更稳健,适合非正态/危机期);务必与优化参数一致。下一节,我们手写 CVaR——不调库,用
np.percentile+ 尾部均值从零理解尾部风险度量的本质。