Mímisbrunnr知恵の泉

← 金融工学 一覧

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

📎 前提:プットコールパリティ | 関連:幾何ブラウン運動による資産価格モデル(μ非依存)・二項木の実装

要点(BLUF)

1. 1期間二項モデルと複製ポートフォリオ

いまの株価 S0S_0 が、1期間後に確率的に Su=uS0S_u=uS_0(上昇)か Sd=dS0S_d=dS_0(下落)のどちらかになる、という最小の世界を考えます。

flowchart LR
  S0["S0 = 100"] -->|"u 倍 (上昇)"| Su["Su = 120, コール価値 20"]
  S0 -->|"d 倍 (下落)"| Sd["Sd = 90, コール価値 0"]

ここで、行使価格 KK のコール(満期ペイオフ fu=max(SuK,0)f_u=\max(S_u-K,0)fd=max(SdK,0)f_d=\max(S_d-K,0))を、Δ\Delta 株の株式と BB 円の債券で複製します。満期の両状態で価値が一致する条件は

ΔSu+BerΔt=fu,ΔSd+BerΔt=fd\Delta S_u + B e^{r\Delta t} = f_u, \qquad \Delta S_d + B e^{r\Delta t} = f_d

辺々引けば株数(デルタ)が、戻せば債券が決まります。

Δ=fufdSuSd,B=erΔt(fuΔSu)\Delta = \frac{f_u - f_d}{S_u - S_d}, \qquad B = e^{-r\Delta t}\,(f_u - \Delta S_u)

満期ペイオフを完全に再現できるなら、このポートフォリオを作るコスト ΔS0+B\Delta S_0 + B が、無裁定で許される唯一のオプション価格です。

import numpy as np

S0, K, r, T = 100.0, 100.0, 0.05, 1.0
u, d = 1.2, 0.9                        # 上昇率・下落率(説明用に丸い値)

Su, Sd = S0*u, S0*d
fu, fd = max(Su-K, 0), max(Sd-K, 0)    # 各状態のコールのペイオフ

# 複製ポートフォリオ
delta = (fu - fd)/(Su - Sd)
bond = np.exp(-r*T)*(fu - delta*Su)
price_replication = delta*S0 + bond

print(f"複製: Δ={delta:.4f}, 債券B={bond:.4f}")
print(f"複製ポートフォリオの価格 = {price_replication:.4f}")

出力:

複製: Δ=0.6667, 債券B=-57.0738
複製ポートフォリオの価格 = 9.5929

出力の意味:コール1単位は「0.667株を買い、57.07円を借りる(債券マイナス=借入)」で完全に再現でき、その正味コストは 9.5929 円。これがこのコールの無裁定価格です。もし市場がこれと違う値をつければ、複製ポートフォリオと反対売買して確実に儲かるので、価格は 9.5929 に決まります。

2. リスク中立確率と価格

複製価格 ΔS0+B\Delta S_0 + B を整理すると、驚くほどきれいな形になります。

価格=erΔt[qfu+(1q)fd],q=erΔtdud\text{価格} = e^{-r\Delta t}\bigl[q\,f_u + (1-q)\,f_d\bigr], \qquad q = \frac{e^{r\Delta t} - d}{u - d}

この qqリスク中立確率と呼びます。qq は「上昇する確率」のように見えますが、実世界の確率ではありません。qq の下では株式の期待リターンがちょうどリスクフリー rr になる(EQ[ST]=S0erΔt\mathbb{E}_Q[S_T]=S_0e^{r\Delta t})——つまり「誰もがリスク中立で、すべての資産が無リスク金利で増える」という架空の世界の確率です。価格は、その世界での期待ペイオフを割り引いた値になります。

import numpy as np

S0, K, r, T = 100.0, 100.0, 0.05, 1.0
u, d = 1.2, 0.9
Su, Sd = S0*u, S0*d
fu, fd = max(Su-K, 0), max(Sd-K, 0)

q = (np.exp(r*T) - d)/(u - d)                       # リスク中立確率
price_riskneutral = np.exp(-r*T)*(q*fu + (1-q)*fd)
print(f"リスク中立確率 q = {q:.4f}")
print(f"リスク中立価格   = {price_riskneutral:.4f}")

出力:

リスク中立確率 q = 0.5042
リスク中立価格   = 9.5929

出力の意味:リスク中立確率 q=0.5042q=0.5042 での期待割引ペイオフは 9.5929 で、複製価格(前節)と完全に一致します。複製という具体的な操作と、「リスク中立世界での期待値」という抽象的な計算が、同じ答えを出すのです。後者のほうが多期間・多資産へ一般化しやすいので、以降の価格づけはもっぱらリスク中立期待値 erTEQ[]e^{-rT}\mathbb{E}_Q[\cdot] で書きます。

3. 実世界の確率は価格に無関係

