🎓 レベル:標準 | 重要度:A(必須)
要点(BLUF)
- 資産に広げると、各目標リターンに対して分散を最小化する配分が決まります。それらを結んだ上側の曲線が効率的フロンティア(同じリスクで最大のリターンを与える最適な組合せの集合)——「同じリスクなら最大リターン」の配分の集合です。
- 左端が最小分散ポートフォリオ(MVP)。MVP より下側は、同じリスクでより低いリターンしか得られないので非効率です。
- リスクフリー資産(価格変動リスクがなく元利が確実な資産(国債など))を加えると、フロンティアへの接線(資本市場線 CML(リスクフリー資産と市場ポートフォリオを結ぶ最も効率的な直線))がすべてを支配し、接点が接点ポートフォリオになります。全投資家は「リスクフリー+接点」の組合せだけを持てばよい(分離定理(最適な危険資産の組合せはリスク許容度によらず全員同じという結果))。
1. n資産への一般化と最適化問題
平均分散分析 の式 、 は資産数 がいくつでもそのまま使えます。効率的フロンティアは、**「目標リターン を達成する中で分散が最小の配分」**を を動かしながら集めたものです。これは制約付き最適化問題になります。
目的関数 は( が正定値なら)凸なので、これは凸最適化です(凸最適化の基礎(機械学習))。空売り(持っていない資産を借りて売り、値下がりで買い戻して利益を狙う取引。配分 が負になる)を禁止するなら の制約を加えます。とくに最小分散ポートフォリオはリターン制約を外した
という閉じた形で書けます(ラグランジュ未定乗数法=制約付き最適化を「制約に重み(乗数)を付けて目的関数に組み込み、まとめて微分=0で解く」定石、で導けます)。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・確実なリターン )を加えると、状況が一変します。リスクフリー資産と任意の危険資産ポートフォリオ を混ぜた組合せは、リスク・リターン平面で直線になります(リスクフリーのボラが0だから)。この直線の傾きはシャープレシオ(リスク1単位あたりに得られる超過リターン=「リスクの取り賃の効率」)。傾きが最大になるのは、 から引いた直線が効率的フロンティアに接するときで、その接点を接点ポートフォリオ、直線を**資本市場線(CML: Capital Market Line)**と呼びます。
接点ポートフォリオも閉じた形で求まります(リスクフリー資産があるとき)。
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}")
# --- フロンティアに資本市場線(CML)を重ねて描く ---
import matplotlib.pyplot as plt, japanize_matplotlib
from scipy.optimize import minimize
n = len(mu)
rng = np.random.default_rng(0)
Wc = rng.random((5000, n)); Wc /= Wc.sum(axis=1, keepdims=True)
cloud_r = Wc @ mu
cloud_v = np.sqrt(np.einsum("ij,jk,ik->i", Wc, Sigma, Wc))
targets = np.linspace(mu.min(), mu.max(), 50); front = []
for tr in targets:
cons = [{"type": "eq", "fun": lambda w: w.sum() - 1},
{"type": "eq", "fun": lambda w, tr=tr: w @ mu - tr}]
front.append(minimize(lambda w: np.sqrt(w @ Sigma @ w),
np.repeat(1/n, n), bounds=[(0, 1)]*n, constraints=cons).fun)
w_mvp = Sinv @ ones / (ones @ Sinv @ ones)
mvp_r, mvp_v = w_mvp @ mu, np.sqrt(w_mvp @ Sigma @ w_mvp)
plt.figure(figsize=(7, 5))
plt.scatter(cloud_v, cloud_r, s=6, alpha=0.25, color="#9aa6c8")
plt.plot(front, targets, "k-", lw=2, label="効率的フロンティア")
x = np.linspace(0, cloud_v.max()*1.02, 50)
plt.plot(x, rf + tan_sharpe*x, "--", color="crimson", lw=2,
label=f"資本市場線 CML(傾き {tan_sharpe:.2f})")
plt.scatter(mvp_v, mvp_r, color="#1f77b4", s=70, zorder=5, label="最小分散ポートフォリオ")
plt.scatter(tan_vol, tan_ret, color="crimson", s=120, marker="*", zorder=6, label="接点ポートフォリオ")
plt.scatter(0, rf, color="black", s=45)
plt.annotate("リスクフリー資産 $R_f$", (0, rf), textcoords="offset points", xytext=(8, -14), fontsize=9)
plt.xlabel("リスク(年率ボラ)"); plt.ylabel("期待リターン")
plt.title("効率的フロンティアと資本市場線"); plt.xlim(0, cloud_v.max()*1.05)
plt.legend(loc="lower right", fontsize=8.5); plt.grid(alpha=0.3); plt.tight_layout(); plt.show()
出力:
接点ポートフォリオ 配分: [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と証券市場線 の出発点になります。
⚠️ よくある誤解
- 「フロンティアは全部が効率的」ではない:効率的なのは MVP より上側だけです。下側(同じリスクで低リターン)は非効率で、誰も選びません。「効率的フロンティア」は上半分を指します。
- 空売りの可否でフロンティアは変わる:上のコードは
bounds=[(0,1)]で空売り禁止にしています。空売りを許すと配分が負も取れ、フロンティアはより外側(左上)に広がります。閉形式の MVP・接点は空売りを許した解です。 - 接点ポートフォリオはリスクフリー金利 に依存する: が変われば接線の起点が動き、接点も動きます。「最良の危険資産ポートフォリオ」は金利環境とセットで決まります。
関連ノート
- 第2章 ポートフォリオ理論 目次
- 平均分散分析 — 前提:期待リターンと分散の行列表現
- CAPMと証券市場線 — 次のトピック:接点=市場ポートフォリオから CAPM へ
- シャープレシオとパフォーマンス評価 — 接点=シャープレシオ最大の意味
- 凸最適化の基礎(機械学習)— 制約付き最適化の数理
- 金融工学テキスト 全体目次