投资组合优化(Black Litterman方法)

此示例显示了如何从Matlab代码生成MEX函数和C源代码,该代码使用Black Citterman方法执行组合优化。

先决条件

这个例子没有先决条件。

有关HLblacklitterman.功能

Hlblacklitterman.m.功能在有关投资组合的财务信息中读取,并使用黑色垃圾方法执行组合优化。

类型HLblacklitterman.
函数[ER,PS,W,PW,λ,θ= hlblacklitterman(三角形,WEQ,西格玛,tau蛋白,P,Q,欧米茄)%#代码生成%hlblacklitterman%该函数执行的现有%布莱克 -  Litterman混合和意见后的回报为%的新验估计由他和Litterman在论文中描述。%输入%的δ- - 从平衡图集%WEQ风险耐受性 - 前协方差矩阵%tau蛋白 -   -  Coefficiet不确定性的平均值(PI)%P的先验估计 - 在平衡组合%西格玛资产的权重接为矩阵视图(S)%Q  - 视图返回的矢量%欧米茄 - 矩阵的意见方差(对角线)的%输出%呃 -  w的平均收益%验估计 - 无约束的权重来计算给出的后路估计均值%和协方差的回报。%拉姆达 - 对后验估计每个视图的影响的度量。%theta  - 用在后部%精度的现有和样本信息共享的一种度量。%反向优化和背出平衡返回%这是式(12)页6. PI = WEQ *西格玛*增量;%我们用头*西格玛很多地方所以只计算一次TS =牛头*西格玛;%计算后的平均值%的估计这是式(8)的第4页上ER = P1 '+ TS * P' * INV(P * TS * P” +欧米茄)*(Q的简化版本 -  P * PI“); % We can also do it the long way to illustrate that d1 + d2 = I d = inv(inv(ts) + P' * inv(Omega) * P); d1 = d * inv(ts); d2 = d * P' * inv(Omega) * P; er2 = d1 * pi' + d2 * pinv(P) * Q; % Compute posterior estimate of the uncertainty in the mean % This is a simplified and combined version of formulas (9) and (15) ps = ts - ts * P' * inv(P * ts * P' + Omega) * P * ts; posteriorSigma = sigma + ps; % Compute the share of the posterior precision from prior and views, % then for each individual view so we can compare it with lambda theta=zeros(1,2+size(P,1)); theta(1,1) = (trace(inv(ts) * ps) / size(ts,1)); theta(1,2) = (trace(P'*inv(Omega)*P* ps) / size(ts,1)); for i=1:size(P,1) theta(1,2+i) = (trace(P(i,:)'*inv(Omega(i,i))*P(i,:)* ps) / size(ts,1)); end % Compute posterior weights based solely on changed covariance w = (er' * inv(delta * posteriorSigma))'; % Compute posterior weights based on uncertainty in mean and covariance pw = (pi * inv(delta * posteriorSigma))'; % Compute lambda value % We solve for lambda from formula (17) page 7, rather than formula (18) % just because it is less to type, and we've already computed w*. lambda = pinv(P)' * (w'*(1+tau) - weq)'; end % Black-Litterman example code for MatLab (hlblacklitterman.m) % Copyright (c) Jay Walters, blacklitterman.org, 2008. % % Redistribution and use in source and binary forms, % with or without modification, are permitted provided % that the following conditions are met: % % Redistributions of source code must retain the above % copyright notice, this list of conditions and the following % disclaimer. % % Redistributions in binary form must reproduce the above % copyright notice, this list of conditions and the following % disclaimer in the documentation and/or other materials % provided with the distribution. % % Neither the name of blacklitterman.org nor the names of its % contributors may be used to endorse or promote products % derived from this software without specific prior written % permission. % % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND % CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, % INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE % DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR % CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, % SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, % BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR % SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, % WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING % NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE % OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH % DAMAGE. % % This program uses the examples from the paper "The Intuition % Behind Black-Litterman Model Portfolios", by He and Litterman, % 1999. You can find a copy of this paper at the following url. % http:%papers.ssrn.com/sol3/papers.cfm?abstract_id=334304 % % For more details on the Black-Litterman model you can also view % "The BlackLitterman Model: A Detailed Exploration", by this author % at the following url. % http:%www.blacklitterman.org/Black-Litterman.pdf %

% # codegen指令表示MATLAB代码用于代码生成。

生成MEX功能进行测试

使用mex函数使用Codegen.命令。

Codegen.HLblacklitterman.arg游戏{0, 0(1、7)0 (7),0,0 (7),0,0}

在生成C代码之前,您应该首先在MATLAB中测试MEX函数,以确保它在功能上与原始MATLAB代码等价,并且不会发生运行时错误。默认情况下,Codegen.生成一个名为hlblacklitterman_mex.在当前文件夹中。这允许您测试MATLAB代码和MEX函数并比较结果。

运行mex函数

调用生成的MEX函数

testMex ();
查看1国家/地区P Mu W *澳大利亚0 4.328 1.524加拿大0 7.576 2.095 France -29.5 9.288 -3.948德国100 11.04 35.41日本0 4.506 11.05英国0.5 6.953 -9.462美国0 8.069 58.57 Q 5 Omega / Tau 0.0213 Lambda 0.317 Theta 0.0714 PrTheta 0.929查看1国家/座澳大利亚0 4.328 1.524加拿大0 7.576 2.095法国-29.5 9.288 -3.948德国100 11.04 35.41日本0 4.506 11.05英国0.5 6.953 -9.462美国0 8.069 58.57 Q 5 Omega / Tau 0.0213 Lambda 0.3170.0714 PR THETA 0.929执行时间 -  MATLAB功能:0.12721秒执行时间 -  MEX功能:0.017795秒

生成C代码

cfg = coder.config('lib');Codegen.配置CFG.HLblacklitterman.arg游戏{0, 0(1、7)0 (7),0,0 (7),0,0}

使用Codegen.用指定的-config cfg.选项生成独立的C库。

检查生成的代码

默认情况下,为库生成的代码位于文件夹中codegen / lib / hbblacklitterman /

文件是:

谜语codegen / lib / hlblacklitterman /
.hlblacklitterman_terminate.o .. hlblacklitterman_types.h buildinfo.mat接口codeinfo.mat inv.codedescriptor.dmr inv.h compileinfo.mat inv.o example pinv.clblacklitterman.a pinv.h hlblacklitterman.cinv.o hlblacklitterman.httge.c hlblacklitterman.o rtGetInf.h hlblacklitterman_data.c rtGetInf.o hlblacklitterman_data.h rtGetNaN.c hlblacklitterman_data.o rtGetNaN.h hlblacklitterman_initialize.c rtGetNaN.o hlblacklitterman_initialize.h rt_nonfinite.c hlblacklitterman_initialize.o rt_nonfinite.h hlblacklitterman_ref.rsp rt_nonfinite.o hlblacklitterman_rtw.mk rtw_proj.tmw hlblacklitterman_terminate.c rtwtypes.h hlblacklitterman_terminate.h

检查C代码为hlblacklitterman.c.功能

类型Codegen / lib / hlblacklitterman / hlblacklitterman.c
/ * *文件:hlblacklitterman.c * * MATLAB编码器版本:28-FEB-2020 22点57分44秒* / / * include文件* /#包括 “hlblacklitterman.h” #上产生5.0 * C / C ++源代码包括 “hlblacklitterman_data.h” 的#include “hlblacklitterman_initialize.h” 的#include “inv.h” 的#include “pinv.h” 的#include “rt_nonfinite.h”/ *函数定义* / / * * * hlblacklitterman执行该功能的黑现有*和意见后的回报为*的新后验估计的-Litterman混合由他和Litterman在论文中描述。*输入*增量 - 从平衡组合风险耐受性* WEQ  - 在平衡组合中的资产的权重*Σ- - 前协方差矩阵* tau蛋白 - 在均值(PI)的先验估计的不确定性Coefficiet * P  - 选择矩阵视图(S)* Q  - 视图返回的矢量*欧米茄 - 的意见方差(对角线)*输出*尔的矩阵 - 平均回报验估计*宽 - 无约束的权重来计算给出的后路估计平均的*和协方差的回报。*波长 - 对后估计每个视图的影响的措施。* theta  - 用在*后精度的现有和样本信息共享的一种度量。*参数:双Δ* const的双WEQ [7] * const的双σ[49] *双tau蛋白* const的双P [7] *双Q *双欧米茄*双ER [7] *双PS [49] *双瓦特[7] *双PW [7] *双*波长*双THETA [3] *返回类型:无效* /空hlblacklitterman(双Δ,常量双WEQ [7],常量双σ[49],双tau蛋白,常量双P [7],双Q,双欧米茄,双ER [7],双PS [49],双瓦特[7],双PW [7],双*波长,双THETA [3]){INT I; double b; int i1; double ts[49]; double pi[7]; double y_tmp; double b_P; double b_b; double er_tmp[7]; double b_y_tmp[7]; double unusedExpr[7]; double b_er_tmp[49]; double posteriorSigma[49]; int ps_tmp; double dv[49]; if (!isInitialized_hlblacklitterman) { hlblacklitterman_initialize(); } /* Reverse optimize and back out the equilibrium returns */ /* This is formula (12) page 6. */ for (i = 0; i < 7; i++) { b = 0.0; for (i1 = 0; i1 < 7; i1++) { b += weq[i1] * sigma[i1 + 7 * i]; } pi[i] = b * delta; } /* We use tau * sigma many places so just compute it once */ for (i = 0; i < 49; i++) { ts[i] = tau * sigma[i]; } /* Compute posterior estimate of the mean */ /* This is a simplified version of formula (8) on page 4. */ y_tmp = 0.0; b_P = 0.0; for (i = 0; i < 7; i++) { b = 0.0; b_b = 0.0; for (i1 = 0; i1 < 7; i1++) { b += ts[i + 7 * i1] * P[i1]; b_b += P[i1] * ts[i1 + 7 * i]; } b_y_tmp[i] = b_b; er_tmp[i] = b; y_tmp += b_b * P[i]; b_P += P[i] * pi[i]; } b_b = 1.0 / (y_tmp + Omega); b = Q - b_P; for (i = 0; i < 7; i++) { er[i] = pi[i] + er_tmp[i] * b_b * b; } /* We can also do it the long way to illustrate that d1 + d2 = I */ y_tmp = 1.0 / Omega; pinv(P, unusedExpr); /* Compute posterior estimate of the uncertainty in the mean */ /* This is a simplified and combined version of formulas (9) and (15) */ b = 0.0; for (i = 0; i < 7; i++) { b += b_y_tmp[i] * P[i]; } b_b = 1.0 / (b + Omega); for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b_er_tmp[i1 + 7 * i] = er_tmp[i1] * b_b * P[i]; } } for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += b_er_tmp[i + 7 * ps_tmp] * ts[ps_tmp + 7 * i1]; } ps_tmp = i + 7 * i1; ps[ps_tmp] = ts[ps_tmp] - b; } } for (i = 0; i < 49; i++) { posteriorSigma[i] = sigma[i] + ps[i]; } /* Compute the share of the posterior precision from prior and views, */ /* then for each individual view so we can compare it with lambda */ inv(ts, dv); for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += dv[i + 7 * ps_tmp] * ps[ps_tmp + 7 * i1]; } ts[i + 7 * i1] = b; } } b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += ts[ps_tmp + 7 * ps_tmp]; } theta[0] = b / 7.0; for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b_er_tmp[i1 + 7 * i] = P[i1] * y_tmp * P[i]; } } for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += b_er_tmp[i + 7 * ps_tmp] * ps[ps_tmp + 7 * i1]; } ts[i + 7 * i1] = b; } } b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += ts[ps_tmp + 7 * ps_tmp]; } theta[1] = b / 7.0; for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b_er_tmp[i1 + 7 * i] = P[i1] * y_tmp * P[i]; } } for (i = 0; i < 7; i++) { for (i1 = 0; i1 < 7; i1++) { b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += b_er_tmp[i + 7 * ps_tmp] * ps[ps_tmp + 7 * i1]; } ts[i + 7 * i1] = b; } } b = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { b += ts[ps_tmp + 7 * ps_tmp]; } theta[2] = b / 7.0; /* Compute posterior weights based solely on changed covariance */ for (i = 0; i < 49; i++) { b_er_tmp[i] = delta * posteriorSigma[i]; } inv(b_er_tmp, dv); for (i = 0; i < 7; i++) { b = 0.0; for (i1 = 0; i1 < 7; i1++) { b += er[i1] * dv[i1 + 7 * i]; } w[i] = b; } /* Compute posterior weights based on uncertainty in mean and covariance */ for (i = 0; i < 49; i++) { posteriorSigma[i] *= delta; } inv(posteriorSigma, dv); for (i = 0; i < 7; i++) { b = 0.0; for (i1 = 0; i1 < 7; i1++) { b += pi[i1] * dv[i1 + 7 * i]; } pw[i] = b; } /* Compute lambda value */ /* We solve for lambda from formula (17) page 7, rather than formula (18) */ /* just because it is less to type, and we've already computed w*. */ pinv(P, er_tmp); *lambda = 0.0; for (ps_tmp = 0; ps_tmp < 7; ps_tmp++) { *lambda += er_tmp[ps_tmp] * (w[ps_tmp] * (tau + 1.0) - weq[ps_tmp]); } /* Black-Litterman example code for MatLab (hlblacklitterman.m) */ /* Copyright (c) Jay Walters, blacklitterman.org, 2008. */ /* */ /* Redistribution and use in source and binary forms, */ /* with or without modification, are permitted provided */ /* that the following conditions are met: */ /* */ /* Redistributions of source code must retain the above */ /* copyright notice, this list of conditions and the following */ /* disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above */ /* copyright notice, this list of conditions and the following */ /* disclaimer in the documentation and/or other materials */ /* provided with the distribution. */ /* */ /* Neither the name of blacklitterman.org nor the names of its */ /* contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */ /* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */ /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR */ /* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR */ /* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ /* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */ /* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH */ /* DAMAGE. */ /* */ /* This program uses the examples from the paper "The Intuition */ /* Behind Black-Litterman Model Portfolios", by He and Litterman, */ /* 1999. You can find a copy of this paper at the following url. */ /* http:%papers.ssrn.com/sol3/papers.cfm?abstract_id=334304 */ /* */ /* For more details on the Black-Litterman model you can also view */ /* "The BlackLitterman Model: A Detailed Exploration", by this author */ /* at the following url. */ /* http:%www.blacklitterman.org/Black-Litterman.pdf */ /* */ } /* * File trailer for hlblacklitterman.c * * [EOF] */