---
title: "3.6.2 Delta hedging, gamma scalping y dispersión"
description: "Qué gana una opción con la delta cubierta: P&L de gamma frente a realizada e implícita, frecuencia de cobertura, estructura temporal, skew y dispersión."
url: "https://pythonparatrading.com/curso-python-trading/nivel-3/delta-hedging-gamma-scalping-y-dispersion/"
lang: "es"
image: "https://pythonparatrading.com/og/curso-python-trading/nivel-3/delta-hedging-gamma-scalping-y-dispersion.png"
---

# 3.6.2 · Delta hedging, gamma scalping y dispersión

> Una opción con la delta cubierta deja de ser una apuesta sobre la dirección y pasa a ser una apuesta sobre la volatilidad: gana si el mercado se mueve más de lo que el precio de la opción descontaba. Esta lección lo mide en 143 straddles cubiertos de los datos del curso, separa el P&L en gamma, vega y resto, y prueba cuánto importa la frecuencia de la cobertura.

- Curso: [Nivel 3: Derivados: futuros, spreads, forex y opciones](https://pythonparatrading.com/curso-python-trading/nivel-3/)
- Módulo: 3.6 · Estrategias sistemáticas de volatilidad y opciones
- Duración: 75 min
- Requisitos: [3.4.3 · Griegas: delta, gamma, vega, theta, rho, vanna, volga y charm](https://pythonparatrading.com/curso-python-trading/nivel-3/griegas-de-primer-y-segundo-orden/), [3.4.6 · Volatilidad realizada frente a implícita; prima de riesgo de volatilidad; VIX y VSTOXX](https://pythonparatrading.com/curso-python-trading/nivel-3/volatilidad-realizada-implicita-y-vix/), [3.6.1 · Venta sistemática de prima: put-write, strangles y su riesgo de cola](https://pythonparatrading.com/curso-python-trading/nivel-3/venta-sistematica-de-prima-y-riesgo-de-cola/)

## Al terminar esta lección

- Derivar y comprobar en los datos la descomposición del P&L de una opción con la delta cubierta: ½·Γ·S²·(r² − σ²·Δt) más el término de vega.
- Explicar por qué el resultado depende del camino (dónde estaba el precio cuando se movió) y no solo de la volatilidad realizada media.
- Medir el efecto de la frecuencia de cobertura y de las bandas de delta sobre la media, la dispersión y el coste, con una simulación de respuesta conocida y con los datos.
- Plantear operaciones de estructura temporal, de skew y de dispersión, y decir qué parte se puede contrastar con estos datos y cuál no.

## Qué queda al cubrir la delta

Una call comprada gana si el subyacente sube. Si al mismo tiempo se vende la cantidad de subyacente que dice su delta,
el primer orden del movimiento desaparece: lo que gana la call por una subida pequeña lo pierde la venta. Lo que queda
es el segundo orden, la curvatura. La lección 3.4.3 hace la atribución completa del P&L de una put ATM en delta,
gamma, vega y theta; aquí basta su resultado para la cartera cubierta (la opción y la posición $-\Delta$ en el
subyacente). Con el desarrollo de Taylor del valor de la opción $V(S, \sigma, t)$, el P&L de un día es

$$
d\Pi \approx \underbrace{\tfrac12 \Gamma\, (dS)^2 + \Theta\, dt}_{\text{gamma y theta}}
+ \underbrace{\mathcal{V}\, d\sigma}_{\text{vega}} + \dots
$$

En Black-Scholes (sin tipos ni dividendos, para ver la idea) la theta y la gamma están atadas por la ecuación de
valoración: $\Theta = -\tfrac12 \Gamma S^2 \sigma_i^2$, con $\sigma_i$ la volatilidad implícita con la que se valora la
opción. Sustituyendo y llamando $r_t = dS/S$ al rendimiento del día:

$$
d\Pi \approx \tfrac12 \Gamma S^2 \left(r_t^2 - \sigma_i^2\, \Delta t\right) + \mathcal{V}\, d\sigma_i .
$$

Es la fórmula central de la lección. El primer término dice que una opción comprada y cubierta gana el día en que el
movimiento al cuadrado supera al que descontaba la implícita ($\sigma_i^2 \Delta t$) y pierde el resto de días, cuando
paga la theta sin compensación. Sumado sobre la vida de la opción, el resultado es la diferencia entre la varianza
realizada y la implícita **ponderada por $\Gamma S^2$** de cada día. El segundo término es el efecto de que la propia
implícita cambie (lección 3.4.3). Bakshi y Kapadia (2003) usan esta misma descomposición para medir la prima de
riesgo de volatilidad en opciones reales del S&P 500: las ganancias de las opciones compradas y cubiertas son
negativas de media.

```mermaid
flowchart TB
  A[Compra straddle] --> B[Calcula delta]
  B --> C[Vende delta]
  C --> D{Se mueve S}
  D -- mucho --> E[Gana gamma]
  D -- poco --> F[Paga theta]
  E --> G[Rehace delta]
  F --> G
  G --> B
```

El bucle es lo que en las mesas se llama **gamma scalping**: con gamma positiva, la delta sube cuando el precio sube
y baja cuando baja, así que rehacer la cobertura obliga a vender después de las subidas y a comprar después de las
bajadas. Cada vuelta del bucle captura un trozo del movimiento. La theta es el precio de ese privilegio.

Convenciones de esta lección: precios por unidad de índice (el contrato real multiplica por 100 USD), $T$ en días
naturales / 365 (las opciones de ORX vencen al cierre), tipo y rentabilidad por dividendo continuos, volatilidad anual
en tanto por uno, vega por unidad de volatilidad (1,00 = 100 puntos; dividida entre 100, por punto) y P&L de cada
operación en % del índice al abrirla.

## Los datos: un straddle ATM cada mes

Los datos son los del índice ficticio ORX, que imita al S&P 500 (lección 3.4.6): `opciones3_indice.csv` con el cierre,
la curva de tipos y la rentabilidad por dividendo, y `opciones3_cadena.parquet`, la cadena diaria con los tres
vencimientos mensuales más cercanos. Son datos sintéticos con una prima de riesgo de varianza plantada: la superficie
del modelo cotiza la varianza 1,30 veces por encima de la esperada en calma y 1,00 en el estrés máximo
(`public/curso/datos/nivel-3/README.md`). Esa es la respuesta conocida que la lección tiene que recuperar.

```python
import numpy as np
import pandas as pd
from scipy.special import ndtr
from scipy.stats import norm

ind = pd.read_csv("opciones3_indice.csv", parse_dates=["fecha"])
ind = ind.set_index("fecha")
cad = pd.read_parquet("opciones3_cadena.parquet")
cad["medio"] = (cad["bid"] + cad["ask"]) / 2
S = ind["cierre"]
r = ind["tipo_1m"] / 100                 # continuo, tanto por uno
q = ind["rentabilidad_dividendo"] / 100  # continuo
print(len(cad), "filas,", cad["fecha"].nunique(), "sesiones")
dia = cad[(cad["fecha"] == "2020-02-21")
          & (cad["vencimiento"] == "2020-03-20")]
k = dia.loc[(dia["strike"] - S["2020-02-21"]).abs().idxmin(),
            "strike"]
print("S =", S["2020-02-21"], " strike ATM =", k)
dia[dia["strike"] == k][["tipo", "bid", "ask", "iv_modelo"]]
```
```output
544548 filas, 3017 sesiones
S = 2978.34  strike ATM = 3000.0
       tipo   bid   ask  iv_modelo
275893    C  28.1  28.5     0.1191
275911    P  52.4  52.9     0.1191
```

El 21 de febrero de 2020 el índice cerraba en 2.978,34 y el strike más cercano era 3.000. La call y la put de ese
strike, con 28 días, tienen la misma `iv_modelo`, la volatilidad implícita verdadera del modelo, sin el ruido de las
cotizaciones: un 11,9 %. En unos datos reales no existe esa columna y la implícita se calcula desde el medio con los
métodos de la lección 3.4.4; aquí se usa para que el error de la implícita no se mezcle con lo que se quiere medir.

Las griegas, con el forward $F = S e^{(r-q)T}$, salen de las fórmulas de Black-Scholes-Merton de la lección 3.4.2. Antes
de usarlas, una comprobación contra QuantLib con la call de ese día:

```python
import QuantLib as ql

def bs(tipo, S, K, T, iv, r, q):
    """Precio, delta, gamma y vega (por unidad de volatilidad)."""
    F = S * np.exp((r - q) * T)
    sd = iv * np.sqrt(T)
    d1 = (np.log(F / K) + 0.5 * sd * sd) / sd
    df = np.exp(-r * T)
    call = df * (F * ndtr(d1) - K * ndtr(d1 - sd))
    precio = np.where(tipo == "C", call, call - df * (F - K))
    delta = np.exp(-q * T) * (ndtr(d1) - (tipo == "P"))
    gamma = np.exp(-q * T) * norm.pdf(d1) / (S * sd)
    vega = S * np.exp(-q * T) * norm.pdf(d1) * np.sqrt(T)
    return precio, delta, gamma, vega

f0 = pd.Timestamp("2020-02-21")
mio = bs("C", S[f0], k, 28 / 365, 0.1191, r[f0], q[f0])

hoy = ql.Date(21, 2, 2020)
ql.Settings.instance().evaluationDate = hoy
dc = ql.Actual365Fixed()
curva = lambda x: ql.YieldTermStructureHandle(
    ql.FlatForward(hoy, float(x), dc))
vol = ql.BlackVolTermStructureHandle(
    ql.BlackConstantVol(hoy, ql.NullCalendar(), 0.1191, dc))
proc = ql.BlackScholesMertonProcess(
    ql.QuoteHandle(ql.SimpleQuote(float(S[f0]))),
    curva(q[f0]), curva(r[f0]), vol)
op = ql.EuropeanOption(ql.PlainVanillaPayoff(ql.Option.Call, k),
                       ql.EuropeanExercise(hoy + 28))
op.setPricingEngine(ql.AnalyticEuropeanEngine(proc))
pd.DataFrame({"propio": [float(x) for x in mio],
              "QuantLib": [op.NPV(), op.delta(), op.gamma(),
                           op.vega()]},
             index=["precio", "delta", "gamma", "vega"]).round(6)
```
```output
            propio    QuantLib
precio   28.323279   28.323279
delta     0.408275    0.408275
gamma     0.003949    0.003949
vega    320.040712  320.040712
```

Coinciden en las seis cifras. La vega de 320,0 es por unidad de volatilidad: un punto (0,01) mueve la call 3,20 puntos
del índice, 320 USD por contrato.

La operación es la de la tabla de realismo del README: el día de cada vencimiento mensual se abre un straddle ATM del
vencimiento siguiente con al menos 20 días, se cubre la delta al cierre de cada sesión y se liquida al vencimiento por
su valor intrínseco. La primera operación entra el 2 de enero de 2014 y cada una de las siguientes, el día en que
vence la anterior; salen 143:

```python
vencs = sorted(cad["vencimiento"].unique())
fechas = S.index
con_cadena = set(cad["fecha"])
ops, j = [], 0
while True:
    f = fechas[j]
    v = next((x for x in vencs if (x - f).days >= 20), None)
    if v is None or v > fechas[-1]:
        break
    if f not in con_cadena:
        j += 1
        continue
    sub = cad[(cad["fecha"] == f) & (cad["vencimiento"] == v)]
    kk = sub.loc[(sub["strike"] - S[f]).abs().idxmin(), "strike"]
    for d in fechas[(fechas >= f) & (fechas <= v)]:
        ops.append((f, v, kk, d))
    j = fechas.get_loc(v)      # la siguiente entra al vencer esta

pan = pd.DataFrame(ops, columns=["entrada", "vencimiento",
                                 "strike", "fecha"])
pan["op"] = pan.groupby("entrada").ngroup()
pc = cad.pivot_table(index=["fecha", "vencimiento", "strike"],
                     columns="tipo", values=["medio", "iv_modelo"])
pc.columns = [f"{a}_{b}" for a, b in pc.columns]
pan = pan.merge(pc.reset_index(), how="left",
                on=["fecha", "vencimiento", "strike"])
for col, serie in (("S", S), ("r", r), ("q", q)):
    pan[col] = serie.reindex(pan["fecha"]).to_numpy()
pan["T"] = (pan["vencimiento"] - pan["fecha"]).dt.days / 365
print(pan["op"].nunique(), "operaciones,", len(pan), "filas")
print("sin cotización:", pan["medio_C"].isna().sum(),
      "filas (los días de vencimiento y el 2019-07-23)")
```
```output
143 operaciones, 3153 filas
sin cotización: 144 filas (los días de vencimiento y el 2019-07-23)
```

## Primero, la respuesta conocida

El README da el resultado de la versión vendida de esta operación (cobro al medio, delta de Black-Scholes con
`iv_modelo`, caja al tipo a 1 mes y dividendos de la cobertura): 143 operaciones, P&L medio del 0,44 % del índice,
positivo en el 71 % y peor operación de −11,8 %, la que entra el 2020-02-21. Reproducirlo es la prueba de que el panel
y las griegas están bien:

```python
def vendido_cubierto(g):
    g = g.reset_index(drop=True)
    kk, s0 = g["strike"][0], g["S"][0]
    caja, h = g["medio_C"][0] + g["medio_P"][0], 0.0
    for t in range(len(g) - 1):
        if np.isfinite(g["iv_modelo_C"][t]):  # hay cadena
            dl = sum(bs(tp, g["S"][t], kk, g["T"][t],
                        g[f"iv_modelo_{tp}"][t], g["r"][t],
                        g["q"][t])[1] for tp in ("C", "P"))
            caja -= (dl - h) * g["S"][t]   # compra la delta
            h = dl
        caja += h * g["S"][t] * g["q"][t] / 252   # dividendos
        caja *= np.exp(g["r"][t] / 252)           # caja al 1 m
    s_fin = g["S"].iloc[-1]
    caja += h * s_fin - abs(s_fin - kk)           # liquidación
    return 100 * caja / s0

corto = pan.groupby("op").apply(vendido_cubierto)
entradas = pan.groupby("op")["entrada"].first()
print(f"{len(corto)} operaciones; media {corto.mean():.2f} %; "
      f"positivas {(corto > 0).mean():.0%}")
print(f"peor {corto.min():.1f} % (entrada "
      f"{entradas[corto.idxmin()].date()})")
```
```output
143 operaciones; media 0.44 %; positivas 71%
peor -11.8 % (entrada 2020-02-21)
```

Las cuatro cifras coinciden con el README. Vender el straddle y cubrirlo gana de media, y gana casi tres de cada
cuatro meses. La peor operación borra de un golpe lo que ganan 27 operaciones medias: es la forma de la venta de prima
de la lección 3.6.1, ahora con la dirección neutralizada. Lo que queda en el resultado es la diferencia entre la
volatilidad que se cobró y la que hubo.

## La descomposición del P&L, operación a operación

A partir de aquí la lección mira el lado comprado, el del gamma scalper, y sin caja ni dividendos (suman menos de
0,01 puntos por operación) para que cada término se vea limpio. Para cada día se calcula el P&L real (cambio del
medio del straddle menos la delta por el cambio del índice; el último día, el valor intrínseco) y los dos términos de
la fórmula: el de gamma, $\tfrac12 \Gamma (\Delta S^2 - S^2 \sigma_i^2 \Delta t)$, con $\Delta t$ en días naturales
entre sesiones (el fin de semana cuenta tres días de theta), y el de vega, $\mathcal{V} \Delta \sigma_i$ con la
implícita del mismo strike.

```python
p = pan.dropna(subset=["medio_C"]).copy()
p["V"] = p["medio_C"] + p["medio_P"]
p["iv"] = p["iv_modelo_C"]          # misma en la call y la put
args = [p[c].to_numpy() for c in ("S", "strike", "T", "iv",
                                  "r", "q")]
gc, gp = bs("C", *args), bs("P", *args)
p["delta"], p["gamma"] = gc[1] + gp[1], gc[2] + gp[2]
p["vega"] = gc[3] + gp[3]
fin = pan[pan["fecha"] == pan["vencimiento"]].copy()
fin["V"] = (fin["S"] - fin["strike"]).abs()   # intrínseco
a = (pd.concat([p, fin]).sort_values(["op", "fecha"])
     .reset_index(drop=True))
sig = a.groupby("op").shift(-1)       # la sesión siguiente
dS = sig["S"] - a["S"]
dt = (sig["fecha"] - a["fecha"]).dt.days / 365
a["real"] = (sig["V"] - a["V"]) - a["delta"] * dS
a["gamma_pnl"] = 0.5 * a["gamma"] * (dS**2
                                     - a["S"]**2 * a["iv"]**2 * dt)
a["vega_pnl"] = (a["vega"] * (sig["iv"] - a["iv"])).fillna(0)
dias = a.dropna(subset=["real"])    # sin la fila del vencimiento

s0 = pan.groupby("op")["S"].first()
por = (dias.groupby("op")[["real", "gamma_pnl", "vega_pnl"]].sum()
       .div(s0, axis=0) * 100)
por["resto"] = por["real"] - por["gamma_pnl"] - por["vega_pnl"]
print(por.describe().loc[["mean", "std", "min", "max"]].round(2))
c1 = por["real"].corr(por["gamma_pnl"])
c2 = por["real"].corr(por["gamma_pnl"] + por["vega_pnl"])
print(f"correlación con el real: gamma {c1:.2f}; "
      f"gamma + vega {c2:.2f}")
```
```output
       real  gamma_pnl  vega_pnl  resto
mean  -0.45      -0.64      0.35  -0.15
std    1.66       1.43      0.98   0.45
min   -3.46      -3.32     -1.81  -2.55
max   11.72       9.62      5.34   2.09
correlación con el real: gamma 0.89; gamma + vega 0.97
```

La figura de la cabecera es esta tabla acumulada operación a operación: el P&L real y el término de gamma bajan casi
en paralelo, mes a mes, y suben de golpe en las crisis. El salto mayor es el del straddle comprado el 2020-02-21:
11,7 puntos de P&L, de los que 9,6 los explica la gamma. Al final de la muestra el real acumula −64,3 puntos (suma
simple de las 143 operaciones) y el término de gamma, −92,1; la distancia entre las dos líneas es, sobre todo, el
término de vega.

Tres lecturas de la tabla:

- **La media del término de gamma es negativa** (−0,64 % por operación). Es la prima de riesgo de varianza plantada:
  la implícita suele estar por encima de la realizada, y quien compra la opción paga más theta de la que recupera con
  los movimientos. El P&L real medio, −0,45 %, es el espejo del +0,44 % del vendido (sin la caja y los dividendos).
- **El término de vega no es ruido.** Su media es positiva (+0,35 %) por un efecto de la sonrisa: la implícita de un
  strike fijo sube cuando el índice se aleja de él hacia arriba (el strike queda por debajo del dinero, en la zona
  cara del skew), y en una muestra con el índice al alza eso pasa más a menudo. Con la vega, la correlación con el
  real sube a 0,97.
- **El resto** recoge los términos de orden superior (vanna y volga, lección 3.4.3), el ruido de las cotizaciones
  alrededor del medio y el error de cubrir solo al cierre. Su media es de −0,15 puntos y su desviación típica, 0,45;
  en alguna operación llega a 2,5 puntos.

<aside class="callout" data-kind="nota">

En unos datos reales la columna `iv_modelo` no existe. Si la implícita se calcula desde el medio de cada día, su error
se cuela en la delta (se cubre con la delta equivocada) y en el término de vega (la implícita «cambia» por ruido). La
descomposición funciona igual, pero el resto crece. La lección 3.6.4 trata el problema de las cotizaciones.

</aside>

## Realizada frente a implícita: el camino importa

La versión de bolsillo de la fórmula dice que el P&L es proporcional a $\sigma_R^2 - \sigma_i^2$, la diferencia entre
la varianza realizada en la vida de la opción y la implícita al comprarla. Es una buena primera aproximación, pero
supone una gamma constante, y la gamma no lo es: es máxima en el dinero y crece al acercarse el vencimiento. El mismo
movimiento del 2 % vale mucho más la última semana y en el strike que el primer día y con el índice lejos.

```python
lr = np.log(S).diff()
filas = []
for o, g in pan.groupby("op"):
    f, v = g["entrada"].iloc[0], g["vencimiento"].iloc[0]
    rr = lr.loc[f:v].iloc[1:]
    rv = np.sqrt((rr**2).sum() / ((v - f).days / 365))
    filas.append((f.date(), g["iv_modelo_C"].iloc[0], rv))
e = pd.DataFrame(filas, columns=["entrada", "iv0", "rv"])
e["pnl"] = por["real"].to_numpy()
e["dif_var"] = e["rv"]**2 - e["iv0"]**2
print(f"realizada > implícita en el {(e.rv > e.iv0).mean():.0%}"
      f" de las operaciones")
print(f"correlación P&L con rv² − iv²: "
      f"{e['pnl'].corr(e['dif_var']):.2f}")
e.sort_values("pnl").iloc[[0, 1, 2, -3, -2, -1]].round(3)
```
```output
realizada > implícita en el 23% de las operaciones
correlación P&L con rv² − iv²: 0.81
        entrada    iv0     rv     pnl  dif_var
81   2020-10-16  0.242  0.123  -3.460   -0.044
84   2021-01-15  0.222  0.116  -3.229   -0.036
83   2020-12-18  0.253  0.125  -2.707   -0.049
29   2016-06-17  0.132  0.271   3.290    0.056
134  2025-03-21  0.228  0.518   7.617    0.216
73   2020-02-21  0.119  0.857  11.719    0.720
```

La realizada supera a la implícita solo en el 23 % de las operaciones, y la correlación del P&L con la diferencia de
varianzas del mes es de 0,81, menos que los 0,89 del término de gamma diario. La tabla enseña los dos extremos. Las
tres peores operaciones del comprador son de finales de 2020 y principios de 2021: se compró con implícitas del 22 al
25 % tras la crisis y el mercado se movió un 12 %. Las mejores son las crisis: la entrada del 2020-02-21 se compró al
11,9 % y el índice se movió al 86 % anualizado (+11,7 %); la del 2025-03-21 se compró al 22,8 % y la realizada fue
del 51,8 % (+7,6 %). Lo que gana el comprador depende de la distancia entre las dos, y en la mayoría de los meses esa
distancia es negativa.

## Frecuencia de cobertura: lo que se sabe y lo que miden los datos

¿Cada cuánto hay que rehacer la delta? La fórmula sale de cubrir en tiempo continuo; en la práctica se cubre de vez en
cuando y cada cobertura cuesta horquilla. Para separar las dos cosas, primero una simulación con la respuesta conocida:
un paseo lognormal con la volatilidad realizada **igual** a la implícita (20 %), una call ATM a 28 días vendida a su
precio de Black-Scholes y cubierta $N$ veces en su vida. Con la volatilidad bien estimada, el valor esperado del
resultado es 0 sea cual sea $N$; lo que cambia es su dispersión:

```python
rng = np.random.default_rng(362)
S0, K0, T0, sg, n_tray, pasos = 100.0, 100.0, 28 / 365, 0.20, 4000, 160

def call_bs(s, t):
    t = np.maximum(t, 1e-12)
    sd = sg * np.sqrt(t)
    d1 = (np.log(s / K0) + 0.5 * sd * sd) / sd
    return s * ndtr(d1) - K0 * ndtr(d1 - sd), ndtr(d1)

prima = call_bs(S0, T0)[0]
dtp = T0 / pasos
z = rng.standard_normal((n_tray, pasos))
cam = S0 * np.exp(np.cumsum(-0.5 * sg**2 * dtp
                            + sg * np.sqrt(dtp) * z, axis=1))
cam = np.c_[np.full(n_tray, S0), cam]
sim = []
for N in [1, 5, 20, 80, 160]:
    i = np.arange(0, pasos + 1, pasos // N)
    s_, t_ = cam[:, i], T0 - i * dtp
    d_ = call_bs(s_[:, :-1], t_[:-1])[1]
    pnl = (prima + (d_ * np.diff(s_, axis=1)).sum(axis=1)
           - np.maximum(cam[:, -1] - K0, 0))
    sim.append((N, pnl.mean(), pnl.std(), pnl.std() * np.sqrt(N)))
sim = pd.DataFrame(sim, columns=["coberturas", "media", "desv",
                                "desv_x_raizN"])
sim = sim.set_index("coberturas")
print(f"prima de la call: {prima:.3f}")
sim.round(3)
```
```output
prima de la call: 2.210
            media   desv  desv_x_raizN
coberturas
1           0.020  1.657         1.657
5           0.016  0.814         1.820
20          0.011  0.428         1.916
80          0.004  0.212         1.899
160         0.001  0.149         1.890
```

La media queda en torno a cero en todas las filas (entre +0,001 y +0,02 puntos sobre una prima de 2,21: error de muestreo con
4.000 caminos), y la desviación típica cae con $1/\sqrt{N}$: la última columna, la desviación por
$\sqrt N$, se mantiene cerca de 1,7-1,9. Pasar de 5 a 80 coberturas (16 veces más) divide la dispersión por 4. Cada
error de cobertura de un intervalo es $\tfrac12 \Gamma S^2 \sigma^2 \Delta t\,(Z^2 - 1)$, con varianza proporcional a
$\Delta t^2$; sumados $N$ intervalos independientes de longitud $T/N$, la varianza total queda en $N (T/N)^2 \propto 1/N$.

*Fig. — Simulación con la volatilidad realizada igual a la implícita (20 %): desviación típica del P&L de una call ATM a 28 días vendida y cubierta N veces, frente a la recta 1/√N (4.000 caminos).* Escala logarítmica en los dos ejes. Cinco puntos que bajan casi en línea recta: 1,66 con una cobertura, 0,81 con 5, 0,43 con 20, 0,21 con 80 (destacado) y 0,15 con 160, pegados a una recta discontinua de pendiente −1/2. La media del P&L es casi cero en todos los casos.

En los datos solo hay cierres diarios, así que la frecuencia máxima es una vez al día: lo que pase dentro de la sesión
no se puede medir aquí. Sí se pueden comparar coberturas menos frecuentes y **bandas** de delta (rehacer la cobertura
solo cuando la delta de la cartera se aleja más de un umbral):

```python
def comprado(g, cada=1, banda=None, coste=0.0):
    """Straddle comprado; vende la delta cada `cada` sesiones o
    cuando se aleja más de `banda`. `coste`: fracción del nominal
    negociado en cada cobertura."""
    s, val, dl = (g[c].to_numpy() for c in ("S", "V", "delta"))
    h, pnl, n, cst = 0.0, -val[0], 0, 0.0
    for t in range(len(s) - 1):
        if np.isfinite(dl[t]):
            obj = -dl[t]
            toca = (t % cada == 0) if banda is None \
                else abs(obj - h) > banda
            if toca:
                cst += abs(obj - h) * s[t] * coste
                h, n = obj, n + 1
        pnl += h * (s[t + 1] - s[t])
    return 100 * (pnl + val[-1] - cst) / s[0], n

def resumen(**kw):
    res = [comprado(g, **kw) for _, g in a.groupby("op")]
    x = np.array([v for v, _ in res])
    return {"media": x.mean(), "desv": x.std(),
            "coberturas": np.median([n for _, n in res])}

reglas = {"cada sesión": {}, "cada 2": {"cada": 2},
          "cada 5": {"cada": 5}, "cada 10": {"cada": 10},
          "solo al abrir": {"cada": 10_000},
          "banda 0,05": {"banda": 0.05}, "banda 0,10": {"banda": 0.1},
          "banda 0,20": {"banda": 0.2}}
pd.DataFrame({k: resumen(**v) for k, v in reglas.items()}).T.round(2)
```
```output
               media  desv  coberturas
cada sesión    -0.45  1.66        20.0
cada 2         -0.38  1.91        10.0
cada 5         -0.17  3.06         4.0
cada 10        -0.17  3.50         2.0
solo al abrir  -0.03  3.63         1.0
banda 0,05     -0.44  1.67        14.0
banda 0,10     -0.43  1.75         9.0
banda 0,20     -0.41  1.83         5.0
```

La desviación típica sube al cubrir menos: 1,66 puntos con la cobertura diaria, 3,06 cada cinco sesiones y 3,63 si
la delta solo se cubre al abrir. La media también cambia (−0,45 % diaria, −0,17 % cada cinco, −0,03 % sin
rehacer), y es tentador leerlo como que cubrir menos «es mejor». No lo es: cubrir menos deja exposición a la
dirección del índice, y en una muestra en la que el índice sube un 12,5 % al año esa exposición ha sumado. Es una
apuesta direccional escondida, no una mejora de la cobertura. Las bandas sí son una mejora: con un umbral de 0,20 de
delta la desviación típica es 1,83, casi la de la cobertura diaria, con 5 coberturas por operación en lugar de 20.

El coste completa la cuenta. Con la cobertura hecha en un futuro del índice o en una cesta, cada rebalanceo paga horquilla
y comisión sobre el nominal negociado. Las cifras que siguen son supuestos (1 y 5 puntos básicos del nominal
negociado), no precios de ningún mercado:

```python
cost = {f"{k} · {c * 1e4:.0f} pb": resumen(coste=c, **v)
        for c in (0.0001, 0.0005)
        for k, v in (("cada sesión", {}),
                     ("banda 0,20", {"banda": 0.2}))}
pd.DataFrame(cost).T.round(2)
```
```output
                    media  desv  coberturas
cada sesión · 1 pb  -0.47  1.65        20.0
banda 0,20 · 1 pb   -0.42  1.83         5.0
cada sesión · 5 pb  -0.57  1.65        20.0
banda 0,20 · 5 pb   -0.49  1.82         5.0
```

Con un coste de 1 pb, la cobertura diaria resta unos 2-3 pb por operación; con 5 pb, más de una décima. Leland (1985)
estudió la réplica con costes proporcionales y revisión a intervalos fijos: acortar el intervalo reduce el error de
réplica pero dispara el coste, y propuso valorar la opción con una volatilidad ajustada por esos costes. En un straddle del índice a un mes, con horquillas
de futuros de una fracción de punto básico, el coste importa poco; en opciones sobre acciones poco líquidas o con
coberturas intradía, mucho.

## Gamma scalping: cuándo gana el comprador

El gamma scalper compra la opción y vive de rehacer la cobertura. La tabla de la descomposición ya dio la respuesta
media: pierde, porque paga la prima de riesgo de varianza. Gana cuando la realizada supera a la implícita, y eso
ocurre casi solo en los inicios de las crisis. Por terciles del VORX (el índice de volatilidad de ORX, que imita al
VIX) el día de entrada:

```python
vx = pd.read_csv("vol3_indices.csv", parse_dates=["fecha"])
vx = vx.set_index("fecha")["vorx"]
e["vorx"] = vx.reindex(pd.to_datetime(e["entrada"])).to_numpy()
e["tercil"] = pd.qcut(e["vorx"], 3, labels=["bajo", "medio", "alto"])
e.groupby("tercil", observed=True)["pnl"].agg(
    ["count", "mean", "median",
     ("positivas", lambda s: (s > 0).mean())]).round(2)
```
```output
        count  mean  median  positivas
tercil
bajo       48  0.11   -0.30       0.38
medio      47 -0.83   -0.88       0.17
alto       48 -0.64   -0.96       0.27
```

Con el VORX bajo al entrar, la media es positiva (+0,11 %) pero la mediana es negativa (−0,30 %) y solo gana el 38 %
de las veces: la media la levanta la operación del 2020-02-21, comprada con el VORX en 15. Con el VORX medio o alto, el
comprador pierde de media y gana en una de cada cuatro o cinco. Es el perfil de un seguro: pérdidas pequeñas casi
todos los meses y una ganancia grande muy de vez en cuando, que llega cuando la volatilidad estaba barata y el
mercado se rompe.

En el 2020-02-21, el gamma scalping se ve a la vista. El strike (3.000) estaba algo por encima del índice, así que
el straddle empezó con delta negativa y la cobertura era una pequeña compra de índice. Al caer el índice en marzo, la
delta del straddle llegó a −0,89 y la cobertura pasó a ser una compra de casi 0,9 unidades de índice, rehecha cada
cierre: cada día de movimiento fuerte la posición gana por la curvatura y, al rehacer la cobertura, compra después de
las caídas y vende después de los rebotes. Los cuatro mejores días (el P&L de cada fila es el del intervalo que
empieza ese día):

```python
d0 = dias[dias["op"] == e["pnl"].idxmax()]
dd = d0.set_index("fecha")[["S", "delta", "gamma_pnl", "real"]]
dd[["gamma_pnl", "real"]] *= 100 / d0["S"].iloc[0]
print(f"{len(dd)} días; P&L real {dd['real'].sum():.2f} %; "
      f"de gamma {dd['gamma_pnl'].sum():.2f} %")
dd.sort_values("real").tail(4).round(3)
```
```output
20 días; P&L real 11.72 %; de gamma 9.62 %
                  S  delta  gamma_pnl   real
fecha
2020-03-11  2713.79 -0.891      1.404  0.753
2020-03-09  2803.60 -0.669      0.598  1.158
2020-03-10  2933.60 -0.223      2.697  2.286
2020-03-06  3034.07  0.205      4.636  5.556
```

Los cuatro intervalos suman 9,8 de los 11,7 puntos; el del 2020-03-06 recoge la caída del 7,6 % hasta el lunes 9, con
la delta todavía en +0,21 tras el rebote del día 6. Sin esos días el mes habría sido el habitual del comprador: theta
pagada día a día. Por eso una cartera de gamma comprada se presenta con su distribución, no con su
media, y por eso quien la vende (lección 3.6.1) debe dimensionar su posición para sobrevivir a ese mes.

<aside class="callout" data-kind="riesgo">

Vender el straddle cubierto ganó en el 71 % de los meses de la muestra, con una media del 0,44 % del índice. En el
2020-02-21 perdió un 11,8 % del índice, con la cobertura diaria funcionando como estaba previsto. La cobertura delta
neutraliza la dirección, no los saltos ni la volatilidad: el vendedor de gamma cubierto sigue corto de cola.

</aside>

## Estructura temporal y skew

Las dos dimensiones de la superficie que no son el nivel también se operan con la delta cubierta. La **estructura
temporal** compara implícitas de vencimientos distintos: un calendario vende el vencimiento corto y compra el largo
(lección 3.5.3) y apuesta a que la pendiente vuelve a su forma habitual. El **skew** compara strikes: un risk
reversal cubierto en delta (comprar la call y vender la put del mismo vencimiento, o al revés) apuesta a que la
diferencia de implícitas entre puts y calls está cara o barata frente a lo que el índice hará.

`opciones3_verdad.parquet` tiene la superficie verdadera: la varianza total ATM (`theta`) de cada vencimiento. Con ella
se interpola la implícita ATM a 30 y a 60 días constantes (interpolación lineal de la varianza total, lección 3.4.5) y
se mide la pendiente:

```python
ver = pd.read_parquet("opciones3_verdad.parquet")
ver["T"] = ver["dias"] / 365
diaria = (ver.sort_values(["fecha", "vencimiento"])
          .groupby("fecha").head(3))

def atm_cte(g, dias):
    t, w = g["T"].to_numpy(), g["theta"].to_numpy()
    tt = dias / 365
    if t[0] >= tt:
        return np.sqrt(w[0] / t[0])
    b = min(np.searchsorted(t, tt), len(t) - 1)
    wi = w[b - 1] + (w[b] - w[b - 1]) * (tt - t[b - 1]) \
        / (t[b] - t[b - 1])
    return np.sqrt(wi / tt)

ts = diaria.groupby("fecha").apply(
    lambda g: pd.Series({"atm30": atm_cte(g, 30),
                         "atm60": atm_cte(g, 60)})) * 100
ts["pendiente"] = ts["atm60"] - ts["atm30"]
ts["vorx"] = vx.reindex(ts.index)
print(f"invertida (30 d > 60 d): {(ts.pendiente < 0).mean():.0%}"
      f" de las sesiones")
print(f"correlación de la pendiente con el VORX: "
      f"{ts['pendiente'].corr(ts['vorx']):.2f}")
ts["pendiente"].describe().round(2)
```
```output
invertida (30 d > 60 d): 28% de las sesiones
correlación de la pendiente con el VORX: -0.67
count    3018.00
mean        0.38
std         1.21
min        -8.26
25%        -0.09
50%         0.56
75%         1.09
max         3.55
Name: pendiente, dtype: float64
```

*Fig. — VORX (arriba) y pendiente de la estructura temporal ATM, implícita a 60 días menos a 30 (abajo), cada dos semanas de 2014 a 2025: la pendiente se invierte en las crisis (datos sintéticos).* Dos paneles con el mismo eje de años. Arriba, el VORX entre 10 y 20 casi todo el tiempo, con picos en 2015, 2018, 2020 (el mayor, por encima de 60) y 2025. Abajo, la pendiente entre 0 y 3 puntos en calma y negativa en cada pico; el mínimo, destacado, en marzo de 2020 con −7,9 puntos.

La pendiente es positiva casi siempre que la volatilidad está baja (la implícita a 60 días por encima de la de 30: la
estructura en contango) y se invierte en las crisis, con una correlación de −0,67 con el VORX. Está invertida en el
28 % de las sesiones, en línea con el 27 % de los miércoles que el README mide entre 1 mes y 1 año. Es la respuesta
conocida del modelo: la varianza a corto plazo vuelve deprisa a una media lenta, así que tras un choque la
implícita corta queda muy por encima de la larga.

Para el skew, la superficie da la implícita a cualquier $k = \ln(K/F)$ con los parámetros SVI. A unos 30 días, la
diferencia entre la implícita a un 5 % por debajo y a un 5 % por encima del forward, y la correlación entre el
rendimiento diario del índice y el cambio de la implícita ATM a 30 días (la correlación spot-vol, lo que el skew
descuenta):

```python
def iv_svi(g, k):
    w = g["svi_a"] + g["svi_b"] * (
        g["svi_rho"] * (k - g["svi_m"])
        + np.sqrt((k - g["svi_m"])**2 + g["svi_sigma"]**2))
    return np.sqrt(w / g["T"])

c30 = (ver[ver["dias"].between(20, 40)].drop_duplicates("fecha")
       .set_index("fecha"))
skew = 100 * (iv_svi(c30, -0.05) - iv_svi(c30, 0.05))
print(f"skew −5 % / +5 %: media {skew.mean():.1f} puntos, "
      f"de {skew.min():.1f} a {skew.max():.1f}")
print(f"correlación del skew con el VORX: "
      f"{skew.corr(vx.reindex(skew.index)):.2f}")
rend = np.log(S).diff()
print(f"correlación rendimiento / cambio de la ATM a 30 días: "
      f"{rend.corr(ts['atm30'].diff()):.2f}")
```
```output
skew −5 % / +5 %: media 9.1 puntos, de 6.8 a 11.9
correlación del skew con el VORX: 0.54
correlación rendimiento / cambio de la ATM a 30 días: -0.62
```

La put a un 5 % por debajo del forward cotiza de media 9,1 puntos de volatilidad por encima de la call a un 5 % por
encima, y la diferencia crece con el nivel de la volatilidad (correlación de 0,54 con el VORX). La correlación
spot-vol medida es de −0,62: cuando el índice cae, la implícita sube. El modelo la planta con una correlación de −0,72
entre los choques de la varianza y los rendimientos; la implícita ATM es una media suavizada de la varianza futura y
recoge una parte menor.

Con estos datos se pueden contrastar las dos operaciones, siempre cubiertas en delta: un calendario vendido cuando la
estructura está muy invertida (apuesta a que se normaliza) o un risk reversal cuando el skew se separa de su relación
habitual con el nivel. Dos advertencias antes de hacerlo. La primera, que los datos tienen solo tres vencimientos
diarios y la superficie completa los miércoles: un calendario de más de tres meses solo se puede valorar una vez por
semana. La segunda, que las dos operaciones llevan vega de signo contrario en cada pata y se mueven con el nivel de la
volatilidad: un calendario vendido «porque la estructura está invertida» se abre justo en la crisis, cuando el nivel
puede seguir subiendo, y pierde por la pata corta lo que no gana la larga.

## Dispersión: lo que estos datos no permiten

La varianza de un índice depende de las varianzas de sus componentes y de sus correlaciones. Con pesos $w_i$ y
volatilidades implícitas $\sigma_i$ de los componentes, y una sola correlación media $\overline{\rho}$:

$$
\sigma_I^2 = \sum_i w_i^2 \sigma_i^2 + \overline{\rho} \sum_{i \neq j} w_i w_j \sigma_i \sigma_j
\quad\Longrightarrow\quad
\overline{\rho}_{imp} = \frac{\sigma_I^2 - \sum_i w_i^2 \sigma_i^2}{\sum_{i \neq j} w_i w_j \sigma_i \sigma_j} .
$$

Es la correlación implícita. Cboe publica índices de correlación implícita del S&P 500 con esta fórmula, con las
implícitas ATM del índice y de sus 50 mayores componentes por capitalización ajustada por free float (libro blanco
de la metodología en los recursos). Una **operación de dispersión** vende volatilidad del índice y compra la de los
componentes, todo cubierto en delta: gana si la correlación realizada queda por debajo de la implícita. Driessen,
Maenhout y Vilkov (2009) estudian opciones del S&P 100 y de todos sus componentes y encuentran que el riesgo de
correlación tiene precio: explica bien los rendimientos de las opciones del índice frente a las de las acciones. Según
su resumen, con fricciones de negociación realistas esa prima no se puede explotar.

```mermaid
flowchart TB
  I[Vende vol índice] --> C[Cartera cubierta]
  A[Compra vol acción] --> C
  C --> R{Correlación real}
  R -- baja --> G[Gana]
  R -- alta --> P[Pierde: crisis]
```

Los datos del curso **no** permiten contrastarla: hay opciones del índice ORX, pero no de sus componentes (la acción
KRN, la única con opciones, no forma parte del índice ni se generó a partir de él). Lo que sí se puede hacer es
calcular la correlación implícita como fórmula. Los números de la celda siguiente son inventados, solo para ver cómo
se mueve:

```python
def correlacion_implicita(sig_indice, w, sig):
    w, sig = np.asarray(w), np.asarray(sig)
    sin_corr = np.sum(w**2 * sig**2)
    cruzados = np.sum(np.outer(w * sig, w * sig)) - sin_corr
    return (sig_indice**2 - sin_corr) / cruzados

w = [0.30, 0.25, 0.20, 0.15, 0.10]    # pesos (inventados)
sig = [0.28, 0.32, 0.25, 0.35, 0.40]  # implícitas de las acciones
for sig_i in (0.15, 0.20, 0.25):
    rho = correlacion_implicita(sig_i, w, sig)
    print(f"índice al {sig_i:.0%}: correlación implícita {rho:.2f}")
```
```output
índice al 15%: correlación implícita 0.03
índice al 20%: correlación implícita 0.27
índice al 25%: correlación implícita 0.57
```

Con las acciones al 25-40 %, un índice al 15 % implica una correlación media de 0,03; al 20 %, de 0,27, y al 25 %,
de 0,57: subir la implícita del índice sin que se muevan las de las acciones es subir la correlación. En una crisis las correlaciones
reales se disparan hacia 1, que es justo cuando el vendedor de volatilidad del índice pierde: la dispersión es otra
forma de vender prima con riesgo de cola, y los costes (decenas de opciones sobre acciones, cada una con su horquilla)
se comen buena parte de la prima.

## Ejercicios

1. En la simulación, haz que la volatilidad realizada sea del 30 % con la call vendida al 20 %. Compara cubrir con la
   delta de la implícita (20 %) y con la de la realizada (30 %) con 160 coberturas: ¿qué pasa con la media y con la
   dispersión?

**Solución.**

```python
z2 = np.random.default_rng(7).standard_normal((n_tray, pasos))
s_r = 0.30
cam2 = S0 * np.exp(np.cumsum(-0.5 * s_r**2 * dtp
                             + s_r * np.sqrt(dtp) * z2, axis=1))
cam2 = np.c_[np.full(n_tray, S0), cam2]
t_ = T0 - np.arange(pasos + 1) * dtp

def delta_con(s, t, sv):
    sd = sv * np.sqrt(np.maximum(t, 1e-12))
    return ndtr((np.log(s / K0) + 0.5 * sd * sd) / sd)

for nombre, sv in (("implícita 20 %", 0.20), ("realizada 30 %", 0.30)):
    d_ = delta_con(cam2[:, :-1], t_[:-1], sv)
    pnl = (prima + (d_ * np.diff(cam2, axis=1)).sum(axis=1)
           - np.maximum(cam2[:, -1] - K0, 0))
    print(f"{nombre}: media {pnl.mean():.3f}, desv {pnl.std():.3f}")
```
```output
implícita 20 %: media -1.081, desv 0.546
realizada 30 %: media -1.099, desv 0.224
```

Las dos medias son parecidas y negativas (−1,08 y −1,10 puntos sobre una prima de 2,21): quien vendió al 20 % una
volatilidad que fue del 30 % pierde, aproximadamente, la diferencia entre el precio de la call al 30 % y al 20 %. Lo
que cambia es la dispersión. Cubriendo con la delta de la realizada el resultado es mucho menos disperso (0,22 frente
a 0,55; lo que queda es el error de cubrir 160 veces y no en continuo), porque la cobertura replica la opción al 30 %;
cubriendo con la de la implícita depende del camino, porque la pérdida diaria se pondera con la gamma de la implícita. Como la realizada no se
conoce de antemano, en la práctica se cubre con la implícita y se acepta esa dependencia del camino.

2. Repite la descomposición del P&L solo con las operaciones que entran con la estructura temporal invertida (pendiente
   30-60 días negativa el día de entrada). ¿Gana más o menos el comprador que en el conjunto?

**Solución.**

```python
e["pend"] = ts["pendiente"].reindex(
    pd.to_datetime(e["entrada"])).to_numpy()
e.groupby(e["pend"] < 0)["pnl"].agg(
    ["count", "mean", "median",
     ("positivas", lambda s: (s > 0).mean())]).round(2)
```
```output
       count  mean  median  positivas
pend
False    102 -0.44   -0.75       0.25
True      41 -0.48   -0.84       0.32
```

Con la estructura invertida al entrar (`True`, 41 operaciones), el comprador está en una crisis o justo después:
compra una implícita corta muy alta. La media (−0,48 %) es casi la del resto (−0,44 %) y gana algo más a menudo (32 %
frente a 25 %): el resultado depende de si la crisis sigue o se calma. Con 41 operaciones y la desviación típica de toda la
muestra (1,66 puntos), el error típico de la media es de 1,66 / √41 ≈ 0,26 puntos: la diferencia de medias no se
distingue del azar. Es el mismo problema que
la estacionalidad de la lección 3.2.6: pocas observaciones independientes por estado.

3. Una mesa propone vender la volatilidad del índice y comprar la de sus diez mayores componentes porque la correlación
   implícita está en 0,60 y la realizada del último año fue 0,35. Enumera lo que puede salir mal.

**Solución.**

La realizada del último año no es la de los próximos meses: la correlación sube en las caídas, y la pata vendida del
índice pierde justo cuando sube. Con diez componentes la cesta no replica el índice (el resto de valores también
aporta varianza), así que queda un riesgo de base. Cada pata necesita su cobertura delta y paga su horquilla, y las
opciones sobre acciones tienen horquillas mucho más anchas que las del índice. Los resultados empresariales y los
dividendos de cada acción mueven sus implícitas por separado (lección 3.6.4). Driessen, Maenhout y Vilkov (2009) concluyen que, con fricciones
realistas, la prima por el riesgo de correlación no se puede explotar: los costes de las decenas de patas se la comen.
Y quien la cobra asume pérdidas grandes en las crisis: hay que dimensionarla con su peor episodio, no con la media.

## Autoevaluación

1. Un straddle ATM comprado y cubierto en delta cada día gana dinero cuando...

   - A. El índice sube durante la vida de la opción
   - B. La volatilidad realizada, ponderada por la gamma de cada día, supera a la implícita con la que se compró
   - C. La volatilidad implícita baja después de la compra
   - D. El tipo de interés sube

   *Respuesta B: La volatilidad realizada, ponderada por la gamma de cada día, supera a la implícita con la que se compró.* Cada día el P&L de gamma es ½·Γ·S²·(r² − σ²·Δt): positivo si el movimiento al cuadrado supera al que descontaba la implícita. La dirección del índice la neutraliza la cobertura. En los datos, el término de gamma explica por sí solo una correlación de 0,89 con el P&L real de las 143 operaciones.

2. Dos straddles con la misma volatilidad realizada en el mes tienen P&L distinto. ¿Por qué?

   - A. Por un error de los datos
   - B. Porque la gamma no es constante: el mismo movimiento cerca del strike y del vencimiento pesa mucho más que lejos del strike o al principio
   - C. Porque uno se compró al bid y otro al ask
   - D. No puede ocurrir si la cobertura es diaria

   *Respuesta B: Porque la gamma no es constante: el mismo movimiento cerca del strike y del vencimiento pesa mucho más que lejos del strike o al principio.* El P&L suma los movimientos al cuadrado ponderados por Γ·S². La gamma es máxima en el dinero y crece al acercarse el vencimiento. Por eso la correlación del P&L con la diferencia de varianzas del mes (0,81) es menor que con el término de gamma día a día (0,89).

3. En la simulación con σ realizada = σ implícita, ¿qué cambia al pasar de 5 a 80 coberturas por opción?

   - A. La media del P&L pasa de negativa a positiva
   - B. La media sigue cerca de cero y la desviación típica cae aproximadamente con 1/√N
   - C. Nada: la cobertura discreta es igual que la continua
   - D. La desviación típica sube porque hay más operaciones

   *Respuesta B: La media sigue cerca de cero y la desviación típica cae aproximadamente con 1/√N.* Con la volatilidad bien estimada, cubrir no crea ni destruye valor esperado: reduce el ruido. Multiplicar por 16 las coberturas divide por unas 4 la desviación típica (0,81 frente a 0,21 en la simulación de la lección).

4. En los datos, cubrir cada 5 sesiones en vez de cada día deja el P&L medio del straddle comprado en −0,17 % en lugar de −0,45 %. ¿Qué significa?

   - A. Que cubrir menos es una estrategia mejor
   - B. Que la cobertura menos frecuente deja exposición a la dirección, y en una muestra con el índice al alza esa exposición ha sumado; a cambio, la desviación típica casi se duplica
   - C. Que la cobertura diaria tiene un error de programación
   - D. Que la prima de riesgo de varianza desaparece al cubrir menos

   *Respuesta B: Que la cobertura menos frecuente deja exposición a la dirección, y en una muestra con el índice al alza esa exposición ha sumado; a cambio, la desviación típica casi se duplica.* La diferencia de medias es deriva direccional, no ventaja de la cobertura: la desviación típica pasa de 1,66 a 3,06 puntos. Una banda de delta de 0,2 consigue casi lo mismo que la cobertura diaria (1,83) con 5 coberturas en lugar de 20.

5. ¿Qué hace falta para contrastar una operación de dispersión?

   - A. Solo las opciones del índice
   - B. Las opciones del índice y las de sus componentes principales, con sus pesos, para comparar la varianza implícita del índice con la de la cesta y obtener la correlación implícita
   - C. El VIX y el VSTOXX
   - D. Un año de datos diarios del índice

   *Respuesta B: Las opciones del índice y las de sus componentes principales, con sus pesos, para comparar la varianza implícita del índice con la de la cesta y obtener la correlación implícita.* La correlación implícita sale de la varianza implícita del índice frente a la de una cesta sin correlación de sus componentes. Los datos del curso solo tienen opciones del índice ORX y de una acción que no forma parte de él: la operación se puede plantear, pero no contrastar.

## Ideas clave

- Con la delta cubierta, el P&L diario de una opción es ½·Γ·S²·(r² − σ²·Δt) más vega por el cambio de la implícita y un resto pequeño: en los datos, gamma y vega juntos dan una correlación de 0,97 con el P&L real.
- El straddle ATM comprado y cubierto pierde de media un 0,45 % del índice por operación y gana solo en el 23 % de los meses (la prima de riesgo de varianza), pero gana un 11,7 % al entrar el 2020-02-21: es un seguro, no una renta.
- Cubrir más a menudo no cambia el valor esperado; reduce la dispersión del resultado con 1/√N y cuesta más horquilla. Las bandas de delta son más eficientes que el calendario fijo.
- La estructura temporal se invierte en el 28 % de las sesiones (30 frente a 60 días) y el skew sube con el nivel de la volatilidad: las dos son operables con opciones del índice, siempre con la cobertura delta y con el riesgo de cola a la vista.
- La dispersión necesita opciones de los componentes; con estos datos solo se puede calcular la correlación implícita como fórmula, no backtestearla.

## Recursos

### Research

- [Usos de la volatilidad](https://pythonparatrading.com/usos-de-la-volatilidad/) · Research-0003 · 6 min

### Documentación

- [Cboe: metodología del Cboe S&P 500 Implied Correlation Index (libro blanco)](https://cdn.cboe.com/resources/indices/documents/Implied_Correlation-WhitePaper-v1.0.5.pdf) · cdn.cboe.com

### Libros

- [Bakshi, G. y Kapadia, N. (2003): Delta-Hedged Gains and the Negative Market Volatility Risk Premium. Review of Financial Studies 16(2), 527-566](https://doi.org/10.1093/rfs/hhg002) · doi.org
- [Carr, P. y Wu, L. (2009): Variance Risk Premiums. Review of Financial Studies 22(3), 1311-1341](https://doi.org/10.1093/rfs/hhn038) · doi.org
- [Driessen, J., Maenhout, P. y Vilkov, G. (2009): The Price of Correlation Risk: Evidence from Equity Options. The Journal of Finance 64(3), 1377-1406](https://doi.org/10.1111/j.1540-6261.2009.01467.x) · doi.org
- [Leland, H. E. (1985): Option Pricing and Replication with Transactions Costs. The Journal of Finance 40(5), 1283-1301](https://doi.org/10.1111/j.1540-6261.1985.tb02383.x) · doi.org

### Datos

- [Datos del nivel 3: cadena diaria de opciones sobre ORX, 2014-2025 (Parquet)](https://pythonparatrading.com/curso/datos/nivel-3/opciones3_cadena.parquet) · Descarga · opciones3_cadena.parquet

Lección anterior: [3.6.1 · Venta sistemática de prima: put-write, strangles y su riesgo de cola](https://pythonparatrading.com/curso-python-trading/nivel-3/venta-sistematica-de-prima-y-riesgo-de-cola/)

Lección siguiente: [3.6.3 · Estrategias con VIX y VSTOXX: futuros y ETP de volatilidad](https://pythonparatrading.com/curso-python-trading/nivel-3/estrategias-con-vix-y-vstoxx/)
