尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

二次规划与二次约束规划:从建模到求解的实战指南

二次规划与二次约束规划:从建模到求解的实战指南 1. 项目概述从“黑箱”到“白盒”的优化建模之旅在工程、金融、科研乃至日常决策中我们常常会遇到一类核心问题如何在众多限制条件下找到那个“最好”的方案比如投资组合如何配置才能在控制风险的前提下最大化收益机器人手臂的运动轨迹如何规划才能最省电且不撞到障碍物工厂的生产计划如何安排才能成本最低、效率最高这些问题背后往往都藏着一个数学模型。而“二次规划”与“二次约束规划”正是解决其中一大类关键问题的强大数学工具。它们不是遥不可及的学术概念而是工程师、分析师和研究者手中实实在在的“手术刀”用于精确地切割复杂问题找到最优解。简单来说二次规划Quadratic Programming, QP可以理解为“升级版”的线性规划。它的目标函数是变量的二次函数比如x² 2xy y²约束条件全是线性的。想象一下你要调整一个抛物面的最低点但只能在某个平面区域内移动QP就是帮你找到这个区域内最低点的工具。而二次约束规划Quadratically Constrained Programming, QCP则更进一步它的约束条件里也可以包含二次项。这就好比不仅要在平面区域内找最低点这个区域本身的边界也可能是弯曲的。QP和QCP共同构成了凸优化理论中极为重要和实用的一环因为许多实际问题如最小二乘拟合、投资组合优化、支持向量机训练等其本质都是二次规划问题。然而从理解概念到真正解决问题中间隔着一道鸿沟建模与求解。很多人学会了数学定义却不知道如何将一个模糊的实际需求转化为严谨的QP/QCP模型或者模型建好了面对一堆求解器和算法选项无从下手只能当个“调参侠”把求解器当作黑箱碰运气式地运行。这篇内容的目的就是带你跨越这道鸿沟。我将结合十多年的项目经验系统性地拆解二次规划与二次约束规划的建模心法与求解实战让你不仅知其然更知其所以然最终能独立、自信地处理这类优化问题。2. 核心概念辨析QP与QCP的数学本质与应用分野在深入建模之前我们必须清晰地界定这两个概念这是所有后续工作的基石。混淆它们会导致模型错误、求解失败。2.1 二次规划的标准形式与直观理解二次规划的标准形式通常写作最小化: (1/2) * xᵀPx qᵀx 约束条件: Gx ≤ h Ax b lb ≤ x ≤ ub其中x是决策变量向量P是一个对称矩阵通常要求是半正定矩阵以保证问题是凸的q是向量G,A是矩阵h,b,lb,ub是向量。为什么是(1/2) xᵀPx这个1/2主要是为了求导方便。对(1/2)xᵀPx求梯度正好是Px形式更整洁。很多求解器内部都默认这种形式。关键点在于“凸性”。当矩阵P是半正定所有特征值非负时目标函数是一个“碗状”的凸函数这意味着它的局部最小值就是全局最小值。对于凸QP存在成熟、高效的算法保证找到全局最优解。如果P不定有正有负特征值问题就是非凸的求解将变得异常困难通常只能找到局部最优解。生活化类比想象一个光滑的、向上开口的碗凸QP你往里面放一颗钢珠无论从哪里放手它最终都会滚到碗底全局最优解。而非凸QP就像一个复杂的山地地形钢珠可能会停在某个小坑里局部最优但不一定是整片区域的最低点。2.2 二次约束规划的扩展与挑战二次约束规划在QP的基础上允许约束条件也包含二次项。其一般形式为最小化: (1/2) * xᵀP₀x q₀ᵀx 约束条件: (1/2) * xᵀPᵢx qᵢᵀx rᵢ ≤ 0, i 1, ..., m Ax b lb ≤ x ≤ ub这里每个约束i都有自己的二次项矩阵Pᵢ。同样地为了问题可解指能找到全局最优解我们通常要求所有二次约束函数也是凸的即每个Pᵢ都是半正定矩阵。这样的问题称为凸二次约束规划。应用场景差异QP典型场景投资组合优化马科维茨模型、带二次惩罚项的回归问题、线性模型预测控制。QCP典型场景包含几何距离约束的问题如||x - c||² ≤ r²表示一个球体内、鲁棒优化中处理不确定性集合如椭球不确定性、某些工程设计中的物理限制。注意并非所有带二次项的问题都是QP或QCP。如果目标函数和约束都是二次的但约束矩阵Pᵢ不是半正定的那么问题就是非凸的QCQP求解难度陡增通常需要全局优化算法或启发式算法这不在本文主要讨论的凸优化范畴内。2.3 凸与非凸一条重要的分界线这是建模时首先要判断的一点。对于凸的QP/QCP求解有保障存在多项式时间算法如内点法可以高效求出全局最优解。工具成熟CVXOPT、Gurobi、CPLEX、MOSEK等商用或开源求解器对其支持非常好。模型可信找到的解就是最好的解可以放心用于决策。对于非凸的QP/QCQP求解困难属于NP难问题没有通用高效算法。结果不确定求解器可能返回局部最优解且无法验证是否全局最优。工具局限通用求解器可能直接报错或给出错误结果需要专门的全局优化求解器如BARON、SCIP或启发式算法。实操心得在建模初期务必花时间验证问题的凸性。一个常用技巧是检查矩阵P和Pᵢ的特征值。在实践中很多物理或经济问题天然具有凸性。如果问题非凸就要思考是否可以通过变量替换、约束松弛等方式将其转化为凸问题如果不行那就需要调整预期准备使用更复杂的求解策略。3. 建模实战将现实问题转化为数学模型的四步法建模是将模糊需求翻译成数学语言的艺术。下面我通过一个经典的投资组合优化案例演示QP建模的全过程。3.1 第一步定义决策变量与参数任何模型都始于明确定义“我们要决定什么”以及“我们知道什么”。决策变量x₁, x₂, ..., xₙ。表示我们投资到第i种资产上的资金比例。例如x₁是股票A的权重x₂是债券B的权重。显然它们需要满足Σxᵢ 1且xᵢ ≥ 0假设不允许卖空。模型参数需要事先估计或设定μᵢ: 第i种资产的预期收益率。σᵢⱼ: 资产i和j之间的协方差衡量它们收益的联动性。所有σᵢⱼ组成协方差矩阵Σ。R_target: 投资者期望的最低平均收益率。risk_aversion: 风险厌恶系数用于权衡收益与风险。3.2 第二步构建目标函数在马科维茨均值-方差模型中目标是“在给定收益下风险最小”或“在给定风险下收益最大”。我们采用前者构建一个二次目标函数。投资组合的方差风险为Risk xᵀΣx投资组合的预期收益为Return μᵀx我们的目标是最小化风险同时要求收益不低于R_target。这自然引出了一个以风险最小化为目标以收益为约束的QP模型。但更常见的是一种权衡形式即最小化总成本 风险 - λ * 收益其中λ是风险厌恶系数。为了保持标准QP形式我们通常将目标函数设为最小化: (1/2) * xᵀΣx - λ * (μᵀx)这里(1/2)是为了与标准形式对齐Σ就是标准形式中的矩阵P-λμ对应向量q。λ越大表示越追求高收益能承受更高风险λ越小表示越厌恶风险。3.3 第三步设定约束条件约束条件体现了现实中的各种限制。预算约束所有投资比例之和为1。Σxᵢ 1。这是一个线性等式约束对应Ax b。非负约束不允许卖空。xᵢ ≥ 0。这是变量的下界约束lb 0。行业集中度约束举例为防止过度集中要求科技类资产总投资比例不超过40%。如果资产1、3、5属于科技类则x₁ x₃ x₅ ≤ 0.4。这是一个线性不等式约束对应Gx ≤ h。二次约束示例如果我们想引入QCP假设我们不仅关心总体风险还要求投资组合对某个特定风险因子如利率的暴露度不能太高。这可以用一个二次约束来表示xᵀFx ≤ φ其中F是描述风险因子暴露的协方差矩阵φ是暴露度上限。这就将模型从QP升级为了QCP。3.4 第四步模型标准化与检查将上述所有部分拼装起来并写成求解器能接受的标准形式。QP模型标准形式决策变量: x [x₁, x₂, ..., xₙ]ᵀ 最小化: (1/2) * xᵀΣx (-λμ)ᵀx 约束条件: [1, 1, ..., 1] * x 1 (预算约束A, b) [1, 0, 1, 0, 1, ...] * x ≤ 0.4 (行业约束G, h) xᵢ ≥ 0 for all i (变量下界lb)检查要点凸性检查协方差矩阵Σ通常是半正定的只要没有完全共线性的资产因此该QP是凸的。可行性检查约束条件是否可能冲突例如如果要求最低收益R_target高得不切实际可能没有投资组合能满足问题就是不可行的。规模评估变量数量n资产数量决定了问题规模。协方差矩阵Σ是n x n的当n很大如上千时矩阵可能稀疏需要选择能利用稀疏性的求解器。注意事项协方差矩阵Σ的估计质量极大影响结果。使用历史数据估计时需要足够长的样本期并注意数据的平稳性。不准确的Σ会导致优化结果看似完美实则在实际中表现糟糕。实践中常采用收缩估计、因子模型等方法来改进协方差矩阵的估计。4. 求解器选型与核心算法原理模型建好接下来是求解。你不能只会点“求解”按钮必须了解背后的原理和工具才能有效诊断问题。4.1 主流求解器一览求解器类型主要特点适用场景许可证Gurobi商用性能顶尖鲁棒性强支持QP、QCP、MIQCP等API友好文档详尽。商业项目、大规模问题、对速度和稳定性要求极高。商业许可有免费学术版。CPLEX商用IBM出品历史悠久功能全面在混合整数规划方面尤其强大。复杂工业优化、包含离散变量的QP问题。商业许可有免费学术版。MOSEK商用在锥优化包括二次锥SOCP领域性能卓越许多QCP问题可转化为SOCP求解。金融工程、涉及二次约束的复杂问题。商业许可有免费试用版。CVXOPT开源Python纯Python实现基于内点法是学习凸优化原理的绝佳工具。教育、研究、中小规模凸优化问题原型开发。GPLv3开源协议。OSQP开源专门针对凸QP的求解器采用一阶算子分裂方法速度极快尤其适合嵌入式或实时系统。模型预测控制、机器学习、大规模但结构简单的QP。Apache 2.0开源协议。ECOS开源嵌入式锥优化求解器擅长处理SOCP问题同样可用于求解许多QCP问题。嵌入式应用、需要轻量级求解器的场景。GPLv3开源协议。选型建议新手入门与研究首选CVXOPT或CVXPY一个基于CVXOPT等求解器的建模语言。它们能让你更专注于模型本身语法直观且方便验证模型正确性。生产环境与性能如果预算允许Gurobi通常是首选。它的默认参数设置就很鲁棒求解日志详细社区支持好。特定问题结构如果问题是大规模的、稀疏的QP且对求解速度有苛刻要求如实时控制可以评估OSQP。如果问题本质是二次锥规划MOSEK或ECOS是更好选择。4.2 核心算法内点法是如何工作的对于凸QP/QCP内点法是当前最主流的算法。它不像单纯形法在可行域的顶点上“蹦跳”而是从可行域内部出发沿着一条中心路径逼近最优解。通俗理解想象最优解在可行域边界上的一个“角落”里。内点法在可行域内“吹”一个气球这个气球被约束边界挡住。算法一边让气球膨胀优化目标一边调整形状让它始终紧贴边界但不穿越保持可行性。最终气球会卡在最优解那个“角落”里。关键步骤构造障碍函数将不等式约束g(x) ≤ 0转化为-log(-g(x))加入目标函数。当x靠近边界时g(x) → 0⁻-log(-g(x)) → ∞形成一道“对数屏障”阻止迭代点越界。求解松弛问题新的目标函数是原目标加上障碍项形成一个无约束或仅含等式约束的优化问题。通过一个参数t控制障碍的强度t越大障碍越“薄”解越接近原问题的最优解。牛顿迭代对于每个固定的t使用牛顿法求解松弛问题的极小点。牛顿法利用了目标函数的二阶信息Hessian矩阵收敛速度很快。中心路径与迭代随着t不断增大这一系列极小点形成一条“中心路径”。算法沿着这条路径迭代直到满足收敛条件。为什么内点法强大对于凸问题它理论上是多项式时间复杂度的。实际应用中通常只需几十次迭代就能达到极高精度。对问题规模变量和约束数量的敏感度低于单纯形法尤其适合大规模稀疏问题。实操心得使用内点法求解器时如果遇到数值困难如迭代步长过小、矩阵奇异往往是模型本身存在问题的信号例如约束接近线性相关、变量尺度差异巨大如x₁范围是[0, 1]x₂范围是[10000, 20000]。预处理数据对变量进行缩放能极大提升求解稳定性和速度。5. 代码实现从Python建模到求解的完整流程我们以Python为例使用CVXPY这个声明式建模库和OSQP求解器来实现一个简单的投资组合QP问题。CVXPY让你用近乎数学公式的方式写模型非常直观。5.1 环境准备与问题数据生成首先安装必要的库并生成模拟数据。import numpy as np import cvxpy as cp import matplotlib.pyplot as plt # 设置随机种子保证可重复性 np.random.seed(42) # 假设有5种资产 n_assets 5 # 模拟预期年化收益率 (例如在 5% 到 15% 之间) expected_returns np.random.uniform(0.05, 0.15, n_assets) # 模拟协方差矩阵先随机生成一个相关矩阵再构造协方差矩阵 # 1. 生成随机相关矩阵半正定 corr_matrix np.random.uniform(-0.3, 0.8, (n_assets, n_assets)) corr_matrix (corr_matrix corr_matrix.T) / 2 # 对称化 np.fill_diagonal(corr_matrix, 1) # 对角线设为1 # 确保半正定通过加一个单位矩阵的倍数 min_eig np.min(np.real(np.linalg.eigvals(corr_matrix))) if min_eig 0: corr_matrix - 1.1 * min_eig * np.eye(n_assets) # 2. 给定各资产波动率标准差 volatilities np.random.uniform(0.1, 0.3, n_assets) # 3. 从相关矩阵和波动率构造协方差矩阵 Σ D np.diag(volatilities) cov_matrix D corr_matrix D # Σ D * Corr * D print(预期收益率:, expected_returns) print(协方差矩阵形状:, cov_matrix.shape)5.2 使用CVXPY构建并求解QP模型我们构建一个经典的马科维茨均值-方差模型寻找给定目标收益下风险最小的组合。# 定义决策变量资产权重 weights cp.Variable(n_assets) # 定义目标收益 target_return 0.10 # 目标年化收益10% # 构建优化问题 # 目标最小化投资组合方差风险 portfolio_variance cp.quad_form(weights, cov_matrix) # 等价于 weights.T cov_matrix weights objective cp.Minimize(portfolio_variance) # 约束条件 constraints [ cp.sum(weights) 1, # 权重和为1 weights 0, # 不允许卖空 expected_returns weights target_return # 期望收益不低于目标 ] # 定义问题并求解 prob cp.Problem(objective, constraints) prob.solve(solvercp.OSQP, verboseTrue) # 指定OSQP求解器并输出详细日志 # 输出结果 print(\n--- 求解结果 ---) print(求解状态:, prob.status) if prob.status optimal: print(最优投资组合风险方差:, portfolio_variance.value) print(最优投资组合收益:, expected_returns weights.value) print(最优权重分配:) for i in range(n_assets): print(f 资产 {i1}: {weights.value[i]:.4f} ({weights.value[i]*100:.2f}%)) else: print(问题未找到最优解。状态:, prob.status)代码解析与注意事项cp.quad_form(weights, cov_matrix)是CVXPY中构建二次型xᵀPx的标准方式它自动识别P即cov_matrix需要是对称矩阵。prob.solve()会自动选择默认求解器。我们显式指定solvercp.OSQP是因为OSQP对于这类凸QP问题非常高效。verboseTrue会打印求解器的迭代日志对于调试和了解求解过程很有帮助。务必检查prob.status。如果状态不是optimal可能是问题不可行或无界需要回头检查模型和参数。5.3 有效前沿绘制权衡收益与风险单一目标收益下的最优解只是有效前沿上的一个点。我们通常想看到整个前沿。# 生成有效前沿 target_returns np.linspace(expected_returns.min(), expected_returns.max(), 20) portfolio_risks [] for ret in target_returns: # 更新约束中的目标收益 constraints [ cp.sum(weights) 1, weights 0, expected_returns weights ret ] prob cp.Problem(objective, constraints) prob.solve(solvercp.OSQP) if prob.status optimal: # 计算标准差波动率更直观 portfolio_risks.append(np.sqrt(portfolio_variance.value)) else: portfolio_risks.append(np.nan) # 绘制有效前沿 plt.figure(figsize(10, 6)) plt.plot(portfolio_risks, target_returns, b-, linewidth2, label有效前沿) plt.xlabel(投资组合波动率风险) plt.ylabel(投资组合预期收益率) plt.title(马科维茨有效前沿) plt.grid(True, alpha0.3) plt.legend() plt.show()这段代码通过循环不同的目标收益率求解对应的最小风险从而描点画出有效前沿。这条曲线上的每个点都代表了在特定收益水平下所能达到的最小风险组合。5.4 引入二次约束一个简单的QCP示例假设我们新增一个约束投资组合对前两种资产假设它们代表一个高风险板块的集中度风险不能太高。我们可以用这两个资产权重的二次和来限制。# 定义一个新的决策变量问题或复用weights变量这里新建一个 weights_qc cp.Variable(n_assets) # 定义集中度风险上限 concentration_limit 0.1 # 例如权重平方和不超过0.1 # 构建二次约束前两种资产的权重平方和 limit # 注意cp.sum_squares 是凸的二次函数 quadratic_constraint cp.sum_squares(weights_qc[0:2]) concentration_limit # 构建QCP问题 objective_qc cp.Minimize(cp.quad_form(weights_qc, cov_matrix)) constraints_qc [ cp.sum(weights_qc) 1, weights_qc 0, expected_returns weights_qc target_return, quadratic_constraint # 这是二次约束 ] prob_qc cp.Problem(objective_qc, constraints_qc) # 尝试求解。注意OSQP不支持一般的QCP我们需要使用支持QCP的求解器如ECOS或SCS。 try: prob_qc.solve(solvercp.ECOS, verboseFalse) print(\n--- 带二次约束的QCP求解结果 ---) print(求解状态:, prob_qc.status) if prob_qc.status in [optimal, optimal_inaccurate]: print(QCP组合收益:, expected_returns weights_qc.value) print(QCP组合风险标准差:, np.sqrt(cp.quad_form(weights_qc, cov_matrix).value)) print(前两种资产权重平方和:, np.sum(weights_qc.value[0:2]**2)) except Exception as e: print(f求解失败错误信息: {e}) print(尝试使用SCS求解器支持更广泛的锥规划...) prob_qc.solve(solvercp.SCS, verboseFalse) print(SCS求解状态:, prob_qc.status)重要提示cp.sum_squares是凸的二次函数。ECOS和SCS求解器能够处理这种凸二次约束。如果二次约束是非凸的CVXPY会直接拒绝建模或者需要使用DCCP等专门处理非凸问题的扩展包。6. 常见问题排查与性能调优实战即使模型在数学上正确求解过程中也可能遇到各种问题。以下是我在实践中总结的常见“坑”及其解决方法。6.1 求解失败状态诊断速查表求解状态/错误信息可能原因排查与解决思路infeasible(不可行)约束条件互相矛盾没有解。1.检查约束逐一检查每个约束是否合理。例如要求的最低收益是否高于任何单一资产的最大收益2.放松约束暂时移除或放宽一些约束如收益要求看问题是否变得可行。3.使用弹性变量在关键约束上添加小的、可惩罚的违反量先求出“近似解”再分析哪个约束导致不可行。unbounded(无界)目标函数值可以无限减小对于最小化问题。1.检查目标函数在QP中如果矩阵P不是半正定的凸且问题无其他强约束可能导致无界。2.检查变量符号是否有变量没有非负约束且其在目标函数中的系数为负3.添加边界为所有变量添加合理的上下界。solver_error或numerical_error求解器内部数值计算失败如矩阵奇异、非正定。1.检查数据尺度变量或约束系数是否数量级差异巨大如1e-10和1e10对数据进行缩放。2.检查凸性确认协方差矩阵P是半正定的。可以用np.linalg.eigvals(P)检查特征值是否有明显负值考虑数值误差。3.正则化在P矩阵上添加一个很小的单位矩阵倍数如P 1e-6 * I使其严格正定。4.更换求解器有些求解器如OSQP对数值条件要求更宽松。optimal_inaccurate求解器找到了一个解但未达到默认的高精度要求。1.调整求解精度增加求解器的迭代次数 (max_iter) 或降低容忍度 (eps_abs,eps_rel)。2.评估解的质量检查目标函数值和约束违反程度是否在可接受范围内。对于许多应用中等精度的解已足够。3.这可能不是问题如果应用不要求极端精度可以接受此状态。求解速度慢问题规模大或结构复杂。1.利用稀疏性如果P,G,A矩阵是稀疏的确保以稀疏格式如SciPy的csc_matrix传递给求解器。2.预热启动如果连续求解一系列相似问题如参数微调将前一个解作为当前问题的初始猜测能大幅加速收敛。3.调整算法参数对于内点法可以调整预测-校正步骤的参数对于OSQP可以调整rho参数。4.问题降维能否通过数学变换减少变量或约束数量6.2 数值稳定性处理技巧数值问题是优化求解中最棘手的部分之一。数据预处理与缩放这是提升稳定性的最有效手段。确保决策变量、约束系数和目标函数系数处于相近的数量级比如都在[-10, 10]或[0, 1]附近。例如如果资产价格是万元级别可以将权重变量定义为“投资万元数”而不是“投资元数”。# 示例缩放变量 # 假设原始变量 x 范围是 [0, 1e6]我们定义新变量 y x / 1e4则 y 范围约为 [0, 100] # 相应地目标函数和约束中的系数也要同步缩放。正则化协方差矩阵金融中直接由历史收益率样本计算的协方差矩阵可能病态特征值接近零。采用Ledoit-Wolf收缩估计等方法是行业标准做法可以显著改善矩阵条件数。from sklearn.covariance import LedoitWolf lw LedoitWolf() cov_matrix_shrunk lw.fit(historical_returns).covariance_求解器参数调优不要总是用默认参数。阅读求解器文档针对你的问题类型调整关键参数。例如对于OSQP参数rho惩罚参数对收敛速度影响很大对于ECOS可以调整feastol可行性容忍度。6.3 模型验证与后分析求解器说“optimal”就万事大吉了吗不你必须验证这个解是否真的合理。约束满足检查手动计算解是否满足所有约束特别是那些容易出错的等式约束和边界约束。# 检查预算约束 print(权重和:, np.sum(weights.value)) # 检查非负约束 print(最小权重:, np.min(weights.value)) # 检查收益约束 achieved_return expected_returns weights.value print(达成收益:, achieved_return, 目标收益:, target_return)敏感性分析影子价格高级求解器如Gurobi可以提供约束的对偶变量影子价格。它告诉你如果某个约束的右端项放松一个单位目标函数能改善多少。这对于理解哪些约束是“紧的”活跃的、哪些资源是瓶颈至关重要。解的唯一性对于凸QP最优解的目标函数值是唯一的但解本身不一定唯一如果目标函数在某个方向上是平坦的。检查Hessian矩阵P是否正定所有特征值大于零。如果是则解唯一如果是半正定则可能存在多个解。7. 从理论到实践一个综合案例——带交易成本的组合再平衡我们用一个更贴近实际的案例来整合所有知识点投资组合定期再平衡。假设我们有一个初始组合w0市场变化后我们希望调整到新的最优组合w*但每次交易都有成本假设成本与交易金额的平方成正比以惩罚大额交易对市场的冲击。问题建模目标最小化新组合的风险 交易成本。决策变量新组合权重w。交易量w - w0。交易成本γ * ||w - w0||²其中γ是成本系数||·||²表示二范数平方即向量各分量平方和。这是一个二次项。约束预算约束、非负约束、最低收益约束。数学模型最小化: (1/2) * wᵀΣw (γ/2) * (w - w0)ᵀI (w - w0) 约束条件: Σwᵢ 1 w ≥ 0 μᵀw ≥ R_target这里目标函数由两部分组成组合风险wᵀΣw和交易成本γ * ||w - w0||²。注意(w - w0)ᵀI (w - w0)就是||w - w0||²其中I是单位矩阵。这仍然是一个标准的凸QP问题因为目标函数是两个凸二次函数之和半正定矩阵Σ和γI之和仍是半正定的。Python实现要点# 假设已有 w0, cov_matrix, expected_returns, target_return, gamma w0 np.array([0.2, 0.2, 0.2, 0.2, 0.2]) # 初始等权组合 gamma 0.001 # 交易成本系数 w cp.Variable(n_assets) portfolio_risk cp.quad_form(w, cov_matrix) trading_cost gamma * cp.sum_squares(w - w0) # cp.sum_squares 就是二范数平方 objective cp.Minimize(portfolio_risk trading_cost) constraints [ cp.sum(w) 1, w 0, expected_returns w target_return ] prob_rebalance cp.Problem(objective, constraints) prob_rebalance.solve(solvercp.OSQP) print(再平衡后权重:, w.value) print(交易量:, w.value - w0)这个模型平衡了“追求最优”和“减少折腾”两个目标。通过调整γ你可以控制再平衡的激进程度。最后的建议建模与求解是一个迭代过程。很少有模型能一次写对。从简单版本开始逐步添加约束和复杂性。每步都验证解的合理性和模型的行为是否符合直觉。善用求解器的详细输出和调试信息它们是你理解问题、定位错误的最佳帮手。记住一个干净、数值稳定的模型远比一个复杂但病态的模型更有价值。
返回列表