Otama's Playground > 投資 > ブラック・リッターマン法による投資ポートフォリオ最適化: 基本概念とPythonでの実践

ブラック・リッターマン法による投資ポートフォリオ最適化: 基本概念とPythonでの実践

今日はブラック・リッターマン法という手法を使って、投資ポートフォリオの資産配分を最適化する方法を解説します。この方法では、市場のデータと投資家の見解を組み合わせて、期待リターンを計算します。この記事では、実際にPythonコードを使用してブラック・リッターマン法を適用し、その結果を確認していきます。

ブラック・リッターマン法 is 何

ブラック・リッターマン法(Black-Litterman Model)は、投資ポートフォリオの資産配分を最適化するためのモデルで、フィッシャー・ブラックとロバート・リッターマンによって開発されました。このモデルは、マーケットのデータ(例えば、株価や債券のリターンデータ)から計算した期待リターンと投資家の見解(アナリストの予測など)を組み合わせて、期待リターンを計算します。この期待リターンを用いて平均分散最適化を行うことで、数値的に計算した数値と投資家の見解、その両方を考慮したポートフォリオを作成することが可能になります。

投資家の見解には特定の資産や資産グループに対する投資家の予測。リターンの予測とその予測の不確実性が含まれます。「投資家の見解」と言っていますが、実は人間が出した予測でなくても構いません。そのため、数値的に計算したリターンに機械学習で予測したリターンをブレンドするために使用されたりもしています。

ブラック・リッターマン法を使うステップ

  1. マーケットポートフォリオから均衡リターンを求める(Reverse Optimization)
  2. 均衡リターンに投資家の見解をブレンドする(Bayesian approach)

ステップ1: マーケットポートフォリオから均衡リターンを求める(Reverse Optimization)

マーケットポートフォリオの資産割合とリスクから計算される各資産クラスの期待リターンを計算します。すべての投資家が同じ情報を持ち、リスクに対する評価が一致している状態を均衡としており、この場合に得られるであろうリターンを均衡リターンと呼称しています。

均衡リターンは以下の式を用いて求めます。

\[\Pi = \lambda \cdot \Sigma \cdot w\]

\[
\begin{align}
\Pi & : \text{均衡リターン} \\
\lambda & : \text{risk aversion(リスク回避度)} \\
\Sigma & : \text{共分散行列(各資産のリスクの関係を示す行列)} \\
w & : \text{マーケットポートフォリオの資産配分}\\
\end{align}
\]

ここでリスク回避度とは投資家がどの程度リスクを取ることを嫌がるかの指標です。

一般的には、risk aversionは以下のように表されます。(0より小さい値は理論上あり得ません)

  • 0 < delta < 1: 非常にリスク許容度が高い(リスクをあまり恐れない)
  • 1 < delta < 10: 通常の範囲でのリスク許容度
  • delta > 10: 非常にリスク回避的(リスクを非常に嫌う)

※ このフェーズでは期待リターンが算出できれば問題ないため、CAPMなど別モデルを使用することも可能です。

ステップ2: 均衡リターンに投資家の見解をブレンドする(Bayesian approach)

マーケットの情報と投資家の見解を組み合わせた期待リターンを計算します。この方程式は以下のような形をとります:

\[
E(R) = \left( (\tau \cdot \Sigma)^{-1} + P^T \cdot \Omega^{-1} \cdot P \right)^{-1} \left( (\tau \cdot \Sigma)^{-1} \cdot \Pi + P^T \cdot \Omega^{-1} \cdot Q \right)
\]

\[
\begin{align}
&E(R): \text{最終的な資産の期待リターン} \\
&\tau: \text{スケーリングファクター(通常、0.025などの小さい値)} \\
&\Omega: \text{見解の不確実性を表す行列(通常、対角行列として設定)} \\
&Q: \text{投資家の見解による期待リターン} \\
&P: \text{投資家の見解が影響する資産を示す行列(pick matrix)} \\
\end{align}
\]

※ \(\tau\)は共分散行列の不確実性を調整するパラメータであり、経験則で選定されるようです。一般的に\(\tau\) の値は小さく設定され、逆に投資家が独自の強い見解を持っている場合は、大きく設定される傾向があります。

式が複雑で少し吐きそうになりますが、パーツ毎に軽く説明をしていきます。

左半分は市場の均衡リターンと投資家の見解の不確実性を統合し、市場情報と投資家の見解を統合した全体的な情報の信頼度を計算しています

\[\left( \left( \tau \Sigma \right)^{-1} + P^{T} \Omega^{-1} P \right)^{-1}\]

  • 市場均衡リターンの信頼度と投資家の見解の信頼度を加算したものの逆行列
  • 事前の市場均衡リターンと投資家の見解の信頼度を統合した新しい情報の信頼度を表します

右半分は事前の市場情報と投資家の見解を統合した新しい期待リターンを計算しています。

\[\left( (\tau \Sigma)^{-1} \Pi + P^{T} \Omega^{-1} Q \right)\]

  • 市場均衡リターンと投資家の見解を統合して、新しい期待リターンを計算しています

最終的に\(\text{(ブレンドされた不確実性)} \times \text{(ブレンドされた期待リターン)}\)を計算することで、最終的な期待リターンを得ることができます。

