Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

ポートフォリオ最適化に対する二次計画法、問題ベース

この例では、問題ベース アプローチを使用してポートフォリオ最適化問題を解く方法を示します。ソルバーベースのアプローチについては、ポートフォリオ最適化問題に対する二次計画法、ソルバーベースを参照してください。

二次モデル

ポートフォリオに $n$ 種類の資産が含まれるとします。資産 $i$ の収益率は、期待値が $m_i$ の確率変数です。問題は、指定された最小期待収益率を条件として、リスクを最小限にするには、どの割合 $x_i$ で各資産 $i$ に投資するかを求めることです。

$C$ は資産収益率の共分散行列を示すとします。

従来の平均分散モデルは、以下の測定でポートフォリオ リスクを最小化し、

$$\frac{1}{2}x^T C x$$

これは一連の制約に従います。

期待される収益は、投資家が望むポートフォリオの最小期待収益率 $r$ を下回ってはなりません。

$$\sum_{i=1}^n m_i \; x_i \ge r,$$

投資割合 $x_i$ の合計は 1 にならなければなりません。

$$\sum_{i=1}^n x_i = 1,$$

そして、割合 (またはパーセント) は、0 と 1 の間の数でなければなりません。

$$0 \le x_i \le 1, \;\;\; i = 1 \ldots n.$$

ポートフォリオ リスクを最小限に抑えるという目的関数は二次で制約は線形であるため、最適化問題は最終的に二次計画、つまり QP となります。

225 資産問題

ここで、225 資産をもつ QP を解いてみます。データセットは、OR ライブラリ [Chang, T.-J., Meade, N., Beasley, J.E. and Sharaiha, Y.M., "Heuristics for cardinality constrained portfolio optimisation" Computers & Operations Research 27 (2000) 1271-1302] からの引用です。

データセットを読み込み、問題ベースのアプローチ用に制約を設定します。このデータセットでは、収益率 $m_i$ は -0.008489 ~ 0.003971 の範囲にあります。その中から望ましい収益 $r$、たとえば 0.002 (0.2%) を選択します。

MAT ファイルに保存されているデータセットを読み込みます。

load('port5.mat','Correlation','stdDev_return','mean_return')

相関行列から共分散行列を計算します。

