Lección 3.6.3 · 70 min
Estrategias con VIX y VSTOXX: futuros y ETP de volatilidad
El VIX es un cálculo, no un activo: lo que se negocia son futuros que convergen a él y productos cotizados que ruedan esos futuros cada día. Esta lección reconstruye con los datos del curso la curva, el índice de futuros a corto plazo y dos ETP, uno largo que pierde un 99,4 % en doce años y uno inverso que desaparece en una sesión, y mide qué queda de las estrategias de venta de volatilidad cuando se mira su peor día.
- Módulo
- 3.6 · Estrategias sistemáticas de volatilidad y opciones
- Duración
- 70 min
Lecciones del nivel 3
3.1 · Futuros en profundidad
3.2 · Spreads de futuros
- 3.2.1 Spreads de calendario, butterflies y condors
- 3.2.2 Spreads intercommodity: crack, spark y crush
- 3.2.3 Spreads de tipos y de índices: 2s10s, NOB, NQ/ES y Europa frente a EE. UU.
- 3.2.4 Ratios de cobertura: por nominal, por DV01 y por volatilidad
- 3.2.5 Datos y backtesting de spreads: cotizados, sintéticos y por patas
- 3.2.6 Estacionalidad de spreads: análisis multi-año, patrones y trampas
3.3 · Forex avanzado
3.4 · Teoría y valoración de opciones
- 3.4.1 Payoffs, paridad put-call y límites de arbitraje
- 3.4.2 Árboles binomiales, Black-Scholes-Merton, Black-76 y Monte Carlo
- 3.4.3 Griegas: delta, gamma, vega, theta, rho, vanna, volga y charm
- 3.4.4 Volatilidad implícita: Newton-Raphson, Brent, py_vollib y QuantLib
- 3.4.5 Sonrisa, skew y estructura temporal; superficie de volatilidad con SVI
- 3.4.6 Volatilidad realizada frente a implícita; prima de riesgo de volatilidad; VIX y VSTOXX
- 3.4.7 Modelos avanzados: Heston, SABR y volatilidad local
3.5 · Estructuras de opciones en Python
- 3.5.1 Estructuras direccionales y verticales: call, put, covered call, collar y spreads
- 3.5.2 Estructuras de volatilidad y rango: straddles, strangles, cóndores y mariposas
- 3.5.3 Calendarios, diagonales, ratios, backspreads, risk reversals y jade lizard
- 3.5.4 Herramienta propia: payoff, griegas agregadas y escenarios
- 3.5.5 Gestión: ajustes, roll, cierre anticipado, asignación temprana y pin risk
3.6 · Estrategias sistemáticas de volatilidad y opciones
3.7 · Cripto derivados y estrategias específicas
Un índice que no se puede comprar
El VIX de Cboe mide la volatilidad esperada a 30 días del S&P 500 con los precios de una franja de sus opciones, con la fórmula de varianza que la lección 3.4.6 aplica al VORX de los datos del curso. Cboe lo publicó en 1993 sobre opciones del S&P 100 y lo cambió en 2003 a la fórmula actual, según su metodología. El VSTOXX es el equivalente europeo, sobre las opciones del Euro Stoxx 50.
Ninguno de los dos se puede comprar. Para mantener «el VIX» habría que tener una cesta de opciones con 30 días que cambia de strikes y de vencimientos cada día; no es una cartera que se compre y se guarde. Lo que se negocia son futuros sobre el índice y, encima de ellos, productos cotizados (ETP: fondos y notas) que mantienen una posición en esos futuros y la ruedan. Cada capa añade una diferencia con el índice que el inversor cree estar comprando.
Fuente Mermaid
flowchart TB O[Opciones a 30 d] --> V[VIX al contado] V -. liquida .-> F[Futuros VX] F --> I[Índice de futuros] I --> L[ETP largo] I --> N[ETP inverso]
Las reglas reales de los futuros, de sus fuentes primarias:
| Futuros sobre el VIX (Cboe, VX) | Futuros sobre el VSTOXX (Eurex, FVS) | |
|---|---|---|
| Multiplicador | 1.000 USD por punto | 100 EUR por punto |
| Tick | 0,05 puntos (50 USD) | 0,05 puntos (5 EUR) |
| Liquidación final | El miércoles 30 días antes del tercer viernes del mes siguiente | 30 días naturales antes del vencimiento de las opciones subyacentes |
| Precio de liquidación | SOQ: el VIX calculado con los precios de apertura de las opciones de ese día | Media del índice entre las 11:00 y las 12:00 CET del último día |
| Liquidación | En efectivo | En efectivo |
La fecha de los dos sale de la misma idea: 30 días antes de que venzan las opciones con las que se calcula el índice, para que el día de la liquidación el índice dependa de un único vencimiento a 30 días. La SOQ (Special Opening Quotation) no es el VIX de esa mañana: se calcula con los precios de apertura de una subasta especial de las opciones del S&P 500, con reglas propias (por ejemplo, admite strikes con bid nulo), según la sección 3.4 de la metodología de Cboe. En los datos del curso los futuros sobre el VORX vencen el miércoles 30 días antes del tercer viernes del mes siguiente, como los VX, y liquidan al cierre del VORX de ese día (simplificación).
La curva de futuros sobre el VORX
Los datos son sintéticos (public/curso/datos/nivel-3/README.md): vol3_indices.csv con el VORX, que imita al VIX y
se recalcula exactamente con la fórmula de Cboe desde la cadena de ORX (lección 3.4.6), y el VVGX, que imita al
VSTOXX; vol3_futuros.parquet con ocho futuros mensuales sobre el VORX, y vol3_etp.csv con el índice de futuros a
corto plazo y dos ETP. El modelo de los futuros es la expectativa del VORX en su vencimiento bajo la medida de
valoración, más la diferencia de hoy entre el VORX y su modelo, que se disipa con 10 días de vida. Y lleva plantado
un episodio: el 2018-02-05 los dos primeros futuros liquidan un 22 % por encima de su valor de modelo, como la compra
de los ETP inversos en la ventana de liquidación, y se deshace al día siguiente.
import numpy as np
import pandas as pd
vi = pd.read_csv("vol3_indices.csv", parse_dates=["fecha"])
vi = vi.set_index("fecha")
fu = pd.read_parquet("vol3_futuros.parquet")
fu = fu.sort_values(["fecha", "vencimiento"])
fu["orden"] = fu.groupby("fecha").cumcount() # 0 = el primero
vx = vi["vorx"]
print(vx.describe().round(2).to_dict())
curvas = {d: fu[fu["fecha"] == d].set_index("dias")["precio"]
for d in ("2017-06-14", "2020-03-16")}
for d, c in curvas.items():
print(d, "VORX", vx[d], "|", c.to_dict()){'count': 3018.0, 'mean': 19.8, 'std': 8.51, 'min': 9.55, '25%': 14.23, '50%': 17.66, '75%': 22.83, 'max': 73.98}
2017-06-14 VORX 11.05 | {7: 12.3, 35: 15.05, 63: 16.4, 98: 17.3, 126: 17.8, 154: 18.3, 189: 18.6, 217: 19.0}
2020-03-16 VORX 73.09 | {2: 71.45, 30: 51.35, 65: 37.9, 93: 31.35, 128: 26.8, 156: 25.15, 184: 24.2, 219: 23.7}Las dos fotos son las dos formas de la curva. El 14 de junio de 2017, con el VORX en 11,05, el futuro a 7 días cotiza a 12,30 y el de 217 días a 19,00: contango, cada vencimiento más caro que el anterior, porque la volatilidad baja se espera que vuelva a su media, más alta. El 16 de marzo de 2020, con el VORX en 73,09, la curva baja de 71,45 a 23,70: backwardation, porque se espera que la crisis pase. La medida en toda la muestra:
f1 = fu[fu["orden"] == 0].set_index("fecha")
f2 = fu[fu["orden"] == 1].set_index("fecha")
print(f"primer futuro sobre el VORX: "
f"{(f1['precio'] > vx).mean():.1%} de las sesiones")
print(f"segundo sobre el primero: "
f"{(f2['precio'] > f1['precio']).mean():.1%}; diferencia "
f"media {(f2['precio'] / f1['precio'] - 1).mean():.1%}")
venc = fu[fu["fecha"] == fu["vencimiento"]].set_index("fecha")
dif = (venc["precio"] - vx.reindex(venc.index)).abs()
print(f"{len(venc)} vencimientos; |futuro − VORX| al vencer: "
f"máx. {dif.max():.3f}")primer futuro sobre el VORX: 62.8% de las sesiones
segundo sobre el primero: 71.1%; diferencia media 4.4%
144 vencimientos; |futuro − VORX| al vencer: máx. 0.000Las tres cifras de la respuesta conocida del README (63 %, 71 % y 4,4 %) salen exactas, y los 144 vencimientos liquidan al VORX de ese día. La convergencia es la clave de todo lo que sigue: un futuro en contango tiene que bajar hasta el índice o el índice subir hasta él antes del vencimiento. ¿Cuál de los dos se mueve?
Roll yield: ¿converge el futuro o el índice?
El roll diario de un futuro es su base repartida entre los días que le quedan: . Si la base fuera una predicción insesgada del índice, el índice subiría de media lo que dice el roll y el futuro no se movería. Si es una prima, el futuro bajaría hacia el índice y el índice no se movería de forma predecible. La regresión de los cambios del día siguiente sobre el roll, con el primer futuro a 10 días o más y errores robustos a la autocorrelación (Newey-West con 5 retardos):
import statsmodels.api as sm
fu["siguiente"] = fu.groupby("contrato")["precio"].shift(-1)
g = fu[(fu["orden"] == 0) & (fu["dias"] >= 10)].set_index("fecha")
g = g.assign(roll=(g["precio"] - vx.reindex(g.index)) / g["dias"],
d_futuro=g["siguiente"] - g["precio"],
d_vorx=(vx.shift(-1) - vx).reindex(g.index)).dropna()
for y in ("d_futuro", "d_vorx"):
m = sm.OLS(g[y], sm.add_constant(g["roll"])).fit(
cov_type="HAC", cov_kwds={"maxlags": 5})
print(f"{y:9}: coeficiente {m.params['roll']:6.2f}, "
f"t {m.tvalues['roll']:5.1f}, R² {m.rsquared:.3f}")d_futuro : coeficiente -1.56, t -4.3, R² 0.024
d_vorx : coeficiente 0.42, t 1.0, R² 0.001El cambio del futuro tiene un coeficiente de −1,56 sobre el roll (t = −4,3): en contango el futuro baja hacia el índice y en backwardation sube. El cambio del VORX no tiene relación significativa con el roll (t = 1,0). Es lo que Simon y Campasano (2014) encuentran en el VIX real de 2006 a 2011: la base no predice el VIX al contado y sí el cambio de los futuros. Para quien mantiene futuros comprados, el contango es un coste que se paga cada día; para quien los vende, una prima. Los R² son pequeños (un 2,4 % para el futuro) porque la volatilidad diaria de los futuros es mucho mayor que el roll: la prima existe, pero se cobra entre mucho ruido y algún salto.
El índice de futuros a corto plazo y el ETP largo
Un producto que quiera «la volatilidad a 30 días» mantiene una mezcla del primer y del segundo futuro que pasa cada día
un poco de peso del primero al segundo, de modo que el vencimiento medio quede en torno a un mes. Es la construcción
del S&P 500 VIX Short-Term Futures Index, que el folleto del primer ETN sobre él describe como «una posición larga que
rueda a diario en el primer y el segundo futuro mensual»1Nota 1 · Barclays Bank PLC, folleto (free writing prospectus) del iPath S&P 500 VIX Short-Term Futures ETN (VXX), 2 de
diciembre de 2009, en la SEC:
https://www.sec.gov/Archives/edgar/data/312070/000119312509245713/dfwp.htm. Describe el índice como una posición
larga que rueda a diario del primer al segundo futuro mensual del VIX, con vencimiento constante de un mes, y una
comisión anual del 0,89 %.. En los datos, indice_futuros_cp sigue la misma regla:
el peso del primer futuro es la fracción de sesiones del periodo de roll (de un vencimiento al siguiente) que quedan
hasta su vencimiento. Reconstruirlo desde los futuros es la prueba de que se entiende:
etp = pd.read_csv("vol3_etp.csv", parse_dates=["fecha"])
etp = etp.set_index("fecha")
tabla = fu.pivot(index="fecha", columns="vencimiento",
values="precio")
vencs, ses = sorted(fu["vencimiento"].unique()), tabla.index
rend = [0.0]
for t in range(len(ses) - 1):
hoy, man = ses[t], ses[t + 1]
e1 = next(v for v in vencs if v > hoy) # primer futuro
e2 = next(v for v in vencs if v > e1) # segundo
previos = [v for v in vencs if v <= hoy]
e0 = max(previos) if previos else e1 - pd.Timedelta(days=35)
w1 = (((ses > hoy) & (ses <= e1)).sum()
/ ((ses > e0) & (ses <= e1)).sum()) # peso del primero
a0 = w1 * tabla.at[hoy, e1] + (1 - w1) * tabla.at[hoy, e2]
a1 = w1 * tabla.at[man, e1] + (1 - w1) * tabla.at[man, e2]
rend.append(a1 / a0 - 1)
rend = pd.Series(rend, ses)
indice = 100 * (1 + rend).cumprod()
print(f"diferencia máxima con el archivo: "
f"{(indice - etp['indice_futuros_cp']).abs().max():.5f}")
print(f"índice: 100 el {ses[0].date()}, "
f"{indice.iloc[-1]:.2f} el {ses[-1].date()}")diferencia máxima con el archivo: 0.00005
índice: 100 el 2014-01-02, 0.49 el 2025-12-31La diferencia máxima es de cinco cienmilésimas: el redondeo del archivo a cuatro decimales. El índice de futuros cae de 100 a 0,49 en doce años. Es el roll en contango acumulado sesión a sesión: cada día se vende un poco del primer futuro, que ha bajado hacia el índice, y se compra el segundo, más caro.
El ETP largo (lvol, que imita al VXX) suma al índice el tipo a 3 meses de su colateral y resta una comisión del 0,89 %
anual, la que fijaba el folleto del VXX1. Con esa regla se reconstruye también, y el resultado por años es este:
ind = pd.read_csv("opciones3_indice.csv", parse_dates=["fecha"])
tb = ind.set_index("fecha")["tipo_3m"] / 100
largo = [100.0]
for t in range(len(ses) - 1):
largo.append(largo[-1] * (1 + rend.iloc[t + 1]
+ tb.iloc[t] / 252 - 0.0089 / 252))
largo = pd.Series(largo, ses)
print(f"diferencia máxima con lvol: "
f"{(largo - etp['lvol']).abs().max():.5f}")
print(f"total 2014-2025: {largo.iloc[-1] / 100 - 1:.1%}")
anual = etp[["lvol", "ivol"]].resample("YE").last()
anual.loc[pd.Timestamp("2013-12-31")] = 100.0
anual = anual.sort_index().pct_change().iloc[1:]
anual.index = anual.index.year
(100 * anual).round(0).Tdiferencia máxima con lvol: 0.00005
total 2014-2025: -99.4%
fecha 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
lvol -48.0 11.0 -34.0 -57.0 44.0 -85.0 114.0 -75.0 61.0 -61.0 -54.0 -4.0
ivol 45.0 -44.0 10.0 96.0 -91.0 NaN NaN NaN NaN NaN NaN NaNLa figura de la cabecera es esta tabla en el tiempo, en escala logarítmica. El ETP largo pierde un 99,4 % en total, con años de −85 % (2019) y −75 % (2021), los que siguen a una crisis, cuando el VORX baja desde niveles altos y la curva vuelve al contango, y subidas fuertes en los años de crisis (+114 % en 2020). Mantenerlo es pagar un seguro caro; quien lo compra para cubrirse tiene que acertar el momento.
El 5 de febrero de 2018 y el ETP inverso
El ETP inverso diario (ivol, que imita al XIV) da cada día −1 vez el rendimiento del índice de futuros, más el tipo y
menos una comisión del 1,35 %. Mientras la curva está en contango, gana lo que pierde el largo: pasa de 100 a 221. Y
tiene una cláusula de aceleración: si pierde más de un 80 % en un día, se liquida. La de los datos imita la del XIV
real: según el aviso de Credit Suisse a la SEC del 6 de febrero de 2018, el valor indicativo intradía del XIV del 5 de
febrero cayó al 20 % o menos del cierre anterior, lo que constituía un evento de aceleración; el último día de
negociación sería el 20 de febrero y los tenedores cobrarían el valor indicativo de cierre de la fecha de valoración.
dias = pd.concat([vx.rename("vorx"),
f1["precio"].rename("f1"), f2["precio"].rename("f2"),
etp], axis=1).loc["2018-01-31":"2018-02-08"]
dias["rend_indice"] = dias["indice_futuros_cp"].pct_change()
print(f"VORX al final de la muestra: {vx.iloc[-1]}")
dias.round(3)VORX al final de la muestra: 13.74
vorx f1 f2 indice_futuros_cp lvol ivol rend_indice
fecha
2018-01-31 15.96 16.00 16.65 14.401 14.121 201.189 NaN
2018-02-01 17.44 17.15 16.95 15.041 14.748 192.256 0.044
2018-02-02 20.37 19.45 18.05 16.488 16.168 173.754 0.096
2018-02-05 36.78 41.65 31.45 31.479 30.868 15.780 0.909
2018-02-06 37.46 35.10 26.40 26.468 25.955 NaN -0.159
2018-02-07 36.74 34.70 26.45 26.390 25.880 NaN -0.003
2018-02-08 37.04 35.25 26.85 26.795 26.278 NaN 0.015El 2 de febrero el índice de futuros ya sube un 9,6 %. El lunes 5 el VORX pasa de 20,37 a 36,78 y el primer futuro, de 19,45 a 41,65, por encima del propio índice: es la subida plantada del 22 % sobre el modelo. El índice de futuros sube un 90,9 % en un día, el ETP inverso cae de 173,75 a 15,78 y se liquida; desde el día 6 su serie está vacía. El largo, que casi duplica su valor ese día, devuelve una parte el día siguiente, cuando la subida plantada se deshace.
¿Por qué los futuros subirían más que el índice justo ese día? Por el rebalanceo de los propios productos. Un ETP con apalancamiento diario y valor tiene una exposición . Si su índice sube un , su valor pasa a y su exposición vale ; para volver a veces su nuevo valor tiene que operar
Para no opera; para o , : los dos compran después de una subida, y los dos lo hacen al cierre, cuando se fija el precio de su índice.
x = dias.loc["2018-02-05", "rend_indice"]
filas = {L: {"valor_tras_subida": 100 * (1 + L * x),
"compra_de_futuros": 100 * L * (L - 1) * x}
for L in (-1.0, -0.5, 1.0, 1.5, 2.0)}
pd.DataFrame(filas).T.round(1) valor_tras_subida compra_de_futuros
-1.0 9.1 181.8
-0.5 54.5 68.2
1.0 190.9 0.0
1.5 236.4 68.2
2.0 281.8 181.8Fuente Mermaid
flowchart TB
S[Sube la vol] --> F[Suben futuros]
F --> P[Pierden inversos]
P --> R[Recompran]
R --> F
P --> A{Pierde 80 %}
A -- sí --> Q[Se liquida]Por cada 100 de valor antes de la subida, un inverso −1× tiene que recomprar 181,8 de futuros, 20 veces lo que le queda de valor (9,1). Un producto de −0,5× tiene que recomprar 68,2 y sobrevive con 54,5. Es la razón por la que ProShares cambió su SVXY de −1× a −0,5× al cierre del 27 de febrero de 2018, según la propia ficha del fondo. Cuando el tamaño de esos productos es grande frente al volumen de los futuros en la ventana de cierre, la compra empuja el precio, la subida aumenta las pérdidas y obliga a recomprar más. En los datos esa presión está plantada como el 22 % sobre el modelo; en el mercado real su tamaño es un dato que hay que estimar, no suponer.
Estrategias: vender, comprar y filtrar la volatilidad
Con los rendimientos diarios del índice de futuros se pueden comparar las estrategias básicas, todas sobre el nominal (vender 1 de futuros por cada 1 de capital, que queda como colateral; se mide el rendimiento en exceso del colateral). Vender siempre es el ETP inverso sin comisiones y sin cláusula de aceleración; a −0,5×, el SVXY posterior a 2018; y el filtro de contango solo vende cuando, al cierre anterior, el primer futuro está por encima del VORX:
def medidas(x):
x = x.iloc[1:]
eq = (1 + x).cumprod()
mes = (1 + x).resample("ME").prod() - 1
return {"anual": eq.iloc[-1] ** (252 / len(x)) - 1,
"vol": x.std() * np.sqrt(252),
"sharpe": x.mean() / x.std() * np.sqrt(252),
"caida_max": (eq / eq.cummax() - 1).min(),
"peor_dia": x.min(), "peor_mes": mes.min(),
"fecha_peor_dia": str(x.idxmin().date())}
corto = -rend
contango = (f1["precio"] > vx).reindex(ses).astype(float)
estr = {"vender siempre": corto, "vender a -0,5x": 0.5 * corto}
for lag in (1, 2, 3):
estr[f"contango, señal t-{lag}"] = corto * contango.shift(lag)
cambios = contango.shift(1).diff().abs()
estr["contango t-1, coste 0,5 %"] = (corto * contango.shift(1)
- 0.005 * cambios)
print(f"entradas y salidas al año: {cambios.sum() / 12:.0f}")
tab = pd.DataFrame({k: medidas(v.fillna(0)) for k, v in estr.items()}).T
num = tab.columns[:-1]
tab[num] = tab[num].astype(float).round(3)
tabentradas y salidas al año: 33
anual vol sharpe caida_max peor_dia peor_mes fecha_peor_dia
vender siempre -0.071 0.592 0.502 -0.989 -0.921 -0.964 2020-03-09
vender a -0,5x 0.101 0.296 0.502 -0.715 -0.460 -0.628 2020-03-09
contango, señal t-1 0.813 0.314 2.058 -0.433 -0.373 -0.332 2016-06-24
contango, señal t-2 0.784 0.313 2.016 -0.456 -0.373 -0.368 2016-06-24
contango, señal t-3 0.281 0.419 1.022 -0.937 -0.909 -0.923 2018-02-05
contango t-1, coste 0,5 % 0.522 0.315 1.499 -0.506 -0.373 -0.342 2016-06-24Vender siempre da un Sharpe de 0,50 y una caída máxima del 98,9 %: el ETP inverso de antes, sin su liquidación. El peor día es el 2020-03-09 (−92,1 %) y el peor mes, marzo de 2020 (−96,4 %): quien vendía a 1× habría perdido prácticamente todo dos veces en la muestra. A −0,5× la caída máxima sigue siendo del 71,5 %. La venta de volatilidad de futuros es la venta de prima de la lección 3.6.1 con la cola más gruesa todavía: lo que se cobra es el roll, y lo que se arriesga es un salto del 90 % en una sesión.
El filtro de contango con la señal del cierre anterior da un Sharpe de 2,06 y una caída máxima del 43,3 %, con el peor día el 2016-06-24. Es demasiado bueno, y la tabla dice por qué: con la señal de dos sesiones antes apenas cambia, pero con la de tres sesiones antes vende el 2018-02-05, pierde un 90,9 % ese día y su caída máxima pasa al 93,7 %. El filtro funciona en estos datos porque, en los dos grandes saltos del VORX de la muestra, el índice al contado sube uno o dos días antes que los futuros y la curva se invierte justo a tiempo de salir. Es una propiedad de cómo están generados los datos (el VORX se separa de su modelo y la diferencia se disipa en 10 días), no una ley del mercado. Con un coste de 0,5 % del nominal cada vez que la posición se abre o se cierra (unas 33 veces al año), el Sharpe baja a 1,50 y la caída máxima sube al 50,6 %.
La otra cara es comprar volatilidad como seguro. Una cartera que mantiene una parte en el ETP largo y el resto en el índice ORX con dividendos, rebalanceada cada mes:
rt = ind.set_index("fecha")["cierre_rt"]
mens = (pd.concat([rt, etp["lvol"]], axis=1).resample("ME").last()
.pct_change().dropna())
seguro = {}
for w in (0.0, 0.05, 0.10):
p = (1 - w) * mens["cierre_rt"] + w * mens["lvol"]
eq = (1 + p).cumprod()
seguro[f"{w:.0%} en LVOL"] = {
"anual": eq.iloc[-1] ** (12 / len(p)) - 1,
"vol": p.std() * np.sqrt(12),
"caida_max": (eq / eq.cummax() - 1).min(),
"peor_mes": p.min()}
pd.DataFrame(seguro).T.round(3) anual vol caida_max peor_mes
0% en LVOL 0.122 0.187 -0.366 -0.288
5% en LVOL 0.116 0.157 -0.269 -0.269
10% en LVOL 0.106 0.146 -0.249 -0.249Con un 10 % en el ETP largo, la caída máxima de la cartera baja del 36,6 % al 24,9 % y el peor mes, del −28,8 % al −24,9 %. A cambio, la rentabilidad anual cae del 12,2 % al 10,6 %: 1,6 puntos al año durante doce años para recortar la peor caída. El seguro funciona porque se rebalancea cada mes (se vende lo que sube en las crisis) y porque las crisis de la muestra fueron cortas; con una crisis lenta, sin saltos de la volatilidad, el coste se paga igual y la cobertura apenas aparece.
VSTOXX y VIX: lo que se puede comparar
El VVGX de los datos imita al VSTOXX: la volatilidad a 30 días de un índice europeo ficticio con una varianza 1,2 veces la de ORX, rendimientos correlados 0,8 con él y ruido propio. Solo hay índice: ni cadena de opciones ni futuros.
dif = vi["vvgx"] - vi["vorx"]
print(f"correlación de niveles: {vi['vorx'].corr(vi['vvgx']):.3f}; "
f"de cambios diarios: "
f"{vi['vorx'].diff().corr(vi['vvgx'].diff()):.3f}")
print(f"VVGX − VORX: media {dif.mean():.2f}, desv. {dif.std():.2f},"
f" de {dif.min():.2f} a {dif.max():.2f} puntos")
vi[["vorx", "vvgx"]].describe().loc[["mean", "50%", "max"]].round(2)correlación de niveles: 0.992; de cambios diarios: 0.964
VVGX − VORX: media 1.50, desv. 1.22, de -3.89 a 6.97 puntos
vorx vvgx
mean 19.80 21.31
50% 17.66 19.05
max 73.98 72.48El índice europeo cotiza de media 1,5 puntos por encima del de EE. UU., con una correlación de niveles de 0,99. Con un diferencial así se suele plantear un spread de volatilidad: comprar futuros del VSTOXX y vender del VIX cuando el diferencial está bajo, o al revés. Con estos datos no se puede contrastar, por tres razones: no hay futuros del VVGX; los futuros de las dos bolsas vencen en fechas distintas (cada uno 30 días antes del vencimiento de sus opciones) y liquidan con métodos distintos (la SOQ de Cboe frente a la media de 11:00 a 12:00 CET de Eurex); y el multiplicador y la divisa cambian (1.000 USD frente a 100 EUR por punto), así que la cobertura necesita un ratio y deja riesgo de divisa (lección 3.3.3).
Ejercicios
- Calcula un ETP largo de 2× diario sobre el índice de futuros (sin comisión ni tipo) y compáralo con dos veces el rendimiento del índice en todo el periodo. ¿Por qué no coinciden?
Solución
doble = (1 + 2 * rend).cumprod()
print(f"índice en el periodo: {indice.iloc[-1] / 100 - 1:.2%}")
print(f"2x diario: {doble.iloc[-1] - 1:.2%}")
print(f"2x del periodo (imposible por debajo de -100 %): "
f"{2 * (indice.iloc[-1] / 100 - 1):.2%}")
print(f"máximo del 2x diario: {doble.max():.2f} el "
f"{doble.idxmax().date()}")índice en el periodo: -99.51%
2x diario: -100.00%
2x del periodo (imposible por debajo de -100 %): -199.02%
máximo del 2x diario: 1.08 el 2014-04-22El 2× diario queda en prácticamente cero (su máximo, 1,08, fue en abril de 2014). Multiplica por 2 cada rendimiento diario, no el del periodo. Con un índice muy volátil y con tendencia a la baja, el producto de los cae mucho más deprisa que el índice: la pérdida por volatilidad crece con el cuadrado del apalancamiento. Por eso los folletos de estos productos dicen que su objetivo es de un solo día.
- Repite la regresión del roll yield con el segundo futuro (
orden == 1). ¿Es el coeficiente mayor o menor que en el primero?
Solución
g2 = fu[fu["orden"] == 1].set_index("fecha")
g2 = g2.assign(roll=(g2["precio"] - vx.reindex(g2.index))
/ g2["dias"],
d_futuro=g2["siguiente"] - g2["precio"]).dropna()
m2 = sm.OLS(g2["d_futuro"], sm.add_constant(g2["roll"])).fit(
cov_type="HAC", cov_kwds={"maxlags": 5})
print(f"coeficiente {m2.params['roll']:.2f}, "
f"t {m2.tvalues['roll']:.1f}")coeficiente -1.48, t -4.3El coeficiente es parecido (−1,48 frente a −1,56, los dos con t = −4,3): el segundo futuro también baja con su roll. Su base frente al VORX al contado es, aun así, una medida más indirecta, porque le faltan más de 30 días para converger y antes ocupa el lugar del primero; con tan poca diferencia entre los dos coeficientes, los datos no permiten decir que uno sea mayor que el otro.
- Un inversor quiere «comprar el VIX» porque cree que habrá una crisis en algún momento de los próximos tres años y propone mantener un ETP largo de volatilidad. Explica qué le pasará si tiene razón en la crisis pero no en el momento.
Solución
El ETP largo no sigue al VIX: sigue a un índice de futuros que rueda en contango. Mientras la crisis no llega, pierde cada año una fracción grande de su valor (en los datos del curso, entre el 4 % y el 85 % en los años que baja). Si la crisis llega en el tercer año, el ETP sube mucho en porcentaje, pero sobre un valor que ya ha perdido la mayor parte: en los datos, tras perder un 85 % en 2019, el +114 % de 2020 deja el ETP muy por debajo de donde estaba a principios de 2019. La alternativa coherente con su idea es comprar opciones con vencimiento lejano (calls sobre futuros de volatilidad o puts del índice), cuyo coste se conoce al comprarlas, o mantener una parte pequeña rebalanceada como en la cartera de esta lección.
Footnotes
-
Barclays Bank PLC, folleto (free writing prospectus) del iPath S&P 500 VIX Short-Term Futures ETN (VXX), 2 de diciembre de 2009, en la SEC: https://www.sec.gov/Archives/edgar/data/312070/000119312509245713/dfwp.htm. Describe el índice como una posición larga que rueda a diario del primer al segundo futuro mensual del VIX, con vencimiento constante de un mes, y una comisión anual del 0,89 %. ↩ ↩2
Respuesta plegada en cada pregunta
Autoevaluación
¿Por qué no existe un ETP que replique el VIX al contado?
- APorque está prohibido por la SEC
- BPorque el VIX es un cálculo sobre los precios de opciones del S&P 500 a 30 días que no se puede mantener como cartera estática: lo replicable son los futuros, que convergen a él solo al vencer
- CPorque el VIX solo se calcula una vez al día
- DPorque las opciones del S&P 500 no tienen liquidez suficiente
Ver respuesta
Respuesta B. Porque el VIX es un cálculo sobre los precios de opciones del S&P 500 a 30 días que no se puede mantener como cartera estática: lo replicable son los futuros, que convergen a él solo al vencer
El VIX mide la volatilidad esperada a 30 días con una cesta de opciones que cambia cada día (strikes y vencimientos). Los productos cotizados tienen futuros, y un futuro sobre el VIX vale la expectativa del VIX en su vencimiento, no el VIX de hoy.
En los datos, el primer futuro está por encima del VORX el 63 % de las sesiones. ¿Qué le pasa de media a quien mantiene un largo en el primer futuro?
- AGana el roll yield, porque el futuro sube hacia el índice
- BPierde: en contango el futuro tiende a bajar hacia el índice al acercarse el vencimiento, y la regresión de la lección da un coeficiente de −1,56 sobre el roll diario, mientras que el índice no se mueve de forma predecible
- CNada: futuro e índice se mueven igual
- DGana solo si el índice sube
Ver respuesta
Respuesta B. Pierde: en contango el futuro tiende a bajar hacia el índice al acercarse el vencimiento, y la regresión de la lección da un coeficiente de −1,56 sobre el roll diario, mientras que el índice no se mueve de forma predecible
La base predice el cambio del futuro (t = −4,3) y no el del índice (t = 1,0). Es la misma conclusión que Simon y Campasano (2014) sacan del VIX real de 2006 a 2011: la base es sobre todo una prima que se cobra vendiendo futuros en contango.
Un ETP inverso diario (−1×) tiene un valor de 100 y su índice sube un 90,9 % en un día. ¿Cuánto índice tiene que recomprar al cierre para volver a −1×?
- ANada: los inversos no rebalancean
- B9,1, lo que le queda de valor
- C181,8: el corto vale ahora 190,9 y el objetivo es 9,1; recomprar es comprar futuros justo después de la subida
- D90,9
Ver respuesta
Respuesta C. 181,8: el corto vale ahora 190,9 y el objetivo es 9,1; recomprar es comprar futuros justo después de la subida
Con apalancamiento L, la compra de rebalanceo es L·(L − 1)·x por unidad de valor. Con L = −1 y x = 0,909, 2·0,909 = 1,818 veces el valor previo. Los inversos y los apalancados compran después de las subidas, lo que empuja el precio en la misma dirección.
La venta del índice de futuros solo cuando el primer futuro está en contango da un Sharpe de 2,06 en los datos. ¿Qué la invalida como evidencia?
- ANada: el filtro de contango funciona
- BQue con la señal de tres sesiones antes en vez de la de ayer cae un 90,9 % el 2018-02-05 y su caída máxima pasa del 43 % al 94 %: el resultado depende de esquivar por uno o dos días un salto plantado en datos sintéticos
- CQue el Sharpe se calcula con rendimientos diarios
- DQue no incluye el dividendo del índice
Ver respuesta
Respuesta B. Que con la señal de tres sesiones antes en vez de la de ayer cae un 90,9 % el 2018-02-05 y su caída máxima pasa del 43 % al 94 %: el resultado depende de esquivar por uno o dos días un salto plantado en datos sintéticos
Un resultado que cambia de forma radical con uno o dos días de retraso está ajustado a unos pocos episodios. En los datos sintéticos, el VORX sube antes de los saltos y la curva se invierte un día antes; en un mercado real nada garantiza ese aviso, y la venta de volatilidad sigue siendo corta de cola.
¿Qué permiten hacer con el VSTOXX los datos del curso?
- ABacktestear sus futuros, como los del VORX
- BComparar su nivel con el del VORX (el índice VVGX), pero no backtestear sus futuros: el archivo solo trae el índice
- CNada, no hay datos europeos
- DReconstruir el VSTOXX desde opciones del Euro Stoxx 50
Ver respuesta
Respuesta B. Comparar su nivel con el del VORX (el índice VVGX), pero no backtestear sus futuros: el archivo solo trae el índice
vol3_indices.csvtraevvgx, la volatilidad a 30 días de un índice europeo ficticio, sin cadena ni futuros. Las reglas de los futuros del VSTOXX (Eurex, FVS) se pueden explicar, pero no contrastar con estos datos.
Ideas clave
- El VIX y el VSTOXX se calculan con opciones a 30 días y no se pueden mantener en cartera; se negocian futuros que liquidan al índice en su vencimiento (Cboe: Special Opening Quotation; Eurex: media de 11:00 a 12:00 CET).
- La curva de futuros está en contango casi siempre (el 63 % de las sesiones con el primer futuro sobre el VORX, el 71 % con el segundo sobre el primero) y se invierte en las crisis; la base predice el cambio del futuro, no el del índice.
- Un índice que rueda a diario del primer al segundo futuro pierde en contango: el ETP largo cae un 99,4 % de 2014 a 2025 y solo gana en las crisis.
- El ETP inverso diario gana mientras dura y pierde un 90,9 % el 2018-02-05: los productos inversos y apalancados tienen que comprar después de las subidas, y su cláusula de aceleración los liquida.
- Vender volatilidad tiene un Sharpe de 0,50 con una caída máxima del 98,9 %; los filtros de contango mejoran mucho el resultado en estos datos, pero dependen de esquivar por uno o dos días los saltos.
Recursos
Documentación
- Cboe: metodología del Cboe Volatility Index (VIX), incluida la liquidación de los derivados (SOQ)
- Cboe Futures Exchange: reglamento (capítulo 12, especificaciones de los futuros VX)
- Eurex: especificaciones de los futuros sobre el VSTOXX (FVS)
- Credit Suisse AG (SEC, formulario 6-K, 6 de febrero de 2018): aceleración de los ETN XIV
- ProShares: SVXY, objetivo de −0,5× del S&P 500 VIX Short-Term Futures Index desde el 27 de febrero de 2018