実際にPythonで計算してみる

簡単のためかなり簡易化した形で計算します。

  • マーケットポートフォリオに全世界株式と全世界債券のみがあるとする

ステップ1: マーケットポートフォリオから均衡リターンを求める(Reverse Optimization)

以下のように仮定します。

全世界株式と全世界債券の期待リターンが5%と2%
全世界株式と全世界債券の割合が60%:40%

\[
\text{共分散行列} = \begin{pmatrix}
0.1 & 0.02 \\
0.02 & 0.08
\end{pmatrix}
\]

このとき均衡リターンを計算するスクリプトは以下のようになります。

import numpy as np

# 市場データの仮定
expected_market_returns = np.array([0.05, 0.02])  # 株式と債券の期待リターン
market_weights = np.array([0.60, 0.40])  # 株式と債券の割合
cov_matrix = np.array([[0.1, 0.02], 
                       [0.02, 0.08]])  # 共分散行列

# リスク回避係数の設定
risk_aversion = 2.5  # リスク回避係数の仮定(実際は計算して求めたりする)

# 市場均衡ポートフォリオの期待リターン (\Pi)
pi = risk_aversion * np.dot(cov_matrix, market_weights)

print("市場均衡ポートフォリオの期待リターン (Pi):", pi)

実行結果

市場均衡ポートフォリオの期待リターン (Pi): [0.17 0.11]

現実の値とはだいぶ乖離してますが、仮定の話なので許して…

ステップ2: 均衡リターンに投資家の見解をブレンドする(Bayesian approach)

まず投資家の見解を設定します。ここでは、株式が10%(不確実性4%)、債券が3%(不確実性2%)のリターンを上げると予測します。

# 投資家の予測
investor_views = np.array([0.10, 0.03])

# 見解に対する不確実性(共分散行列)
omega = np.diag([0.04, 0.02])  # 予測の不確実性を反映

# 見解の影響を示す行列(株式と債券に関する予測)
P = np.array([[1, 0], 
              [0, 1]])

次に、設定した投資家の見解を使用して各資産の期待リターンを計算

# スケーリングファクターの設定
tau = 0.025

# 最終期待リターンの計算
inv_cov_matrix = np.linalg.inv(tau * cov_matrix)
omega_inv = np.linalg.inv(omega)
PT_omega_inv_P = np.dot(np.dot(P.T, omega_inv), P)

middle_matrix = np.linalg.inv(inv_cov_matrix + PT_omega_inv_P)
part_one = np.dot(inv_cov_matrix, pi)
part_two = np.dot(np.dot(P.T, omega_inv), investor_views)
final_expected_returns = np.dot(middle_matrix, (part_one + part_two))

print("最終的な期待リターン:", final_expected_returns)

実行結果

最終的な期待リターン: [0.16418829 0.10199786]

ステップ1の結果と比べて、投資家の見解を踏まえて少し補正が入ってるのがわかると思います。

最終的なコード

import numpy as np

# 市場データの仮定
expected_market_returns = np.array([0.05, 0.02])  # 株式と債券の期待リターン
market_weights = np.array([0.60, 0.40])  # 株式と債券の割合
cov_matrix = np.array([[0.1, 0.02], 
                       [0.02, 0.08]])  # 共分散行列

# リスク回避係数の設定
risk_aversion = 2  # リスク回避係数の仮定(適切に調整可能)

# 市場均衡ポートフォリオの期待リターン (\Pi)
pi = risk_aversion * np.dot(cov_matrix, market_weights)

# 投資家の予測
investor_views = np.array([0.10, 0.03])

# 見解に対する不確実性(共分散行列)
omega = np.diag([0.04, 0.02])  # 予測の不確実性を反映

# 見解の影響を示す行列(株式と債券に関する予測)
P = np.array([[1, 0], 
              [0, 1]])

# スケーリングファクターの設定
tau = 0.025

# 最終期待リターンの計算
inv_cov_matrix = np.linalg.inv(tau * cov_matrix)
omega_inv = np.linalg.inv(omega)
PT_omega_inv_P = np.dot(np.dot(P.T, omega_inv), P)

middle_matrix = np.linalg.inv(inv_cov_matrix + PT_omega_inv_P)
part_one = np.dot(inv_cov_matrix, pi)
part_two = np.dot(np.dot(P.T, omega_inv), investor_views)
final_expected_returns = np.dot(middle_matrix, (part_one + part_two))

print("市場均衡ポートフォリオの期待リターン (Pi):", pi)
print("最終的な期待リターン:", final_expected_returns)

最後に

ここまででブラック・リッターマン法によって補正された期待リターンを求めることができました。この期待リターンを使用して平均分散最適化を行うことで、最適化された効率の良いポートフォリオを作成することができます。

計算自体は単純なのでそんなにコードは必要ありませんでした。今回は端折りましたが、どちらかというと均衡リターンを求める部分、投資家の見解を持ってくる部分が鬼門になるのかなと思います。気が向いたらそこらへんも調べてまとめてみようと思うので、見つけたらまた読みにきていただけると嬉しいです。

ポートフォリオ構築に関連する他のモデルを知りたい方は下記のリンク集をぜひご活用ください。

otama-playground.com

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です