你用历史模拟法生成了 4000 个多资产收益情景,每个情景等概率 p_k = 1/4000。这是你的先验——它包含了数据里所有的相关性、厚尾、联动。现在投研说了一句:「我觉得股票下月能涨到 1.2%(比历史均值 0.58% 乐观)」。传统做法是什么?要么拍脑袋改分布、要么丢弃先验重新估。熵池化(Entropy Pooling, Meucci 2008)给了一条更优雅的路:在所有「满足这个观点」的分布里,挑一个离先验最近(相对熵最小)的。一句话,把主观观点变成对先验的一次「最小手术」。
本文用 3 个资产(股票/债券/黄金)、4000 个情景,把整套逻辑从数学推导一路跑到可交易的组合权重。核心结论先放这里:一个「股票月均 1.2%」的软观点,只把股票权重从 17% 抬到 29%,对先验的相对熵仅 KL=0.012(极小扭曲);而一个「崩盘概率抬到 15%」的压力观点,把股票权重从 17% 砍到 1.6%、债券加到 87%,KL=0.068——观点越强,对先验的扭曲越大,这正是熵池化最诚实的「代价函数」。

一、问题形式化:最小化相对熵 + 线性约束#
设先验情景为 x_k(共 K 个),先验概率 p_k。我们希望后验 q_k 满足投研的主观观点,而观点在数学上几乎总可以写成关于情景的线性矩约束:
E_q[f_i(X)] = μ_i 即 Σ_k q_k · f_i(x_k) = μ_iplaintext例如「股票月均 = 1.2%」就是 f(x_k)=r_k^{股票}、μ=0.012;「崩盘概率 = 15%」就是 f(x_k)=1{股票月跌>6%}、μ=0.15。熵池化求解:
min_q Σ_k q_k ln(q_k / p_k)
s.t. Σ_k q_k = 1, Σ_k q_k f_i(x_k) = μ_iplaintext目标 Σ q ln(q/p) 就是 Kullback–Leibler 散度 D_KL(q‖p)——衡量后验相对先验「被扭曲了多少」。约束保证观点被精确满足。这个带约束的优化有闭式解:引入拉格朗日乘子 λ,对 q_k 求偏导可得
q_k ∝ p_k · exp(λ · f(x_k))plaintext乘子 λ 由约束方程 E_q[f] = μ 反解。所以熵池化本质上就是对先验做一次指数倾斜(exponential tilt),倾斜方向和强度由 λ 决定。
二、对偶与牛顿求解#
把 q ∝ p·exp(λf) 代回,原问题变成无约束的对偶最大化:
G(λ) = λ·μ − ln Σ_k p_k exp(λ·f(x_k))plaintextG 是关于 λ 的凹函数,梯度 ∇G = μ − E_q[f],黑塞 ∇²G = −Cov_q(f)(负半定)。凹函数求最大值 → 牛顿方向必是上升方向,再配一个回溯线搜索保证目标单调上升,就能稳定收敛到唯一根 E_q[f]=μ。下面是完整实现(纯 numpy,log 空间防溢出):
import numpy as np
def g_lam(lam, f, p, tgt):
"""熵池化对偶函数 G(λ)=λ·μ − ln Σ p·exp(λ·f),log 空间稳定。"""
a = np.log(p) + (lam @ f.T) # (K,)
m = a.max()
logZ = m + np.log(np.sum(np.exp(a - m)))
return float(lam @ tgt - logZ)
def ep_solve(f, target, p, maxit=100, reg=1e-9, tol=1e-12):
f = np.atleast_2d(f.T).T # (K, m)
tgt = np.atleast_1d(np.asarray(target, float))
lam = np.zeros(f.shape[1])
gv = g_lam(lam, f, p, tgt)
for _ in range(maxit):
ef = lam @ f.T
w = np.exp(ef - ef.max()) # q ∝ p·exp(+λf),稳定
q = (w * p) / (w * p).sum()
fbar = (q[:, None] * f).sum(0)
grad = tgt - fbar # = ∇G(λ)
if np.max(np.abs(grad)) < tol:
break
d = f - fbar
Cov = (d * q[:, None]).T @ d + reg * np.eye(f.shape[1])
step = np.linalg.solve(Cov, grad)
alpha = 1.0 # 回溯线搜索
gnew = g_lam(lam + alpha * step, f, p, tgt)
while (not np.isfinite(gnew) or gnew < gv - 1e-10) and alpha > 1e-12:
alpha *= 0.5
gnew = g_lam(lam + alpha * step, f, p, tgt)
lam = lam + alpha * step
gv = gnew
ef = lam @ f.T
q = (np.exp(ef - ef.max()) * p) / (np.exp(ef - ef.max()) * p).sum()
return q, lampython先验用 3 资产多元正态生成 4000 情景、等权 p;先验月均:股票 0.58% / 债券 0.34% / 黄金 0.53%。「股票月跌 >6%」的崩盘情景先验概率仅 5.12%。
三、观点1:软倾斜「股票月均能到 1.2%」#
q1, _ = ep_solve(X[:, 0], 0.012, p) # 约束:E^q[r_股票] = 1.2%/月python后验把概率质量推向高股票收益区(见图1右),精确达成 E^q[r_股票]=1.200%。有意思的副作用:因为高股票收益区本就不是崩盘区,崩盘概率反而从 5.12% 降到 3.66%——观点在「拉高中枢」的同时,也顺手压低了尾部。对先验的扭曲极小:KL(q1‖p)=0.012,后验熵 8.282(先验 8.294,几乎没动)。这正是「软观点」应有的样子:轻推,不撕裂。

