此示例显示了如何使用基于问题的方法来解决混合整数二次编程(MIQP)产品组合优化问题。该想法是迭代地解决局部近似MIQP问题的混合整数线性编程(MILP)问题的序列。对于基于求解器的方法,请参阅混合整数二次规划投资组合优化:基于求解器.
正如Markowitz所示(“投资组合选择”,J. Finance第7卷,第1卷,第77-91号),1952年3月77-91),可以表达许多投资组合优化问题作为二次编程问题。假设你有一组N
资产和想要选择的投资组合,一起
在你的投资中占资产的比例
.如果你知道这个向量
每种资产的平均收益,以及协方差矩阵
回报,然后是给定的风险估计级别
您最大限度地提高风险调整的预期返回:
这Quadprog.
求解器解决了这个二次规划问题。然而,除了简单的二次规划问题,你可能想要以各种方式限制一个投资组合,例如:
没有超过m
组合中的资产,其中m <= n
.
有至少m
组合中的资产,其中0
拥有断断续续的约束,意思 , 或者 对于一些固定的分数 和 .
您不能包含这些约束Quadprog.
.困难在于约束的离散性。此外,当混合整数线性规划求解器处理离散约束时,它不处理二次目标函数。
该示例构造了一系列满足约束的MILP问题,并且越来越近似二次目标函数。虽然此技术适用于此示例,但它可能不适用于不同的问题或约束类型。
首先对约束进行建模。
是资产分配分数的矢量 为每一个 .要模拟投资组合中的资产数量,您需要指示器变量 这样 当 , 当 .要获得满足此限制的变量,请设置 向量为二元变量,并施加线性约束
这些不平等都强制执行这一点 和 是同时为0吗 每当 .
此外,为了加强对投资组合中资产数量的约束,施加线性约束
首先配制,您尝试最大化目标函数。但是,所有优化工具箱™索盘最小化。因此,为最小化目标的负面制定问题:
这个目标函数是非线性的。MILP求解器需要一个线性目标函数。有一种标准的技术可以将这个问题重新表述为一个线性目标和非线性约束的问题。引入松弛变量 代表二次术语。
当你迭代地求解MILP近似时,你包含了新的线性约束,每一个都近似于当前点附近的非线性约束。特别是,对 在哪里 是一个常数矢量和 是一个可变矢量,对约束的一阶泰勒近似值是
更换 经过 给
对于每个中间溶液 您介绍了一个新的线性约束 和 如上面表达式的线性部分:
这具有表单 ,在那里 ,有一个 乘数的 项, .
这种向问题添加新的线性约束的方法称为切割平面方法。有关详细信息,请参阅J. E. Kelley,Jr.“用于解决凸面的纤维化方法。”J. SoC。犹苹果。数学。卷。8,4,第4页,第403-712号,1960年12月。
为了表达优化问题:
决定你的变量代表什么
在这些变量中表达下限和上限
提供线性平等和不等式表达
为问题加载数据。这个数据在向量中有225个预期回报R.
以及225 × 225矩阵中收益的协方差问:
.数据与在POSTFOLIO优化问题上使用二次编程中的数据相同。
加载port5r = mean_return;q =相关性。*(stddev_return * stddev_return');
设置资产的数量为N
.
n =长度(r);
创建连续变量XVARS.
代表资产分配分数,二进制变量vvars
代表是否关联XVARS.
是零或严格阳性的,Zvar.
代表
变量,一个正标量。
xvars = Optimvar('xvars'N 1'indowbound'0,'上行'1);vvars = optimvar ('vvars'N 1“类型”那“整数”那'indowbound'0,'上行'1);zvar = Optimvar(“zvar”, 1'indowbound', 0);
所有的下界2n + 1
这个问题中的变量是零。的上界XVARS.
和yvars.
变量是一个,而且Zvar.
没有上界。
设置解决方案中的资产数量在100到150之间。将此约束合并到表单中的问题中,即
通过编写两个线性约束:
M = 150;m = 100;qpprob = optimproblem ('ObjectiveSense'那“最大化”);qpprobe . constraints .mconstr = sum(vars) <= M;qpprob.Constraints。mconstr2 = sum(vvars) >= m;
包括半连续约束。采取最小的非零部分资产0.001
对于每个资产类型,最大分数0.05
.
fmin = 0.001;fmax = 0.05;
包括不平等 和 .
qpprob.constraints.fmaxconstr = xvars <= fmax * vvars;qpprob.constraints.fminconstr = fmin * vvars <= xvars;
包括投资组合100%投入的约束,意思 .
qpprob.constraints.Allin = Sum(xvars)== 1;
设置风险规避系数
至100.
.
lambda = 100;
定义目标函数 并把它包含在问题中。
qpprob。O.B.jective = r'*xvars - lambda*zvar;
为了迭代地解决问题,首先解决当前约束的问题,该问题尚未反映任何线性化。
选项= Optimoptions(@Intlinprog,“显示”那“关闭”);%抑制迭代显示[xlinint,fval,extflagint,输出] =求解(qpprob,'选项',选项);
为迭代准备一个停止条件:停止时停止变量 在真正二次值的0.01%以内。
thediff = 1e-4;iter = 1;%迭代计数器资产= xLinInt.xvars;truequadratic =资产' * Q *资产;zslack = xLinInt.zvar;
为绘图保留计算的真实二次变量和松弛变量的历史。设置比默认更严格的容错以帮助迭代收敛到正确的解决方案。
历史= [stryquadratic,zslack];选项= Optimoptions(选项,'lpoptimalandaltolerance'1平台以及“RelativeGapTolerance”1 e-8......'约束专利'1 e-9'integertolerance',1E-6);
计算二次值和松弛值。如果它们不同,那么添加另一个线性约束,然后再次求解。
每个新的线性约束 来自线性近似
找到新的解决方案后,在旧解决方案和新解决方案之间使用线性约束。金宝搏官方网站这种包括线性约束的启发式方式可以比简单地采用新的解决方案更快。要使用解决方案而不是中途启发式,评论下面的“中途”行,并取消了以下一个。
而ABS((ZSLACK - RUREQUADRATIC)/ TRUEQUADRATIC)> CHEDIFF%相对误差constr = 2 *资产'* q * xvars - zvar <=资产'* q *资产;newname = ['迭代',num2str(erter)];qpprob.constraints。(newname)= contr;%用新的约束条件解决问题[xlinint,fval,extflagint,输出] =求解(qpprob,'选项',选项);资产=(资产+ Xlinint.xvars)/ 2;从之前到当前的%中途% assets = xLinInt(xars);%使用前一行或这一行truequadratic = xLinInt.xvars ' * Q * xLinInt.xvars;zslack = xLinInt.zvar;历史=(历史;truequadratic, zslack);Iter = Iter + 1;结尾
绘制松弛变量的历史和目标函数的二次部分,看看它们是如何收敛的。
情节(历史)传奇('二次'那“松弛”)xlabel(的迭代次数)标题('二次和线性近似(松弛)')
MILP解决方案的质量是什么?这输出
结构包含该信息。在解决方案的目标上检查内部计算的界限之间的绝对差距。
disp(output.absolutegap)
0.
绝对间隙为零,表明MILP解决方案是准确的。
绘制最佳分配。用xLinInt.xvars
, 不是资产
, 因为资产
使用中途更新时可能无法满足约束。
栏(xLinInt.xvars)网格上包含(“资产指数”)ylabel('投资比例')标题('最优资产配置')
你可以很容易地看到所有非零资产分配都在半连续边界之间 和 .
有多少非零资产?约束条件是有100到150个非零资产。
总和(xlinint.vvars)
ans = 100
这一配置的预期回报是什么,以及风险调整后的回报的价值是什么?
fprintf('预期的回报是%g,风险调整的返回是%g。\ n'那......r'* xlinint.xvars,fval)
预期收益为0.000595107,风险调整后的收益为-0.0360382。
通过使用专门用于FinancialToolbox®的产品组合优化专门设计的功能,可以进行更详细的分析。有关显示如何使用投资组合类直接处理半连续和基数约束的示例,请参阅具有半连续和基数约束的投资组合优化(金融工具箱).