σμ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.1·~50 分上級

ブラウン運動

ロードマップ上の位置モジュール 8/11 · トピック 1/10
8.1 ブラウン運動
—ラボスコア— / 100合計XP—連続日数—

歩幅を縮めたランダムウォーク

価格が毎秒ランダムな量だけ上下する様子を想像してください。間隔をどんどん短くし、全体のばらつきが適切になるよう各ステップを小さくした極限がブラウン運動 W(t) です。水中の花粉の動きを記述するために導入され、1900年にバシュリエが価格のモデルに採用しました。3つの性質で定義されます。W(0) = 0、重ならない区間の増分は独立、W(t) - W(s) は平均0・分散 t - s の正規分布に従う。

import numpy as np

rng = np.random.default_rng(1)
dt = 0.01
z = rng.standard_normal(5)                         # standard normal draws
increments = z * np.sqrt(dt)                       # each step over dt has standard deviation sqrt(dt)
print(np.round(increments, 4))

経路は累積和

時刻 0, dt, 2 dt, ... の格子上で経路をシミュレートするには、ステップごとに標準正規乱数 z を1つ引いて sqrt(dt) を掛け、足し上げます。W(k * dt) は最初の k 個の増分の和で、np.cumsum です。経路は0から始まるので先頭に 0 を置きます。W(t) の分散は t なので、位置のばらつきは時間の平方根で増え、ボラティリティやVaRの換算と同じ平方根則です。

import numpy as np

def brownian_path(z, dt):
    return np.concatenate([[0.0], np.cumsum(z * np.sqrt(dt))])

rng = np.random.default_rng(1)
n, dt = 252, 1 / 252
ends = np.array([brownian_path(rng.standard_normal(n), dt)[-1] for _ in range(4000)])
print(round(float(ends.mean()), 3), round(float(ends.var()), 3))      # about 0 and 1: W(1) is a standard normal

無限に粗い経路

ブラウン運動の経路は連続ですがどこも滑らかでなく、長さは無限です。その粗さには正確な尺度があり、ステップの二乗和である二次変分です。滑らかな曲線ではこの和は格子を細かくすると0に縮みますが、ブラウン運動では格子によらず経過時間 t のままです。各ステップの二乗はおよそ dt で、それが t / dt 個あるからです。この事実 (dW)^2 = dt が確率解析を通常の解析から区別し、次のトピックの鍵になります。

import numpy as np

def quadratic_variation(path):
    return float(np.sum(np.diff(path) ** 2))

rng = np.random.default_rng(2)
t = 2.0
for steps in (10, 100, 10000):
    dt = t / steps
    path = np.concatenate([[0.0], np.cumsum(rng.standard_normal(steps) * np.sqrt(dt))])
    print(steps, round(quadratic_variation(path), 3))              # settles near 2.0 as the grid gets finer

smooth = np.linspace(0, 1, 10001) * 2
print(round(quadratic_variation(smooth), 5))                       # a straight line: close to 0

ドリフトとボラティリティ

価格にはトレンドとスケールがあります。ドリフト付き算術ブラウン運動は X(t) = mu * t + sigma * W(t) で、mu がドリフト(単位時間あたりのトレンド)、sigma がボラティリティ(ランダム部分のスケール)です。価格変化の最も単純なモデルですが負になりうるため、価格そのものは次のトピックで幾何ブラウン運動としてモデル化されます。金利やスプレッドの基本部品としては今も使われます。

import numpy as np

def drifted_path(z, dt, mu, sigma):
    t = np.arange(len(z) + 1) * dt
    w = np.concatenate([[0.0], np.cumsum(z * np.sqrt(dt))])
    return mu * t + sigma * w

rng = np.random.default_rng(3)
n, dt = 252, 1 / 252
path = drifted_path(rng.standard_normal(n), dt, 0.08, 0.2)             # 8% a year drift, 20% volatility
print(round(float(path[-1]), 4), "after one year; the drift alone would give 0.08")
print(np.round(drifted_path(np.zeros(4), 0.25, 0.08, 0.2), 4))         # no noise: just the trend line
シミュレーション経路は乱数の質次第このラボでは乱数が与えられているので、結果は正確でテスト可能です。実際のシミュレーションではシード付きの生成器(np.random.default_rng(seed))から得られ、実行が再現可能になります。1本の経路では何も証明できません。W(1) の平均や分散といった統計量は数千本の経路で初めて現れ、モンテカルロ推定の誤差は 1 / sqrt(paths) で縮みます。
  • ブラウン運動は0から始まり、分散 dt の独立な正規増分を持つ。z * sqrt(dt) と累積和でシミュレートする
  • W(t) の分散は t、経路の二次変分は経過時間のまま:(dW)^2 = dt
  • X(t) = mu * t + sigma * W(t) でトレンドとスケールを加える。1本の経路では何も証明できず、統計には多数の経路が要る

次は幾何ブラウン運動です。価格が負にならないモデルです。

ラボ:採点される内容

  • brownian_increments でショックをスケールする25点
  • brownian_path で経路を作る25点
  • quadratic_variation で粗さを測る25点
  • drifted_path でトレンドを加える25点
エクスプローラー · lab-102-1
▾ lab-102-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-102-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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