σμ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 ロードマップ›モジュール 3 · 確率とモンテカルロ・シミュレーション›トピック 3.3·~45 分中級

ファットテールと正規性検定

ロードマップ上の位置モジュール 3/11 · トピック 3/12
3.3 ファットテールと正規性検定
—ラボスコア— / 100合計XP—連続日数—

釣鐘型曲線の約束

多くのリスクモデルは、平均と標準偏差だけですべて計算できるため、リターンが正規分布に従うと仮定します。正規分布は極端な値について非常に明確です。平均からk標準偏差より遠く(どちら向きでも)にある確率は erfc(k / sqrt(2)) で、1で31.7%、2で4.55%、3で0.27%、4で0.0063%です。すると4シグマの日は約15,800営業日に1回、およそ63年に1回、5シグマの日は数千年に1回しか起きないことになります。

import math
import numpy as np

for k in (1, 2, 3, 4, 5):
    probability = math.erfc(k / math.sqrt(2))      # P(|Z| > k) for a normal variable
    print(k, f"{probability:.2e}")
# 1 3.17e-01
# 2 4.55e-02
# 3 2.70e-03
# 4 6.33e-05
# 5 5.73e-07

print(round(1 / math.erfc(4 / math.sqrt(2))))                  # 15787   trading days between 4-sigma days, if returns were normal
print(round(1 / math.erfc(5 / math.sqrt(2)) / 252))            # 6922    years between 5-sigma days

市場には裾の厚さがある

実際の市場では、1987年、2008年、2020年のように、4シグマや5シグマの日が一生のうちに何度も起きます。リターンの分布にはファットテールがあり、釣鐘型が許すより極端な日が多く、中央は高く細くなります。簡単に確かめる方法がテールレシオで、k 標準偏差を超えるリターンの観測割合を、正規分布が与える割合で割ったものです。1に近ければ正規並みの裾、5なら極端な日が5倍多いことを意味し、日次データの k = 4 では数百になることもあります。正規性を仮定するリスクモデルは、最も重要な日をまさに過小評価します。

returns = np.array([0.010, 0.012, 0.008, 0.011, 0.009, 0.010, 0.012, -0.060, 0.010, 0.009])

def tail_ratio(x, k):
    observed = np.mean(np.abs(x - x.mean()) > k * x.std(ddof=1))     # share beyond k standard deviations
    return observed / math.erfc(k / math.sqrt(2))                    # divided by what a normal would give

print(round(float(tail_ratio(returns, 2)), 2))    # 2.2   the one crash is 2.2 times too frequent at 2 sigma (a tiny sample, though)

ジャーク・ベラ検定

形式的な検定は、標本が正規分布から得られたと考えて不自然でないかを問います。ジャーク・ベラ統計量は前のトピックの2つの形状指標を組み合わせます:JB = n / 6 * (S² + K² / 4)(S は歪度、K は超過尖度)。正規な標本ではどちらも0に近く、JBは小さくなります。正規性の下でJBは自由度2のカイ二乗分布に従い、その裾は閉じた式 exp(-JB / 2) で、これがp値です。0.05を下回れば正規性を棄却します。臨界値は JB = 5.99 です。暴落を1回含む10日間の標本では JB = 22.4、p値は0.00001になります。

x = returns
n = len(x)
deviations = x - x.mean()
m2, m3, m4 = (np.mean(deviations ** k) for k in (2, 3, 4))
skew, kurt = m3 / m2 ** 1.5, m4 / m2 ** 2 - 3

jb = n / 6 * (skew ** 2 + kurt ** 2 / 4)
p_value = math.exp(-jb / 2)
print(round(float(jb), 2), p_value < 0.05)     # 22.37 True   normality rejected
print(f"{p_value:.1e}")                         # 1.4e-05
# The p-value falls fast as the statistic grows: 5.99 is the 5% critical value
for jb in (0, 2, 5.99, 10, 22.37):
    print(jb, round(math.exp(-jb / 2), 5))
# 0 1.0
# 2 0.36788
# 5.99 0.05004
# 10 0.00674
# 22.37 1e-05
正規性を棄却して終わりではない日次リターンが数百件あれば、ほとんどの資産で検定は正規性を棄却するので、棄却は想定内です。重要なのは裾がどれだけ違うかです。テールレシオで問題の大きさを測り、釣鐘型を信じる代わりに、実際の暴落、スチューデントのt分布のような裾の重い分布、ヒストリカル・シミュレーションでストレステストを行いましょう。
  • 正規変数が k 標準偏差より遠くにある確率は erfc(k / sqrt(2))。2で4.55%、4で0.0063%
  • テールレシオ(観測割合 ÷ 正規の割合)が裾の厚さを示す。市場は4シグマで1を大きく上回る
  • ジャーク・ベラ:n / 6 * (S**2 + K**2 / 4)。p値は exp(-JB / 2) で、0.05未満なら正規性を棄却(JBが5.99超)

次は仮説検定:t検定です。平均リターンが本当にゼロと違うかどうかを判断します。

ラボ:採点される内容

  • jarque_bera で標本が正規分布からどれだけ外れているかを測る25点
  • normality_p_value で検定統計量を p 値に変換する25点
  • normal_tail_probability で釣鐘型が予測する確率を計算する25点
  • tail_ratio で裾がどれだけ厚いかを数える25点
エクスプローラー · lab-56-1
▾ lab-56-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-56-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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