此示例演示如何使用基于问题的方法解决混合整数二次规划(MIQP)投资组合优化问题。其思想是迭代求解局部近似于MIQP问题的一系列混合整数线性规划(MILP)问题。有关基于解算器的方法,请参阅基于求解器的混合整数二次规划组合优化.
正如马科维茨所指出的(“投资组合选择”,J. Finance卷7,第1期,第77-91页,1952年3月),你可以将许多投资组合优化问题表示为二次规划问题。假设你有一组N
资产,并希望选择一个投资组合
资产占你投资的比例
.如果你知道向量
每个资产的平均回报率和协方差矩阵
在给定的风险规避水平下
您最大化风险调整后的预期回报:
这个二次规划优化函数
解算器解决了这个二次规划问题。但是,除了普通的二次规划问题外,您可能还希望以多种方式限制投资组合,例如:
不超过M
投资组合中的资产,其中M < = N
.
至少有m
投资组合中的资产,其中0 < m <= m
.
有半连续约束,也就是说 ,或 对于某些固定分数 和 .
中不能包含这些约束二次规划优化函数
.困难在于约束的离散性质。此外,当混合整数线性规划求解器处理离散约束时,它不处理二次目标函数。
这个例子构造了一系列MILP问题,这些问题满足约束条件,并且越来越接近二次目标函数。虽然此技术适用于本示例,但可能不适用于不同的问题或约束类型。
首先对约束进行建模。
是资产配置分数的向量,带有 为每一个 。要对投资组合中的资产数量进行建模,您需要指标变量 这样 当 ,及 当 .要获得满足此限制的变量,请设置 向量为二进制变量,并施加线性约束
这些不平等都强化了这一点 和 它们在同一时间为零,并且它们也强制执行 每当 .
此外,为了对投资组合中的资产数量施加约束,可以施加线性约束
正如第一次表述的那样,你试图最大化目标函数。然而,所有的最优化工具箱™求解器最小化。所以把问题表述成最小化目标的负面影响:
这个目标函数是非线性的。MILP解算器需要线性目标函数。有一种标准的技术可以将这个问题转化为一个具有线性目标和非线性约束的问题。引入松弛变量 表示二次项。
当你迭代地解决MILP逼近时,你包含了新的线性约束,每一个都在当前点附近局部逼近非线性约束。特别是,对 在哪里 是常数向量吗 是一个变量向量,约束的一阶泰勒近似是
替换 通过 给了
对于每个中间溶液 在中引入新的线性约束 和 作为上述表达式的线性部分:
这是一种形式 ,在那里 ,有一个 经济增长的乘数 项, .
这种向问题中添加新线性约束的方法称为割平面法。有关详细信息,请参见J.E.Kelley,Jr.《求解凸规划的割平面法》,J.Soc.Indust.Appl.Math.Vol.8,No.4,pp.703-712,1960年12月。
表示优化问题:
决定你的变量代表什么
用这些变量表示上界和下界
给出线性等式和不等式的表达式
加载问题的数据。此数据在向量中有225个预期返回r
以及225乘225矩阵中收益的协方差Q
.数据与在投资组合优化问题上使用二次规划的例子相同。
负载端口5r = mean_return;Q = Correlation .* (stdDev_return * stdDev_return');
将资产的数量设置为N
.
N =长度(r);
创建连续变量xvars
表示资产分配分数的二进制变量vvars
表示是否关联的xvars
是零还是严格为正兹瓦尔
代表
变量,一个正标量。
xvars=optimvar(“xvars”,N,1,下界的0,“上限”,1); vvars=optimvar(“vvars”,N,1,“类型”,“整数”,下界的0,“上限”,1);zvar=optimvar(“zvar”1.下界的,0);
所有函数的下界2N+1
问题中的变量为零。的上界xvars
和伊瓦尔
变量是1,和兹瓦尔
没有上限。
将解决方案中的资产数量设置为100到150之间。将这个约束条件以形式合并到问题中,即
通过编写两个线性约束:
M=150;m=100;Qprob=优化问题(“ObjectiveSense”,“最大化”); qprob.Constraints.mconstr=总和(vvars)<=M;qprob.Constraints.mconstr2=总和(vvars)>=m;
包括半连续约束。取资产的最小非零部分为0.001
每个资产类型的最大分数0.05
.
fmin = 0.001;fmax = 0.05;
包括不平等 和 .
qprob.Constraints.fmaxconstr=xvars<=fmax*vvars;qprob.Constraints.fmincontratr=fmin*vvars<=xvars;
包括投资组合100%投资的约束,意思是 .
qppro . constraints .allin = sum(xvars) == 1;
设置风险规避系数
来One hundred.
.
λ=100;
定义目标函数 并将其包含在问题中。
qprob.Objective=r'*xvars-lambda*zvar;
要迭代地解决问题,首先使用当前约束解决问题,这些约束尚未反映任何线性化。
options=options(@intlinprog,“显示”,“关”);%抑制迭代显示[xLinInt, fval exitFlagInt、输出]=解决(qpprob,“选项”、选择);
为迭代准备停止条件:当slack变量 在真实二次值的0.01%范围内。
thediff = 1的军医;iter = 1;%迭代计数器assets=xLinInt.xvars;truequadratic=assets'*Q*assets;zslack=xLinInt.zvar;
保留计算出的真实二次变量和松弛变量的历史记录,以便绘图。设置比默认值更严格的公差,以帮助迭代收敛到正确的解决方案。
历史=[truequadratic,zslack];选项=最佳选项(选项,“最佳耐受性”1平台以及“相对宽容”,1e-8,...“约束宽容”,1e-9,“整体容忍度”,1e-6);
计算二次值和松弛值。如果它们不同,则添加另一个线性约束并再次求解。
每个新的线性约束 来自线性近似
找到新的解决方案后,在新旧解决方案之间使用一个线性约束。这种包含线性约束的启发式方法可能比简单地使用新解决方案更快。要使用该解决方案而不是中间启发式,请在下面的“中间”行加上万博 尤文图斯注释,并取消注释下面的一行。
虽然abs((zslack-truequadratic)/truequadratic)>thediff%相对误差const = 2*assets'*Q*xvars - zvar <= assets'*Q*assets;新名称= [“迭代”,num2str(iter)];qprob.Constraints.(newname)=constr;%使用新约束解决问题[xLinInt, fval exitFlagInt、输出]=解决(qpprob,“选项”、选择);资产=(资产+ xLinInt.xvars) / 2;从前到现在的中间%资产=xLinInt(xvars);%使用上一行或这一行truequadratic=xLinInt.xvars'*Q*xLinInt.xvars;zslack=xLinInt.zvar;history=[history;truequadratic,zslack];iter=iter+1;结束
绘制松弛变量和目标函数的二次部分的历史,以查看它们是如何收敛的。
情节(历史)传说(“二次”,“松弛”)包含(“迭代次数”)头衔(“二次和线性近似(松弛)”)
MILP解决方案的质量如何?这个输出
结构包含该信息。检查内部计算的边界与目标在解之间的绝对差距。
disp (output.absolutegap)
0
绝对间隙为零,表明MILP解是准确的。
绘制最优配置图。使用xLinInt.xvars
,而不是资产
,因为资产
使用中途更新时可能不满足约束。
条形(xLinInt.xvars)栅格在xlabel(“资产指数”) ylabel (投资的比例)头衔(“最优资产配置”)
您可以很容易地看到,所有非零资产分配都在半连续边界之间 和 .
有多少非零资产?约束条件是有100到150个非零资产。
总和(最小值Vvar)
ans = 100
这种分配的预期回报是多少,以及风险调整后回报的价值是多少?
fprintf('预期回报率为%g,风险调整后回报率为%g。\n',...r * xLinInt.xvars, fval)
预期收益为0.000595107,风险调整收益为-0.0360382。
通过使用Financial Toolbox®中专门为投资组合优化设计的功能,可以进行更详细的分析。有关如何使用Portfolio类直接处理半连续和基数约束的示例,请参见具有半连续和基数约束的投资组合优化(金融工具箱).