# ドキュメンテーション

## ポートフォリオの最適化 (Black Litterman 法)

この例では、Black Litterman 法を使用して、ポートフォリオの最適化を実行する MATLAB コードから MEX 関数と C のソースコードを生成する方法を説明します。

この例には必要条件はありません。

コマンドの実行: 新規フォルダーの作成と関連ファイルのコピー

```coderdemo_setup('coderdemo_portfolio_optimization'); ```

```type hlblacklitterman ```
```function [er, ps, w, pw, lambda, theta] = hlblacklitterman(delta, weq, sigma, tau, P, Q, Omega)%#codegen % hlblacklitterman % This function performs the Black-Litterman blending of the prior % and the views into a new posterior estimate of the returns as % described in the paper by He and Litterman. % Inputs % delta - Risk tolerance from the equilibrium portfolio % weq - Weights of the assets in the equilibrium portfolio % sigma - Prior covariance matrix % tau - Coefficiet of uncertainty in the prior estimate of the mean (pi) % P - Pick matrix for the view(s) % Q - Vector of view returns % Omega - Matrix of variance of the views (diagonal) % Outputs % Er - Posterior estimate of the mean returns % w - Unconstrained weights computed given the Posterior estimates % of the mean and covariance of returns. % lambda - A measure of the impact of each view on the posterior estimates. % theta - A measure of the share of the prior and sample information in the % posterior precision. % Reverse optimize and back out the equilibrium returns % This is formula (12) page 6. pi = weq * sigma * delta; % We use tau * sigma many places so just compute it once ts = tau * sigma; % Compute posterior estimate of the mean % This is a simplified version of formula (8) on page 4. er = pi' + ts * P' * inv(P * ts * P' + Omega) * (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 コードがコード生成用であることを示します。

'codegen' コマンドを使って MEX 関数を生成します。

```codegen hlblacklitterman -args {0, zeros(1, 7), zeros(7,7), 0, zeros(1, 7), 0, 0} ```

C コードを生成する前に、MATLAB で MEX 関数をテストして、その関数が元の MATLAB コードと機能的に等価であることと実行時エラーが発生しないことを確認しなければなりません。既定の設定では、'codegen' は現在のフォルダーの中に 'hlblacklitterman_mex' という名前の MEX 関数を生成します。これにより、MATLAB コードと MEX 関数をテストして結果を比較することができます。

MEX 関数の実行

```testMex(); ```
```View 1 Country P mu w* Australia 0 4.328 1.524 Canada 0 7.576 2.095 France -29.5 9.288 -3.948 Germany 100 11.04 35.41 Japan 0 4.506 11.05 UK -70.5 6.953 -9.462 USA 0 8.069 58.57 q 5 omega/tau 0.0213 lambda 0.317 theta 0.0714 pr theta 0.929 View 1 Country P mu w* Australia 0 4.328 1.524 Canada 0 7.576 2.095 France -29.5 9.288 -3.948 Germany 100 11.04 35.41 Japan 0 4.506 11.05 UK -70.5 6.953 -9.462 USA 0 8.069 58.57 q 5 omega/tau 0.0213 lambda 0.317 theta 0.0714 pr theta 0.929 Execution Time - MATLAB function: 0.041607 seconds Execution Time - MEX function : 0.008954 seconds ```

C コードの生成

```cfg = coder.config('lib'); codegen -config cfg hlblacklitterman -args {0, zeros(1, 7), zeros(7,7), 0, zeros(1, 7), 0, 0} ```

'-config cfg' オプションを指定して 'codegen' を使用し、スタンドアロン C ライブラリを生成します。

ファイルは、以下のとおりです。

```dir codegen/lib/hlblacklitterman/ ```
```. inv.c .. inv.h buildInfo.mat inv.o codeInfo.mat pinv.c hlblacklitterman.a pinv.h hlblacklitterman.c pinv.o hlblacklitterman.h rtGetInf.c hlblacklitterman.o rtGetInf.h hlblacklitterman_initialize.c rtGetInf.o hlblacklitterman_initialize.h rtGetNaN.c hlblacklitterman_initialize.o rtGetNaN.h hlblacklitterman_ref.rsp rtGetNaN.o hlblacklitterman_rtw.mk rt_nonfinite.c hlblacklitterman_terminate.c rt_nonfinite.h hlblacklitterman_terminate.h rt_nonfinite.o hlblacklitterman_terminate.o rtw_proj.tmw hlblacklitterman_types.h rtwtypes.h interface ```

```type codegen/lib/hlblacklitterman/hlblacklitterman.c ```
```/* * File: hlblacklitterman.c * * MATLAB Coder version : 2.7 * C/C++ source code generated on : 21-Jul-2014 19:08:57 */ /* Include Files */ #include "rt_nonfinite.h" #include "hlblacklitterman.h" #include "pinv.h" #include "inv.h" /* Function Definitions */ /* * hlblacklitterman * This function performs the Black-Litterman blending of the prior * and the views into a new posterior estimate of the returns as * described in the paper by He and Litterman. * Inputs * delta - Risk tolerance from the equilibrium portfolio * weq - Weights of the assets in the equilibrium portfolio * sigma - Prior covariance matrix * tau - Coefficiet of uncertainty in the prior estimate of the mean (pi) * P - Pick matrix for the view(s) * Q - Vector of view returns * Omega - Matrix of variance of the views (diagonal) * Outputs * Er - Posterior estimate of the mean returns * w - Unconstrained weights computed given the Posterior estimates * of the mean and covariance of returns. * lambda - A measure of the impact of each view on the posterior estimates. * theta - A measure of the share of the prior and sample information in the * posterior precision. * Arguments : double delta * const double weq[7] * const double sigma[49] * double tau * const double P[7] * double Q * double Omega * double er[7] * double ps[49] * double w[7] * double pw[7] * double *lambda * double theta[3] * Return Type : void */ void hlblacklitterman(double delta, const double weq[7], const double sigma[49], double tau, const double P[7], double Q, double Omega, double er[7], double ps[49], double w[7], double pw[7], double *lambda, double theta[3]) { double b_weq[7]; double pi[7]; int i0; int i1; double ts[49]; double b; double b_b; double b_ts[7]; double unusedExpr[7]; double c_ts[7]; double d_ts[49]; int i2; double posteriorSigma[49]; double y[49]; double x[49]; /* Reverse optimize and back out the equilibrium returns */ /* This is formula (12) page 6. */ for (i0 = 0; i0 < 7; i0++) { b_weq[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { b_weq[i0] += weq[i1] * sigma[i1 + 7 * i0]; } pi[i0] = b_weq[i0] * delta; } /* We use tau * sigma many places so just compute it once */ for (i0 = 0; i0 < 49; i0++) { ts[i0] = tau * sigma[i0]; } /* Compute posterior estimate of the mean */ /* This is a simplified version of formula (8) on page 4. */ b = 0.0; for (i0 = 0; i0 < 7; i0++) { b_weq[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { b_weq[i0] += P[i1] * ts[i1 + 7 * i0]; } b += b_weq[i0] * P[i0]; } b_b = inv(b + Omega); b = 0.0; for (i0 = 0; i0 < 7; i0++) { b += P[i0] * pi[i0]; b_ts[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { b_ts[i0] += ts[i0 + 7 * i1] * P[i1]; } } b = Q - b; for (i0 = 0; i0 < 7; i0++) { er[i0] = pi[i0] + b_ts[i0] * b_b * b; } /* We can also do it the long way to illustrate that d1 + d2 = I */ 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 (i0 = 0; i0 < 7; i0++) { b_weq[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { b_weq[i0] += P[i1] * ts[i1 + 7 * i0]; } b += b_weq[i0] * P[i0]; c_ts[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { c_ts[i0] += ts[i0 + 7 * i1] * P[i1]; } } b_b = inv(b + Omega); for (i0 = 0; i0 < 7; i0++) { b_ts[i0] = c_ts[i0] * b_b; for (i1 = 0; i1 < 7; i1++) { d_ts[i0 + 7 * i1] = b_ts[i0] * P[i1]; } } for (i0 = 0; i0 < 7; i0++) { for (i1 = 0; i1 < 7; i1++) { b = 0.0; for (i2 = 0; i2 < 7; i2++) { b += d_ts[i0 + 7 * i2] * ts[i2 + 7 * i1]; } ps[i0 + 7 * i1] = ts[i0 + 7 * i1] - b; } } for (i0 = 0; i0 < 49; i0++) { posteriorSigma[i0] = sigma[i0] + ps[i0]; } /* Compute the share of the posterior precision from prior and views, */ /* then for each individual view so we can compare it with lambda */ invNxN(ts, y); b = 0.0; for (i0 = 0; i0 < 7; i0++) { for (i1 = 0; i1 < 7; i1++) { x[i0 + 7 * i1] = 0.0; for (i2 = 0; i2 < 7; i2++) { x[i0 + 7 * i1] += y[i0 + 7 * i2] * ps[i2 + 7 * i1]; } } b += x[i0 + 7 * i0]; } theta[0] = b / 7.0; b_b = inv(Omega); b = 0.0; for (i0 = 0; i0 < 7; i0++) { for (i1 = 0; i1 < 7; i1++) { d_ts[i0 + 7 * i1] = P[i0] * b_b * P[i1]; } for (i1 = 0; i1 < 7; i1++) { y[i0 + 7 * i1] = 0.0; for (i2 = 0; i2 < 7; i2++) { y[i0 + 7 * i1] += d_ts[i0 + 7 * i2] * ps[i2 + 7 * i1]; } } b += y[i0 + 7 * i0]; } theta[1] = b / 7.0; b_b = inv(Omega); b = 0.0; for (i0 = 0; i0 < 7; i0++) { for (i1 = 0; i1 < 7; i1++) { d_ts[i0 + 7 * i1] = P[i0] * b_b * P[i1]; } for (i1 = 0; i1 < 7; i1++) { y[i0 + 7 * i1] = 0.0; for (i2 = 0; i2 < 7; i2++) { y[i0 + 7 * i1] += d_ts[i0 + 7 * i2] * ps[i2 + 7 * i1]; } } b += y[i0 + 7 * i0]; } theta[2] = b / 7.0; /* Compute posterior weights based solely on changed covariance */ for (i0 = 0; i0 < 49; i0++) { y[i0] = delta * posteriorSigma[i0]; } invNxN(y, x); for (i0 = 0; i0 < 7; i0++) { b_weq[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { b_weq[i0] += er[i1] * x[i1 + 7 * i0]; } w[i0] = b_weq[i0]; } /* Compute posterior weights based on uncertainty in mean and covariance */ for (i0 = 0; i0 < 49; i0++) { posteriorSigma[i0] *= delta; } invNxN(posteriorSigma, y); for (i0 = 0; i0 < 7; i0++) { b_weq[i0] = 0.0; for (i1 = 0; i1 < 7; i1++) { b_weq[i0] += pi[i1] * y[i1 + 7 * i0]; } pw[i0] = b_weq[i0]; } /* 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, b_weq); *lambda = 0.0; for (i0 = 0; i0 < 7; i0++) { *lambda += b_weq[i0] * (w[i0] * (1.0 + tau) - weq[i0]); } /* 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] */ ```

クリーンアップ

ファイルを削除して元のフォルダーに戻ります。

コマンドの実行: クリーンアップ

```cleanup ```
この情報は役に立ちましたか?