σμ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 AcademyRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Rutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Ruta de Python›Módulo 11 · Sistemas de producción y modelos de vanguardia›Tema 11.9·~1 h 30 minExperto

El modelo SABR

Posición en la rutaMódulo 11 de 11 · Tema 9 de 13
11.9 El modelo SABR
—Puntuación del lab— / 100XP total—Racha—

Una sonrisa en cuatro números

Las opciones de tipos y de divisas se negocian en muchos strikes y las mesas necesitan una forma suave y consciente del arbitraje de interpolar y extrapolar las volatilidades cotizadas. SABR (Hagan, Kumar, Lesniewski, Woodward, 2002) es el estándar del mercado. Modela un forward F con su propia volatilidad aleatoria alpha: dF = alpha F^beta dW y d alpha = nu alpha dZ, con correlación rho entre los choques. Cuatro parámetros dan forma a la sonrisa de un vencimiento: alpha fija el nivel global, beta cómo depende la volatilidad del nivel de precio (0 normal, 1 lognormal), rho la inclinación (skew) y nu la curvatura (cuánto suben las alas).

# 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)

La fórmula de Hagan

El desarrollo asintótico de Hagan da la volatilidad implícita de Black sin simulación. En el dinero (K = F) es alpha / F^(1-beta) por una corrección temporal 1 + (...) * T, donde el paréntesis combina tres efectos: la curvatura beta de la columna vertebral, el término de skew rho * nu y el término de sonrisa nu^2. Fuera del dinero, la misma corrección multiplica dos factores más: un denominador en la log-moneyness L = ln(F/K) y el cociente z / chi(z), con z = (nu/alpha) (FK)^((1-beta)/2) L y chi(z) = ln((sqrt(1 - 2 rho z + z^2) + z - rho) / (1 - rho)). Cuando z tiende a 0 el cociente tiende a 1, así que la fórmula enlaza suavemente con el valor en el dinero, pero calcular 0 / 0 directamente fallaría: trata un z diminuto como un límite.

# 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

Leer la sonrisa y ajustarla

Traza la volatilidad implícita frente al strike y los parámetros tienen firmas claras. Un rho negativo eleva los strikes bajos y baja los altos (skew descendente, típico de acciones y de muchos tipos); rho = 0 da una sonrisa simétrica. Un nu mayor eleva ambas alas. beta mueve la columna vertebral: cuánto cambia la volatilidad en el dinero cuando se mueve el forward. Los profesionales fijan beta por convención o por el histórico y luego calibran el resto con las volatilidades cotizadas de cada vencimiento (tema siguiente), resolviendo a menudo alpha a partir de la cotización en el dinero para que coincida exactamente. Dos advertencias: la fórmula es una aproximación que se degrada en vencimientos largos y strikes muy bajos, donde puede implicar densidades de probabilidad 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
Una aproximación con un punto débil conocidoLa fórmula de Hagan es precisa cerca del dinero y para vencimientos cortos, pero puede dar precios de mariposas negativos en strikes bajos y vencimientos largos, lo que significa un arbitraje en la sonrisa ajustada. Comprueba las volatilidades ajustadas valorando mariposas, restringe los rangos de parámetros (rho estrictamente entre -1 y 1, nu no enorme) y reajusta cada vencimiento por separado y con suavidad en el tiempo. Para tipos bajos o negativos usa la versión normal (Bachelier) de la fórmula, que no se rompe cerca de cero.
  • SABR da a cada vencimiento una sonrisa con cuatro parámetros: alpha (nivel), beta (columna vertebral), rho (skew) y nu (curvatura).
  • Fórmula de Hagan = prefactor x z / chi(z) x corrección temporal; en el dinero se reduce a alpha / F^(1-beta) por la corrección, y z / chi(z) tiende a 1 cuando z tiende a 0.
  • Un rho negativo inclina la sonrisa hacia abajo, un nu mayor eleva las alas; ajusta cada vencimiento por separado, comprueba el arbitraje en las alas y usa la versión normal con tipos cercanos a cero.

A continuación: calibración de modelos, ajustar los parámetros de un modelo a los precios de mercado.

Lab: qué se califica

  • Añadir la corrección temporal con sabr_correction25 pts
  • Leer el punto en el dinero con sabr_atm_vol25 pts
  • Domar el 0 / 0 en z_over_chi25 pts
  • Dibujar la sonrisa con sabr_implied_vol25 pts
Explorador · lab-138-1
▾ lab-138-1
…
bash · en el navegador
learner@quantcraft:~/lab-138-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-138-1 vuelve a los archivos iniciales y se limpia el terminal. Tu solución actual se perderá: no se puede deshacer.

Se restablecerá
  • main.py → código inicial
  • Historial del terminal y salida de pruebas
  • Cambios sin enviar
Se conservará
  • Mejor puntuación del lab
  • Tu XP y tu racha
  • Progreso de la lección y notas

Inicia sesión para ejecutar tu código.

Todas las clases se pueden leer gratis. Crea una cuenta o inicia sesión para ejecutar código, lanzar las pruebas y enviar este lab.

  • IDE en el navegador con terminal bash — sin instalar nada
  • Corrección instantánea, XP y tu lugar en la ruta
Crear una cuentaIniciar sesión
O
Continuar con GitHub