把巴菲特和量子投资组合优化放进同一个句子里,乍看像是一个跨服聊天现场。但如果你把巴菲特过去几十年的资本配置决策摊开看,会发现那本质上是一长串"组合优化问题的高质量解":在几十只候选标的中选哪些、每只配多少、最多押几只、留多少现金缓冲。这些问题一旦写成数学约束,就变成带整数变量的二次优化。而这类问题,恰恰是量子退火最常被研究的应用场景。这篇文章想聊的,不是"量子马上要取代主观投资"这种浮夸叙事,而是:巴菲特式配置原则如何转译成可计算的组合优化模型,QUBO矩阵怎么搭、惩罚项怎么调、现阶段量子硬件的限制在哪儿,以及跑出来的权重又如何回到长期主义的校验框架里。适合对量化投资感兴趣的基金经理助理、量化研究员,以及想给传统组合管理流程引入新工具的工程师参考。
1. 巴菲特式配置的内在数学:集中持仓如何变成约束
1.1 从"少而精"到基数约束:巴菲特式集中的数学实质
巴菲特有句流传很广的话,大意是"分散化是保护无知的手段"。这句话放到现代组合理论的坐标系里,几乎是在和马克维茨唱反调。马克维茨的均值-方差框架默认把所有风险资产都装进一个篮子里,再用协方差矩阵把相关性摊平;巴菲特则把注意力压到极少数标的上,用深度的企业基本面理解来抵消集中持仓带来的波动。
但这两种思路并非水火不容。关键分歧只在于:马克维茨模型没有约束"持仓数量",所以它天然鼓励分散;而巴菲特的实践在数学上等价于给优化问题加了一条"最多持有k只股票"的约束。这条约束在学术上有一个非常明确的名字:基数约束(cardinality constraint)。
把均值-方差模型改写一下就清楚了。假设你有一个候选股票池,共n只标的,权重向量为w,预期收益向量为μ,协方差矩阵为Σ,那么经典配置问题写作:
min wᵀΣw - λμᵀw s.t. Σᵢwᵢ = 1, 0 ≤ wᵢ ≤ 1
如果加入"最多选k只股票"的限制,优化问题会变成:
min wᵀΣw - λμᵀw s.t. Σᵢwᵢ = 1, ‖w‖₀ ≤ k, 0 ≤ wᵢ ≤ 1
其中‖w‖₀表示权重向量中非零元素的数量。‖w‖₀ ≤ k看起来只比原来多了一个小小条件,但它把问题从连续的二次规划(QP)变成了混合整数二次规划(MIQP)。n只有几十只时,经典分支定界法还能扛得住;当n扩展到几百只、还叠加行业暴露限制、单票上限、换手惩罚时,求解规模会迅速膨胀。
这就是量子投资组合优化出现的直接理由:退火设备天然处理二进制离散变量,而"买或不买"恰恰就是0/1决策。把整数变量映射成量子比特的取值,是对偶问题天然吸引人的地方。
1.2 能力圈与安全边际:进优化器之前发生了什么
很多人讨论巴菲特时只盯着"集中持仓"这个结果,忽略了他做配置前先做的一次重要操作:把不符合能力圈的标的直接剔除出股票池。这一步过滤器,本质上是在给优化器划定可行域。
能力圈在数学上的体现不是权重,而是资产池的准入条件。你的模型可以在几百个变量上寻找最优加权,但如果池子里混入了你完全不了解的公司,优化器并不会替你识别风险,它只会找出数学意义上的最优解。这一点常被量化新手忽略——他们花大量时间折腾优化器参数,却对输入端的资产质量不做任何审查。
安全边际则需要翻译成期望收益的取值方式。巴菲特的习惯是不依赖精确预测来买股票,而是要求价格比内在价值有明显折让。在组合优化模型里,这对应的操作是:对每只股票的预期收益率μᵢ打一个审慎的折扣,而不是把卖方一致预期直接填进去。你可以把它理解成"参数对冲"——让μ值偏保守,模型给出的权重才不容易因为预测偏差而崩坏。
所以到这里可以总结一个判断:巴菲特式配置的数学本质是"带约束的二次优化"。这个约束包括基数上限、单票上限、能力圈过滤后的股票池、以及打折后的预期收益。剩下的问题,是怎么把这些约束和偏好装进一个量子计算能处理的模型里去。
2. 量子投资组合优化的QUBO建模:把偏好写成矩阵
2.1 为什么量子退火恰好适合离散配置问题
量子投资组合优化这个词,最近在金融科技圈变得很热,但真正把它落到模型层面,核心就一句话:把组合优化问题转化成QUBO(Quadratic Unconstrained Binary Optimization)形式,然后交给退火设备或者模拟器去搜索低能量状态。
QUBO的标准形式长这样:
H(x) = Σᵢ qᵢxᵢ + Σᵢⱼ Qᵢⱼxᵢxⱼ
其中xᵢ是二进制变量,取值0或1。二次项的系数构成矩阵Q,线性项可以放在Q的对角线上。整个问题的目标是找到一组二进制取值,使得能量函数H最小。
为什么连续梯度下降那一套经典优化方法在这里不太行?因为权重配置里的"选哪几只"是离散跳变的。你在连续空间里求导、做梯度下降,得到的是一个接近满仓分散的解,而不是"只押3只"的稀疏解。退火设备不一样,它用二进制变量直接做搜索,天然适合处理这种组合爆炸问题。
实际建模时,想把组合优化翻译成QUBO,最常用的路线是把权重离散化:每只股票的权重不是任意的连续实数,而是一个可选档位集合。档位可以是0、5%、10%、20%,甚至更高。每一档对应一个二进制变量,优化器要做的是在这些档位里选出一组组合,满足满仓约束和持仓数量约束。
2.2 QUBO矩阵的构造与惩罚项调参逻辑
我们把前面的均值-方差框架改写成QUBO。假设wᵢ是一段连续的权重,但每个股票只能从若干离散档位里取一个值。于是组合优化的能量函数可以写成:
H(w) = (1/2)wᵀΣw - λμᵀw + ρ(Σᵢwᵢ - 1)² + κ(‖z‖₀ - k)²
逐个解释这些项:
第一项是风险项,它让模型回避高方差和高相关的组合。第二项是收益项,λ是风险厌恶系数,λ越高模型越激进。第三项是满仓惩罚项,逼着所有权重之和逼近1。第四项是基数惩罚项,z是每只股票的持仓标志向量,这一顶强逼优化器把非零持仓的数量压到k附近。
具体到QUBO矩阵上,每个位置上的系数是这么来的:如果股票i和股票i′的权重都是二进制变量的线性表达,那么协方差Σᵢᵢ′乘以这两个权重表达后,会展开成一组二进制变量的二次项,这些二次项的系数就填进Q矩阵的对应位置。同理,收益项展开后产生线性项系数。满仓惩罚和基数惩罚展开后,各自贡献一批二次项和线性项。
这里面最容易被低估的是惩罚参数的选择。ρ和κ的目标是让约束被满足,但它们不能无限大。第一,量子硬件或者模拟器上的数值精度有限,惩罚项太大时,约束项的数值会淹没真正的风险收益信息,导致模型只"记得"遵守约束、完全忘了组合质量。第二,从物理学角度看,过大的惩罚会拉高能量标度,退火过程容易出现能量势垒过陡、隧穿失效的问题。
我自己的做法是"参考解校准法":先用经典求解器跑一个简化模型,拿到一个可行的连续解,看看这个解在目标函数各项上的数量级;然后设置ρ和κ,使惩罚项数值是目标项数值的10到100倍;最后再做一次扫描,检测不同惩罚系数下合法解的比例。
2.3 权重编码与离散精度
权重从连续值变成离散档位,具体怎么做?最直接的是one-hot编码:给每只股票定义m个档位,设v₁,v₂,...,vₘ是允许的权重值,再把"选第j档"映射为二进制变量xᵢⱼ=1。于是股票i的权重可以写成:
wᵢ = Σⱼ vⱼxᵢⱼ
强制每只股票必须恰好选一个档位,需要加入one-hot约束:Σⱼxᵢⱼ = 1。这个约束在QUBO里也是用惩罚项实现的,系数可以合并进建设好的矩阵里。如果该股票可以完全不持仓,那么档位集合里要包含0这一档。
档位粒度的选择值得多说一句。粒度越细,变量越多,QUBO规模越大;粒度太粗,又可能找不到合规的满仓组合。比如你只允许5%、10%、15%和20%四档,但股票池只有6只股票,20%×6最多120%可以满仓,问题不大;但如果要求最多持仓3只,每只最高只有20%,满仓就根本做不到,优化器只能返回一个非法解。所以在设计档位的时候,一定要先确认最极端的约束场景是否可达。这是一个我在早期实验中踩过的坑:花了半天调参数,最后发现是档位上限设计得太保守,根本不存在可行解。
3. 量子退火实战:从QUBO到可执行持仓的完整流程
3.1 最小可复现案例设计
理论讲完之后,最重要的是能跑通一个端到端的流程。我以一个示意性的小案例为例:股票池8只标的历史日收益率数据,目标是选最多3只标的,权重档位设置为0、10%、30%、60%四档,满仓约束严格等于1。
为什么选8只、4档这么小的规模?因为QUBO变量数大约等于8×4=32个二进制变量,在本地模拟器上可以快速调试,又能完整走一遍从建模、采样到解码的流程。做量化研究有个原则:先在最小规模上验证全部约束和代码逻辑,再放大量级。直接拿几百只股票的池子上量子硬件,出了问题你根本分不清是建模错误还是硬件噪声。
案例中使用的历史收益向量和协方差矩阵都是随机生成的示意数据,但这不影响流程演示。关键点是:真实的预期收益估计和协方差估计应该来自可靠的统计模型,比如用Ledoit-Wolf收缩估计来做协方差去噪。
3.2 构建QUBO矩阵的Python核心代码
我用Python和dimod库来实现。核心逻辑是遍历所有股票对、所有档位对,把协方差项、收益项、满仓惩罚和基数惩罚展开成QUBO系数。对刚接触QUBO的人,我建议先不要用自动转化工具,自己手写一遍系数展开,能帮你建立起对Q矩阵结构的直觉。
from collections import defaultdict def build_qubo(mu, cov, lam=0.8, rho=600.0, kappa=900.0, k=3, values=(0, 0.1, 0.3, 0.6)): n = len(mu) # 股票数量 m = len(values) # 档位数量 Q = defaultdict(float) def flat(i, j): return i * m + j # 把二维变量映射成一维索引 # 1) 风险项和收益项 for i in range(n): for j in range(m): # 收益项线性系数 Q[(flat(i, j), flat(i, j))] += -lam * mu[i] * values[j] for ip in range(n): for jp in range(m): coeff = cov[i][ip] * values[j] * values[jp] Q[(flat(i, j), flat(ip, jp))] += coeff # 2) 满仓惩罚项 rho * (sum(w) - 1)^2 # 展开: rho * (sum(w)^2 - 2*sum(w) + 1), 常数项在优化时省略 for i in range(n): for j in range(m): for ip in range(n): for jp in range(m): Q[(flat(i, j), flat(ip, jp))] += rho * values[j] * values[jp] Q[(flat(i, j), flat(i, j))] += -2.0 * rho * values[j] # 3) 基数惩罚项 kappa * (count_nonzero - k)^2 # 每只股票持仓标志: z_i = sum_j x_ij (values[j] > 0) # 但更稳的做法是显式展开系数,简化展示省略详细展开 for i in range(n): for j in range(m): if values[j] > 0: Q[(flat(i, j), flat(i, j))] += -2.0 * kappa * k for ip in range(n): for jp in range(m): if values[jp] > 0: Q[(flat(i, j), flat(ip, jp))] += kappa return dict(Q) # 然后转成dimod三模型并采样 import dimod mu = [0.0012, 0.0008, 0.0015, 0.0010, 0.0009, 0.0014, 0.0011, 0.0013] cov = [[0.0004 if i == j else 0.0001 for j in range(8)] for i in range(8)] Q = build_qubo(mu, cov) bqm = dimod.BinaryQuadraticModel.from_qubo(Q) sampler = dimod.SimulatedAnnealingSampler() sampleset = sampler.sample(bqm, num_reads=2000)这段代码里的成分并不复杂,但有几个细节值得注意:风险项展开时,对角线元素产生了二次变量和自身的交互,实际QUBO中x_{i,j}²等于x_{i,j},所以程序运行时会自动落入线性项;满仓惩罚里的常数项1在优化过程中不影响变量取值,可以直接忽略。
初次运行可能会发现解不满足"每只股票只选一档"的one-hot约束,因为我在代码里没有显式加入one-hot惩罚。这在实际建模中是必须的。通常做法是再加一项γΣᵢ(Σⱼxᵢⱼ-1)²,γ设置为比风险和收益项高一个数量级。我在示例里有意省略,是想让读者意识到"约束项不齐全会出现什么结果"——你会得到一个权重表达混乱的非法组合。
3.3 采样、解码与结果有效性检查
拿到采样结果后,第一步不是看收益,而是检查可行性。我通常按这个顺序做事:
先取能量最低的前100个样本,逐个检查满仓误差、持仓数量、one-hot合法性和单票权重上限是否合规;统计可行样本占比。如果占比低于90%,说明惩罚参数太弱,需要调高ρ、κ或γ;如果占比很高但目标函数值比经典解差太多,说明惩罚参数过强,把目标项压扁了。
解码权重时,把每个变量按档位取值还原。例如某只股票在最低能量样本中non-zero档位是第2档,取值30%,那这只股票的权重就是0.3。全部解码之后再求和检查满仓。
有一种常见误解是"能量最低的样本就是最好答案"。实际中,因为惩罚项和目标项的量级不同,最低能量样本往往来自惩罚项未被满足的局部极小值。所以我的习惯是:把最低能量的50个样本都解码,看它们的解是否稳定收敛到同一个组合。如果排名前几的样本频繁出现完全不同的持仓组合,说明问题本身的惩罚不够强,模型正处于"目标函数不平坦"的状态。这时候再去调风险厌恶系数λ,出来的权重往往会大相径庭。
这个环节也是一台真正的"信心考验机"。很多人跑通流程后会直接相信模型的输出,而我更建议先人工复核一下:模型选出的组合是否让你自己觉得安心?若某个重仓标的你连业务模式都讲不清楚,那不是模型错了,而是资产池筛选环节出了问题。回到巴菲特的能力圈原则,优化器永远无法替你补上认知短板。
4. 经典求解器的降维打击:量子硬件的真实边界
4.1 诚实的现状:几十个变量之外的噪声困境
在把量子投资组合优化推向真实市场之前,有必要先把聚光灯转向硬件限制。量子退火设备目前能处理的QUBO规模并不大,原因有三个。
第一是量子比特数量与连接度的限制。以超导量子退火设备为例,比特之间的连接不是全连接的,而是受物理拓扑约束的。一个结构稀疏的Q矩阵,往往会因为嵌入问题被迫复制变量、消耗大量额外比特,实际可嵌入的问题规模远低于标称比特数。
第二是精度问题。QUBO系数在硬件上需要被转换成模拟信号的耦合强度,而硬件自身有噪声和校准误差。惩罚系数一旦超过某个量级,硬件给出的结果甚至会与模拟器产生显著偏差。我的经验是,当你看到某些论文里为了强行满足约束把惩罚项设成1e6量级时,就要对结果的可靠性打一个大问号。
第三是采样质量。退火设备的一次运行只能得到一次近似采样,你需要大量重复采样再统计分布。对金融场景来说,这个问题还叠加了矩阵本身的病态性:协方差矩阵估计误差一旦偏大,QUBO结果会比经典求解器更敏感,因为能量面的局部极小值非常不稳定。
4.2 为什么经典优化器在数千变量上依然碾压
这里说句可能不少人不太爱听的话:对绝大多数现实中的组合优化问题,经典求解器仍然是当前的最优选择。Gurobi、MOSEK这类成熟的MIQP求解器,处理两三千个变量、几十条约束的配置问题,往往能在秒级到分钟级给出相当好的可行解。相比之下,纯量子退火硬件在处理同样规模时,单是嵌入步骤就可能失败。
为什么会这样?经典分支定界法在过去几十年积累了大量启发式剪枝技术,对稀疏的金融问题非常有效。而金融场景中的投资组合优化矩阵通常并不具备"量子优势"所需的特殊结构。许多科技新闻里宣传的"量子加速"往往只在极端合成数据下成立,且忽略了端到端流程中问题传输、嵌入和采样后处理的巨大开销。
一个明确的判断是:现阶段纯量子硬件适合研究和小规模验证,真正进入生产环境时,混合架构比纯量子架构务实的多。
4.3 混合解算器:当前真正可落地的路线
混合解算器的思路很简单:让经典计算机处理大规模、结构良好的那部分问题,把最棘手的离散子问题交给量子处理器。这种模式在D-Wave的Leap平台上已经运行多年,用户体验就是提交一个QUBO或CQM(Constrained Quadratic Model),云端自动调度经典和量子资源。
对于个人研究者和中小型团队,这是最推荐的路线。你不需要关心比特拓扑、嵌入细节,只要把QUBO写清楚,设置好超时时间,就能拿到一组不错的候选解。我在自己的实验里用200只股票、每只8个权重档位,变量数大约1600个,纯QPU在嵌入阶段就卡住了;同样的模型提交给混合求解器,几十秒内返回了质量尚可的解。
但混合求解器也非万能。它仍然要求你把问题完整地表达成QUBO或CQM,惩罚参数的选择依然会影响结果质量。这意味着,即使你使用了混合求解器,前面章节里的调参经验、可行性检查流程一个都不能省。工具变了,工程纪律不能变。
5. 结果解读与动态化:向长期主义的回归
5.1 单期模型的局限:跨期稳定比单次最优更重要
量子投资组合优化跑出来的结果,天然是一次"单期快照"。它告诉你在当前给定参数下,最优的持仓结构长什么样。但巴菲特式配置强调的恰恰是跨期持有的耐心,而不是在每个时点都追求静态最优。
单期模型的常见问题是:换一个月的收益率样本,最优组合可能剧烈变化。今天模型说该重仓A和B,下个月可能就换成C和D。如果直接照做,交易成本会吃掉大部分超额收益,而且组合缺乏延续性。这种波动本身不是量子优化器的缺陷,而是均值-方差框架对参数估计过于敏感的老问题。
应对办法是在QUBO里直接加入换手惩罚。记上一期权重为w₀,当期权重为w,在目标函数里增加一项γ‖w - w₀‖²,惩罚偏离上一期持仓的组合。这一项同样是二次的,可以无缝并入Q矩阵。引入换手惩罚后,模型输出的权重会天然向上一期组合靠拢,只有在新数据提供的预期收益和风险改善足够大时,才愿意改变仓位。这其实和"长期持有、只在逻辑变化时调整"的投资纪律非常吻合。
5.2 把持有期与稳定性放进同一套管道
如果你想把这套流程做成一个真正的决策支持系统,建议做三件事。
第一,把资产池筛选前置成一个独立模块。用基本面指标做粗筛,比如连续多年ROIC高于阈值、资产负债率低于某个门槛、管理层持股比例不低于某个比例。筛完之后,再把通过的标的送进量子组合优化器。这个"能力圈编码"步骤,比任何优化参数都重要。
第二,对λ和k做walk-forward敏感性分析。不要拍脑袋定风险厌恶系数和持仓数量上界,而是把历史数据切成滚动窗口,回测不同参数组合下的组合表现,看哪些参数在跨周期时依然稳定。
第三,把模型的输出当作"决策支持和对抗性核查"工具,而不是直接下单的自动交易信号。我个人的工作习惯是:拿到优化器的权重后,要求自己对每一个重仓标的写出一句话解释。解释不清楚就删掉,手动替换成下一个有把握的标的。这个看似违背优化器的操作,恰恰是能力圈在最终决策环节的落定。
5.3 权重是结果,资产池质量才是起点
用数学语言讲,QUBO优化器解决的是"给定候选集时的最优分配问题",它不解决"候选集本身是否值得买"的问题。巴菲特的资本配置艺术,最大的权重在输入端:他花大量时间阅读、调研、筛选,最后把一个上百只股票的投资宇宙压成他真正理解的十来个标的。优化器只是在那个已经极度压缩的可行域里做最后的权重分配。
对于想把量子投资组合优化用起来的读者,我最想传达的一点是:不要把模型当成预测机器,把它当成约束求解器。它擅长的是在你做清楚所有偏好约束之后,找到一组符合约束的、统计意义上较优的权重;但如果你的候选池里塞满了看不懂的高波动标的,再好的退火设备也救不了你。
我自己在实际操作中的体会是,量子优化项目在金融场景中最有价值的产出,不是那些权重数字本身,而是它逼你把投资哲学写成了数学约束。当你不得不回答"我能持有多少只股票""哪些东西我坚决不碰""我给预期收益打几折"这些问题时,你的投资框架已经被迫变得异常清晰了。单就这一点,这套工作流就值得认真试一次。