Mímisbrunnr知恵の泉

← 金融工学 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:平均分散分析 | 数理:凸最適化の基礎(機械学習・制約付き最適化)

要点(BLUF)

1. n資産への一般化と最適化問題

平均分散分析 の式 μp=wμ\mu_p=\mathbf{w}^\top\boldsymbol\muσp2=wΣw\sigma_p^2=\mathbf{w}^\top\Sigma\mathbf{w} は資産数 nn がいくつでもそのまま使えます。効率的フロンティアは、**「目標リターン μ\mu^\ast を達成する中で分散が最小の配分」**を μ\mu^\ast を動かしながら集めたものです。これは制約付き最適化問題になります。

minw wΣws.t.wμ=μ,  w1=1\min_{\mathbf{w}}\ \mathbf{w}^\top\Sigma\,\mathbf{w} \quad\text{s.t.}\quad \mathbf{w}^\top\boldsymbol\mu = \mu^\ast,\ \ \mathbf{w}^\top\mathbf{1}=1

目的関数 wΣw\mathbf{w}^\top\Sigma\mathbf{w} は(Σ\Sigma が正定値なら)凸なので、これは凸最適化です(凸最適化の基礎(機械学習))。空売り禁止なら wi0w_i\ge 0 の制約を加えます。とくに最小分散ポートフォリオはリターン制約を外した

wMVP=Σ111Σ11\mathbf{w}_{\text{MVP}} = \frac{\Sigma^{-1}\mathbf{1}}{\mathbf{1}^\top\Sigma^{-1}\mathbf{1}}

という閉じた形で書けます(ラグランジュ未定乗数法で導けます)。4資産で実際にフロンティアを描きます。

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
from scipy.optimize import minimize

mu = np.array([0.08, 0.12, 0.15, 0.10])      # 各資産の期待リターン
sig = np.array([0.12, 0.20, 0.25, 0.15])     # 各資産のボラ
corr = np.array([
    [1.00, 0.30, 0.20, 0.40],
    [0.30, 1.00, 0.50, 0.30],
    [0.20, 0.50, 1.00, 0.25],
    [0.40, 0.30, 0.25, 1.00],
])
Sigma = np.outer(sig, sig) * corr            # 共分散行列
n = len(mu)

# ランダムなロングオンリー配分の雲
rng = np.random.default_rng(0)
W = rng.random((5000, n)); W /= W.sum(axis=1, keepdims=True)
rets = W @ mu
vols = np.sqrt(np.einsum("ij,jk,ik->i", W, Sigma, W))

# 効率的フロンティア(目標リターンごとに分散最小化、long-only)
def pvol(w): return np.sqrt(w @ Sigma @ w)
targets = np.linspace(mu.min(), mu.max(), 50)
front_vols = []
for tr in targets:
    cons = [{"type": "eq", "fun": lambda w: w.sum() - 1},
            {"type": "eq", "fun": lambda w, tr=tr: w @ mu - tr}]
    res = minimize(pvol, np.repeat(1/n, n), bounds=[(0, 1)]*n, constraints=cons)
    front_vols.append(res.fun)
front_vols = np.array(front_vols)

# 最小分散ポートフォリオ(解析解、ショート許容)
ones = np.ones(n); Sinv = np.linalg.inv(Sigma)
w_mvp = Sinv @ ones / (ones @ Sinv @ ones)
mvp_ret, mvp_vol = w_mvp @ mu, np.sqrt(w_mvp @ Sigma @ w_mvp)

plt.figure(figsize=(7, 5))
plt.scatter(vols, rets, s=6, alpha=0.3, label="ランダムな配分")
plt.plot(front_vols, targets, "k-", lw=2, label="効率的フロンティア")
plt.scatter(mvp_vol, mvp_ret, color="crimson", zorder=5, label="最小分散ポートフォリオ")
plt.xlabel("リスク(年率ボラ)"); plt.ylabel("期待リターン")
plt.title("効率的フロンティア(4資産)")
plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show()

print("MVP 配分:", np.round(w_mvp, 4))
print(f"MVP リターン {mvp_ret:.4%}, ボラ {mvp_vol:.4%}")

出力:

MVP 配分: [0.6001 0.0875 0.0516 0.2607]
MVP リターン 9.2329%, ボラ 10.7047%

