σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academyロードマップ
Ctrl K
AO
+1.2k 人の学習者
ログイン参加する ↗
ロードマップ
AO
+1.2k 人の学習者
ログイン
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python ロードマップ›モジュール 4 · 債券とオプションの価格計算›トピック 4.8·~55 分中級

ブラック–ショールズの公式

ロードマップ上の位置モジュール 4/11 · トピック 8/16
4.8 ブラック–ショールズの公式
—ラボスコア— / 100合計XP—連続日数—

オプションの価格式

1973年にブラックとショールズは、株価が一定のボラティリティの対数正規モデルに従うなら、株式と債券の売買でオプションを複製でき、その価格は投資家が上昇をどれだけ見込むかに依存しないことを示しました。ヨーロピアン・コールの価格は S * N(d1) - K * exp(-rT) * N(d2) です。オプションがイン・ザ・マネーで終わるときに受け取る株を確率に似た数で重み付けしたものから、支払う割引後の行使価格を、行使されるリスク中立確率 N(d2) で重み付けしたものを引きます。プットはパリティから得られます。

d1 = (ln(S/K) + (r + sigma^2/2) T) / (sigma sqrt(T)) d2 = d1 - sigma sqrt(T) C = S N(d1) - K e^(-rT) N(d2)
import math

def norm_cdf(x):
    return 0.5 * (1 + math.erf(x / math.sqrt(2)))      # N(x): the probability that a standard normal is below x

print(round(norm_cdf(0.0), 4), round(norm_cdf(1.96), 4))      # 0.5 0.975

def d1_d2(spot, strike, rate, sigma, t):
    d1 = (math.log(spot / strike) + (rate + 0.5 * sigma ** 2) * t) / (sigma * math.sqrt(t))
    return d1, d1 - sigma * math.sqrt(t)

d1, d2 = d1_d2(100, 100, 0.05, 0.2, 1)
print(round(d1, 4), round(d2, 4))                               # 0.35 0.15

コールとプット

N は標準正規分布の分布関数で、Python の math.erf を使えば 0.5 * (1 + erf(x / sqrt(2))) で得られます。d1 と d2 は、ln(S/K)(現在の位置)、ドリフト、オプションの期間にわたるボラティリティをまとめた量です。これらを使って、コール = S * N(d1) - K * exp(-rT) * N(d2)、プット = K * exp(-rT) * N(-d2) - S * N(-d1)。現物100、行使価格100、金利5%、ボラティリティ20%、1年なら、コールは10.45、プットは5.57で、差の4.88はパリティ値 S - K * exp(-rT) とちょうど一致します。

def bs_call(spot, strike, rate, sigma, t):
    d1, d2 = d1_d2(spot, strike, rate, sigma, t)
    return spot * norm_cdf(d1) - strike * math.exp(-rate * t) * norm_cdf(d2)

def bs_put(spot, strike, rate, sigma, t):
    d1, d2 = d1_d2(spot, strike, rate, sigma, t)
    return strike * math.exp(-rate * t) * norm_cdf(-d2) - spot * norm_cdf(-d1)

call, put = bs_call(100, 100, 0.05, 0.2, 1), bs_put(100, 100, 0.05, 0.2, 1)
print(round(call, 4), round(put, 4))                            # 10.4506 5.5735
print(round(call - put, 4), round(100 - 100 * math.exp(-0.05), 4))   # 4.8771 4.8771   put-call parity holds

価格を動かすもの

価格を決める入力は5つです。行使価格が高いほどコールは安くなります(80:24.59、100:10.45、120:3.25)。ボラティリティが高いほど、不確実性は保有者に上昇の余地だけを加えるので、両方のオプションが高くなります(10%:6.81、20%:10.45、40%:18.02)。満期までの時間が長いほど価格も上がります(3か月:4.62、1年:10.45、4年:25.21)。株の期待リターンは式にまったく現れません。推定が必要なのはボラティリティだけなので、オプションの提示価格はボラティリティで表されることがよくあります。

for strike in (80, 100, 120):
    print("strike", strike, round(bs_call(100, strike, 0.05, 0.2, 1), 4))      # 24.5888, 10.4506, 3.2475
for sigma in (0.1, 0.2, 0.4):
    print("sigma", sigma, round(bs_call(100, 100, 0.05, sigma, 1), 4))         # 6.805, 10.4506, 18.023
for t in (0.25, 1, 4):
    print("t", t, round(bs_call(100, 100, 0.05, 0.2, t), 4))                   # 4.615, 10.4506, 25.2133
# Time value: the call is worth more than its intrinsic value (what it would pay if it expired today)
intrinsic = max(100 - 100 * math.exp(-0.05), 0)
print(round(intrinsic, 4), round(bs_call(100, 100, 0.05, 0.2, 1) - intrinsic, 4))     # 4.8771 5.5735   intrinsic value and time value
仮定を伴うモデルブラック=ショールズは、一定のボラティリティ、ジャンプのない対数正規の価格、無配当、ヨーロピアン行使、摩擦のない取引を仮定します。実際の市場では、ボラティリティが行使価格や日付で変わり(ボラティリティ・スマイル)、ジャンプや裾の厚さもあります。それでもこの式は市場の共通言語であり、価格がインプライド・ボラティリティで提示されるのはそのためです(後のトピックで扱います)。
  • N(x) = 0.5 * (1 + erf(x / sqrt(2)))、d1 = (ln(S/K) + (r + sigma²/2) T) / (sigma sqrt(T))、d2 = d1 - sigma sqrt(T)
  • コール = S N(d1) - K e^(-rT) N(d2)、プット = K e^(-rT) N(-d2) - S N(-d1)。その差はパリティ値 S - K e^(-rT)
  • 価格はボラティリティと期間で上がり、コールの行使価格で下がる。株の期待リターンは不要で、必要なのはボラティリティだけ

次はデルタです。株が1ドル動いたときにオプション価格がどれだけ動くかを学びます。

ラボ:採点される内容

  • norm_cdf で釣鐘型の累積確率を作る25点
  • d1_d2 でブラック=ショールズの2つの量を計算する25点
  • bs_call でコールを価格付けする25点
  • bs_put でプットを価格付けする25点
エクスプローラー · lab-73-1
▾ lab-73-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-73-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

このトピックをリセットしますか?

lab-73-1 の内容はすべてスターターファイルに戻り、ターミナルも消去されます。現在の解答は失われ、元に戻せません。

リセットされるもの
  • main.py → スターターコード
  • ターミナル履歴とテスト出力
  • 未提出の変更
保持されるもの
  • ラボの最高スコア
  • XPと連続日数
  • 講義の進捗とメモ

コードを実行するにはログインしてください。

レクチャーはすべて無料で読めます。コードの実行、テスト、ラボの提出にはアカウントの作成かログインが必要です。

  • ブラウザ内IDEとbashターミナル。インストール不要
  • 即時採点、XP、ロードマップでの現在地
アカウントを作成ログイン
または
GitHubで続ける