本来であれば「ファイナンス・数学・プログラミングをサボってた私が5時間で効率的フロンティアを書けるようになるまで」的なタイトルにするつもりだったのですが、思いっきり失敗して苦し紛れのレポートが完成したので記念パピコ。
【効率的フロンティアとは】
複数の金融資産を保有しているときに、その資産配分(ポートフォリオ)が取り得るリスク・リターンの組み合わせをグラフ化し、特に、あるリターンを実現する最もリスクの小さい組み合わせを効率的フロンティアと呼ぶ。
【前提】
・最低限の行列の知識はある。というか積の前提条件と結果が分かれば良い。
http://www.geisya.or.jp/~mwm48961/kou2/matrix2.html
・Windows OS上でMicrosoft Excelを動かすことができる。最悪、置換でゴリ押し。
http://ms-excel.jp/excel-22.php
【やったこと】
1:銘柄の選定(今回はオリンピック関連業界 > 企業の成長性・安定性にポイントを付けて59銘柄に絞る)
2:各銘柄の時系列株価を3年分取得:
利用したツール http://kabubegin.web.fc2.com/
3:ネットで見つけた最高に分かりやすい資料(下記URL)を参考にして計算。
清水千弘『複数資産ポートフォリオにおける効率的フロンティア曲線の導出について(平均・分散アプローチ)』
http://www.cs.reitaku-u.ac.jp/sm/shimizu/Lecture/Reitaku-Univ/RealEstateFinance/Markowitz_Portfolio.pdf
①収益率を導出:
株価(時系列)データを元に、(n期の株価 ÷ n-1期の株価)から1を引いて、新たに時系列データを作る。必要に応じて年率換算。
②期待収益率を導出:
⇒収益率(①の計算結果)の平均を求める。使用関数はAVERAGE。
※反省点:ヒストリカルデータだけでなく、シナリオ手法などを用いてデータ加工したほうが良い。
③リスクを導出:
⇒収益率(①の計算結果)の標準偏差を求める。使用関数はVAR。
※反省点:各種リスクに対応した複合的な計算をした方が良い。それが無理ならせめてテールリスクに対してVaRを。
④分散・共分散行列Vを導出:
⇒収益率(①の計算結果)について、銘柄間の分散を求めて正方行列の形式でExcelにまとめる。使用関数はCOVAR()。*(n/(n‐1))も忘れずに。
※反省点:株価のデータ数が必ずしも同じではない(抜けがある)ときの例外処理はプログラムを組んだ方が良い。手動だと面倒臭すぎる。
⑤一階の条件式、第1項Aを導出:
⇒行列V(④の結果)に以下を付け加える。
・右1列目に「期待収益率(②の結果)」に(-1)を掛けた値を列挙。
・右2列目に -1 を列挙。
・下1列目に「期待収益率(②の結果)」を列挙。
・下2列目に 1 を列挙。
・右下の余ったスペース(2×2)に 0 を列挙。
⑥Aの逆行列を導出:
⇒張付先のセル範囲を指定し、関数MINVERSEを選択し、行列A(⑤で既述)を引用元として選び、Ctrl+Shift+Enter。
⑦一階の条件式、bを導出:
⇒bは列ベクトルで1行目〜k行目(k種類の銘柄を扱うとき)は 0 となり、k+1行目に「目標となるリターン」、K+2行目に 1 を記入する。
※反省点:目標リターンの数値を自由に動かせるようにプログラムを組んだ方が良い。手動だと面倒臭い。
⑧最適比率を導出:
⇒Aの逆行列(⑥)とb(⑦)の行列積を求める。階は列ベクトルになるので、1列で k+2 の張付先セル範囲を指定し、関数MMULTを選択し、引用元をそれぞれ選んだ後、Ctrl+Shift+Enter。結果の 1〜K 行目までは、それぞれ 1〜k 番目の銘柄の比率になる。
※反省点:本来ならばここでVBAを起動させ、各リターンごとの最適比率をシミュレーションする。
※反省点:制約条件を付けずにやったので、負の数(ショートポジション:保有比率を決める題意に沿わない)や、極めて小さい値(1/10の8乗など:この比率を満たすために1株10,000円×100株=1,000,000の最小単位を保有したとして、予算は100,000,000,000,000=100兆円も必要になるので実現不可能)が出てしまう。実務上は離散型しか適用されないはずなので、制約条件をアルゴリズムに加えて分析する必要があるかも。そこまで行かなくても株式保有の下限・上限・予算などは織り込んだ方が良い。
⑨ウエイト・ベクトルを導出:
⇒1〜k番目の銘柄の比率(⑧)を列ベクトルで表示する。
⑩ウエイト・ベクトルの逆行列を導出:
⇒列ベクトル(⑨)の行と列を入れ替えて行ベクトルを表示する。
⑪リスクを導出:
⇒まずは、行列V(④の結果)と、銘柄比率の列ベクトル(⑨の結果)の積=Vwを求める。MMULTで算出結果は列ベクトルになる。
⇒次に、ウエイト・ベクトルの逆行列(⑩の結果)と、Vw(⑪前半)の積=分散 σ^2 を求める。MMULTで算出結果は1つの数字になる。
※メモ:関数ABSで分散 σ^2 の絶対値を取った後、関数SQRTで平方根を取れば標準偏差が計算できる。
⑫縦軸に収益率 / 横軸に最小リスク量 を取るグラフを作成する。
※反省点:一通りの結果を得た後に、シミュレーションおよびストレステストを行う。疲れた状態で考えるの大変だから事前準備は必須。
【反省点】
・そもそも銘柄の選択が適切ではなかった。投資ユニバース > スクリーニング の段階が重要。
・銘柄ごとのリスク、リターンを過去のデータに依存しすぎた。将来の数値に付いてロジックを構築した方が良い。
・面倒な処理はなるべくプログラミング。Maltabは30万円もするし大学だと利用申請が必要で面倒臭い。マクロVBAをきちんと使いこなそう。
・制約条件に関するロジックを構築した方が良い。連続変数として一応の解答は出せるけど、実現不可能な結果になる。
・事前にシミュレーションやストレステストのデータを準備しておいた方が良い。
※というか、多分、これらの反省点を考慮した理論モデル・アルゴリズムは、普通に教科書に掲載されているんじゃないだろうか、と思った。でも、1度自分の手を動かしてやってみて失敗したからこそ、教科書から効率的に吸収できるのです、きっとね。