出力の意味:ランダムな配分(点の雲)はすべて、フロンティアの曲線より右側(高リスク側)に入ります。フロンティアは「与えられたリスクで到達できるリターンの上限」です。MVP(赤点)はボラ 10.70% で、どの単独資産(最小でも資産Aの12%)より低リスク。フロンティアの MVP より上側だけが「効率的」——下側は同じリスクでわざわざ低リターンを選ぶことになり、誰も選びません。

2. リスクフリー資産と資本市場線

ここにリスクフリー資産(国債など、ボラ 0・確実なリターン RfR_f)を加えると、状況が一変します。リスクフリー資産と任意の危険資産ポートフォリオ PP を混ぜた組合せは、リスク・リターン平面で直線になります(リスクフリーのボラが0だから)。この直線の傾きはシャープレシオ (μPRf)/σP(\mu_P-R_f)/\sigma_P。傾きが最大になるのは、RfR_f から引いた直線が効率的フロンティアに接するときで、その接点を接点ポートフォリオ、直線を**資本市場線(CML: Capital Market Line)**と呼びます。

μ=Rf+μtanRfσtan接点のシャープレシオσ\mu = R_f + \underbrace{\frac{\mu_{\text{tan}}-R_f}{\sigma_{\text{tan}}}}_{\text{接点のシャープレシオ}}\,\sigma

接点ポートフォリオも閉じた形で求まります(リスクフリー資産があるとき)。

wtan=Σ1(μRf1)1Σ1(μRf1)\mathbf{w}_{\text{tan}} = \frac{\Sigma^{-1}(\boldsymbol\mu - R_f\mathbf{1})}{\mathbf{1}^\top\Sigma^{-1}(\boldsymbol\mu - R_f\mathbf{1})}
import numpy as np

mu = np.array([0.08, 0.12, 0.15, 0.10])
sig = np.array([0.12, 0.20, 0.25, 0.15])
corr = np.array([
    [1.00, 0.30, 0.20, 0.40],
    [0.30, 1.00, 0.50, 0.30],
    [0.20, 0.50, 1.00, 0.25],
    [0.40, 0.30, 0.25, 1.00],
])
Sigma = np.outer(sig, sig) * corr
ones = np.ones(len(mu)); Sinv = np.linalg.inv(Sigma)

rf = 0.03                              # リスクフリー金利
excess = mu - rf*ones
w_tan = Sinv @ excess / (ones @ Sinv @ excess)   # 接点ポートフォリオ

tan_ret = w_tan @ mu
tan_vol = np.sqrt(w_tan @ Sigma @ w_tan)
tan_sharpe = (tan_ret - rf) / tan_vol

print("接点ポートフォリオ 配分:", np.round(w_tan, 4))
print(f"接点 リターン {tan_ret:.4%}, ボラ {tan_vol:.4%}")
print(f"接点 シャープレシオ(=資本市場線の傾き): {tan_sharpe:.4f}")

出力:

接点ポートフォリオ 配分: [0.3124 0.151  0.2142 0.3223]
接点 リターン 10.7484%, ボラ 11.9353%
接点 シャープレシオ(=資本市場線の傾き): 0.6492

出力の意味:接点ポートフォリオは4資産すべてをプラスで保有し(配分はすべて正)、シャープレシオは 0.6492。これが**「危険資産だけで作れる最良の組合せ」**です。投資家は、自分のリスク許容度に応じて「リスクフリーをどれだけ持つか」を変えるだけ——危険資産の中身(接点ポートフォリオ)は誰でも同じになります。

3. 分離定理:誰もが同じ危険資産ポートフォリオを持つ

この「全投資家がリスクフリー資産と同一の接点ポートフォリオの組合せを持つ」という結論を**分離定理(two-fund separation)**と呼びます。リスク回避度の違いは「リスクフリーと接点の比率」だけに現れ、危険資産の構成比は共通です。

flowchart LR
  RF["リスクフリー資産 (国債)"] --> CML["資本市場線 (CML)"]
  TAN["接点ポートフォリオ (危険資産の最適配分)"] --> CML
  CML --> INV["各投資家の最適 = RF と接点の比率を変えるだけ"]

この「みんなが同じ危険資産ポートフォリオを持つ」という発想を、市場全体に当てはめると——接点ポートフォリオは市場ポートフォリオそのものになり、次の CAPMと証券市場線 の出発点になります。

⚠️ よくある誤解

関連ノート