深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

工具实战

【cvxpy 系列 第1讲】量化适用边界与约束转化入门

本文系统构建cvxpy在量化研究中的‘问题可解性判定框架’,严格界定凸优化适用边界:从目标函数曲率、约束集几何性质到数值可实现性三维度展开。详解线性/二次/指数锥等常见凸结构映射路径,给出12类典型量化场景(含风险预算、杠杆约束、行业暴露硬限、VaR软惩罚)的cvxpy建模范式与反例推演,并提供约束松弛度量化评估表、KKT残差诊断模板及不可凸化问题的替代建模策略。

2026-04-21 智铨研究 阅读时长 16 分钟

目录

cvxpy量化优化完整学习计划 · 工具实战

  1. 第 1 讲【cvxpy 系列 第1讲】量化适用边界与约束转化入门
  2. 第 2 讲【cvxpy 系列 第2讲】建模基础:变量、目标函数与约束表达

一、目标与场景:cvxpy 在量化研究里到底解决什么问题

很多人第一次接触 cvxpy,会把它想成一个“把收益和约束写进去,系统自动给最优答案”的工具。这种理解不能说全错,但很容易带来两个误区。第一个误区,是把任何组合问题都往凸优化里塞;第二个误区,是只盯着最后那组权重,却不检查问题本身是不是写对了。对量化研究来说,cvxpy 真正有价值的地方,从来都不只是求解,而是强迫研究者把目标、约束、边界和权衡关系写得足够清楚。

在组合研究里,你经常会碰到几类典型问题。比如我想在不做空的前提下最小化波动;我想控制行业暴露,又不希望单一资产权重过大;我想做一轮再平衡,但换手不能超过某个上限;我想在目标收益和风险之间找一个更透明的折中。只要这些问题能被表达成清晰的凸结构,cvxpy 就很合适。它让你面对的不是“拍脑袋配权”,而是“把问题本身写清楚,然后看结果是否支持你的研究逻辑”。

但反过来,如果问题里充满离散选择、强路径依赖、复杂的交易分段规则,或者很多约束天然不是凸的,那就不应强行用 cvxpy 去硬解。一个成熟研究者首先要学会的,不是怎么写更多优化器代码,而是先判断:这个问题是否真的适合放在凸优化框架里。如果这一步判断错了,后面无论换多少求解器,结果都只会越来越乱。

二、环境准备:先把依赖和数值条件做稳

入门阶段并不需要很复杂的环境。通常准备 cvxpynumpypandas 就够了。如果只做小规模实验,常见的求解器配置已经足以支撑学习。真正值得注意的,不是“要不要上更高级的求解器”,而是你在送问题进去之前,是否已经把输入数据检查干净。很多人以为求解失败是库不稳定,实际上往往是收益率、协方差、权重边界、惩罚项量级差得太远,导致数值条件变得很差。

因此,准备阶段至少要做三件事。第一,确认你要优化的是价格数据还是收益数据,二者不要混用。第二,确认协方差矩阵是对称、维度一致且没有明显异常。第三,确认约束里的数字量级和目标函数大体匹配,避免出现目标函数是小数级别、惩罚项却放大几十倍的情况。只要这几件事没做好,后面哪怕问题数学上可解,求解过程也很容易表现得不稳定。

另外,建议从一开始就固定一个最小实验环境。比如三到五个资产、一份小型收益矩阵、一套清晰的边界条件。不要一开始就拿几十上百个资产做完整组合,这样一旦结果异常,你几乎没办法迅速判断到底是数据问题、建模问题还是求解问题。小问题先做清楚,是 cvxpy 入门最划算的路径。

三、操作步骤:三资产最小波动模型怎么搭

对于入门者来说,最值得亲手敲一遍的不是复杂框架,而是最小波动模型。它足够简单,又能完整体现目标、约束和求解这三层逻辑。一个典型的最小示例通常只包含三件事:定义权重变量、最小化组合波动、加上权重和为一与不做空限制。