Covariance = Correlation .* (stdDev_return * stdDev_return');
nAssets = numel(mean_return); r = 0.002;     % number of assets and desired return

最適化問題、目的、および制約の作成

最小化する最適化問題を作成します。

portprob = optimproblem;

nAssets 個の要素がある最適化ベクトル変数 'x' を作成します。この変数は各資産に投資した資産額の割合を表すので、0 と 1 の間になければなりません。

x = optimvar('x',nAssets,'LowerBound',0,'UpperBound',1);

目的関数は 1/2*x'*Covariance*x です。この目的関数を問題に含めます。

objective = 1/2*x'*Covariance*x;
portprob.Objective = objective;

変数の合計は 1 であり、ポートフォリオ全体が投資されたことを意味します。これを制約として表し、問題に含めます。

sumcons = sum(x) == 1;
portprob.Constraints.sumcons = sumcons;

平均利益は r より大きくなければなりません。これを制約として表し、問題に含めます。

averagereturn = dot(mean_return,x) >= r;
portprob.Constraints.averagereturn = averagereturn;

225 資産問題の解法

いくつかのオプションを設定し、ソルバーを呼び出します。

反復表示をオンにするオプションと、最適性に関する終了許容誤差を小さくするオプションを設定します。

options = optimoptions('quadprog','Display','iter','TolFun',1e-10);

ソルバーを呼び出し、時計時間を測定します。

tic
[x1,fval1] = solve(portprob,'Options',options);
toc
Solving problem using quadprog.

 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    7.212813e+00   1.227500e+02   1.195948e+00     2.217295e-03  
    1    8.160874e-04   3.615084e-01   3.522160e-03     2.250524e-05  
    2    7.220766e-04   3.592574e-01   3.500229e-03     3.378157e-05  
    3    4.309434e-04   9.991108e-02   9.734292e-04     2.790551e-05  
    4    4.734300e-04   2.220446e-16   6.661338e-16     4.242216e-06  
    5    4.719034e-04   1.110223e-16   3.139849e-16     8.002618e-07  
    6    3.587475e-04   2.220446e-16   2.602085e-18     3.677066e-07  
    7    3.131814e-04   4.440892e-16   2.168404e-18     9.586695e-08  
    8    2.760174e-04   5.551115e-16   2.114194e-18     1.521063e-08  
    9    2.345751e-04   4.440892e-16   1.138412e-18     4.109608e-09  
   10    2.042487e-04   4.440892e-16   1.029992e-18     6.423267e-09  
   11    1.961775e-04   4.440892e-16   9.757820e-19     6.068329e-10  
   12    1.949281e-04   0.000000e+00   9.757820e-19     4.279951e-12  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Elapsed time is 0.115332 seconds.

結果をプロットします。

plotPortfDemoStandardModel(x1.x)

グループ制約付き 225 資産問題

資産 1 ~ 75、76 ~ 150、151 ~ 225 のそれぞれに投資金額の 30% を投資することを要求する制約をモデル グループに追加します。これらの資産グループのそれぞれは、たとえば技術、自動車、医薬品など産業が異なることもあります。この新しい要件を含む制約は、以下のとおりです。

$$\sum_{i=1}^{75} x_i \ge 0.3, \qquad$$
$$\sum_{i=76}^{150} x_i \ge 0.3, \qquad$$
$$\sum_{i=151}^{225} x_i \ge 0.3.$$

既存の等式にグループ制約を追加します。

grp1 = sum(x(1:75)) >= 0.3;
grp2 = sum(x(76:150)) >= 0.3;
grp3 = sum(x(151:225)) >= 0.3;
portprob.Constraints.grp1 = grp1;
portprob.Constraints.grp2 = grp2;
portprob.Constraints.grp3 = grp3;

ソルバーを呼び出し、時計時間を測定します。

tic
[x2,fval2] = solve(portprob,'Options',options);
toc
Solving problem using quadprog.

 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    7.212813e+00   1.227500e+02   3.539920e-01     5.253824e-03  
    1    7.004556e-03   2.901399e+00   8.367185e-03     2.207460e-03  
    2    9.181962e-04   4.095630e-01   1.181116e-03     3.749424e-04  
    3    7.515047e-04   3.567918e-01   1.028932e-03     3.486333e-04  
    4    4.238346e-04   9.005778e-02   2.597127e-04     1.607718e-04  
    5    3.695008e-04   1.909891e-04   5.507829e-07     1.341881e-05  
    6    3.691407e-04   6.146337e-07   1.772508e-09     6.817457e-08  
    7    3.010636e-04   7.691892e-08   2.218222e-10     1.837302e-08  
    8    2.669065e-04   1.088252e-08   3.138350e-11     5.474712e-09  
    9    2.195767e-04   8.122576e-10   2.342425e-12     2.814320e-08  
   10    2.102910e-04   2.839771e-10   8.189465e-13     1.037476e-08  
   11    2.060985e-04   6.713785e-11   1.936135e-13     2.876950e-09  
   12    2.015107e-04   7.771561e-16   9.215718e-19     1.522226e-10  
   13    2.009670e-04   6.661338e-16   1.029992e-18     5.264375e-13  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Elapsed time is 0.115345 seconds.

結果を前の問題の結果に重ね合わせてプロットします。

plotPortfDemoGroupModel(x1.x,x2.x);

これまでの結果の概要

2 番目の棒グラフを見ると、このポートフォリオは、グループ制約を追加したことにより、最初のポートフォリオと比べて 3 つの資産グループへの分配がより均一であることがわかります。また、この多様性により、目的関数 (両実行の反復表示で最後の反復に "f(x)" が付いている列を参照) で測定したところ、リスクがわずかに増加する結果となりました。

乱数データを使用した 1000 資産問題

より大きい問題でソルバーがどのような動作を行うかを示すため、1000 資産のランダムに生成されたデータセットを使用します。MATLAB® で関数 gallery を使用して、ランダム相関行列 (対称、半正定値、対角要素が 1) を生成します。

再現性が必要な場合は、乱数ストリームをリセットします。

rng(0,'twister');
nAssets = 1000; % desired number of assets

ランダム データの作成

-0.1 ~ 0.4 の収益の平均を生成します。

a = -0.1; b = 0.4;
mean_return = a + (b-a).*rand(nAssets,1);
r = 0.15;                                     % desired return

0.08 ~ 0.6 の収益の標準偏差を生成します。

a = 0.08; b = 0.6;
stdDev_return = a + (b-a).*rand(nAssets,1);

Correlation = gallery('randcorr',nAssets) を使用して生成した相関行列を読み込みます (このサイズの相関行列を生成するには時間がかかるので、事前に生成したものを代わりに読み込みます)。

load('correlationMatrixDemo.mat','Correlation');

相関行列から共分散行列を計算します。

Covariance = Correlation .* (stdDev_return * stdDev_return');

最適化問題、目的、および制約の作成

最小化する最適化問題を作成します。

portprob2 = optimproblem;

nAssets 個の要素がある最適化ベクトル変数 'x' を作成します。

x = optimvar('x',nAssets,'LowerBound',0,'UpperBound',1);

目的関数を問題に含めます。

objective = 1/2*x'*Covariance*x;
portprob2.Objective = objective;

変数の合計が 1 になるという制約と、平均利益が r より大きいという制約を含めます。

sumcons = sum(x) == 1;
portprob2.Constraints.sumcons = sumcons;
averagereturn = dot(mean_return,x) >= r;
portprob2.Constraints.averagereturn = averagereturn;

1000 資産問題の解法

ソルバーを呼び出し、時計時間を測定します。

tic
x3 = solve(portprob2,'Options',options);
toc
Solving problem using quadprog.

 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    2.142849e+01   5.490000e+02   3.031839e+00     5.210929e-03  
    1    9.378552e-03   6.439102e+00   3.555978e-02     6.331676e-04  
    2    1.128129e-04   3.705915e-03   2.046582e-05     1.802721e-05  
    3    1.118804e-04   1.852958e-06   1.023291e-08     1.170562e-07  
    4    8.490176e-05   7.650016e-08   4.224702e-10     7.048637e-09  
    5    3.364597e-05   4.440892e-16   2.574980e-18     1.037370e-09  
    6    1.980189e-05   8.881784e-16   9.419006e-19     8.465558e-11  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Elapsed time is 5.070618 seconds.

まとめ

この例では、ポートフォリオ最適化問題に対して問題ベースのアプローチを使用する方法を説明し、さまざまなサイズの二次問題におけるアルゴリズム実行時間を示します。

特に Financial Toolbox™ でのポートフォリオ最適化用に設計された機能を使用すると、より詳細な分析が可能です。

関連するトピック