σμ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.6·~45分钟中级

波动率

路线进度模块 3/11 · 主题 6/12
3.6 波动率
—实验得分— / 100总 XP—连续天数—

用一个数表示风险

波动率是收益率的标准差,以年为单位报告,以便比较不同资产:股票指数约 15% 到 20%,单只股票 30% 到 60%,现金接近 0。它用来确定仓位、给期权定价和设定风险限额。最简单的估计是窗口内的已实现波动率:收益率的样本标准差乘以 sqrt(每年期数)。它对窗口内每一天一视同仁,这既是优点(稳定)也是缺点(迟钝)。

import math
import numpy as np

# Eight quiet days, one -3% shock, three more days
returns = np.array([0.004, -0.002, 0.001, 0.003, -0.004, 0.002, 0.006, -0.001, -0.030, 0.004, 0.002, -0.003])

print(round(returns[:8].std(ddof=1) * math.sqrt(252), 4))    # 0.0526   before the shock: 5.3% a year
print(round(returns.std(ddof=1) * math.sqrt(252), 4))        # 0.1505   with the shock: 15.1% a year

反应更快:EWMA

波动率会聚集:平静期和动荡期各自会持续一段时间,所以昨天的冲击比一个月前的平静日更能说明明天。指数加权移动平均(EWMA,由 RiskMetrics 推广)每天更新方差:方差_t = lam * 方差_(t-1) + (1 - lam) * 收益率_t²。当 lam = 0.94 时,最新收益率占 6% 的权重,旧的按几何级数衰减。估计值在冲击时跳升然后逐渐衰减,而不是一直高到冲击离开窗口,再一下子落下来。

lam = 0.94
variance = np.empty(len(returns))
variance[0] = returns[0] ** 2
for t in range(1, len(returns)):
    variance[t] = lam * variance[t - 1] + (1 - lam) * returns[t] ** 2    # the recursion needs the previous value

ewma = np.sqrt(variance)
print(ewma.round(5).tolist())
# [0.004, 0.00391, 0.0038, 0.00375, 0.00377, 0.00369, 0.00387, 0.00376, 0.0082, 0.00801, 0.00778, 0.00758]
#                                                                       ^ the shock doubles the estimate, then it fades
print(round(ewma[-1] * math.sqrt(252), 4))     # 0.1204   today's annualised estimate

利用波幅与目标波动率

收盘价忽略了日内发生的事。每日的最高价和最低价包含更多信息:Parkinson 估计量 sqrt(mean(ln(high/low)²) / (4 ln 2)) 的效率是收盘到收盘估计的数倍,也就是用少得多的天数就能达到同样的精度(它假设日与日之间没有大跳空)。任何波动率估计的一个实际用途是波动率目标:如果你想要 10% 的风险而已实现波动率是 15%,就持有 10 / 15 = 0.67 的仓位。杠杆在动荡时收缩,在平静时放大。

high = np.array([101.5, 102.0, 103.2, 102.8, 104.0])
low = np.array([99.8, 100.9, 101.7, 101.1, 102.4])
parkinson = math.sqrt(np.mean(np.log(high / low) ** 2) / (4 * math.log(2)))
print(round(parkinson, 5))                      # 0.00905   per-day volatility from the daily ranges

target = 0.10
realized = returns.std(ddof=1) * math.sqrt(252)
print(round(target / realized, 3))              # 0.664   hold two thirds of the position to run at 10% risk
# Close-to-close versus range: the same five days
close = np.array([100.0, 101.2, 102.5, 101.9, 103.4])
print(round(float(np.diff(np.log(close)).std(ddof=1)), 5))     # 0.00955   from the closes only
print(round(parkinson, 5))                                      # 0.00905   from the high-low ranges of the same days
波动率不是方向,而且会变动波动率把 +3% 和 -3% 的日子一视同仁,但投资者只害怕后者。它也不是恒定的:每种估计都取决于窗口或衰减,而 252 个交易日只是惯例。每次引用波动率时,都要说明用了哪种估计量、窗口和年化方式。
  • 已实现波动率:样本标准差乘以 sqrt(每年期数);稳定但反应慢。
  • EWMA:方差_t = lam * 方差_(t-1) + (1 - lam) * 收益率_t²;近期冲击权重更大,并按几何级数衰减。
  • Parkinson 使用每日最高/最低价区间;波动率目标按 目标 / 已实现 缩放仓位。

下一节:夏普比率,每单位风险的回报,以及它值得信任到什么程度。

实验:评分内容

  • 用 realized_volatility 计算年化波动率25 分
  • 用 ewma_volatility 让近期冲击权重更大25 分
  • 用 parkinson_volatility 利用日内波幅25 分
  • 用 volatility_target_leverage 按风险预算确定仓位25 分
资源管理器 · lab-59-1
▾ lab-59-1
…
bash · 浏览器内
learner@quantcraft:~/lab-59-1$
Python 尚未加载PythonLn 1, Col 1Spaces: 4UTF-8

要重置此主题吗?

lab-59-1 中的所有内容将恢复为初始文件,终端也会被清空。你当前的解答将丢失,且无法撤销。

将被重置
  • main.py → 初始代码
  • 终端历史与测试输出
  • 未提交的更改
将被保留
  • 实验最高得分
  • 你的 XP 与连续天数
  • 讲解进度与笔记

登录后即可运行你的代码。

所有讲解均可免费阅读。创建账户或登录后,即可运行代码、运行测试并提交此实验。

  • 浏览器内 IDE 与 bash 终端,无需安装
  • 即时评分、XP 以及你在学习路线中的位置
创建账户登录
或
使用 GitHub 继续