import cvxpy as cp
import numpy as np

cov = np.array([
    [0.04, 0.01, 0.00],
    [0.01, 0.09, 0.02],
    [0.00, 0.02, 0.06],
])

w = cp.Variable(3)
objective = cp.Minimize(cp.quad_form(w, cov))
constraints = [
    cp.sum(w) == 1,
    w >= 0,
    w <= 0.6,
]

problem = cp.Problem(objective, constraints)
problem.solve(solver=cp.ECOS)

print(problem.status)
print(w.value)

这段代码短得不能再短,但它足够让你回答几个关键问题。为什么目标函数是 quad_form,而不是别的形式。为什么单资产上限要存在。为什么不做空约束会改变最终分布。为什么同一个协方差矩阵里,某些资产天然更容易被压低权重。只有当你能解释这些问题时,cvxpy 才不再只是一个“我跑通了”的库,而是一个“我知道自己在表达什么”的建模工具。

很多人学到这里就急着往上叠约束,这时最容易出问题。正确的顺序应该是先确认这个最小例子状态正常、结果稳定、轻微改动输入时输出不会完全失真。只有这一步扎实了,再往上加行业约束、目标收益或换手惩罚,才不会完全失去判断基准。

四、从最小模型扩展到研究模型:一层一层加条件

真正的组合研究很少只停留在最小波动。你通常会继续加行业约束、目标收益、上一期权重、换手限制,甚至加入一定程度的风险预算近似控制。但这里最重要的不是“加得越多越好”,而是每次只加一层,并且记录加完以后模型发生了什么变化。

比较稳妥的扩展路径可以是这样的。第一层,在最小波动问题上加行业暴露约束,看看可行域是否明显收窄。第二层,再加预期收益下限,观察权重是否开始频繁贴边。第三层,引入上一期权重与换手约束,检查再平衡结果是否比静态配置更敏感。第四层,如果仍然稳定,再考虑加入更接近实务的业务条件。

这种分层扩展的价值在于,一旦出问题,你能定位是哪一层开始让模型变得脆弱。若反过来一开始就把目标收益、行业中性、换手限制、上下限、惩罚项全部塞进去,最后只要结果一怪,你几乎没办法知道该怀疑哪一个部分。很多团队会在这时把问题简单归咎于求解器,其实真正的问题通常是:模型表达从一开始就没有被逐层验证。

五、结果解释:有解不代表问题就健康

cvxpy 最危险的使用方式,不是完全跑不出来,而是顺利跑出了一组数字,于是大家默认问题已经解决。实务里恰好相反。有解只能说明“从当前表达看,求解器找到了一个可接受的答案”,并不能说明这个答案在金融上合理、在研究上稳健、在实盘上可用。

因此,每次求解后最应该先看的不是权重,而是状态。是不是 optimal。目标值有没有突然跳变。约束有没有长期贴边。输出权重是不是极端集中在几个资产上。稍微换一个样本区间或参数,结果会不会完全翻面。只要这些问题没有回答清楚,就不能急着解释“为什么这个资产权重大”。

特别要注意一种假稳定现象,即结果每次都能解出来,但关键约束长期贴边。例如单资产上限总是被顶满、行业约束总是压在边界上、或者目标收益下限每次都只差一点就不可行。这类现象往往说明你写出来的模型虽然还在工作,但表达已经非常脆弱。若不及时回头调整结构,后面只要数据稍微变化,模型就会从“还能用”直接跳到“完全不稳”。

六、问题排查:先查可行性,再查数值,再查业务表达

遇到求解问题时,最需要固定的是排错顺序。第一步,先查可行性。也就是这些约束从逻辑上能不能同时成立。很多人会在这一步偷懒,结果明明是目标收益和风控边界互相打架,却一直在换求解器。第二步,查数值条件。收益率、协方差、惩罚项量级是否失衡,矩阵是否病态,数据中是否含有明显异常。第三步,才查业务表达,也就是当前写法是否真的对应你想研究的问题。

