σμ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 AcademyRoteiros
Ctrl K
AO
+1,2 mil alunos
EntrarParticipar ↗
Roteiros
AO
+1,2 mil alunos
Entrar
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Roteiro de Python›Módulo 11 · Sistemas de produção e modelos de ponta›Tópico 11.9·~1 h 30 minEspecialista

O modelo SABR

Posição no roteiroMódulo 11 de 11 · Tópico 9 de 13
11.9 O modelo SABR
—Nota do lab— / 100XP total—Sequência—

Um smile em quatro números

Opções de juros e de câmbio negociam em muitos strikes, e as mesas precisam de um jeito suave e ciente de arbitragem para interpolar e extrapolar as volatilidades cotadas. O SABR (Hagan, Kumar, Lesniewski, Woodward, 2002) é o padrão de mercado. Ele modela um forward F com sua própria volatilidade aleatória alpha: dF = alpha F^beta dW e d alpha = nu alpha dZ, com correlação rho entre os choques. Quatro parâmetros moldam o smile de um vencimento: alpha define o nível geral, beta como a volatilidade depende do nível de preço (0 normal, 1 lognormal), rho a inclinação (skew) e nu a curvatura (quanto as pontas sobem).

# The four parameters of one expiry, for a rate forward of 3%
f, t = 0.03, 1.0                              # forward rate and expiry in years
alpha, beta, rho, nu = 0.035, 0.5, -0.3, 0.4
print(round(alpha / f ** (1 - beta), 4))      # 0.2021   alpha / f^(1-beta) is roughly the at-the-money volatility (before the correction)

A fórmula de Hagan

A expansão assintótica de Hagan dá a volatilidade implícita de Black sem simulação. No dinheiro (K = F) é alpha / F^(1-beta) vezes uma correção de tempo 1 + (...) * T, em que o parêntese combina três efeitos: a curvatura beta da espinha dorsal, o termo de skew rho * nu e o termo de smile nu^2. Fora do dinheiro, a mesma correção multiplica mais dois fatores: um denominador na log-moneyness L = ln(F/K) e a razão z / chi(z), com z = (nu/alpha) (FK)^((1-beta)/2) L e chi(z) = ln((sqrt(1 - 2 rho z + z^2) + z - rho) / (1 - rho)). Quando z tende a 0 a razão tende a 1, de modo que a fórmula se une suavemente ao valor no dinheiro, mas calcular 0 / 0 diretamente falharia: trate um z minúsculo como um limite.

# The pieces of Hagan's formula: the time correction, the at-the-money volatility and z / chi(z)
import math

def sabr_correction(f, k, t, alpha, beta, rho, nu):
    fk = f * k
    return 1 + ((1 - beta) ** 2 / 24 * alpha ** 2 / fk ** (1 - beta) + rho * beta * nu * alpha / (4 * fk ** ((1 - beta) / 2)) + (2 - 3 * rho ** 2) * nu ** 2 / 24) * t

def sabr_atm_vol(f, t, alpha, beta, rho, nu):
    return alpha / f ** (1 - beta) * sabr_correction(f, f, t, alpha, beta, rho, nu)

def z_over_chi(z, rho):
    if abs(z) < 1e-7:
        return 1.0
    return z / math.log((math.sqrt(1 - 2 * rho * z + z ** 2) + z - rho) / (1 - rho))

print(round(sabr_atm_vol(0.03, 1.0, 0.035, 0.5, -0.3, 0.4), 6))      # 0.203877   the at-the-money volatility
print(round(z_over_chi(0.5, -0.3), 6), z_over_chi(0.0, -0.3))        # 1.103683 1.0   near 1, and exactly 1.0 at z = 0

Lendo o smile e ajustando-o

Trace a volatilidade implícita contra o strike e os parâmetros têm assinaturas claras. Um rho negativo eleva os strikes baixos e abaixa os altos (skew descendente, típico de ações e de muitos juros); rho = 0 dá um smile simétrico. Um nu maior eleva as duas pontas. beta move a espinha dorsal: quanto a volatilidade no dinheiro muda quando o forward se move. Os profissionais fixam beta por convenção ou pelo histórico e depois calibram o resto às volatilidades cotadas de cada vencimento (próximo tópico), muitas vezes resolvendo alpha a partir da cotação no dinheiro para que ela case exatamente. Duas cautelas: a fórmula é uma aproximação que se degrada em vencimentos longos e strikes muito baixos, onde pode implicar densidades de probabilidade negativas.

