Mímisbrunnr知恵の泉

← 金融工学 一覧

🎓 レベル:基礎 | 重要度:A(必須)

📎 前提:リターンの測り方 | 数理:期待値・分散の性質(線形性・和の分散・共分散)(統計)・分散共分散行列・相関行列(統計)

要点(BLUF)

1. 分散・標準偏差(ボラティリティ)

リターン RR の期待値(平均)を μ=E[R]\mu = E[R] とすると、分散は平均からのズレの2乗の期待値です。

σ2=Var(R)=E ⁣[(Rμ)2]\sigma^2 = \mathrm{Var}(R) = E\!\left[(R-\mu)^2\right]

その平方根 σ\sigma標準偏差で、金融ではこれをボラティリティと呼びます(リターンと同じ単位=%で測れるので扱いやすい)。データから推定するときは、不偏分散(n1n-1 で割る)を使います。

s2=1n1t=1n(RtRˉ)2s^2 = \frac{1}{n-1}\sum_{t=1}^{n}(R_t - \bar R)^2

日次リターンを合成して、平均・分散・ボラを測ってみます。

import numpy as np

rng = np.random.default_rng(2)

# 日次リターン(真の平均0.05%/日, 日次ボラ1%)を 252 営業日分
daily = rng.normal(0.0005, 0.01, size=252)

mean = daily.mean()
var = daily.var(ddof=1)        # 不偏分散(n-1 で割る)
std = daily.std(ddof=1)        # 標準偏差=日次ボラ

print(f"平均日次リターン  : {mean:.4%}")
print(f"日次分散          : {var:.6f}")
print(f"日次ボラ(標準偏差): {std:.4%}")

出力:

平均日次リターン  : 0.0400%
日次分散          : 0.000100
日次ボラ(標準偏差): 1.0023%

出力の意味:日次ボラは 1.0023% で、設定した真の値1%をほぼ正確に当てています。いっぽう平均は 0.0400% と、設定した0.05%からそこそこズレています。これは偶然ではなく重要な事実——金融では「平均(リターン)の推定はボラの推定よりはるかに難しい」。同じ252日でも、ボラは精度よく測れるのに、平均は大きく外し得ます。だからリスク管理はボラを軸に組み立てられます。

2. 時間スケールとアニュアライズ(√t則)

ボラは「どの時間間隔で測ったか」に依存します。日次の1%と月次の1%はまったく違うリスクです。リターンが期間ごとに独立なら、TT 期間ぶんを足したリターンの分散は各期の分散のになります(独立なら共分散が消えるため)。

Var ⁣(t=1Trt)=t=1TVar(rt)=Tσ2σT=σT\mathrm{Var}\!\left(\sum_{t=1}^{T} r_t\right) = \sum_{t=1}^{T}\mathrm{Var}(r_t) = T\,\sigma^2 \qquad\Longrightarrow\qquad \sigma_{T} = \sigma\sqrt{T}

分散は時間に比例、ボラは時間の平方根に比例します(√t則)。いっぽう平均リターンは時間に比例します(μT=Tμ\mu_T = T\mu)。これを使い、日次の値を年次(252営業日)に換算します。

import numpy as np

rng = np.random.default_rng(2)
daily = rng.normal(0.0005, 0.01, size=252)
mean, std = daily.mean(), daily.std(ddof=1)

# 年次換算:平均は ×252(時間に比例)、ボラは ×√252(√t則)
print(f"年次リターン (×252)  : {mean*252:.2%}")
print(f"年次ボラ   (×√252) : {std*np.sqrt(252):.2%}")

出力:

年次リターン (×252)  : 10.09%
年次ボラ   (×√252) : 15.91%

出力の意味:日次ボラ約1%は、年次にすると 約16%1%×25215.9%1\% \times \sqrt{252} \approx 15.9\%)。日次の小さなブレが、1年積み重なるとこれだけの幅になります。√t則のおかげで、リターン(時間比例)よりリスク(√時間)のほうがゆっくり増える——だから長期投資ではリスク対比のリターンが改善します(リターン/リスク比が T/T=TT/\sqrt{T}=\sqrt{T} で伸びる)。これは第2章のシャープレシオの土台です。

注意:√t則は「リターンが独立同分布」という仮定の上の話です。現実には自己相関やボラティリティ・クラスタリング(時系列解析(定常性・ACF/PACF・AR・MA・ARMA・ARIMA)(統計))があり、厳密には成り立ちません。実務の標準的な近似として使います。

3. 共分散と相関

複数の資産を持つとき、各資産のボラだけでなく「一緒に動くか」が効きます。2資産 A,BA, B のリターンの連動性は共分散で測ります。

Cov(RA,RB)=E ⁣[(RAμA)(RBμB)]\mathrm{Cov}(R_A, R_B) = E\!\left[(R_A-\mu_A)(R_B-\mu_B)\right]

共分散は単位(%の2乗)が直感的でないので、各ボラで割って 1-1 から 11 に正規化した相関係数を使います。