四、观点2:压力情景「崩盘概率抬到 15%」#
crash = (X[:, 0] < -0.06).astype(float)
q2, _ = ep_solve(crash, 0.15, p) # 约束:崩盘概率 = 15%python后验精确达成崩盘概率 = 15.00%,代价是股票月均从 0.58% 被压到 −0.28%(概率质量被赶到崩盘情景,那些情景股票都很差)。这次对先验的扭曲大得多:KL(q2‖p)=0.068,是软观点的 5.6 倍。
把两个后验分别喂给均值-方差优化器(用后验情景重算 μ=E_q[X]、Σ=Cov_q(X)),配置变化立竿见影:

| 配置 | 股票 | 债券 | 黄金 |
|---|---|---|---|
| 先验(无观点) | 17.0% | 71.6% | 11.4% |
| 观点1:看多股票 | 29.1% | 59.5% | 11.4% |
| 观点2:崩盘压力 | 1.6% | 87.2% | 11.2% |
一个看多观点让股票 +12 个点;一个崩盘压力直接把股票砍到近乎清零、债券加到 87%。观点不是装饰,它直接改写了整张配置表。
五、压力阶梯:观点越强,扭曲越大#
把崩盘目标从 3% 一路抬到 40%,观察股票权重与 KL 的联动:

曲线非常干净:崩盘目标每升一档,股票权重单调递减(去风险),同时 KL 单调上升(对先验的偏离变贵)。这就是熵池化最诚实的地方——它把「你有多自信」量化成了「你愿意离数据多远」,二者通过 KL 一一对应。风控可以用 KL 给投研的观点设预算:「这个季度全组合的观点总 KL 不得超过 X」,本质上就是给主观判断上了仓位上限。
六、真实陷阱(落地前必须知道)#
- 先验质量决定天花板:熵池化只在「先验已经包含了相关结构」时好用。如果先验情景里根本没有 −30% 的崩盘样本(例如只用平稳期数据),你再怎么倾斜也「造」不出没见过的尾部——它只能重新分配已有情景的概率,不能凭空生成新情景。
- 约束必须可识别:对 4000 个
q_k只给 1~2 个矩约束,是高度欠定的;熵池化用「最小 KL」这个额外原则唯一确定解。但如果你的观点与先验严重冲突(比如要求股票月均 10%),解会塌缩到单个极端情景(KL→lnK),此时「最小 KL」已失去平滑意义,应当拒掉该观点。 - 过自信惩罚的是自己:KL 随观点强度超线性增长,强观点会过度集中仓位。实践中应对观点强度做 shrinkage(如
μ_eff = (1−ρ)μ_prior + ρμ_view),等价于在 KL 里加一个对先验的拉力。 - 与 Black-Litterman 的区别:BL 通常用正态先验 + 正态观点、解析解;熵池化不要求任何分布假设,只吃情景和线性约束,因此能处理非高斯、非参的先验(历史模拟、蒙特卡洛、甚至机器学习生成的情景集),这是它在量化实操里更通用的原因。
- 计算复杂度:每次
ep_solve要扫全部 K 个情景,牛顿迭代几十步;组合里有几十个资产、几百条观点时,可改用稳健一阶法(梯度上升 + 主动集处理不等式约束)。
七、小结#
熵池化把「主观观点」这件模糊的事,变成了一个有数学定义的优化问题:在精确满足观点的前提下,对先验做最小破坏。它的产物 q ∝ p·exp(λf) 既是概率分布,也是一套可直接进组合优化的输入;而 KL 散度则天然充当「观点强度」的记账单位。下一篇我们聊一个反直觉的实证发现——低风险股票长期跑赢高风险,那又是另一种「数据在说话、理论在脸红」的故事。
(本文情景为自洽合成,仅用于演示熵池化机制;真实落地请用机构的历史模拟/蒙特卡洛情景集作为先验 p,并把投研观点写成可核验的线性矩约束。)