はじめに
今回の記事では、ポートフォリオ理論の実装します。
ポートフォリオ理論とは、1952年にハリーマーコウィッツに発表した重要な論文で記された理論です。
今回は、そのポートフォリオ理論をPythonで実装したいと思います。
マーコウィッツのポートフォリオ理論の概要
一つの銘柄を大量に保有するよりも、様々な銘柄を分散して保有した方がリスクが低減し、またその保有割合には最適解が存在するという考えに基づく理論をポートフォリオ理論と呼びます。
前回求めた共分散が二つの銘柄の関係性を示すパタメータであることを説明いたしました。
つまり、この共分散の値が低いほど、分散可能なリスクというのが低減します。
よって、お互いに相関し合わない株を保有することが、リスク低減には、大切だということです。
効率的フロンティアとは
ここでは、簡単な例として、二つの銘柄のポートフォリオの最適解を得るために、効率的フロンティアを描きたいと思います。
効率的フロンティアとは、以下をとったグラフを指します。
- 縦軸に期待利益
- 横軸に標準偏差

ここで、リスクは小さく、リターンは最大化できる条件が最適という考えにたったのが、マーコウィッツのポートフォリオ理論です。
上のグラフで言えば、横軸の0.055のポートフォリオがリスクが最小化するという意味になります。
このグラフは、二つの銘柄を以下のように設定して得られた効率的フロンティアです。
株式A | 株式B | |
リターン | 0.01 | 0.08 |
標準偏差 | 0.06 | 0.1 |
相関係数 | 0.2 |
各ポートフォリオの割合は、以下のように設定しました。つまり、ポートフォリオ6が最適解(リスクがもっとも小さいポートフォリオ)ということです。
保有割合 | 保有割合 | 期待利益 | 標準偏差 | |
ポートフォリオ_1 | 0 | 1 | 0.08 | 0.1 |
ポートフォリオ_2 | 0.2 | 0.8 | 0.066 | 0.08323460819 |
ポートフォリオ_3 | 0.4 | 0.6 | 0.052 | 0.06893475176 |
ポートフォリオ_4 | 0.6 | 0.4 | 0.038 | 0.05892367945 |
ポートフォリオ_5 | 0.8 | 0.2 | 0.024 | 0.05556977596 |
ポートフォリオ_6 | 1 | 0 | 0.01 | 0.06 |
ここで、標準偏差とは、ポートフォリオのリスクを表します。ポートフォリオのリスクに関しては、以下の記事を参考にしてみてください。
この効率的フロンティアのプロット方法の詳細に関しては、以下のスプレッドシートで確認することができます。
pythonによる効率的フロンティアの実装
それでは、Pythonで実装していきます。
コード
ライブラリのインポート
pandas_datareaderだけは、Anacondaには含まれていないので、こちらは、別途インストールしてください。
インストール方法は、以下のコマンドを入力することで可能です。
- Mac:ターミナル
- Windows:コマンドプロンプト
pip install pandas_datareader
以下のライブラリをインポートします。
- numpy
- pandas
- pandas_datareader
- matplotlib
import numpy as np
import pandas as pd
from pandas_datareader import data as wb
import matplotlib.pyplot as plt
%matplotlib inline
株価の読み込み
今回は、以下2社の2007年から現在までの株価を取得します。
- MSTF:マイクロソフト
- APPL:アップル
tickers = ['9433.jp', '^TPX']
data = pd.DataFrame()
for t in tickers:
data[t] = wb.DataReader(t, data_source='stooq', start='2015-1-1', end='2020-12-31')['Close']
二つの株価の可視化
(pf_data / pf_data.iloc[0] * 100).plot(figsize=(10, 5))
実行結果は、以下です。Appleの方が圧倒的に成長性していることが分かりますね。

- 一見すると、Appleのみを購入すれば良さそうですが、そうではないのです。
- リスクを考慮する必要があり、それがマーコウィッツのポートフォリオ理論です。

対数利益率を算出
以下で算出可能です。
log_returns = np.log(pf_data / pf_data.shift(1))
対数利益率が不明な方は、以下の記事を参考にしてみてください。
共分散・相関係数の確認
以下で算出可能です。
log_returns.cov() * 250#共分散

log_returns.corr()#相関係数

相関係数0.54。

- んー相関はあるかもねくらいの感覚ですね。
- 正の相関なので、片方の価格が上がれば、もう片方の価格も上がる関係ということです。
共分散・相関係数が不明な方は、以下の記事を参考にしてみてください。
効率的フロンティアの算出
pfolio_returns = []
pfolio_volatilities = []
pfplio_num = 2
for x in range (1000):
weights = np.random.random(pfplio_num)
weights /= np.sum(weights)
pfolio_returns.append(np.sum(weights * log_returns.mean()) * 250)
pfolio_volatilities.append(np.sqrt(np.dot(weights.T,np.dot(log_returns.cov() * 250, weights))))
#データフレーム化
p_folio_returns = np.array(pfolio_returns)
p_folio_volatilities = np.array(pfolio_volatilities)
p_folios = pd.DataFrame({'Return': p_folio_returns, 'Volatility': p_folio_volatilities})
#可視化
portfolios.plot(x='Volatility', y='Return', kind='scatter', figsize=(8, 6));
plt.xlabel('Expected Volatility')
plt.ylabel('Expected Return')
効率的フロンティアが算出されました。二つのポートフォリオの割合は、乱数を使うことで表現しているのが大切なテクニックです。(これがモンテカルロ法の元となる考え方です)
- pfplio_num = 2
- weights = np.random.random(pfplio_num)#これで、配列に二つの乱数を格納
- weights /= np.sum(weights)#これで0〜1の値に規格化
実行結果は、以下です。

再確認となりますが、効率的フロンティアとは、以下をとったグラフを指します。
- 縦軸に期待利益
- 横軸に標準偏差
まとめ
今回の記事では、ポートフォリオ理論について解説しました。
ポートフォリオ理論とは、一つの銘柄を大量に保有するよりも、様々な銘柄を分散して保有した方がリスクが低減し、またその保有割合には最適解が存在するという考えに基づく理論をポートフォリオ理論と呼びます。
ポートフォリオの最適解を得るための効率的フロンティアを描き方について解説しました。
Pythonをもっと勉強したいという方は、以下を参考にしてみてください。私が、勉強に使っている本や勉強方法などを解説しています。
ファイナンス理論に関しては、以下の記事を参照ください。
今回の記事は、以上です。
最後までお読みいただきありがとうございました。
コメント
[…] マーコウィッツのポートフォリオ理論の実装_1 […]