这个顺序非常重要,因为很多看似复杂的错误其实非常朴素。比如权重和为一、单资产上限 10%、行业暴露又极其严格,合起来就可能根本没有可行解。又比如目标收益被写得太高,模型只能不断顶边。还有一种情况,是协方差矩阵输入尺度不一致,让结果表现得像“求解器很奇怪”。如果没有固定排错顺序,研究者很容易一上来就从结果反推原因,效率极低。

建议从第 1 次实验开始就保留一份扩展日志。每加一层约束,就记录当前约束清单、问题状态、目标值、是否贴边和权重分布。长远看,这份日志比单次最优结果更重要。因为它能帮助你回答一个更成熟的问题:这个模型是怎么一步步变复杂的,又是在什么节点开始变脆的。

七、常见误区:初学者往往不是不会写,而是不会收

第一个常见误区,是把非凸问题硬塞进 cvxpy,再期待求解器帮自己“智能处理”。第二个误区,是样本还没清洗、协方差还没确认,就急着做优化。第三个误区,是一开始就想把所有业务条件一次性完整表达。第四个误区,是只看回测绩效,不看模型本身是不是每次都稳定可解。第五个误区,则是即便模型已经开始贴边和失真,也不愿意回头删减表达复杂度。

其实 cvxpy 入门最难学会的一点,不是怎么加东西,而是怎么收住。什么条件暂时不该进模型,什么问题应该先拆开做,什么时候该承认当前框架不适合表达这类业务要求。这些判断,往往比写更多约束更能决定研究质量。因为优化从来都不是“把一切都塞进去”,而是“把真正关键的权衡表达清楚”。

八、典型场景:为什么组合优化看上去没错,结果却仍然难用

在量化研究里,最令人困惑的一类情况是:模型明明能解,约束也都写上了,输出结果看起来也说得过去,但一接到更长样本或更换一批输入,权重就明显变形。这通常不是 cvxpy 本身的问题,而是研究者把“求解成功”误当成了“表达健康”。例如某次优化里单一资产总被压在上限,表面上仍是可行解,实际上是在告诉你目标函数正在强烈偏向某一类资产;又比如行业约束每次都贴边,看起来规则被满足了,实际上意味着这套约束结构已经非常紧绷,稍微换数据就容易失稳。

因此,组合优化最值得养成的习惯之一,是把“结果能不能解释”和“结果能不能稳定重现”分开看。能解释,说明当前输出在金融上大体合理;能重现,说明问题表达本身没有过分依赖某一份样本。很多量化团队的问题,不在于不会做优化,而在于没有把这两层检查做成固定流程。

九、工具落地:为什么优化问题一定要留下版本记录

优化研究还有一个很容易被低估的环节,就是版本记录。很多团队会保存代码,却不保存模型表达版本。结果过几周以后,虽然还能找到脚本,却已经说不清当时到底用了哪一版目标函数、哪一版约束边界、哪一版协方差估计。对组合研究来说,这是非常大的隐患。因为优化结果对表达方式高度敏感,只要约束和目标稍有变化,输出权重就可能完全不同。

更稳妥的做法,是把每一版优化问题都记录四项内容:目标函数是什么、关键约束有哪些、输入数据范围是什么、结果有没有明显贴边。这样后面即使回头比较两次优化结果,也能迅速分清差异来自市场变化,还是来自模型表达变化。只要这类记录长期存在,cvxpy 才会真正融入研究流程,而不是成为一个偶尔跑一下、但很难复盘的黑盒工具。

十、复盘方法:别只看最优解,也要看次优解和边界解

很多研究者求解完以后,只关注那组最终权重。其实在组合优化里,次优解和边界解往往同样有信息量。次优解能告诉你当前问题是否存在一片相对稳定的可行区域,还是只有一个看似漂亮但非常尖锐的最优点;边界解则能提醒你哪些约束正在强烈主导输出。如果这些额外信息都不看,团队会很容易高估单次求解的可信度。

