σμ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 ロードマップ›モジュール 8 · 確率モデルと機械学習›トピック 8.3·~55 分上級

伊藤の補題

ロードマップ上の位置モジュール 8/11 · トピック 3/10
8.3 伊藤の補題
—ラボスコア— / 100合計XP—連続日数—

落とし穴のある連鎖律

S が時間の滑らかな関数なら、f(S) の変化は通常の連鎖律どおり f'(S) * dS です。しかし dS には dW が含まれ、(dW)^2 = dt は dt と同じオーダーで無視できません。f(S + dS) を2次まで展開すると 0.5 * f''(S) * (dS)^2 の項が残り、(dS)^2 = sigma^2 * S^2 * dt です。この追加項が伊藤の補題で、オプション価格を導く主要な道具です。

def ito_drift(s, mu, sigma, f_t, f_s, f_ss):
    return f_t + mu * s * f_s + 0.5 * sigma ** 2 * s ** 2 * f_ss

# f(S) = S: the drift is just mu * S (no curvature, no extra term)
print(ito_drift(100.0, 0.08, 0.2, 0.0, 1.0, 0.0))             # 8.0
# f(S) = S squared: f_S = 2 S and f_SS = 2, so the curvature term appears
print(ito_drift(100.0, 0.08, 0.2, 0.0, 2 * 100.0, 2.0))        # 1600 + 400 = 2000.0
# The drift for several functions of the price, S = 100, mu = 8%, sigma = 20%
def ito_drift(s, mu, sigma, f_t, f_s, f_ss):
    return f_t + mu * s * f_s + 0.5 * sigma ** 2 * s ** 2 * f_ss

s, mu, sigma = 100.0, 0.08, 0.2
print("S      ", ito_drift(s, mu, sigma, 0.0, 1.0, 0.0))                  # 8.0
print("S^2    ", ito_drift(s, mu, sigma, 0.0, 2 * s, 2.0))                # 2000.0
print("S^3    ", ito_drift(s, mu, sigma, 0.0, 3 * s ** 2, 6 * s))         # 240000 + 120000 = 360000.0
print("sqrt(S)", round(ito_drift(s, mu, sigma, 0.0, 0.5 / s ** 0.5, -0.25 / s ** 1.5), 4))    # 0.35 : curvature pulls it down

対数価格とシグマ二乗の2分の1

補題を f = ln S に適用します。f_t = 0、f_S = 1/S、f_SS = -1/S^2 なので、ドリフトは mu - 0.5 * sigma^2、拡散は sigma で、d ln S = (mu - sigma^2/2) dt + sigma dW です。対数価格は算術ブラウン運動であり、GBMの解の指数に mu - sigma^2/2 が入る理由がまさにこれです。exp の凸性と ln の凹性は同じ事実の表裏です。

def ito_drift(s, mu, sigma, f_t, f_s, f_ss):
    return f_t + mu * s * f_s + 0.5 * sigma ** 2 * s ** 2 * f_ss

def log_drift(mu, sigma):
    s = 1.0                                        # the answer does not depend on s
    return ito_drift(s, mu, sigma, 0.0, 1.0 / s, -1.0 / s ** 2)

print(log_drift(0.08, 0.20))                       # 0.06   = 0.08 - 0.5 * 0.2**2
print(round(log_drift(0.08, 0.60), 4))             # -0.1   a high volatility makes the typical growth negative

シミュレーションで補題を確かめる

補題を鵜呑みにする必要はありません。s_new = s + mu * s * dt + sigma * s * sqrt(dt) * z というランダムな1ステップの動きを多数作り、関数 f について f(s_new) - f(s) を計算して平均し、dt で割ります。結果は補題のドリフトに収束します。f = S^2 で曲率項を省くとシミュレーションとはっきりずれ、追加項が本物だと確認できます。

import numpy as np

def mean_change_estimate(f, s, mu, sigma, dt, z):
    s_new = s + mu * s * dt + sigma * s * np.sqrt(dt) * z
    return float(np.mean(f(s_new) - f(s)) / dt)

half = np.random.default_rng(1).standard_normal(200_000)
z = np.concatenate([half, -half])                 # pairs of opposite draws: the noise at first order cancels
estimate = mean_change_estimate(lambda x: x ** 2, 100.0, 0.08, 0.2, 0.001, z)
print(round(estimate))                                       # about 2000
print(round(0.08 * 100.0 * 2 * 100.0))                       # 1600  the ordinary chain rule alone: the curvature term (400) is missing
オプションにとって重要な理由オプションを値付けするには、その価値 V(S, t) に補題を適用します。ドリフトには V_t、mu * S * V_S、0.5 * sigma^2 * S^2 * V_SS が含まれ、デルタヘッジで dW の項を消すとブラック=ショールズ方程式が残ります。そこにはこれまでのトピックのシータ、デルタ、ガンマが入っています。mu は無リスク金利に置き換わり、株の期待リターンは価格から消えます。
  • 伊藤の補題:f(S, t) のドリフトは f_t + mu * S * f_S + 0.5 * sigma^2 * S^2 * f_SS、ノイズ係数は sigma * S * f_S
  • 曲率項があるのは (dW)^2 = dt だから。ln S ではGBMの解のドリフト mu - sigma^2 / 2 を与える
  • シミュレーションで確認する:f(s_new) - f(s) の平均を dt で割ると補題と一致する。オプション価値に適用するとブラック=ショールズが得られる

次はアジアンオプションです。ペイオフがオプション期間中の平均価格に依存します。

ラボ:採点される内容

  • ito_drift で関数のドリフトを求める25点
  • ito_diffusion でノイズの係数を求める25点
  • log_drift で対数価格に適用する25点
  • mean_change_estimate でシミュレーションにより確かめる25点
エクスプローラー · lab-104-1
▾ lab-104-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-104-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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