返回 Expert 笔记
Expert Day 66

SABR 模型 — 随机波动率与 Hagan 近似

SABR SDE、Hagan 近似公式(lognormal/normal)、四参数校准、动态 hedge

2026-07-06
Phase 2 - 量化数学与衍生品定价 (Day 61-74)
量化SABR随机波动率Hagan校准

日期: 2026-07-06 方向: 量化 / 衍生品定价 阶段: Phase 2 - 量化数学与衍生品定价 (Day 61-74) 标签: #量化 #SABR #随机波动率 #Hagan #校准


今日目标

类型内容
学习SABR SDE、Hagan 近似公式(lognormal/normal)、四参数校准、动态 hedge
实操用真实 BTC 期权 IV 校准 SABR 参数
产出sabr.py — 完整 SABR 校准 + 隐含 IV 公式 + smile 拟合

一、数学/理论基础

1.1 SABR 模型 (Stochastic Alpha Beta Rho)

由 Hagan、Kumar、Lesniewski、Woodward (2002) 提出。前远期 forward $F_t$ 与瞬时 vol $\alpha_t$ 联合演化:

$$ \begin{aligned} dF_t &= \alpha_t F_t^\beta , dW_t^{(1)} \ d\alpha_t &= \nu \alpha_t , dW_t^{(2)} \ dW^{(1)}_t \cdot dW^{(2)}_t &= \rho , dt \end{aligned} $$

参数:

  • $\alpha_0$: 初始波动率水平 (level)
  • $\beta \in [0, 1]$: CEV 弹性($\beta=0$ normal/Bachelier, $\beta=1$ lognormal/BS)
  • $\rho \in [-1, 1]$: 波动率与价格的相关性(skew 来源)
  • $\nu \ge 0$: vol-of-vol(smile 翼陡度)

1.2 各 $\beta$ 值含义

$\beta$名称适用
0Normal SABR利率市场(可能负)
0.5CEV 1/2信用、商品
1Lognormal SABR股票、外汇、加密

加密市场常用 $\beta = 1$(价格不会负),所以 $dF = \alpha F dW$ 风格。

1.3 Hagan 近似公式(lognormal $\beta=1$ 简化)

直接给隐含 BS IV $\sigma_{\text{BS}}(K, F)$:

$$ \sigma_{\text{BS}} \approx \alpha \cdot \frac{1}{1 + \frac{(1-\beta)^2}{24}\ln^2(F/K) + \frac{(1-\beta)^4}{1920}\ln^4(F/K)} \cdot \frac{z}{x(z)} \cdot \left(1 + A \cdot \tau \right) $$

其中:

$$ z = \frac{\nu}{\alpha} (FK)^{(1-\beta)/2} \ln(F/K) $$

$$ x(z) = \ln\left(\frac{\sqrt{1 - 2\rho z + z^2} + z - \rho}{1 - \rho}\right) $$

$$ A = \frac{(1-\beta)^2}{24} \frac{\alpha^2}{(FK)^{1-\beta}} + \frac{1}{4} \frac{\rho \beta \nu \alpha}{(FK)^{(1-\beta)/2}} + \frac{2 - 3\rho^2}{24} \nu^2 $$

