周五下午三点,你在某 公募 基金管理一只 沪深300 指数增强(CSI 300 enhanced index)产品。当前基金合同把年化 跟踪误差(tracking error)上限设在 300 bp。求解器把当日再平衡的解返回过来——主仓位都合理,但对偶价格表里 跟踪误差 约束的乘子写着 −ντ∗≈−35 bp。翻译成 PM 听得懂的语言:若把上限从 300 bp 放到 400 bp,每放宽 100 bp 大约能换回 35 bp 的预期 Alpha。你把这一行截图发给 PM;半小时后投委会回话——合同的活跃风险预算改到 350 bp,下周一生效。这一节要让你能像 PM 一样,把求解器的原始输出读成「可议价的边际」。
之前三节课你掌握了凸集、标准形式与 KKT 条件这套抽象工具。本节把它们装配成 资产管理 行业能直接用的产物:一只 长仓(long-only)公募 增强基金的 组合优化(portfolio optimization)。我们从最简单的 均值方差优化(mean-variance optimization, MVO)开始,每加一层 mandate 就上升一层锥——LP → QP → 二阶锥规划(second-order cone program, SOCP)→ 半定规划(semidefinite program, SDP)——并把每一层求解器返回的 对偶变量 译成 PM 听得懂的话。
长仓 MVO 与 KKT 系统
记 w∈Rn 为权重,μ 为预期收益向量,Σ 为 协方差矩阵(covariance matrix,假设 半正定(positive semidefinite, PSD))。最基础的长仓全仓问题写作:
wmin21wTΣw−λμTws.t.1Tw=1,w≥0.
引入预算乘子 ν∈R、长仓乘子 η∈R≥0n,KKT 系统为
Σw∗−λμ+ν∗1−η∗=0,1Tw∗=1,w∗≥0,η∗≥0,ηi∗wi∗=0.
互补松弛条件 ηi∗wi∗=0 的 PM 读法:若某只 A 股在最优解上 wi∗=0 而 ηi∗>0,说明求解器本想做空它 ηi∗ 单位的「风险调整 Alpha 边际」,但 公募 不允许做空个股,于是 mandate 把这块边际硬压回零。KKT 把每只名字「想空的强度」变成了一个可读的数——这是它在投研日报里的真正用法。
把 mandate 一层一层叠上去
继续按 沪深300 增强 真实合同的形状加约束。
- 行业暴露上限:对每个行业 s 写 1sTw≤cs;以 CSI 300 行业权重为锚,典型偏离 ±3%。仍是线性约束,问题保持 QP。
- 换手率约束:相对上次持仓 wprev,要求 ∥w−wprev∥1≤T。ℓ1 范数不可微,但引入辅助变量 ui 满足 ui≥wi−wi,prev、ui≥wi,prev−wi,约束改写为 ∑iui≤T,重新落回线性。T≈250% 年化是 公募 增强 mandate 的典型上限。
- 跟踪误差 上限:相对 基准 权重 wb(CSI 300 各成分权重),ex-ante 活跃风险约束写为
∥A(w−wb)∥2≤τ,ATA=Σ.
这里 A 是 Σ 的 Cholesky 因子;凸性由 ATA=Σ 这一步「锁住」,约束变成标准 二阶锥。把 (1)(2)(3) 与预算、长仓拼到一起,整个 mandate 就是单一 SOCP——能直接喂给 CVXPY + ECOS 或 Mosek 等现代锥求解器。
Formula Explorer
sqrt((w - wb)' * Sigma * (w - wb))
把 w 往 wb 拽一点,τ 就能再松一截;这是约束「活」的部分,也是 PM 与风控议价时最常拿来比较的曲线。
最大 夏普比率:齐次化技巧
PM 有时不想调 λ,而想直接求切线组合(tangency portfolio),即最大 夏普比率(Sharpe ratio):
wmaxwTΣwμTw,1Tw=1.
裸写不是 凸 问题——分子线性、分母是二次根,比值结构两层都不可控。技巧是齐次(homogenization)替换:令 y=w/(μTw)、t=1/(μTw),问题等价为
yminyTΣys.t.μTy=1,y≥0,
求解后用 w∗=y∗/(1Ty∗) 拿回切线组合权重。这是一道干净的 QP,CVXPY 调 ECOS 几毫秒就能跑完——比直接对原比值做非凸搜索可靠得多。
鲁棒 MVO:再上升到 SDP
最后一层:把 Σ 本身也当作不可信。在 量化研究 里,Σ^ 来自样本协方差或 因子模型(factor model),噪声本身就有 O(n2) 量级;把它 plug-in 进 MVO 等于盲信。鲁棒版本写成
wminΣ∈UmaxwTΣw−λμTw,U={Σ:ΣL⪯Σ⪯ΣU}.
其中 ⪯ 表示 半正定 偏序。把内层「最坏 Σ」的对偶取出来,整体落到一个 SDP;其对偶给出的影子价格直接读作「协方差不确定性的边际成本」——这是 PM 在 mandate 谈判时第二常问的数字,仅次于 跟踪误差 的影子价格。
求解器输出怎么读
在 私募 / 公募 量化研究 场景里,研发期用 CVXPY + ECOS / SCS,量产期 私募 通常切到 Mosek 或 Gurobi 经 Python wrapper 调用。输出里你最该盯的不是 w∗,而是:
- 预算乘子 ν∗:每多一元资金的边际预期 收益;
- 跟踪误差 乘子 ντ∗:每放宽 1 bp 跟踪误差 能换的 Alpha——hook 里那 35 bp / 100 bp 就来自这里;
- 行业乘子:哪些行业上限正在 binding,常意味着模型在该行业被 mandate 截掉了一笔强信号。
若返回 infeasible,分两种诊断:mandate-fault 是约束互相矛盾(行业上下限不留预算、turnover 与再平衡幅度冲突),需要升到 PM 一级沟通;data-fault 是 Σ^ 被估计噪声破坏了 半正定 性,先做最近 PSD 投影再重跑。
练习:手算 3 资产 KKT
Exercise
设 3 资产小组合,μ=(0.10, 0.08, 0.02)T,
Σ=0.040.0100.010.0250000.01,λ=1.(i) 写出长仓全仓 MVO 的完整 QP 与对应 KKT 系统;(ii) 凭手算(KKT + 试探哪条长仓约束 active)求 w∗;(iii) 给出预算约束的 对偶值 ν∗,并把它解读成 shadow price——「每多一元再平衡资金的边际预期 收益」。
提示
先猜「全是内点」:假设
w>0 都严格成立,KKT 退化为
Σw−μ+ν1=0 与
1Tw=1 的四元一次方程组。若解出的
w 某一分量为负,说明那只名字实质想做空——把对应
wi 拍到 0,把
ηi 设为活跃后重解剩下的方程。
提示
资产 3 active:
w3=0,
η3=ν∗−0.02;
w1=7/9、
w2=2/9、
ν∗=1/15≈0.067、
η3≈0.047。约定
L=f0+ν(1Tw−1) ⇒
∂p∗/∂b=−ν∗;
f0 是风险减收益,
−ν∗ 译作「预算 +1 元,净预期收益 +6.7%」。
下一站
到这里你已经能把一只 沪深300 增强 mandate 完整地映射成 QP / SOCP / SDP,并把对偶值翻成 PM 听得懂的「可议价边际」。但你还没真正解过这些问题——CVXPY 调的是黑盒求解器。下一模块 2.5.2「迭代与正则化方法」会打开那个盒子:内点法(interior-point method)、ADMM、proximal splitting 是怎么把 SOCP / SDP 收敛到指定精度的;当 Σ^ 的噪声让上面这套不稳时,岭回归(ridge)、Lasso 与弹性网(elastic net)又怎么把统计估计层接回优化层。本模块给你 mandate 的语言;下一模块给你执行 mandate 的引擎。