# The smile for three values of rho: a negative rho lifts the low strikes (downward skew)
import math

def sabr_vol(f, k, t, alpha, beta, rho, nu):
    fk = f * k
    log = math.log(f / k)
    mid = fk ** ((1 - beta) / 2)
    z = nu / alpha * mid * log
    ratio = 1.0 if abs(z) < 1e-7 else z / math.log((math.sqrt(1 - 2 * rho * z + z ** 2) + z - rho) / (1 - rho))
    denominator = mid * (1 + (1 - beta) ** 2 / 24 * log ** 2 + (1 - beta) ** 4 / 1920 * log ** 4)
    bracket = 1 + ((1 - beta) ** 2 / 24 * alpha ** 2 / fk ** (1 - beta) + rho * beta * nu * alpha / (4 * mid) + (2 - 3 * rho ** 2) * nu ** 2 / 24) * t
    return alpha / denominator * ratio * bracket

for rho in (-0.5, 0.0, 0.5):
    print(rho, [round(sabr_vol(0.03, k, 1.0, 0.035, 0.5, rho, 0.4), 4) for k in (0.02, 0.03, 0.04)])
# one line per rho: the first value (low strike) is the highest when rho is negative and the lowest when rho is positive
# A free sanity check: with beta = 1 and nu = 0 SABR is Black-Scholes, so the at-the-money volatility is alpha at every expiry
def atm(f, t, alpha, beta, rho, nu):
    fk = f * f
    bracket = 1 + ((1 - beta) ** 2 / 24 * alpha ** 2 / fk ** (1 - beta) + rho * beta * nu * alpha / (4 * fk ** ((1 - beta) / 2)) + (2 - 3 * rho ** 2) * nu ** 2 / 24) * t
    return alpha / f ** (1 - beta) * bracket

print(atm(100.0, 0.5, 0.2, 1.0, -0.3, 0.0), atm(100.0, 5.0, 0.2, 1.0, -0.3, 0.0))      # 0.2 0.2
Uma aproximação com um ponto fraco conhecidoA fórmula de Hagan é precisa perto do dinheiro e para vencimentos curtos, mas pode dar preços de borboleta negativos em strikes baixos e vencimentos longos, o que significa uma arbitragem no smile ajustado. Verifique as volatilidades ajustadas precificando borboletas, restrinja as faixas de parâmetros (rho estritamente entre -1 e 1, nu não enorme) e reajuste cada vencimento separadamente e de forma suave no tempo. Para juros baixos ou negativos use a versão normal (Bachelier) da fórmula, que não quebra perto de zero.
  • O SABR dá a cada vencimento um smile com quatro parâmetros: alpha (nível), beta (espinha dorsal), rho (skew) e nu (curvatura).
  • Fórmula de Hagan = pré-fator x z / chi(z) x correção de tempo; no dinheiro reduz-se a alpha / F^(1-beta) vezes a correção, e z / chi(z) tende a 1 quando z tende a 0.
  • Um rho negativo inclina o smile para baixo, um nu maior eleva as pontas; ajuste cada vencimento separadamente, verifique arbitragem nas pontas e use a versão normal perto de juros zero.

A seguir: calibração de modelos, ajustar os parâmetros de um modelo aos preços de mercado.

Lab: o que é avaliado

  • Somar a correção de tempo com sabr_correction25 pts
  • Ler o ponto no dinheiro com sabr_atm_vol25 pts
  • Domar o 0 / 0 em z_over_chi25 pts
  • Desenhar o smile com sabr_implied_vol25 pts
Explorador · lab-138-1
▾ lab-138-1
…
bash · no navegador
learner@quantcraft:~/lab-138-1$
Python ainda não carregadoPythonLn 1, Col 1Spaces: 4UTF-8

Redefinir este tópico?

Tudo em lab-138-1 volta aos arquivos iniciais e o terminal é limpo. Sua solução atual será perdida — isso não pode ser desfeito.

Será redefinido
  • main.py → código inicial
  • Histórico do terminal e saída dos testes
  • Alterações não enviadas
Será mantido
  • Melhor nota do lab
  • Seu XP e sua sequência
  • Progresso da aula e anotações

Entre para executar o seu código.

Todas as aulas são gratuitas para ler. Crie uma conta ou entre para executar código, rodar os testes e enviar este lab.

  • IDE no navegador com terminal bash — nada para instalar
  • Correção instantânea, XP e o seu lugar no roteiro
Criar uma contaEntrar
OU
Continuar com o GitHub