Lección 1.6.1 · 60 min
Rentabilidades, volatilidad, correlaciones móviles y drawdown
La volatilidad no es una cifra, es una serie que cambia de régimen, y cada forma de estimarla llega a un régimen nuevo con un retraso distinto. Esta lección compara la ventana fija con la EWMA de RiskMetrics, mide qué correlaciones móviles son señal y cuáles ruido, y descompone el drawdown en profundidad y en tiempo bajo el agua.
- Módulo
- 1.6 · Análisis exploratorio financiero
- Duración
- 60 min
Lecciones del nivel 1
1.1 · Cómo funcionan los mercados
1.2 · Clases de activos
- 1.2.1 Acciones: splits, dividendos y eventos corporativos
- 1.2.2 ETFs: réplica, tracking error, apalancados y UCITS
- 1.2.3 Futuros: especificaciones, margen, roll y contango
- 1.2.4 Forex: pares, pips, lotes, rollover y CFD
- 1.2.5 Opciones: call, put, valor intrínseco y valor temporal
- 1.2.6 Cripto: spot, perpetuos, funding y custodia
- 1.2.7 Renta fija y tipos de interés; CFDs y productos apalancados
1.3 · Fuentes de datos de mercado
- 1.3.1 Tipos de datos de mercado: EOD, barras, ticks, libro y referencia
- 1.3.2 Fuentes de datos gratuitas
- 1.3.3 APIs de datos retail y prosumer
- 1.3.4 Proveedores de datos profesionales
- 1.3.5 Datos de cripto y on-chain
- 1.3.6 Brókeres como fuente de datos
- 1.3.7 Licencias y términos de uso de datos
- 1.3.8 Cómo elegir proveedor de datos
1.4 · Ingeniería de datos financieros
- 1.4.1 Descarga por REST y websockets: paginación, límites y reintentos
- 1.4.2 Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias
- 1.4.3 Ajustes por splits y dividendos: precios ajustados y sin ajustar
- 1.4.4 Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo
- 1.4.5 Construcción de barras: tiempo, ticks, volumen, dólar y desequilibrio
- 1.4.6 Series continuas de futuros: reglas de roll, ajuste por diferencia y ajuste por ratio
- 1.4.7 Almacenamiento: CSV, Parquet, particionado, DuckDB, TimescaleDB y ArcticDB
- 1.4.8 Pipeline reproducible: descarga, validación, actualización incremental y tests de calidad
1.5 · Datos fundamentales y macro
1.6 · Análisis exploratorio financiero
1.7 · Análisis técnico programado
Dos índices, siete años
En el nivel 0 calculaste rentabilidades, la volatilidad de una ventana de 21 sesiones y el drawdown de un ETF ficticio (lecciones 0.5.3 y 0.7.1). Esta lección parte de ahí y va a lo que importa para operar: cómo cambia la volatilidad, con qué retraso la detecta cada estimador, cuánto se puede fiar uno de una correlación móvil y cómo es un drawdown por dentro.
Los datos son dos índices ficticios del nivel 1, con las sesiones reales de la NYSE de 2019 a 2025: ISX, un índice
de rentabilidad total (etf_indice_diario.csv), y FIX, un índice de precios con futuros (fix_indice_diario.csv).
Los dos tienen episodios de volatilidad alta en 2020, 2022 y la primavera de 2025.
import numpy as np
import pandas as pd
isx = pd.read_csv("etf_indice_diario.csv", parse_dates=["fecha"],
index_col="fecha")["indice"]
fix = pd.read_csv("fix_indice_diario.csv", parse_dates=["fecha"],
index_col="fecha")["indice"]
px = pd.DataFrame({"ISX": isx, "FIX": fix})
r = np.log(px).diff().dropna() # rentabilidades logarítmicas
print(px.index[0].date(), "a", px.index[-1].date(), len(px), "sesiones")
anual = pd.DataFrame({
"media_%": 100 * 252 * r.mean(),
"vol_%": 100 * np.sqrt(252) * r.std(),
"peor_dia_%": 100 * r.min(),
"mejor_dia_%": 100 * r.max()})
anual.round(2)2019-01-02 a 2025-12-31 1760 sesiones
media_% vol_% peor_dia_% mejor_dia_%
ISX 12.83 20.87 -7.95 7.84
FIX 14.55 20.07 -8.98 8.15Los dos tienen una volatilidad anual en torno al 20 %, peores días de −8 % y −9 %, mejores de +8 % y rentabilidades medias del 12,8 y el 14,6 % (en log, anualizadas por 252). Una volatilidad de toda la muestra dice poco: es la media de años muy tranquilos y meses muy agitados. Lo útil es la serie.
Volatilidad de ventana fija
La volatilidad histórica de n sesiones es la desviación típica de las n últimas rentabilidades, anualizada por √252. El tamaño de la ventana es un compromiso: corta, ruidosa y rápida; larga, estable y lenta.
x = r["ISX"]
vol = pd.DataFrame({
f"v{n}": x.rolling(n).std() * np.sqrt(252)
for n in (21, 63, 252)})
(100 * vol.loc["2020-02-14":"2020-05-29"].iloc[::10]).round(1) v21 v63 v252
fecha
2020-02-14 10.6 12.1 11.4
2020-03-02 17.5 13.2 11.7
2020-03-16 22.7 17.9 13.1
2020-03-30 27.7 23.4 15.1
2020-04-14 34.3 26.1 16.7
2020-04-28 38.2 29.8 18.4
2020-05-12 45.5 36.7 20.9
2020-05-27 37.2 38.6 21.7A mediados de febrero de 2020 las tres ventanas ven un mercado tranquilo, en torno al 11-12 %. La de 21 sesiones llega al 34,3 % a mediados de abril y al 45,5 % en mayo; la de 63, al 26,1 % y al 36,7 %; la de 252, que lleva un año de días tranquilos dentro, no pasa del 21,7 % en todo el periodo. Una ventana rectangular pondera igual todos sus días: hasta que los días tranquilos salen de ella, infravalora el régimen nuevo.
EWMA: el peso decrece con la antigüedad
La media móvil exponencial (EWMA) de los cuadrados de las rentabilidades da a cada día un peso que decrece de forma geométrica. Es la de RiskMetrics, la metodología de riesgo de J.P. Morgan de los noventa, que fijó λ = 0,94 para los datos diarios y λ = 0,97 para los mensuales1Nota 1 · J.P. Morgan/Reuters, RiskMetrics — Technical Document, 4.ª edición, 1996: correlaciones y volatilidades con medias exponenciales y factores de decaimiento de 0,94 (datos diarios, «74 day cutoff 1%») y 0,97 (mensuales).:
La rentabilidad de ayer pesa 1 − λ = 6 %; la de anteayer, 6 % × 0,94; la de hace k días, 0,06 × 0,94^(k−1). RiskMetrics supone media cero, razonable con datos diarios, y por eso usa r² en lugar de (r − media)².
lam = 0.94
k = np.arange(1, 253)
w = (1 - lam) * lam ** (k - 1)
print(f"Vida media: {np.log(0.5) / np.log(lam):.1f} sesiones")
for n in (10, 21, 63, 74):
print(f"Peso de las {n} últimas: {w[:n].sum():.1%}")Vida media: 11.2 sesiones
Peso de las 10 últimas: 46.1%
Peso de las 21 últimas: 72.7%
Peso de las 63 últimas: 98.0%
Peso de las 74 últimas: 99.0%La mitad del peso está en las once últimas sesiones y el 99 % en las 74 últimas (la cifra de corte que da el propio documento de RiskMetrics para λ = 0,94). Una ventana de 63 sesiones da 1/63 = 1,6 % a cada día y 0 al 64.º: el día que sale de la ventana provoca un salto en la estimación aunque no pase nada hoy.
La recursión se escribe en un bucle o con ewm. Con adjust=False, pandas aplica exactamente la recursión; con
alpha = 1 − λ:
def ewma_var(x, lam=0.94, var0=None):
"""Varianza EWMA de cada día con datos hasta el día anterior."""
v = np.empty(len(x))
v[0] = np.var(x[:21]) if var0 is None else var0
for t in range(1, len(x)):
v[t] = lam * v[t - 1] + (1 - lam) * x[t - 1] ** 2
return v
xa = x.to_numpy()
a_mano = ewma_var(xa)
# ewm(adjust=False) incluye el día t: se desplaza uno
con_ewm = (x.pow(2).ewm(alpha=0.06, adjust=False).mean()
.shift(1).to_numpy())
dif = np.abs(np.sqrt(a_mano[300:]) - np.sqrt(con_ewm[300:]))
print(f"Diferencia máxima tras 300 sesiones: {dif.max():.2e}")
ewma = pd.Series(np.sqrt(252 * a_mano), index=x.index)
vol["ewma"] = ewma
(100 * vol.loc["2020-02-14":"2020-05-29"].iloc[::10]).round(1)Diferencia máxima tras 300 sesiones: 2.32e-11
v21 v63 v252 ewma
fecha
2020-02-14 10.6 12.1 11.4 10.6
2020-03-02 17.5 13.2 11.7 17.4
2020-03-16 22.7 17.9 13.1 26.5
2020-03-30 27.7 23.4 15.1 34.5
2020-04-14 34.3 26.1 16.7 33.7
2020-04-28 38.2 29.8 18.4 37.4
2020-05-12 45.5 36.7 20.9 40.3
2020-05-27 37.2 38.6 21.7 37.7Las dos versiones coinciden salvo por el valor inicial, cuyo efecto desaparece en unas semanas (0,94³⁰⁰ es despreciable). Y la diferencia de timing está en la tabla: la EWMA pasa del 10,6 % al 34,5 % en seis semanas y se estabiliza entre el 34 y el 40 % mientras la de 21 sesiones sigue subiendo hasta el 45,5 %.
La figura de la cabecera lo dibuja día a día con la ventana de 63 sesiones, las dos con datos hasta el día anterior. ¿Cuándo pasa cada una del 30 %?
v63 = (x.rolling(63).std() * np.sqrt(252)).shift(1)
for nombre, serie in [("EWMA", ewma), ("Ventana 63", v63)]:
s = serie.loc["2020"]
print(f"{nombre:>10}: 30 % el {s[s >= 0.30].index[0].date()},"
f" máximo {s.max():.1%} el {s.idxmax().date()}") EWMA: 30 % el 2020-03-24, máximo 51.1% el 2020-06-16
Ventana 63: 30 % el 2020-04-30, máximo 45.1% el 2020-06-22La EWMA cruza el 30 % el 24 de marzo; la ventana de 63 sesiones, el 30 de abril, cinco semanas después. Un sistema que reduce la exposición cuando la volatilidad supera un umbral habría reaccionado con más de un mes de diferencia según el estimador. A la salida pasa lo mismo al revés: la EWMA vuelve antes a niveles bajos y devuelve la exposición antes.
Un detalle de la celda importa más que el resto: la varianza del día t usa las rentabilidades hasta t − 1. Si la
volatilidad se usa para dimensionar la posición de hoy (volatility targeting, lección 0.7.3), el estimador no puede
incluir la rentabilidad de hoy, que aún no ha ocurrido cuando se decide. rolling(...).std() y ewm(...).mean()
incluyen el día t: en un backtest, siempre shift(1).
Fuente Mermaid
flowchart LR R[r hasta t-1] --> S[σ estimada en t] S --> P[Posición en t] P --> G[Resultado r en t]
Qué estimador prevé mejor
Un estimador de volatilidad es una previsión: dice cuánto se va a mover mañana. Se puede evaluar como cualquier previsión, comparando la varianza estimada con el cuadrado de la rentabilidad del día siguiente. Dos medidas habituales: el error cuadrático medio y la pérdida QLIKE, que penaliza más quedarse corto que pasarse y es robusta al ruido de r²:
Otra forma, más intuitiva: dividir cada rentabilidad por la volatilidad prevista. Si el estimador es bueno, las rentabilidades estandarizadas tienen desviación típica cercana a 1, la curtosis más baja posible y una proporción de días por debajo de −2,33 desviaciones cercana a la que espera la normal (1 %).
prev = pd.DataFrame({
"v21": x.rolling(21).std(), "v63": x.rolling(63).std(),
"v252": x.rolling(252).std(),
"ewma94": np.sqrt(x.pow(2).ewm(alpha=0.06, adjust=False).mean()),
"ewma97": np.sqrt(x.pow(2).ewm(alpha=0.03, adjust=False).mean()),
}).shift(1) # previsión para el día siguiente
d = prev.join(x.rename("r")).dropna()
filas = {}
for c in prev:
s2, r2 = d[c] ** 2, d["r"] ** 2
z = d["r"] / d[c]
filas[c] = {"qlike": (r2 / s2 - np.log(r2 / s2) - 1).mean(),
"z_desv": z.std(), "z_curtosis": z.kurt(),
"bajo_-2,33_%": 100 * (z < -2.326).mean()}
pd.DataFrame(filas).T.round(3) qlike z_desv z_curtosis bajo_-2,33_%
v21 1.818 1.195 10.664 2.190
v63 1.827 1.122 9.979 2.057
v252 2.180 1.193 11.176 2.588
ewma94 1.696 1.088 7.326 1.924
ewma97 1.751 1.061 9.304 1.924La EWMA con λ = 0,94 tiene la QLIKE más baja (1,696) y la curtosis más baja (7,3 frente a los 10-11 de las ventanas); la de λ = 0,97 deja la desviación típica más cerca de 1 (1,06 frente a 1,09), y las dos empatan en días bajo −2,33 (1,9 %). Las ventanas quedan por detrás en todo. Ninguna llega al 1 % de días bajo −2,33: las colas siguen siendo más gruesas que las de la normal incluso después de estandarizar (lección 1.6.2). La ventana de 252 sesiones es la peor en QLIKE, curtosis y días bajo −2,33: una volatilidad «del último año» es una mala previsión de la de mañana.
Correlaciones móviles: señal y ruido
La correlación entre dos activos también cambia, y una cartera diversificada depende de ella. La correlación móvil de 63 sesiones entre ISX y FIX:
rc = r["ISX"].rolling(63).corr(r["FIX"])
banda = 1.96 / np.sqrt(63)
print(f"Correlación de toda la muestra: {r.corr().iloc[0, 1]:.3f}")
print(rc.describe().round(3).to_string())
print(f"Banda del 95 % si la correlación real es 0: ±{banda:.3f}")
print(f"Fuera de la banda: {(rc.abs() > banda).mean():.1%}")
print("Máximo:", rc.idxmax().date(), round(rc.max(), 3))Correlación de toda la muestra: 0.066
count 1697.000
mean 0.010
std 0.155
min -0.438
25% -0.080
50% -0.006
75% 0.099
max 0.511
Banda del 95 % si la correlación real es 0: ±0.247
Fuera de la banda: 10.1%
Máximo: 2025-04-23 0.511La correlación de toda la muestra es casi nula y la móvil oscila de −0,44 a +0,51. ¿Cambia la relación entre los dos índices o es ruido? Con 63 datos y una correlación real de cero, el 95 % de las estimaciones cae dentro de ±0,247 (error típico ≈ 1/√n). Aquí cae fuera el 10,1 % del tiempo: el doble del 5 % que daría el azar, pero lejos de lo que haría falta para leer cada pico como un cambio. El máximo, de 0,51, es del 23 de abril de 2025, en plena caída de los dos índices, y el pico de marzo de 2020 llega casi a 0,50: los dos episodios de estrés son los dos picos.
Para comprobar cuánto oscila una correlación móvil sin ninguna relación, basta con simularla:
rng = np.random.default_rng(7)
ind = pd.DataFrame(rng.standard_normal((len(r), 2)))
rc0 = ind[0].rolling(63).corr(ind[1])
print(f"Mínimo {rc0.min():.3f}, máximo {rc0.max():.3f}")
print(f"Fuera de la banda: {(rc0.abs() > banda).mean():.1%}")Mínimo -0.255, máximo 0.300
Fuera de la banda: 1.2%Dos series sin ninguna relación producen una correlación móvil que va de −0,26 a +0,30. En esta simulación solo el 1,2 % del tiempo queda fuera de la banda: con ventanas solapadas, los valores de días seguidos no son independientes y la fracción de un solo camino varía mucho alrededor del 5 %. Cualquier gráfico de correlación móvil hay que leerlo con esa referencia al lado.
¿Y los periodos de estrés? En los mercados reales suele observarse que las correlaciones entre activos de riesgo suben en las caídas, justo cuando la diversificación haría más falta. En estos datos hay una huella de eso, pero viene de la frecuencia, no del día a día:
for regla, nombre in [("W-FRI", "semanal"), ("ME", "mensual"),
("QE", "trimestral")]:
rr = np.log(px.resample(regla).last()).diff().dropna()
print(f"{nombre:>10}: {rr.corr().iloc[0, 1]:.3f}"
f" ({len(rr)} datos)")
vol21 = r.rolling(21).std()
print(f"Correlación de las volatilidades de 21 sesiones: "
f"{vol21['ISX'].corr(vol21['FIX']):.3f}") semanal: 0.156 (365 datos)
mensual: 0.453 (83 datos)
trimestral: 0.819 (27 datos)
Correlación de las volatilidades de 21 sesiones: 0.650En diario la correlación es 0,06; en semanal, 0,16; en mensual, 0,45, y en trimestral, 0,82. Los dos índices comparten las grandes tendencias del calendario (las caídas de 2020, 2022 y 2025 y las subidas posteriores), pero no los movimientos de cada día, que en estos datos son independientes. Al agregar, el ruido diario se cancela y queda la parte común. Y sus volatilidades sí van juntas (0,65): los regímenes de volatilidad alta son los mismos. Para una cartera, la consecuencia es clara: la diversificación que se mide con datos diarios puede no existir en el horizonte que de verdad importa, el de meses.
Drawdown y tiempo bajo el agua
El drawdown de cada día es la caída desde el máximo anterior:
Su mínimo es el drawdown máximo, la cifra que todo el mundo cita. Pero un drawdown tiene dos dimensiones: cuánto cae y cuánto dura. Un episodio bajo el agua empieza el día en que el precio cae por debajo de su máximo y termina el día en que lo supera de nuevo.
Fuente Mermaid
stateDiagram-v2 [*] --> EnMaximo EnMaximo --> BajoElAgua: cae del máximo BajoElAgua --> BajoElAgua: sigue por debajo BajoElAgua --> EnMaximo: supera el máximo
def episodios(precio):
pico = precio.cummax()
dd = precio / pico - 1
bajo = dd < 0
grupo = (~bajo).cumsum() # un número por episodio
filas = []
for _, e in dd[bajo].groupby(grupo[bajo]):
fin = e.index[-1]
sig = precio.index.searchsorted(fin, side="right")
recuperado = sig < len(precio)
filas.append({
"inicio": e.index[0].date(),
"minimo": e.idxmin().date(),
"recupera": precio.index[sig].date()
if recuperado else None,
"profundidad_%": 100 * e.min(),
"sesiones_hasta_minimo": e.index.get_loc(e.idxmin()) + 1,
"sesiones_bajo_agua": len(e)})
return pd.DataFrame(filas), dd
ep, dd_isx = episodios(px["ISX"])
print(f"Sesiones bajo el agua: {(dd_isx < 0).mean():.1%}")
print(f"Episodios: {len(ep)}")
ep.sort_values("profundidad_%").head(5).round(1)Sesiones bajo el agua: 92.9%
Episodios: 54
inicio minimo recupera profundidad_% sesiones_hasta_minimo sesiones_bajo_agua
22 2020-02-20 2020-04-21 2021-03-29 -43.2 43 278
31 2022-02-15 2022-05-25 2023-04-17 -28.9 70 292
41 2025-02-20 2025-04-04 2025-06-25 -28.0 32 86
35 2023-07-17 2024-01-02 2024-10-03 -18.6 118 307
36 2024-10-09 2024-11-26 2025-01-13 -7.2 35 64El 92,9 % de las sesiones ISX está por debajo de su máximo anterior: casi siempre se está «bajo el agua», aunque sea por poco. Lo que distingue a un episodio es su profundidad y su duración, y no van juntas:
ep.sort_values("sesiones_bajo_agua", ascending=False).head(4)[
["inicio", "recupera", "profundidad_%",
"sesiones_hasta_minimo", "sesiones_bajo_agua"]].round(1) inicio recupera profundidad_% sesiones_hasta_minimo sesiones_bajo_agua
35 2023-07-17 2024-10-03 -18.6 118 307
31 2022-02-15 2023-04-17 -28.9 70 292
22 2020-02-20 2021-03-29 -43.2 43 278
41 2025-02-20 2025-06-25 -28.0 32 86El desplome de 2020 es el más profundo (−43,2 %) pero tarda 278 sesiones en recuperarse, menos que el episodio que empieza en julio de 2023, con solo −18,6 % de profundidad y 307 sesiones bajo el agua: una caída moderada seguida de una recuperación lenta. La caída de 2022 dura 292. Para quien sigue una estrategia, catorce meses sin un máximo nuevo pesan tanto como una caída grande: es cuando se abandonan los sistemas. Por eso las métricas de riesgo del nivel 2 (lección 2.6.1) incluyen la duración del drawdown y el Ulcer Index, que combina profundidad y duración.
Lo que esto cambia en un sistema
- Volatilidad con
shift(1). Toda estimación que alimente una decisión del día t usa datos hasta t − 1. Con rolling y ewm de pandas, el día t está dentro: desplázalo. - Elige el estimador por su uso. Para dimensionar posiciones día a día, uno rápido (EWMA, λ = 0,94 o ventana corta); para comparar estrategias o fijar límites de riesgo, uno lento y estable.
- Ninguna correlación sin su banda. Con n datos, el ruido es del orden de ±2/√n. Y mide la correlación a la frecuencia de tu horizonte, no solo en diario.
- Profundidad y duración. Informa el drawdown máximo y el episodio más largo bajo el agua. Son riesgos distintos.
Ejercicios
- Repite la evaluación de estimadores con FIX y con λ = 0,90, 0,94 y 0,97. ¿Qué λ da la QLIKE más baja en cada índice?
Solución
def qlike(serie, lam):
s2 = serie.pow(2).ewm(alpha=1 - lam, adjust=False).mean()
dd = pd.DataFrame({"s2": s2.shift(1),
"r2": serie.pow(2)}).iloc[63:]
dd = dd[dd["r2"] > 0] # días sin variación: ln(0)
q = dd["r2"] / dd["s2"]
return (q - np.log(q) - 1).mean()
tabla = pd.DataFrame({ind: {lam: qlike(r[ind], lam)
for lam in (0.90, 0.94, 0.97)}
for ind in ["ISX", "FIX"]})
tabla.round(4) ISX FIX
0.90 1.6955 1.6794
0.94 1.6973 1.6746
0.97 1.7454 1.7173Las diferencias son pequeñas y el λ óptimo depende del índice: en ISX gana 0,90 por dos milésimas; en FIX, 0,94. Con siete años de un solo activo, elegir λ por la QLIKE es una optimización en la muestra: el 0,94 de RiskMetrics es un valor por defecto razonable precisamente porque no se ajustó a tus datos.
- Calcula la correlación EWMA (λ = 0,94) entre ISX y FIX y compárala con la de ventana de 63 sesiones: ¿cuál oscila más?
Solución
a = 0.06
cov = (r["ISX"] * r["FIX"]).ewm(alpha=a, adjust=False).mean()
var_i = r["ISX"].pow(2).ewm(alpha=a, adjust=False).mean()
var_f = r["FIX"].pow(2).ewm(alpha=a, adjust=False).mean()
corr_ewma = (cov / np.sqrt(var_i * var_f)).iloc[63:]
pd.DataFrame({"ventana_63": rc.iloc[63:].describe(),
"ewma_094": corr_ewma.describe()}).round(3) ventana_63 ewma_094
count 1696.000 1696.000
mean 0.010 0.020
std 0.155 0.182
min -0.438 -0.517
25% -0.080 -0.083
50% -0.006 0.006
75% 0.099 0.110
max 0.511 0.699La EWMA oscila más: su vida media de 11 sesiones equivale a una ventana mucho más corta que 63, y su ruido de muestreo es mayor. Es la otra cara de reaccionar antes. Las primeras 63 sesiones se descartan porque la recursión arranca de un solo dato y da correlaciones de ±1 al principio.
- Una estrategia tiene un drawdown máximo del −15 % y otra del −25 %. ¿Qué más necesitas saber antes de decir cuál es menos arriesgada?
Solución
La duración de sus episodios bajo el agua (el más largo y el típico), la volatilidad de cada una (un −15 % con una volatilidad del 5 % es un evento de tres desviaciones; un −25 % con un 25 %, uno normal) y cuántos años cubre el histórico: el drawdown máximo crece con la longitud de la muestra. También importa si el drawdown viene de un único desplome o de una sangría lenta, porque se gestionan de forma distinta (stops frente a revisión del sistema).
Footnotes
-
J.P. Morgan/Reuters, RiskMetrics — Technical Document, 4.ª edición, 1996: correlaciones y volatilidades con medias exponenciales y factores de decaimiento de 0,94 (datos diarios, «74 day cutoff 1%») y 0,97 (mensuales). ↩
Respuesta plegada en cada pregunta
Autoevaluación
Con λ = 0,94, ¿qué peso tiene en la EWMA la rentabilidad de ayer?
- AEl 94 %
- BEl 6 %: (1 − λ)
- C1/63, como en una ventana de 63 sesiones
- DDepende del nivel de volatilidad
Ver respuesta
Respuesta B. El 6 %: (1 − λ)
σ²(t) = λ σ²(t−1) + (1 − λ) r²(t−1): la última rentabilidad pesa 1 − λ = 6 %, la anterior 6 % × 0,94, y así sucesivamente. La vida media del peso es ln 0,5 / ln 0,94 ≈ 11,2 sesiones.
En marzo de 2020, ¿por qué la volatilidad de ventana de 63 sesiones va por detrás de la EWMA?
- APorque está mal calculada
- BPorque pondera igual los 63 días: los días tranquilos de enero y febrero pesan lo mismo que los del desplome
- CPorque usa rentabilidades simples
- DPorque la EWMA usa información futura
Ver respuesta
Respuesta B. Porque pondera igual los 63 días: los días tranquilos de enero y febrero pesan lo mismo que los del desplome
Una ventana rectangular reparte el peso por igual. Hasta que los días tranquilos salen de la ventana, el estimador infravalora el régimen nuevo; la EWMA da más peso a lo reciente y reacciona antes. Ninguna de las dos usa el día que estima si se desplaza un día.
La correlación móvil de 63 sesiones entre dos índices oscila entre −0,44 y +0,51 con una media de 0,01. ¿Qué es lo más probable?
- AQue la relación entre los dos índices cambia de signo cada pocos meses
- BQue gran parte de la oscilación es ruido de muestreo: con 63 datos y correlación cero, el 95 % de las estimaciones cae entre ±0,25
- CQue hay un error en el cálculo
- DQue hay que usar una ventana de 5 sesiones
Ver respuesta
Respuesta B. Que gran parte de la oscilación es ruido de muestreo: con 63 datos y correlación cero, el 95 % de las estimaciones cae entre ±0,25
El error típico de una correlación cercana a cero con n datos es aproximadamente 1/√n. Antes de interpretar un cambio de correlación hay que compararlo con esa banda.
La correlación diaria de ISX y FIX es 0,06 y la trimestral 0,82. ¿Cómo puede ser?
- APor un error de redondeo
- BPorque los dos índices comparten las grandes tendencias (las caídas de 2020, 2022 y 2025) pero no los movimientos diarios: a frecuencias bajas domina la parte común
- CPorque la correlación trimestral siempre es mayor
- DPorque hay menos días festivos
Ver respuesta
Respuesta B. Porque los dos índices comparten las grandes tendencias (las caídas de 2020, 2022 y 2025) pero no los movimientos diarios: a frecuencias bajas domina la parte común
La correlación depende de la frecuencia. Lo que domina el día a día de estos índices es ruido independiente; al agregar, ese ruido se cancela y queda la tendencia común. Con 27 trimestres, además, la estimación es muy imprecisa.
El drawdown más profundo de ISX es del −43,2 %, pero su episodio más largo bajo el agua no es ese. ¿Qué mide cada cosa?
- ALo mismo
- BLa profundidad mide cuánto se pierde desde el máximo; la duración, cuánto tiempo se tarda en volver a él. Una caída rápida con rebote rápido puede durar menos que una caída suave sin rebote
- CLa duración solo cuenta días con pérdidas
- DEl drawdown no se puede medir en días
Ver respuesta
Respuesta B. La profundidad mide cuánto se pierde desde el máximo; la duración, cuánto tiempo se tarda en volver a él. Una caída rápida con rebote rápido puede durar menos que una caída suave sin rebote
En ISX, la caída de 2020 se recupera en 278 sesiones; el episodio de 2023-2024, con solo −18,6 % de profundidad, dura 307. Para quien vive la estrategia, las dos dimensiones duelen de forma distinta.
Ideas clave
- Una ventana fija pondera igual todos sus días y llega tarde a los regímenes nuevos; la EWMA con λ = 0,94 (RiskMetrics, datos diarios) tiene una vida media de unas 11 sesiones.
- Para usar una volatilidad en el sizing de hoy, se estima con datos hasta ayer:
shift(1). Un estimador se evalúa como previsión, con QLIKE o con rentabilidades estandarizadas. - Una correlación móvil de n datos tiene un ruido de en torno a ±2/√n: con 63 sesiones, ±0,25. Antes de leer un cambio, compáralo con esa banda.
- La correlación depende de la frecuencia: ISX y FIX tienen 0,06 en diario y 0,82 en trimestral.
- El drawdown tiene profundidad y duración. En ISX, el episodio más profundo (−43,2 %) no es el más largo (307 sesiones bajo el agua).