所以,实务里很值得保留一种简单做法:在主结果之外,再看两三组邻近条件下的结果,例如略微改变收益预期、略微放宽或收紧单项上限、略微改变协方差估计。若这些轻微改动就让权重大幅翻转,说明问题还不够稳。反过来,如果结果虽然有变化,但核心结构仍然大体一致,才说明你真正找到的是一个更耐用的表达,而不是样本上的偶然解。

十一、总结:cvxpy 的核心价值是让问题越来越清楚

这篇文章如果只留下一个结论,那就是:cvxpy 在量化研究里的最大价值,并不是“帮你解出一个答案”,而是“逼着你把问题说得越来越清楚”。从最小示例开始、逐层加约束、固定排错顺序、记录状态和贴边情况、保存问题版本、比较次优和边界解,这一整套动作共同决定了你用的是一个研究工具,还是一个只在顺利时看起来很聪明的求解器。

当团队真正把这些习惯建立起来时,cvxpy 的角色就会发生变化。它不再是写完一段代码就期待答案跳出来的地方,而是组合研究里最能暴露问题表达是否健康的工作台。对量化团队来说,这种能力远比某一次求出一组漂亮权重更值钱,因为真正可靠的研究,靠的是问题越来越清楚,而不是结果偶尔很好看。

对量化研究来说,cvxpy 第 1 讲真正该建立的,不是“我已经会优化组合了”,而是四个更实际的习惯。第一,任何优化前都先用自然语言写出目标和约束。第二,从最小示例开始,逐层扩展,不一次性堆满。第三,每次求解同时记录状态、结果和是否贴边。第四,失败先怀疑问题表达,再怀疑工具本身。

只要这四个习惯养成,cvxpy 在研究流程里的角色就会很清楚。它不再只是一个偶尔拿来求权重的库,而是一个持续帮助你检查问题表达是否健康的工作台。对于量化团队来说,这种能力比单次跑出一组漂亮结果更值钱。因为长期可维护的研究,靠的从来不是某一次求解“刚好成功”,而是团队越来越清楚自己到底在优化什么。

十二、从研究走向实务时,最该警惕哪一步

很多组合优化在研究阶段看起来都很漂亮,真正准备进入实务时却开始暴露问题。最常见的断点是,研究里的问题表达足够清楚,但还没有和真实交易约束真正接起来。例如模型里限制了单资产上限,却没有考虑某些资产的最小成交单位;模型里加入了换手惩罚,却没有和真实再平衡频率绑定;模型里控制了行业暴露,却没有和账户层面的其他风险限制联动。这样一来,优化结果虽然数学上仍然合理,落到真实流程里却常常需要再做一层人工修正。

因此,从研究走向实务的关键,不是急着把所有交易细节都塞进第一个模型,而是先明确当前这一步到底在解决哪一层问题。cvxpy 第 1 讲更适合解决“问题能否被清楚表达并稳定求解”,而不是一次性解决所有实务约束。只要这层边界被说清楚,团队就不容易对优化结果产生不切实际的期待,也更知道下一步应在哪一层继续扩展。

十三、为什么组合优化最怕“结果好看但没人敢用”

量化团队里还有一种非常真实的现象,就是结果看起来不错,但真正要接入流程时没有人敢拍板。原因通常不是结果本身有多差,而是模型表达不够透明,团队无法判断它究竟是在正常工作,还是在吃样本运气。只要研究者讲不清目标函数为何这样设计,约束为什么这样组合,输出为什么长期贴边,结果就很难被风险、执行和管理层真正接受。

所以,cvxpy 入门如果只教会“怎么求”,其实还不够。它更应该帮团队形成一种共同语言:问题是怎么写出来的,哪些边界是主动设定的,哪些结果现象值得警惕。只有当这种共同语言存在,优化模型才更容易从研究脚本走向团队工具。对长期流程来说,这一点和模型本身同样重要。

十四、风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。