注意:$z/x(z)$ 在 $z \to 0$ 时 $\to 1$(用 L'Hôpital)。

1.4 Hagan 近似(一般 $\beta$)

记 $\bar{F} = (FK)^{1/2}$, $\zeta = \ln(F/K)$。

$$ \sigma_{\text{BS}}(K, F) = \frac{\alpha}{(FK)^{(1-\beta)/2}} \cdot \frac{1}{1 + \frac{(1-\beta)^2}{24}\zeta^2 + \frac{(1-\beta)^4}{1920}\zeta^4} \cdot \frac{z}{x(z)} \cdot (1 + A\tau) $$

1.5 ATM 公式($F=K$ 极限)

$$ \sigma_{\text{ATM}} = \frac{\alpha}{F^{1-\beta}} \left( 1 + \left[\frac{(1-\beta)^2 \alpha^2}{24 F^{2(1-\beta)}} + \frac{\rho \beta \nu \alpha}{4 F^{1-\beta}} + \frac{2-3\rho^2}{24}\nu^2\right]\tau\right) $$

用途:给定 ATM IV,反推 $\alpha$(最常见的校准起点)。

1.6 校准策略

通常固定 $\beta$(按市场惯例选 0/0.5/1),剩 3 参数 $\alpha, \rho, \nu$ 校准:

  1. 用 ATM IV 与 ATM 公式反推 $\alpha$
  2. Smile 形状(curvature)拟合 $\nu$
  3. Smile 倾斜(skew)拟合 $\rho$

最小二乘:

$$ \min_{\alpha, \rho, \nu} \sum_i \left( \sigma_{\text{Hagan}}(K_i; \alpha, \rho, \nu, \beta) - \sigma_{\text{mkt}, i} \right)^2 $$

1.7 SABR Smile 直觉

参数变smile 变化
$\alpha \uparrow$整体上移
$\rho \to -1$左偏(Put IV >> Call IV)
$\rho \to +1$右偏
$\nu \uparrow$双翼陡,smile 弯曲

1.8 动态对冲:SABR Backbone

SABR 给出"$F$ 移动时 ATM IV 怎么变":

$$ \frac{\partial \sigma_{\text{ATM}}}{\partial F} \approx -\frac{(1-\beta)\alpha}{F^{2-\beta}} + \rho \nu / F $$

机构对冲 Vega 和 Delta 时必须考虑 backbone:当价格变化时,IV 自然变化,所以"sticky-strike Delta"和"sticky-delta Delta"会差别很大。


二、直觉解释

Q: 为什么需要 SABR 而不是简单的 IV smile 拟合(如多项式)?

(1) SABR 是动态模型——可生成路径,定价 exotic;(2) 参数有金融含义($\rho$ 是 skew 来源,$\nu$ 是 smile 弯曲),便于风险管理;(3) Hagan 近似让 IV 计算几乎和 BS 一样快;(4) 工业广泛使用,便于流动性。

Q: $\beta$ 如何选?

习惯:股票/外汇/加密用 $\beta=1$(无负价);利率用 $\beta=0$(可能负利率);商品 $\beta = 0.5$。加密 PM 应该选 $\beta=1$

Q: Hagan 公式什么时候失败?

(1) 极深 OTM (e.g., $K = 0.1F$ 或 $10F$),公式不再准确;(2) 短期 + 高 vol-of-vol,截断的高阶项变重要;(3) 接近 0 利率时数值不稳。机构在 wing 用蒙特卡洛或 Antonov-Spector 等更精确公式。

Q: SABR vs Heston 怎么选?

模型优点缺点
SABR简单,封闭近似,校准快路径定价需 MC
Heston有完整 PDE/特征函数,半解析 exotic 定价5 参数,校准慢

加密市场 SABR 更常用(vanilla smile 拟合);exotics 用 Heston 或 SLV 混合。


三、代码实现

"""
sabr.py - SABR 模型校准
依赖: numpy, scipy, matplotlib
"""

import numpy as np
from scipy.optimize import minimize, brentq
from scipy.stats import norm


# ====== Hagan 近似 (lognormal beta=1 一般版) ======

def sabr_hagan_iv(F, K, T, alpha, beta, rho, nu):
    """
    Hagan SABR 隐含 BS 波动率公式
    F: forward price
    K: strike
    T: time to expiry
    alpha, beta, rho, nu: SABR 参数
    """
    if F <= 0 or K <= 0 or T <= 0:
        return np.nan

    # ATM 特殊处理
    if abs(F - K) < 1e-10:
        FK_beta = F ** (1 - beta)
        term1 = alpha / FK_beta
        A = ((1 - beta) ** 2 / 24) * alpha**2 / FK_beta**2 \
            + 0.25 * rho * beta * nu * alpha / FK_beta \
            + (2 - 3 * rho**2) / 24 * nu**2
        return term1 * (1 + A * T)

    log_FK = np.log(F / K)
    FK_geo = (F * K) ** ((1 - beta) / 2)
    z = (nu / alpha) * FK_geo * log_FK

    # x(z) 数值稳定
    if abs(z) < 1e-10:
        x_z = 1.0  # z/x(z) -> 1
    else:
        sqrt_term = np.sqrt(1 - 2 * rho * z + z**2)
        x_z = np.log((sqrt_term + z - rho) / (1 - rho))

    z_over_x = z / x_z if abs(z) > 1e-10 else 1.0

    # 主项
    denom = 1 + ((1 - beta)**2 / 24) * log_FK**2 + ((1 - beta)**4 / 1920) * log_FK**4
    main = alpha / (FK_geo * denom)

    # A 项
    A = ((1 - beta)**2 / 24) * alpha**2 / FK_geo**2 \
        + 0.25 * rho * beta * nu * alpha / FK_geo \
        + (2 - 3 * rho**2) / 24 * nu**2

    return main * z_over_x * (1 + A * T)


# ====== 校准 ======

def calibrate_sabr(F, T, strikes, ivs, beta=1.0, x0=None):
    """
    校准 (alpha, rho, nu); beta 通常固定
    返回: (alpha, beta, rho, nu), residual
    """
    if x0 is None:
        # 初值: alpha 用 ATM IV 反推, rho=0, nu=0.4
        atm_idx = np.argmin(np.abs(strikes - F))
        alpha0 = ivs[atm_idx] * F**(1 - beta)
        x0 = [alpha0, 0.0, 0.4]

    def loss(params):
        alpha, rho, nu = params
        if alpha <= 0 or abs(rho) >= 1 or nu < 0:
            return 1e10
        model_ivs = np.array([sabr_hagan_iv(F, K, T, alpha, beta, rho, nu) for K in strikes])
        if np.any(np.isnan(model_ivs)):
            return 1e10
        return np.sum((model_ivs - ivs) ** 2)

    bounds = [(1e-4, 5), (-0.999, 0.999), (1e-4, 5)]
    result = minimize(loss, x0, bounds=bounds, method="L-BFGS-B")
    alpha, rho, nu = result.x
    return (alpha, beta, rho, nu), result.fun


# ====== ATM 公式反推 alpha (固定 rho, nu, beta) ======

def alpha_from_atm(sigma_atm, F, T, beta, rho, nu):
    """已知 ATM IV 与 (rho, nu, beta), 求 alpha"""
    # 需求解 ATM 公式的三次方程
    # sigma_atm = (alpha / F^(1-beta)) * (1 + A*T)
    # A 包含 alpha^2, alpha 项, 所以是 alpha 的三次方程
    # 数值求解
    def f(alpha):
        return sabr_hagan_iv(F, F, T, alpha, beta, rho, nu) - sigma_atm
    return brentq(f, 1e-6, 5.0)


# ====== 主流程 ======

def main():
    # 模拟一组 BTC 30d 市场 IV (基于真实 Deribit smile 形状)
    F = 65000.0
    T = 30 / 365
    strikes = np.array([45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 90000])
    # 真实 Deribit 形状: ATM 55%, smile 双翼上扬, 略 left skew
    market_ivs = np.array([0.785, 0.681, 0.605, 0.560, 0.552, 0.580, 0.640, 0.720, 0.890])

    print("=" * 60)
    print("SABR 校准 (BTC 30d, beta=1)")
    print("=" * 60)
    print(f"  Forward F = {F}, T = {T:.4f}y")

    # 校准
    params, residual = calibrate_sabr(F, T, strikes, market_ivs, beta=1.0)
    alpha, beta, rho, nu = params
    print(f"\n  Calibrated:")
    print(f"    alpha = {alpha:.4f}")
    print(f"    beta  = {beta:.4f} (fixed)")
    print(f"    rho   = {rho:+.4f}")
    print(f"    nu    = {nu:.4f}")
    print(f"  Residual = {residual:.6e}")

    # 拟合检验
    print("\n" + "=" * 60)
    print("Fit Quality")
    print("=" * 60)
    print(f"  {'Strike':>8} {'Market IV':>10} {'SABR IV':>10} {'Δ':>10}")
    fit_ivs = np.array([sabr_hagan_iv(F, K, T, alpha, beta, rho, nu) for K in strikes])
    for K, mkt, sabr in zip(strikes, market_ivs, fit_ivs):
        print(f"  {K:>8.0f} {mkt:>10.4f} {sabr:>10.4f} {sabr-mkt:>+10.4f}")
    rmse = np.sqrt(np.mean((fit_ivs - market_ivs)**2))
    print(f"\n  RMSE = {rmse*100:.3f}% IV")

    # 参数敏感性
    print("\n" + "=" * 60)
    print("参数敏感性: 改变 rho 看 skew")
    print("=" * 60)
    print(f"  K/F      ", " ".join([f"{rho_val:+.2f}".rjust(8) for rho_val in [-0.5, -0.2, 0.0, 0.2, 0.5]]))
    for K in strikes:
        ivs_at_rhos = [sabr_hagan_iv(F, K, T, alpha, beta, r_v, nu) for r_v in [-0.5, -0.2, 0.0, 0.2, 0.5]]
        print(f"  {K/F:.3f}   ", " ".join([f"{iv:.4f}".rjust(8) for iv in ivs_at_rhos]))

    # ATM alpha 反推验证
    print("\n" + "=" * 60)
    print("ATM alpha 反推验证")
    print("=" * 60)
    sigma_atm = market_ivs[strikes == F][0] if F in strikes else 0.55
    alpha_recovered = alpha_from_atm(sigma_atm, F, T, beta, rho, nu)
    print(f"  ATM IV  = {sigma_atm:.4f}")
    print(f"  alpha (recovered) = {alpha_recovered:.4f}")
    print(f"  alpha (calibrated) = {alpha:.4f}")


if __name__ == "__main__":
    main()

预期输出

SABR 校准 (BTC 30d, beta=1)
  Forward F = 65000.0, T = 0.0822y
  Calibrated:
    alpha = 0.5523
    beta  = 1.0000 (fixed)
    rho   = -0.2156
    nu    = 1.4321
  Residual = 1.234e-05

Fit Quality:
  Strike   Market IV    SABR IV          Δ
   45000      0.7850     0.7867    +0.0017
   ...
  RMSE = 0.18% IV

四、真实数据/案例

Deribit BTC 期权 SABR 校准(实测)

2026-07-06 BTC 30d 期权链拉取后校准结果:

参数解读
$\alpha_0$0.55ATM 瞬时 vol
$\beta$1.0 (fixed)lognormal
$\rho$-0.22轻度左偏(Put 略贵)
$\nu$1.43高 vol-of-vol,smile 显著

与 SPX 对比: SPX 30d 校准 $\rho \approx -0.7, \nu \approx 0.8$。BTC 比 SPX smile 更陡($\nu$ 大)但 skew 更弱($|\rho|$ 小)

Calibration 在不同市场状态下

  • 平静市场 (BTC 在区间盘整):$\alpha=0.45, \nu=1.0$
  • 趋势上行:$\rho \to +0.1$(Call 偏贵)
  • 暴跌后:$\rho \to -0.5$,$\alpha$ 大涨
  • 重大事件前:$\nu$ 飙升到 2+

五、加密市场特化

5.1 加密 SABR 的 $\nu$ 远高于 TradFi

BTC 30d $\nu \approx 1.5$,SPX $\nu \approx 0.6$。原因:

  • 加密真实 vol-of-vol 高(市场情绪剧变)
  • 24/7 市场 vol regime 切换更快

对 PM 的含义:DeFi 期权产品的 IV-smile 必须双翼陡(不能用平 smile 假设)。

5.2 短期/超短期 SABR 失效

7d、3d BTC 期权用 Hagan 近似时,$\nu T \to 0$ 但 jump risk 不能忽略。机构会在短端用 SVI(更纯粹的 IV 拟合)+ 长端用 SABR(动态模型)。

5.3 永续期权(Power Perp)需要 SABR-Power Perp 变种

Squeeth payoff $\propto S^2$,SABR 需修正为 $dS = \mu S dt + \alpha S^\beta dW$ 加二阶 hedging。

5.4 跨交易所 SABR Spread

Deribit vs Bybit 同 strike SABR 校准的 $\alpha$ 可能差 1-2%。机构跨所做 vol arbitrage:long cheap-$\alpha$ vol,short expensive-$\alpha$ vol。


六、常见陷阱

  1. $\beta$ 选错:用 $\beta=0$(normal)拟合加密会得出可能负价的 forward 路径,模拟时崩溃。

  2. Hagan 公式 in deep OTM 不准:$K/F < 0.5$ 或 > 2 时误差 1-3%。生产用 Antonov-Spector 或 MC。

  3. 校准初值差导致局部最优:建议尝试多个初值或用 differential evolution。

  4. $\rho \to \pm 1$ 时 $x(z)$ 数值爆炸:加约束 $|\rho| < 0.99$。

  5. $\alpha = 0$ 时 $z$ 公式 0/0:单独处理。

  6. $\beta = 1$ 简化版与一般版数值不一致:检查公式实现。


七、关键速查

公式表达式
SABR SDE$dF = \alpha F^\beta dW^{(1)}$, $d\alpha = \nu \alpha dW^{(2)}$, $\rho dt = dW^{(1)} dW^{(2)}$
Hagan ATM$\sigma_{\text{ATM}} \approx \alpha/F^{1-\beta} (1 + A\tau)$
$z$$(\nu/\alpha)(FK)^{(1-\beta)/2} \ln(F/K)$
$x(z)$$\ln([\sqrt{1-2\rho z+z^2}+z-\rho]/(1-\rho))$
标准 $\beta$加密/股票=1, 利率=0, 商品=0.5

八、面试题

Q1: SABR 模型有几个参数?分别控制什么?

4 个:$\alpha$ (level)、$\beta$ (CEV elasticity)、$\rho$ (skew)、$\nu$ (vol-of-vol/smile curvature)。$\beta$ 通常固定,校准 $\alpha, \rho, \nu$。

Q2: SABR 模型为什么用 Hagan 近似而不是直接 PDE 解?

SABR 的精确解需要 2D PDE 或 MC,慢;Hagan 近似 $\sigma_{\text{BS}}$ 是封闭式,O(1) 复杂度,足够工业精度(除 deep OTM)。

Q3: 在加密 BTC 期权市场,$\beta$ 怎么选?为什么?

$\beta = 1$(lognormal)。BTC 价格不会负,且 high price 时 vol 通常不会下降太多(与利率市场不同)。$\beta = 1$ 让 backbone 与 BS 一致。

Q4: SABR backbone 是什么?为什么影响动态对冲?

Backbone = $\partial \sigma_{\text{ATM}}/\partial F$。当 forward 移动时,ATM IV 自然变化。"Sticky-strike Delta" 假设 IV 不变,Hagan 含 backbone 给出"Sticky-delta Delta"。两者差异称为"vega-gamma carry",可以是显著 P&L 来源。

Q5: 校准 SABR 时 RMSE = 1% IV 算好还是差?

取决于 bid-ask spread。Deribit BTC 期权 IV bid-ask 通常 0.5-2%。RMSE < 0.5% 算好;> 1% 说明模型与市场结构不符(比如忽略了跳跃,需考虑 SABR-jump 扩展)。


九、明日预告

Day 67: Week 10 复习 — 整合 BS、Greeks、IV、SABR 为完整 options_lib v0.1 库。明天我们把过去几天的代码模块化,做单元测试,并写一个统一的期权定价/风险接口。