σμ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 3 · Probabilidad y simulación Monte Carlo›Tema 3.6·~45 minIntermedio

Volatilidad

Posición en la rutaMódulo 3 de 11 · Tema 6 de 12
3.6 Volatilidad
—Puntuación del lab— / 100XP total—Racha—

El riesgo en un solo número

La volatilidad es la desviación típica de los rendimientos, expresada anualmente para poder comparar activos: alrededor del 15 al 20 % en un índice bursátil, del 30 al 60 % en una acción concreta, cerca de 0 en efectivo. Sirve para dimensionar posiciones, valorar opciones y fijar límites de riesgo. La estimación más simple es la volatilidad realizada en una ventana: la desviación típica muestral de los rendimientos por sqrt(periodos por año). Trata igual todos los días de la ventana, lo que es a la vez su fuerza (estable) y su debilidad (lenta).

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

Reaccionar más rápido: EWMA

La volatilidad se agrupa: los periodos tranquilos y los agitados duran un tiempo, así que el choque de ayer dice más sobre mañana que un día tranquilo de hace un mes. La media móvil exponencial (EWMA, popularizada por RiskMetrics) actualiza la varianza cada día: varianza_t = lam * varianza_(t-1) + (1 - lam) * rendimiento_t². Con lam = 0,94 el rendimiento más reciente pesa un 6 % y los antiguos se desvanecen geométricamente. La estimación salta con un choque y decae poco a poco, en lugar de seguir alta hasta que el choque sale de la ventana y caer de golpe.

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

Usar el rango y fijar una volatilidad objetivo

Los precios de cierre ignoran lo ocurrido durante el día. El máximo y el mínimo diarios llevan más información: el estimador de Parkinson sqrt(mean(ln(high/low)²) / (4 ln 2)) es varias veces más eficiente que la estimación de cierre a cierre, es decir, alcanza la misma precisión con muchos menos días (supone que no hay grandes saltos entre días). Un uso práctico de cualquier estimación de volatilidad es el objetivo de volatilidad: si quieres un 10 % de riesgo y la volatilidad realizada es del 15 %, mantén 10 / 15 = 0,67 de la posición. El apalancamiento se reduce en la tormenta y crece en la calma.

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
La volatilidad no es dirección, y se mueveLa volatilidad trata igual un día de +3 % y uno de -3 %, pero los inversores solo temen el segundo. Tampoco es constante: toda estimación depende de su ventana o de su decaimiento, y los 252 días bursátiles son una convención. Indica qué estimador, ventana y anualización usaste siempre que cites una volatilidad.
  • Volatilidad realizada: desviación típica muestral por sqrt(periodos por año); estable pero lenta en reaccionar.
  • EWMA: varianza_t = lam * varianza_(t-1) + (1 - lam) * rendimiento_t²; los choques recientes pesan más y se desvanecen geométricamente.
  • Parkinson usa el rango máximo/mínimo diario; el objetivo de volatilidad escala la posición por objetivo / realizada.

A continuación: el ratio de Sharpe, la recompensa por unidad de riesgo, y hasta dónde fiarse de él.

Lab: qué se califica

  • Medir la volatilidad anual con realized_volatility25 pts
  • Dar más peso a los choques recientes con ewma_volatility25 pts
  • Usar el rango diario con parkinson_volatility25 pts
  • Dimensionar una posición a un presupuesto de riesgo con volatility_target_leverage25 pts
Explorador · lab-59-1
▾ lab-59-1
…
bash · en el navegador
learner@quantcraft:~/lab-59-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-59-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