σμ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 ロードマップ›モジュール 7 · アルファ研究とリスク›トピック 7.5·~50 分上級

パラメトリックVaR

ロードマップ上の位置モジュール 7/11 · トピック 5/9
7.5 パラメトリックVaR
—ラボスコア— / 100合計XP—連続日数—

履歴の代わりに公式を

ヒストリカルVaRは過去のリターンから損失を読み取ります。パラメトリックVaRはリターンが正規分布に従うと仮定し、平均と標準偏差の2つの数だけを使います。確率 1 - confidence で超える損失は z * sigma - mu で、z は標準正規分布の分位点(95%で1.645、99%で2.326)です。高速で滑らかで、ポートフォリオ全体にも簡単に拡張できるため、何十年も業界標準でした。

from statistics import NormalDist

def normal_var(mu, sigma, confidence):
    z = NormalDist().inv_cdf(confidence)
    return z * sigma - mu

print(round(NormalDist().inv_cdf(0.95), 4), round(NormalDist().inv_cdf(0.99), 4))
print(round(normal_var(0.0005, 0.012, 0.95), 5))        # a 95% one-day loss limit
print(round(normal_var(0.0005, 0.012, 0.99), 5))        # a higher confidence, a larger limit
# The multiplier z for common confidence levels
from statistics import NormalDist

for confidence in (0.90, 0.95, 0.975, 0.99, 0.999):
    print(confidence, round(NormalDist().inv_cdf(confidence), 3))       # 1.282, 1.645, 1.96, 2.326, 3.09

1資産からポートフォリオへ、10日へ

ポートフォリオでは平均が weights @ mu、標準偏差が sqrt(weights @ cov @ weights) で、ポートフォリオの分散のトピックで扱った量です。分散効果がそのまま現れ、相関が低いほど標準偏差とVaRが小さくなります。より長い期間では、平均は日数に比例し、標準偏差はその平方根で増えるので、10日VaRは z * sigma * sqrt(10) - mu * 10 です。

import numpy as np
from statistics import NormalDist

def normal_var(mu, sigma, confidence):
    return NormalDist().inv_cdf(confidence) * sigma - mu

weights = np.array([0.6, 0.4])
mu = np.array([0.0005, 0.0003])
cov = np.array([[0.00016, 0.00004], [0.00004, 0.00009]])             # volatilities 1.26% and 0.95%, correlation 0.33

mean, std = float(weights @ mu), float(np.sqrt(weights @ cov @ weights))
print(round(mean, 5), round(std, 5))
print(round(normal_var(mean, std, 0.99), 5))
print(round(normal_var(mean * 10, std * np.sqrt(10), 0.99), 5))      # the 10-day figure

正規性の仮定が破れるところ

実際のリターンにはファットテールがあり、極端な日は正規分布が許すよりずっと頻繁に起きます。そのためパラメトリックVaRは、特に高い信頼水準で小さすぎるように見えます。同じデータでヒストリカルVaRと比べるとその差が分かり、正なら正規モデルがリスクを過小評価しています。95%では近いことが多く、99%では大きく違うことがあります。

# Fat-tailed returns: the normal model understates the 99% loss
import numpy as np
from statistics import NormalDist

rng = np.random.default_rng(2)
returns = rng.standard_t(3, size=5000) * 0.008           # a fat-tailed distribution (3 degrees of freedom)

for confidence in (0.95, 0.99):
    historical = -np.quantile(returns, 1 - confidence)
    parametric = NormalDist().inv_cdf(confidence) * returns.std(ddof=1) - returns.mean()
    print(confidence, round(float(historical), 5), round(float(parametric), 5), round(float(historical - parametric), 5))
問いに合わせて手法を選ぶパラメトリックVaRは、手早く滑らかな数字を得たいときや、線形なポジションのポートフォリオには十分です。リターンがリスクファクターに対して線形でないオプションや、分布の裾に関しては当てになりません。多くのデスクはパラメトリック、ヒストリカル、モンテカルロの複数のVaRを計算し、大きな乖離をモデルへの警告と受け止めます。
  • パラメトリックVaR=z * sigma - mu、z = NormalDist().inv_cdf(confidence)。必要なのは平均と標準偏差だけ
  • ポートフォリオは weights @ mu と sqrt(weights @ cov @ weights) を使う。期間は平均を days 倍、ボラティリティを sqrt(days) 倍する
  • 実際のリターンにはファットテールがある。ヒストリカルVaRと比べ、差が正なら正規モデルがリスクを過小評価している

次は期待ショートフォールです。VaRを超えた日の平均損失です。

ラボ:採点される内容

  • normal_var で2つの数から限度額を求める25点
  • portfolio_normal_var でポートフォリオ全体を扱う25点
  • horizon_var でより先の期間を見通す25点
  • normality_gap でファットテールの大きさを測る25点
エクスプローラー · lab-97-1
▾ lab-97-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-97-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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