2.17 ポートフォリオ最適化問題
ここでは,ポートフォリオが与える収益率の分布を評価する統計量として平均と分散を用いるマルコビッツモデルの例を示します.具体的にはポートフォリオのもたらす収益率の変動の大きさ(リスク)を分散で計測することにし,それを最小化するような資産配分を求めます.
例題
銘柄1,2に対する収益率のサンプル20期分が以下の図のように得られているとします.
この収益率のサンプルを用いてポートフォリオの収益率の分散が最小となる投資配分を求めます.ただし,空売りはできないものとし,またポートフォリオの収益率の期待値は0以上とします.
この問題を定式化すると以下のようになります.
集合 | |
銘柄の集合 | |
サンプルの集合 | |
定数 | |
サンプルにおける銘柄の収益率 | |
銘柄の平均収益率 | |
変数 | |
銘柄の組入比率 | |
目的関数(最小化) | |
ポートフォリオが与える期待収益率の分散(リスク) | |
サンプルにおける平均からのぶれ | |
ポートフォリオの期待収益率 | |
制約条件 | |
非負制約(空売り禁止) | |
組入比率の総和は1 | |
ポートフォリオが与える期待収益率は0以上 |
この問題は目的関数が二次であり制約式は全て線形ですので二次計画問題になります.
定式化した結果をC++SIMPLEで記述すると以下のようになります.
// 集合と添字 Set Asset(name = "銘柄"); Element j(set = Asset); Set Sample(name = "サンプル"); Element t(set = Sample); // パラメータ Parameter r(name = "収益率", index = (t, j)); Parameter rb(name = "平均収益率", index = j); rb[j] = sum(r[t, j], t) / Sample.card(); // Sample.card():集合 Sample の要素数 // 変数 Variable x(name = "組入比率", index = j); // 式 Expression rpb(name = "期待収益率"); rpb = sum(rb[j] * x[j], j); Expression dev(name = "偏差", index = t); dev[t] = sum(r[t, j] * x[j], j) - rpb; // 目的関数 Objective V(name = "リスク"); V = sum(dev[t] * dev[t], t) / Sample.card(); // 制約条件 x[j] >= 0.0; sum(x[j], j) == 1.0; rpb >= 0.0; // 求解 solve(); // 結果出力 V.val.print(); rpb.val.print(); x.val.print();
データファイル(.dat形式)は以下のようになります.
収益率 = [ 1, 1] 0.0000 [ 1, 2] 0.100 [ 2, 1] 0.0162 [ 2, 2] 0.161 [ 3, 1] 0.0307 [ 3, 2] 0.197 [ 4, 1] 0.0419 [ 4, 2] 0.192 [ 5, 1] 0.0485 [ 5, 2] 0.148 [ 6, 1] 0.0498 [ 6, 2] 0.084 [ 7, 1] 0.0458 [ 7, 2] 0.026 [ 8, 1] 0.0368 [ 8, 2] 0.000 [ 9, 1] 0.0238 [ 9, 2] 0.016 [10, 1] 0.0082 [10, 2] 0.068 [11, 1] -0.0082 [11, 2] 0.132 [12, 1] -0.0238 [12, 2] 0.184 [13, 1] -0.0368 [13, 2] 0.200 [14, 1] -0.0458 [14, 2] 0.174 [15, 1] -0.0498 [15, 2] 0.116 [16, 1] -0.0485 [16, 2] 0.052 [17, 1] -0.0419 [17, 2] 0.008 [18, 1] -0.0307 [18, 2] 0.003 [19, 1] -0.0162 [19, 2] 0.039 [20, 1] 0.0000 [20, 2] 0.100 ;
このモデルを実行すると以下のような解が得られます.
リスク = 0.000951734 期待収益率 = 0.0199126 組入比率[1] = 0.800874 組入比率[2] = 0.199126
上に戻る