ρAB=Cov(RA,RB)σAσB,1ρAB1\rho_{AB} = \frac{\mathrm{Cov}(R_A, R_B)}{\sigma_A\,\sigma_B}, \qquad -1 \le \rho_{AB} \le 1

共通のショック zz(市場全体の動き)に両資産が反応する形で、相関のあるリターンを合成して測ります。

import numpy as np

rng = np.random.default_rng(1)
n = 1000

z = rng.normal(0, 1, n)                              # 市場共通ショック
a = 0.0004 + 0.012 * (0.7*z + 0.7*rng.normal(0, 1, n))   # 資産A
b = 0.0003 + 0.009 * (0.6*z + 0.8*rng.normal(0, 1, n))   # 資産B

returns = np.vstack([a, b])
cov = np.cov(returns)            # 共分散行列
corr = np.corrcoef(returns)     # 相関行列

print("共分散行列:\n", np.round(cov, 6))
print("相関行列:\n", np.round(corr, 3))

出力:

共分散行列:
 [[1.49e-04 4.30e-05]
 [4.30e-05 7.50e-05]]
相関行列:
 [[1.    0.403]
 [0.403 1.   ]]

出力の意味:行列の対角成分は各資産の分散(AA は 0.000149、BB は 0.000075)、非対角成分が共分散(0.000043)です。相関行列にすると読みやすく、対角は必ず1(自分自身との相関)、AABB の相関は 0.403——共通ショック zz を通じて中程度に連動しています。この共分散行列 Σ\Sigma こそ、次のポートフォリオ・リスク計算の主役です(行列としての扱いは 分散共分散行列・相関行列(統計))。

4. ポートフォリオの分散と分散投資

資産 A,BA, B を構成比 wA,wB (wA+wB=1)w_A, w_B\ (w_A+w_B=1) で持つポートフォリオのリターンは、リターンの測り方 のとおり単純リターンの加重平均 Rp=wARA+wBRBR_p = w_A R_A + w_B R_B。その分散は、分散の性質(期待値・分散の性質(線形性・和の分散・共分散)(統計))から共分散項が現れます。

σp2=wA2σA2+wB2σB2+2wAwBρABσAσB\sigma_p^2 = w_A^2\sigma_A^2 + w_B^2\sigma_B^2 + 2\,w_A w_B\,\rho_{AB}\,\sigma_A\sigma_B

行列でまとめれば σp2=wΣw\sigma_p^2 = \mathbf{w}^{\top}\Sigma\,\mathbf{w} です。ここで決定的なのは、ρAB<1\rho_{AB} < 1 なら σp\sigma_p各ボラの加重平均より小さくなること。相関を 1-1 から 11 まで動かして確かめます。

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib

sigma_a, sigma_b = 0.20, 0.15      # 年率ボラ(A=20%, B=15%)
w = 0.5                            # 等加重

rhos = np.linspace(-1, 1, 201)
port_var = (w*sigma_a)**2 + ((1-w)*sigma_b)**2 + 2*w*(1-w)*rhos*sigma_a*sigma_b
port_vol = np.sqrt(port_var)

weighted_avg = w*sigma_a + (1-w)*sigma_b   # 単純な加重平均ボラ

plt.figure(figsize=(7, 4))
plt.plot(rhos, port_vol, label="ポートフォリオのボラ")
plt.axhline(weighted_avg, color="crimson", ls="--",
            label=f"加重平均ボラ {weighted_avg:.1%}")
plt.xlabel("相関係数 ρ"); plt.ylabel("ポートフォリオの年率ボラ")
plt.title("相関が低いほど分散投資の効果が大きい")
plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show()

print(f"加重平均ボラ = {weighted_avg:.2%}")
for rho in [-1, 0, 0.5, 1]:
    pv = np.sqrt((w*sigma_a)**2 + ((1-w)*sigma_b)**2
                 + 2*w*(1-w)*rho*sigma_a*sigma_b)
    print(f"ρ={rho:+.1f}: ポートフォリオボラ = {pv:.4f} ({pv:.2%})")

出力:

加重平均ボラ = 17.50%
ρ=-1.0: ポートフォリオボラ = 0.0250 (2.50%)
ρ=+0.0: ポートフォリオボラ = 0.1250 (12.50%)
ρ=+0.5: ポートフォリオボラ = 0.1521 (15.21%)
ρ=+1.0: ポートフォリオボラ = 0.1750 (17.50%)

出力の意味:相関が 11 のとき、ポートフォリオのボラは加重平均(17.50%)にぴったり一致します——完全連動なら混ぜても何も減りません。ところが相関が下がると、ρ=0\rho=0 で 12.50%、ρ=1\rho=-1 では 2.50% まで激減します。同じ2資産でも、相関が低いほどリスクだけが削れる。これが「タダの昼食」とも呼ばれる分散投資の正体で、リターンを犠牲にせずリスクを下げられます。次の第2章ではこれを多資産に広げ、リスクとリターンの最適なバランス(効率的フロンティア)を求めます。

⚠️ よくある誤解

関連ノート