では、実世界で株が上がる確率 pp はどこに効くのか——価格には一切効きません。素朴に「実世界の確率で期待ペイオフを割り引く」と、pp ごとに違う値が出てしまい、しかもどれも正しい価格 9.5929 と一致しません。

import numpy as np

S0, K, r, T, u, d = 100.0, 100.0, 0.05, 1.0, 1.2, 0.9
Su, Sd = S0*u, S0*d
fu, fd = max(Su-K, 0), max(Sd-K, 0)
q = (np.exp(r*T) - d)/(u - d)
correct = np.exp(-r*T)*(q*fu + (1-q)*fd)

for p in [0.3, 0.5, 0.7]:
    naive = np.exp(-r*T)*(p*fu + (1-p)*fd)   # 実世界確率で割引(誤った価格)
    print(f"実世界 p={p}: 期待割引ペイオフ = {naive:.4f}  (正しい無裁定価格 {correct:.4f})")

出力:

実世界 p=0.3: 期待割引ペイオフ = 5.7074  (正しい無裁定価格 9.5929)
実世界 p=0.5: 期待割引ペイオフ = 9.5123  (正しい無裁定価格 9.5929)
実世界 p=0.7: 期待割引ペイオフ = 13.3172  (正しい無裁定価格 9.5929)

出力の意味:実世界確率 pp を 0.3→0.7 と変えると、素朴な期待値は 5.71→13.32 と大きく動き、どれも無裁定価格 9.5929 に一致しません(p=0.5p=0.5 が近いのは偶然)。「株が上がると思うか」は価格に関係ない——複製さえできれば、トレーダーの強気・弱気とは無関係に価格は1つに決まる。これが 幾何ブラウン運動による資産価格モデル で「ドリフト μ\mu は推定できない」と悩んだことの解決でもあります。価格づけに μ\mu(実世界の期待リターン)は要らないのです。

4. 多期間二項木とブラック–ショールズへの収束

1期間を多数の小ステップ nn に刻めば、より細かい値動きを表せます(二項木)。各ステップでリスク中立評価を後ろ向きに繰り返すだけです。ここで u=eσΔt, d=1/uu=e^{\sigma\sqrt{\Delta t}},\ d=1/u とボラティリティ σ\sigma に合わせて取ると(CRR モデル)、刻みを細かくした極限はブラック–ショールズ価格になります。

import numpy as np
from scipy.stats import norm

def binomial_call(S0, K, r, T, sigma, n):
    dt = T/n
    u = np.exp(sigma*np.sqrt(dt)); d = 1/u            # σに合わせた上昇/下落率
    q = (np.exp(r*dt) - d)/(u - d)
    j = np.arange(n+1)
    ST = S0*u**j * d**(n-j)                            # 満期株価(上昇 j 回)
    val = np.maximum(ST - K, 0)                        # 満期ペイオフ
    for i in range(n, 0, -1):                          # 後ろ向きに1期ずつ割引
        val = np.exp(-r*dt)*(q*val[1:i+1] + (1-q)*val[0:i])
    return val[0]

# ブラック–ショールズ厳密値
S0, K, r, sigma, T = 100.0, 100.0, 0.05, 0.2, 1.0
d1 = (np.log(S0/K) + (r + 0.5*sigma**2)*T)/(sigma*np.sqrt(T)); d2 = d1 - sigma*np.sqrt(T)
bs = S0*norm.cdf(d1) - K*np.exp(-r*T)*norm.cdf(d2)

for n in [1, 5, 50, 500]:
    print(f"n={n:>3}: 二項木コール価格 = {binomial_call(100, 100, 0.05, 1.0, 0.2, n):.4f}")
print(f"ブラック–ショールズ厳密値 = {bs:.4f}")

出力:

n=  1: 二項木コール価格 = 12.1623
n=  5: 二項木コール価格 = 10.8059
n= 50: 二項木コール価格 = 10.4107
n=500: 二項木コール価格 = 10.4466
ブラック–ショールズ厳密値 = 10.4506

出力の意味:ステップ数 nn を増やすほど、二項木の価格はブラック–ショールズ厳密値 10.4506 に収束します(n=500n=500 で 10.4466)。離散の複製を限りなく細かくすると、連続時間の複製=ブラック–ショールズになるのです(第5章で連続版を導きます)。二項木は直感的で実装が易しく、アメリカン型(早期行使)も扱えるので、第6章 二項木の実装 で数値計算の道具として深掘りします。

注:第1〜3節の例は説明用に u=1.2, d=0.9u=1.2,\ d=0.9 という丸い値を使い、第4節は u=eσΔtu=e^{\sigma\sqrt{\Delta t}} とボラに合わせています。前者の価格 9.59 と後者の極限 10.45 が違うのは、設定したボラティリティが異なるためで、矛盾ではありません。

⚠️ よくある誤解

関連ノート