現代の投資戦略において、多くの投資家はポートフォリオのリスク管理に注力しています。その中で、「リスクパリティポートフォリオ」という手法が注目を集めています。本記事では、リスクパリティポートフォリオの基本概念、メリット、計算方法、そしてPythonでの実装方法について解説します。
リスクパリティポートフォリオとは
リスクパリティポートフォリオは、ポートフォリオのリスク(つまり変動性やボラティリティ)、を均等に分散させることを目指す投資戦略です。この戦略は、各資産クラスがポートフォリオ全体に同等のリスク寄与を持つように設計されています。これにより、特定の資産クラスに依存しないバランスの取れたポートフォリオを構築することが可能になります。
リスクパリティポートフォリオのメリット
リスクパリティポートフォリオの主なメリットは以下の通りです
- 安定性の向上
- 異なる資産クラスのリスクを均等に分散させるため、特定の資産クラスのパフォーマンスに依存しない安定したパフォーマンスが期待できます。
- リスク管理
- ポートフォリオのリスク管理がしやすく、リスクが過度に集中することを避けることができます。特定の市場や経済状況に対する耐性が向上します。
- 予測の必要性の低減
- 未来の市場動向を予測する必要が少なく、リスクの均等化を基本原則とするため、予測の失敗による影響が少なくなります。
リスクパリティポートフォリオのデメリット
リスクパリティポートフォリオには、以下のようにデメリットも存在します。
- リターンの低下
- リスクを均等に分散させることで、ポートフォリオ全体のリターンが低くなる可能性があります。特定の高リスク・高リターン資産に集中投資する戦略と比べると、リターンが少なくなる可能性があります。
- 特に債権のようなリスクが特に低い資産を取り入れる場合、(相関の状況にもよりますが)ほとんど債券になってしまうケースがあります。
リスクパリティポートフォリオの計算方法
リスクパリティポートフォリオでは、各資産のリスク寄与度が均等になるように設定されます。そして、各資産のリスク寄与度の差の二乗和が最小化するポートフォリオがリスクパリティポートフォリオと呼ばれます。
最適化問題として定式化する
各資産のリスク寄与度が等しくなるような資産のウェイトを探索します。
目的関数
制約条件
上記の目的関数はリスクパリティの定義に乗っ取って各資産のリスク割合が同じになるように定義したものですが、下記のようにリスクの平均を使用して表すこともできます。この目的関数はリスク寄与度を平均に近づけることを目的としています。(結果的にすべての資産のリスク割合が均等になる)
資産の標準偏差の計算方法
Tは観測点の数です。他の説明は端折ります。
共分散行列の計算方法
ここも説明は端折ります。
リスク寄与度の計算方法
資産iのリスク寄与度は以下のように計算します。リスク寄与度とはポートフォリオ全体のリスクにおいて資産のリスクが占める割合を示します。
ポートフォリオ全体の標準偏差を計算する方法
ポートフォリオ全体の標準偏差(リスク) は次のように計算されます。
Pythonで計算してみる
コード
> コード(クリックして展開してください)
import yfinance as yf import numpy as np import pandas as pd from scipy.optimize import minimize import matplotlib.pyplot as plt # ポートフォリオ全体の標準偏差 def sigma_P(w,cov): return np.sqrt((w*cov*w.T)[0,0]) # リスク寄与度 def RC(w,cov): return np.multiply(cov*w.T, w.T)/sigma_P(w,cov) # 目的関数 def objective_function(x, params): wt = np.asmatrix(x) cov = params[0] # ポートフォリオ全体の標準偏差 sig_p = sigma_P(wt, cov) # 資産毎のリスク寄与度 rc = RC(wt, cov) # 目標とするリスク(sigma_Pを資産数で割ったもの) target_risk = np.full((1, len(x)), sig_p/len(x)) # 目的関数の計算(penaltyを大きくするため1000をかける) return sum(np.square(rc - target_risk.T))[0]*1000 def total_weight_constraint(x): return np.sum(x)-1.0 def long_only_constraint(x): return x # データの取得と日次リターンの計算 tickers = ['VTI','BND','GLDM'] data = yf.download(tickers, start='2021-06-01', end='2024-06-01')['Adj Close'] returns = data.pct_change().dropna() # 共分散行列を計算 V = returns.cov().to_numpy() # 最適化する num_assets = len(tickers) w0 = [1 / num_assets for i in range(num_assets)] # ウェイトの初期値 cons = ({'type': 'eq', 'fun': total_weight_constraint},{'type': 'ineq', 'fun': long_only_constraint}) res= minimize(objective_function, x0=w0, args=[V], method='SLSQP',constraints=cons, options={'disp': True, 'ftol': 1e-12}) w_final = np.asmatrix(res.x) rc_final = RC(np.matrix(w_final), V) w_final = np.array(w_final).flatten() rc_final = np.array(rc_final).flatten() df = pd.DataFrame({'Weight': w_final, 'Risk Contrib': rc_final}, index = data.columns) print(df) plt.figure() df.plot.bar(y = "Weight") plt.savefig('weight.png') plt.figure() df.plot.bar(y = "Risk Contrib") plt.savefig('risk_contrib.png')
実行結果
Weight Risk Contrib Ticker BND 0.513202 0.001661 GLDM 0.263960 0.001661 VTI 0.222837 0.001661
最後に
今回はリスクパリティポートフォリオを紹介しました。このポートフォリオは以前紹介したリターンを重視したポートフォリオとは違い、リスクの均等性を意識したものになっています。そのため、リターンは少なくなる可能性がありますが、資産毎にリスクを均等化してるだけあって、安定したポートフォリオになっているので、自分のライフステージに合わせてこういうポートフォリオを選ぶのも選択かと思います。最終的に選択するのは自分自身なので、ポートフォリオ毎のメリットデメリットを突き合わせながら、自分に合うポートフォリオを考えてみてください。
ポートフォリオ構築に関連する他のモデルを知りたい方は下記のリンク集をぜひご活用ください。