1.问题描述
资产配置,投资组合是指通过分散投资资金的方式来规避投资过程中的风险。在实际的投资过程中,如何决定投资哪些产品来实现收益最大化和风险最小化是一个关键的问题。
美国经济学家马科维茨在上世纪50年代首次使用数学方法给出风险与收益的定义,其主要思想是使用均值方差的方法来建立了投资组合理论。该理论构成了现代投资组合理论的基础。马科维茨提出的投资组合理论认为投资某种金融产品的风险可以划分为系统性风险和非系统性风险。其中系统性风险主要指市场风险,例如政策影响或者宏观经济波动。非系统性风险主要指一些具体事件,例如公司破产,财务造假或者产品质量问题等。非系统性风险对某个金融产品或者某只股票冲击比较显著,但是人们在投资时可以选择多只股票或者多个金融产品,将风险分摊。
在本节讨论的例子中,我们将使用1960年到2003年标普500的股票,债券,和货币市场指数为数据来简要介绍投资组合问题。数据文件参考:2011-Optimization-Portfolio-Table1.csv。投资总是伴随着风险,通常越高的投资回报对应着更高的风险(通常如下表所示)。
引用:本案例数据和部分解题思路参考自互联网资料,仅供学习交流用。
股票 |
高回报 |
高风险 |
债券 |
较高回报 |
较高风险 |
货币市场 |
低回报 |
低风险 |
本例子涉及的优化是非线性规划(QP和QC问题)。
2. 量化问题:收益与风险
2.1. 单一资产投资回报率的计算
我们用来表示指数,表示某种投资选择在某一年的回报率。则的计算公式为:
根据以上公式,我们可以进一步计算得到该投资选择的平均回报率:
根据以上公式,我们可以计算数据文件中股票,债券,和货币市场的平均收益率分别为12.0569%,7.8501%,6.323%。下图为三种投资选择的标普500指数,年度收益率,和平均收益率。
一个好的投资组合将具有较高的投资回报和较低的投资风险,因此我们需要解决如何分散化风险并实现收益与风险最优配比的问题。解决该问题有三种思路,每种思路分别对应了一种问题建模:
- Problem 1:在获得预期收益率基础上,承受最小的投资风险
- Problem 2:在可接受的投资风险水平上,实现最大的投资收益
- Problem 3:最小化风险和负的预期收益的加权和
2.2. 单一资产投资风险的计算
“风险”可以用资产年回报率的“方差”来度量,其计算公式如下:
根据上述公式,我们从数据文件中可以计算出股票,债券,和货币市场的风险分别为0.027778434,0.011118948,0.001153996。下表列出了我们刚刚计算得出的股票,债券,和货币市场的平均回报率和风险。
股票 |
债券 |
货币 |
|
年均回报率 |
12.0569% |
7.8501% |
6.323% |
风险 |
0.027778434 |
0.011118948 |
0.001153996 |
2.3. 组合资产投资收益的计算
在马科维茨投资组合理论中,组合投资的收益可以用各个资产平均回报率的均值来定义。假设
用于表示我们投资的资产组合,则该投资组合的收益可以用如下公式来计算:
其中,是第种资产的平均回报率。
2.4. 组合资产投资风险的协方差矩阵
在概率论和统计学中,协方差是两个随机变量一起变化的度量(方差是两个变量相同时协方差的特殊情况)。协方差的数学定义如下:
如果两个变量趋于同时变化(即当其中一个变量高于其期望值时,那么另一个变量也趋于高于其期望值),那么两个变量之间的协方差将是正的。另一方面,如果两个变量趋于相反变化时(即当一个变量低于其期望值时,其中一个变量趋于高于其期望值),则两个变量之间的协方差为负。在金融市场中,不同资产之间的回报率是呈现一定的相关性的。例如,当股票行情好的时候,债券一般也会有较好的表现。为了挖掘出不同资产之间的关联性,我们用如下公式来计算两种资产的协方差:
由此,我们可以从数据文件中计算得到股票,债券和货币之间的协方差矩阵:
股票 |
债券 |
货币市场 |
|
股票 |
0.027778 |
0.003866 |
0.000207 |
债券 |
0.003866 |
0.011119 |
-0.000195 |
货币市场 |
0.000207 |
-0.000195 |
0.001154 |
3. 模型建立
集合
投资选择集合,即{股票、债券、货币市场}。
参数
投资选择的平均收益
投资组合和之间的协方差
预期的最低投资收益
可承担的最高投资风险
目标中风险的权重系数
目标中收益的权重系数
决策变量
每种投资选择的投资比例
数学模型
Problem 1:在获得预期收益率基础上,承受最小的投资风险
Problem 2:在可接受的投资风险水平上,实现最大的投资收益
Problem 3:最小化风险和负的预期收益的加权和
4.MindOpt APL建模和求解
接下来我们采用MindOptAPL来建模问题,并且调用求解器来求解。其中有些影响的参数我们可以修改,然后汇总统计运行结果。
Problem 1:在获得预期收益率基础上,承受最小的投资风险
我们将从6.5%,7%...不断增加至10.5%,以此来观察结果。下面给出0.065和0.105的示例。
这个是个二次规划(QP)问题,可以采用MindOpt来求解。
clear model; # 建模 # problem1.mapl param R:=0.065; #目标收益,修改此处从6.5%,7%...不断增加至10.5%来运行 set I ={"Stocks","Bonds","MoneyMarket"}; param avg_return[I]:=<"Stocks"> 0.120569233,<"Bonds"> 0.078501498,<"MoneyMarket"> 0.063230293; param cov_matrix[I*I]:= |"Stocks","Bonds","MoneyMarket"| |"Stocks"|0.027778434,0.003865623,0.000207039| |"Bonds"|0.003865623,0.011118948,-0.000195386| |"MoneyMarket"|0.000207039,-0.000195386,0.001153996|; var x[I] real >= 0; #变量:在三类资产上的投资比例 minimize risk: sum {<i,j> in I*I } (cov_matrix[i,j]*x[i]*x[j]); subto returnR: sum {<i> in I} (avg_return[i]*x[i]) >= R; subto sumto1: sum {<i> in I} x[i] == 1; print "-----------------用MindOpt求解---------------"; option solver mindopt; # (可选)指定求解用的求解器,默认是MindOpt option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印 solve; # 求解 print "-----------------Display---------------"; display; # 展示结果 print "期望收益=",R,"时,优化决策后最低风险 = ", sum {<i,j> in I*I } (cov_matrix[i,j]*x[i]*x[j]);;
运行代码结果为:
-----------------用MindOpt求解--------------- Running mindoptampl wantsol=1 mip_integer_tolerance=1e-9 print=0 MindOpt Version 0.24.1 (Build date: 20230423) Copyright (c) 2020-2023 Alibaba Cloud. Start license validation (current time : 29-JUN-2023 17:57:05). License validation terminated. Time : 0.006s OPTIMAL; objective 0.00 0 simplex iterations Completed. -----------------Display--------------- Primal Solution: x@Stocks = 0.01557551846056755 x@Bonds = 0.1003952141090600 x@MoneyMarket = 0.8840292674303752 期望收益=0.065时,优化决策后最低风险 = 0.001003774880094264
clear model; # 建模 # problem1_2.mapl param R:=0.105; #目标收益,修改此处从6.5%,7%...不断增加至10.5%来运行 set I ={"Stocks","Bonds","MoneyMarket"}; param avg_return[I]:=<"Stocks"> 0.120569233,<"Bonds"> 0.078501498,<"MoneyMarket"> 0.063230293; param cov_matrix[I*I]:= |"Stocks","Bonds","MoneyMarket"| |"Stocks"|0.027778434,0.003865623,0.000207039| |"Bonds"|0.003865623,0.011118948,-0.000195386| |"MoneyMarket"|0.000207039,-0.000195386,0.001153996|; var x[I] real >= 0; #变量:在三类资产上的投资比例 minimize risk: sum {<i,j> in I*I } (cov_matrix[i,j]*x[i]*x[j]); subto returnR: sum {<i> in I} (avg_return[i]*x[i]) >= R; subto sumto1: sum {<i> in I} x[i] == 1; print "-----------------用MindOpt求解---------------"; option solver mindopt; # (可选)指定求解用的求解器,默认是MindOpt option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印 solve; # 求解 print "-----------------Display---------------"; display; # 展示结果 print "期望收益=",R,"时,优化决策后最低风险 = ", sum {<i,j> in I*I } (cov_matrix[i,j]*x[i]*x[j]);;
运行代码结果为:
-----------------用MindOpt求解--------------- Running mindoptampl wantsol=1 mip_integer_tolerance=1e-9 print=0 MindOpt Version 0.24.1 (Build date: 20230423) Copyright (c) 2020-2023 Alibaba Cloud. Start license validation (current time : 29-JUN-2023 17:57:06). License validation terminated. Time : 0.006s OPTIMAL; objective 0.01 0 simplex iterations Completed. -----------------Display--------------- Primal Solution: x@Stocks = 0.6623911385783557 x@Bonds = 0.2481075493747278 x@MoneyMarket = 0.08950131204911776 期望收益=0.105时,优化决策后最低风险 = 0.01416827579918437
Problem 2:在可接受的投资风险水平上,实现最大的投资收益
我们将风险上限从0.020,0.015不断减少至0.005观察结果.
注意:这个是个二次约束(QC)的规划问题,目前MindOpt还不支持,我们更换用开源的求解器,查阅MindOpt APL支持的求解器来选择求解器。下面我们选用Ipopt求解器来求解。
clear model; # 建模 # problem2.mapl param S = 0.005; #风险上限,修改此处从0.020,0.015不断减少至0.005来运行 set I ={"Stocks","Bonds","MoneyMarket"}; param avg_return[I]:=<"Stocks"> 0.120569233,<"Bonds"> 0.078501498,<"MoneyMarket"> 0.063230293; param cov_matrix[I*I]:= |"Stocks","Bonds","MoneyMarket"| |"Stocks"|0.027778434,0.003865623,0.000207039| |"Bonds"|0.003865623,0.011118948,-0.000195386| |"MoneyMarket"|0.000207039,-0.000195386,0.001153996|; var x[I] real >= 0; #变量:在三类资产上的投资比例 maximize returnR: sum {<i> in I} (avg_return[i]*x[i]); subto risk: sum {<i,j> in I*I } (cov_matrix[i,j]*x[i]*x[j]) <= S; subto sumto1: sum {<i> in I} x[i] == 1; print "-----------------用Ipopt求解---------------"; option solver ipopt; option ipopt_options 'outlev=0'; solve; # 求解 print "-----------------Display---------------"; display; # 展示结果 print "风险上限=",S,"时,优化决策后最高回报 = ", sum {<i> in I} (avg_return[i]*x[i]);
运行代码结果为:
-----------------用Ipopt求解--------------- Running ipopt wantsol=1 outlev=0 ****************************************************************************** This program contains Ipopt, a library for large-scale nonlinear optimization. Ipopt is released as open source code under the Eclipse Public License (EPL). For more information visit http://projects.coin-or.org/Ipopt ****************************************************************************** Ipopt 3.12.13: Optimal Solution Found Completed. -----------------Display--------------- Primal Solution: x@Stocks = 0.3719475671271639 x@Bonds = 0.1817795679218096 x@MoneyMarket = 0.4462728649510265 风险上限=0.005时,优化决策后最高回报 = 0.0873333652811958
Problem 3:最小化风险和负预期收益的加权和
这里令,逐渐调整和观察结果。
需要注意的是,由于风险和收益我们评估用的数的量级差异大,直接这样处理不一定合适,可以再引入系数消除数据量级差异。
这个是个二次规划(QP)问题,可以采用MindOpt来求解。
clear model; # 建模 # problem3.mapl param alpha:=0.5; param beta:= 1.0 * (1 - alpha); #也可以单独取值,与alpha独立;也可以增加个调整系数比例,这里用1.0,用户可以调整0.5试一试。 set I ={"Stocks","Bonds","MoneyMarket"}; param avg_return[I]:=<"Stocks"> 0.120569233,<"Bonds"> 0.078501498,<"MoneyMarket"> 0.063230293; param cov_matrix[I*I]:= |"Stocks","Bonds","MoneyMarket"| |"Stocks"|0.027778434,0.003865623,0.000207039| |"Bonds"|0.003865623,0.011118948,-0.000195386| |"MoneyMarket"|0.000207039,-0.000195386,0.001153996|; var x[I] real >= 0; #变量:在三类资产上的投资比例 minimize weighted_sum: sum {<i,j> in I*I} (alpha*cov_matrix[i,j]*x[i]*x[j]) - sum {<i> in I} (beta*avg_return[i]*x[i]); subto sumto1: sum {<i> in I} x[i] == 1; print "-----------------用MindOpt求解---------------"; option solver mindopt; # (可选)指定求解用的求解器,默认是MindOpt option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印 solve; # 求解 print "-----------------Display---------------"; display; # 展示结果 print "优化决策后,最优加权评估值是 = ", sum {<i,j> in I*I} (alpha*cov_matrix[i,j]*x[i]*x[j]) - sum {<i> in I} (beta*avg_return[i]*x[i]); print "此时,"; print "风险 = ", sum {<i,j> in I*I } (cov_matrix[i,j]*x[i]*x[j]); print "收益 = ", sum {<i> in I} (avg_return[i]*x[i]);
运行结果为:
-----------------用MindOpt求解--------------- Running mindoptampl wantsol=1 mip_integer_tolerance=1e-9 print=0 MindOpt Version 0.24.1 (Build date: 20230423) Copyright (c) 2020-2023 Alibaba Cloud. Start license validation (current time : 29-JUN-2023 17:57:09). License validation terminated. Time : 0.006s OPTIMAL; objective -0.05 0 simplex iterations Completed. -----------------Display--------------- Primal Solution: x@Stocks = 0.9076253313372271 x@Bonds = 0.09237466866274598 x@MoneyMarket = 0.00000 优化决策后,最优加权评估值是 = -0.0465283693952063 此时, 风险 = 0.02362650112756696 收益 = 0.1166832399179795
5.结果
Problem 1:在获得预期收益率基础上,承受最小的投资风险
我们将R从6.5%,7%...不断增加至10.5%观察结果,发现预期收益越高,对应的最优投资组合风险越高,其中,货币市场投资比例逐渐下降,债券的投资比例逐渐缓慢上升,股票的投资比例上升更快。以下为求解结果及其可视化。注意,R=0.065时最优投资组合风险低于单货币市场投资风险,即,通过资产组合实现了较高的投资收益并分散化风险。
R |
0.065 |
0.070 |
0.075 |
0.080 |
0.085 |
0.090 |
0.095 |
0.100 |
0.105 |
风险 |
0.001 |
0.001 |
0.002 |
0.003 |
0.004 |
0.006 |
0.008 |
0.011 |
0.014 |
股票 |
1.56% |
8.70% |
16.92% |
25.14% |
33.36% |
41.58% |
49.80% |
58.02% |
66.24% |
债券 |
10.04% |
11.67% |
13.55% |
15.42% |
17.30% |
19.18% |
21.06% |
22.93% |
24.81% |
货币市场 |
88.40% |
79.63% |
69.53% |
59.44% |
49.34% |
39.24% |
29.14% |
19.05% |
8.95% |
Problem 2:在可接受的投资风险水平上,实现最大的投资收益
我们将S从0.020,0.015不断减少至0.005观察结果,同样发现可承担风险越低,对应的最优投资组合期望收益越低,其中,货币市场投资比例逐渐增加,债券的投资比例逐渐下降,股票的投资比例逐渐下降。以下为求解结果及其可视化。
S |
0.020 |
0.015 |
0.010 |
0.005 |
收益 |
0.112790 |
0.106224 |
0.098180 |
0.087333 |
股票 |
81.51% |
68.25% |
55.03% |
37.19% |
债券 |
18.49% |
25.27% |
22.25% |
18.18% |
货币市场 |
0.00% |
6.48% |
22.72% |
44.63% |
绘图如下:
Problem 3:最小化风险和负的预期收益的加权和
α+β=1,逐渐调整α和β观察结果,发现α比例越高,即风险的权重系数越大,加权目标值越大,对应的最优投资组合的风险越低,期望收益越低,其中,货币市场投资比例逐渐增加,债券的投资比例逐渐下降,股票的投资比例逐渐下降。以下为求解结果及其可视化。
α |
0.3 |
0.5 |
0.7 |
β |
0.7 |
0.5 |
0.3 |
加权目标 |
-0.076065 |
-0.046528 |
-0.022774 |
风险 |
0.027778 |
0.023627 |
0.006403 |
收益 |
0.120569 |
0.116683 |
0.090853 |
股票 |
100.00% |
90.76% |
42.98% |
债券 |
0.00% |
9.24% |
19.50% |
货币市场 |
0.00% |
0.00% |
37.52% |
绘图如下: