Mímisbrunnr知恵の泉

← 金融工学 一覧

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

📎 前提:伊藤の補題 | 関連:モンテカルロ法によるオプション価格(モンテカルロ価格づけ)

要点(BLUF)

1. GBMによる価格経路の生成

伊藤の補題 で導いた解は、各時刻の価格をシミュレーションの近似なしに直接与えてくれます(厳密解なので離散化誤差ゼロ)。

St=S0exp ⁣((μσ22)t+σWt),Wt=ΔW,  ΔWN(0,Δt)S_t = S_0\exp\!\left(\Big(\mu-\frac{\sigma^2}{2}\Big)t + \sigma W_t\right), \qquad W_t = \sum \Delta W,\ \ \Delta W\sim\mathcal{N}(0,\Delta t)

ブラウン運動 WtW_t を増分の累積で作り、その経路に上の式を当てれば価格経路ができます。1万本の経路を生成し、**パーセンタイルバンド(ファンチャート)**で将来の散らばりを可視化します。

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

rng = np.random.default_rng(3)
S0, mu, sigma, T, N = 100.0, 0.10, 0.20, 1.0, 252
dt = T/N
t = np.linspace(0, T, N+1)

M = 10000
dW = rng.normal(0, np.sqrt(dt), (M, N))                       # 増分
W = np.concatenate([np.zeros((M, 1)), np.cumsum(dW, axis=1)], axis=1)
S = S0*np.exp((mu - 0.5*sigma**2)*t + sigma*W)               # 全経路(厳密解)

qs = [5, 25, 50, 75, 95]
bands = np.percentile(S, qs, axis=0)

plt.figure(figsize=(8, 5))
for i in range(30):                                          # 経路を数本だけ薄く描く
    plt.plot(t, S[i], lw=0.4, color="gray", alpha=0.5)
for q, band in zip(qs, bands):
    plt.plot(t, band, lw=2, label=f"{q}パーセンタイル")
plt.plot(t, S0*np.exp(mu*t), "k--", lw=2, label="平均 S0·e^(μt)")
plt.xlabel("時間 t(年)"); plt.ylabel("価格")
plt.title("GBM の価格経路とパーセンタイルバンド")
plt.legend(); plt.tight_layout(); plt.show()

print("1年後の価格のパーセンタイル:")
for q in qs:
    print(f"  {q:>2}% : {np.percentile(S[:, -1], q):.2f}")

出力:

1年後の価格のパーセンタイル:
   5% : 77.59
  25% : 94.45
  50% : 107.88
  75% : 123.61
  95% : 149.83

出力の意味:1年後の価格は5%点で 77.59、95%点で 149.83 と、大きく広がります(中央値は 107.88)。時間とともにバンドがラッパ状に開いていくのが、不確実性が √t で増える様子です。バンドは中央値より上側に広い——対数正規の右の裾です。この「将来分布を経路ごと丸ごと持っている」状態が強力で、たとえば「1年後に120円を超える確率」も np.mean(S[:, -1] > 120) で即座に計算できます。デリバティブの価格づけ(第6章)は、まさにこの経路群の上でペイオフを平均する操作です。

2. キャリブレーション:データからμ・σを逆推定

モデルを使うには μ,σ\mu,\sigma を決める必要があります。観測した日次対数リターンから逆算します。GBM では日次対数リターンが平均 (μσ22)Δt(\mu-\tfrac{\sigma^2}{2})\Delta t・標準偏差 σΔt\sigma\sqrt{\Delta t} なので、

σ^=std(日次対数リターン)Δt,μ^=mean(日次対数リターン)Δt+σ^22\hat\sigma = \frac{\mathrm{std}(\text{日次対数リターン})}{\sqrt{\Delta t}}, \qquad \hat\mu = \frac{\mathrm{mean}(\text{日次対数リターン})}{\Delta t} + \frac{\hat\sigma^2}{2}

で推定できます(μ^\hat\mu の式の +σ^2/2+\hat\sigma^2/2 は伊藤補正の戻し)。40年ぶんの「観測データ」を作って、μ=0.10,σ=0.20\mu=0.10,\sigma=0.20 を復元できるか試します。

import numpy as np

rng = np.random.default_rng(19)
S0, mu, sigma, T, N = 100.0, 0.10, 0.20, 1.0, 252
dt = T/N
n_years = 40

# n_years 年ぶんの日次対数リターン(観測データのつもり)
dW = rng.normal(0, np.sqrt(dt), N*n_years)
log_ret_daily = (mu - 0.5*sigma**2)*dt + sigma*dW

# 逆推定(キャリブレーション)
sigma_hat = log_ret_daily.std(ddof=1) / np.sqrt(dt)
mu_hat = log_ret_daily.mean()/dt + 0.5*sigma_hat**2

print(f"真の値 : μ = {mu},  σ = {sigma}")
print(f"推定値 : μ_hat = {mu_hat:.4f},  σ_hat = {sigma_hat:.4f}")
print(f"μ_hat の標準誤差 およそ {sigma_hat/np.sqrt(n_years):.4f}(40年でもこの大きさ)")

出力:

真の値 : μ = 0.1,  σ = 0.2
推定値 : μ_hat = 0.0947,  σ_hat = 0.2001
μ_hat の標準誤差 およそ 0.0316(40年でもこの大きさ)

出力の意味σ^=0.2001\hat\sigma=0.2001 は真の 0.200.20 をほぼ完璧に復元します。いっぽう μ^=0.0947\hat\mu=0.0947 は近いものの、標準誤差が ±0.0316\pm0.0316 もあります——40年というありえないほど長いデータを使っても、ドリフト μ\mu は ±3%程度の精度でしか決まらないμ^\hat\mu の標準誤差は σ/年数\sigma/\sqrt{\text{年数}} で、これを ±1% にするには約400年が必要です。ボラはサンプルを細かくするほど精度が上がるのに、ドリフトはサンプル期間の長さでしか改善せず、現実的には測れません。「μ\mu は推定できない」というこの事実が、次章で**オプション価格が μ\mu に依存しない(リスク中立評価)**という驚きの結果につながります。

3. 何に使うのか

GBM+モンテカルロのセットは、金融工学の数値計算エンジンです。

いずれも「価格の将来分布を経路ごと持つ」ことが出発点で、その分布を与えるのが GBM です。

⚠️ よくある誤解

関連ノート