---
title: "3.2.3 Spreads de tipos y de índices: 2s10s, NOB y NQ/ES"
description: "Spreads de tipos (2s10s, NOB) neutrales en DV01 y de índices (NQ/ES, Europa frente a EE. UU.): qué apuestan, betas residuales y riesgo de divisa."
url: "https://pythonparatrading.com/curso-python-trading/nivel-3/spreads-de-tipos-y-de-indices/"
lang: "es"
image: "https://pythonparatrading.com/og/curso-python-trading/nivel-3/spreads-de-tipos-y-de-indices.png"
---

# 3.2.3 · Spreads de tipos y de índices: 2s10s, NOB, NQ/ES y Europa frente a EE. UU.

> Con futuros de bonos se apuesta por la pendiente de la curva sin apostar por el nivel de los tipos, y con futuros de índices, por un mercado frente a otro sin apostar por la bolsa. En los dos casos el ratio entre las patas decide qué queda de verdad en la posición. Esta lección construye el empinador 2s10s y el NOB neutrales en DV01, el NQ/ES neutral por nominal y por beta y el spread de Europa frente a EE. UU., y mide qué exposición les queda.

- Curso: [Nivel 3: Derivados: futuros, spreads, forex y opciones](https://pythonparatrading.com/curso-python-trading/nivel-3/)
- Módulo: 3.2 · Spreads de futuros
- Duración: 60 min
- Requisitos: [3.2.1 · Spreads de calendario, butterflies y condors](https://pythonparatrading.com/curso-python-trading/nivel-3/spreads-de-calendario-butterflies-y-condors/), [1.2.7 · Renta fija y tipos de interés; CFDs y productos apalancados](https://pythonparatrading.com/curso-python-trading/nivel-1/renta-fija-tipos-y-productos-apalancados/)

## Al terminar esta lección

- Construir un spread de tipos neutral en DV01 con futuros y explicar por qué gana o pierde con la pendiente y no con el nivel.
- Medir con una regresión la exposición residual al nivel de un empinador y explicar por qué no es cero cerca de tipos cero.
- Construir un spread de índices neutral por nominal y por beta, y medir su deriva relativa y su exposición al mercado.
- Distinguir el riesgo de divisa de un spread entre índices de distintas monedas operado con futuros y con contado.

## Apostar por la pendiente, no por el nivel

La pendiente 2s10s es la diferencia entre el rendimiento a 10 años y el de 2 (lección 1.2.7). Una opinión sobre ella
(que la curva se va a empinar, o a aplanar) no es una opinión sobre los tipos: la curva puede empinarse con tipos que
suben (el 10 años sube más) o que bajan (el 2 años baja más). Para operar solo la pendiente con futuros hay que
comprar uno y vender otro de forma que un movimiento paralelo de toda la curva no gane ni pierda.

La herramienta es el **DV01** de cada futuro: cuántos dólares gana o pierde un contrato si el rendimiento de su bono
de referencia baja un punto básico. Los datos (`tipos3_dv01.csv`) lo dan para el contrato que se tiene de cada futuro
de tipos. Son datos sintéticos: `TPA`, `TPB`, `TPC` y `TPD` imitan a las notas a 2, 5 y 10 años y al bono del Tesoro
de EE. UU. (ZT, ZF, ZN, ZB), y `TPE` al Bund; cada contrato es el precio a plazo de un bono estándar con cupón del
6 % (el «CTD» del modelo, con factor de conversión 1).

```python
import numpy as np
import pandas as pd

dv = pd.read_csv("tipos3_dv01.csv", parse_dates=["fecha"])
cols = ["mercado", "contrato", "liquidacion", "rendimiento_ctd",
        "vencimiento_ctd_anos", "duracion_modificada", "dv01"]
dv.loc[dv["fecha"] == "2025-12-31", cols].set_index("mercado")
```
```output
        contrato  liquidacion  rendimiento_ctd  vencimiento_ctd_anos  duracion_modificada    dv01
mercado
TPA       TPAH26   104.273438           3.6651                 2.147                2.040   42.55
TPB       TPBH26   108.750000           3.7311                 4.447                3.973   43.21
TPC       TPCH26   112.546875           3.8286                 6.816                5.729   64.47
TPD       TPDH26   121.625000           4.1319                16.216               11.056  134.46
TPE       TPEH26   126.910000           2.5060                 8.878                7.240   91.88
```

Un contrato de `TPC` gana o pierde 64,47 USD por punto básico; uno de `TPA`, 42,55, aunque su nominal es el doble
(200.000 frente a 100.000): el bono a 2 años es mucho menos sensible a los tipos. Para igualar el DV01 de un contrato
de `TPC` hacen falta $h = 64{,}47 / 42{,}55 = 1{,}52$ contratos de `TPA`. Esa es la cobertura neutral en DV01:

$$
\text{PyG} = h \cdot \text{PyG}_{\text{corto}} - \text{PyG}_{\text{largo}}, \qquad
h = \frac{\text{DV01}_{\text{largo}}}{\text{DV01}_{\text{corto}}},
$$

donde «corto» y «largo» se refieren al plazo, no al signo: el **empinador** está largo en $h$ contratos del plazo
corto y corto en uno del largo.

```mermaid
flowchart TB
  M[Curva se mueve] --> P[Paralelo]
  M --> E[Se empina]
  M --> A[Se aplana]
  P --> P0[Empinador: 0]
  E --> E1[Empinador: gana]
  A --> A1[Empinador: pierde]
```

El NOB (*notes over bonds*) es el mismo spread entre la nota a 10 años y el bono. El ratio no es fijo: el DV01 de cada
futuro cambia con el nivel de los tipos y con el bono que se entrega.

```python
d01 = dv.pivot(index="fecha", columns="mercado", values="dv01")
ratios = pd.DataFrame({"2s10s (TPA por TPC)": d01["TPC"] / d01["TPA"],
                       "NOB (TPC por TPD)": d01["TPD"] / d01["TPC"]})
print(ratios.describe().loc[["min", "50%", "max"]].round(2))
ratios.resample("YE").mean().round(2).T.iloc[:, ::3]
```
```output
     2s10s (TPA por TPC)  NOB (TPC por TPD)
min                 1.41               1.94
50%                 1.59               2.23
max                 1.87               2.93
fecha                2010-12-31  2013-12-31  2016-12-31  2019-12-31  2022-12-31  2025-12-31
2s10s (TPA por TPC)        1.52        1.55        1.62        1.68        1.56        1.53
NOB (TPC por TPD)          2.03        2.11        2.30        2.53        2.22        2.15
```

*Fig. — Contratos del plazo corto por contrato del largo que hacen neutral en DV01 el 2s10s y el NOB de los datos, 2010–2025, frente al ratio fijo 2:1 que lista CME.* Dos líneas de 2010 a 2025. El ratio por DV01 del NOB (notas a 10 años por bono a 30) se mueve entre 1,94 y 2,93, con un máximo hacia 2019-2020; el del 2s10s (notas a 2 años por nota a 10), entre 1,41 y 1,87. Una línea destacada marca el ratio fijo de 2:1 con el que CME lista el TUT y el NOB.

En los datos, el 2s10s necesita entre 1,41 y 1,87 contratos de `TPA` por cada uno de `TPC`, y el NOB entre 1,94 y
2,93 de `TPC` por cada `TPD`. CME lista estos spreads como instrumentos con ratios fijos: 2:1 en el 2 años frente al
10 (TUT) y 2:1 en el 10 años frente al bono (NOB), entre otros, que según la propia CME se espera que no cambien salvo
cambios sustanciales del mercado. Un ratio fijo es cómodo (una sola orden, un solo precio), pero solo es neutral en
DV01 cuando coincide con el de los DV01. Las coberturas por nominal, por DV01 y por volatilidad, y cómo elegir entre
ellas, son el tema de la lección 3.2.4.

## El empinador neutral en DV01

Antes de construir el spread conviene comprobar que el DV01 dice lo que promete. El P&L diario de un largo en `TPC`
(con los mismos contratos de un día a otro, como en la lección 3.2.1), dividido por el cambio del rendimiento de su
bono de referencia en puntos básicos:

```python
cur = pd.read_parquet("futuros3_curvas.parquet")
ctr = pd.read_csv("futuros3_contratos.csv",
                  parse_dates=["vencimiento", "fecha_roll"])
esp = pd.read_csv("futuros3_especificaciones.csv",
                  index_col="mercado")

def cambio(mercado, log=False):
    """Cambio diario del contrato que se tenía al cierre anterior
    (el primero que no ha llegado a su fecha_roll; lección 3.2.1)."""
    c = cur[cur["mercado"] == mercado].merge(
        ctr[["contrato", "vencimiento", "fecha_roll"]], on="contrato")
    px = c.pivot(index="fecha", columns="contrato",
                 values="liquidacion")
    d = (np.log(px) if log else px).diff().stack()
    c = c[c["fecha"] < c["fecha_roll"]].sort_values(
        ["fecha", "vencimiento"])
    ley = c.groupby("fecha")["contrato"].first().shift(1).dropna()
    idx = pd.MultiIndex.from_arrays([ley.index, ley.to_numpy()])
    return pd.Series(d.reindex(idx).to_numpy(), index=ley.index)

def pyg(mercado):
    """P&L diario por contrato, en la divisa del contrato."""
    return cambio(mercado) * esp.loc[mercado, "multiplicador"]

usd_pb = pyg("TPC") / (dv[dv["mercado"] == "TPC"].set_index("fecha")
                       ["rendimiento_ctd"].diff() * 100)
print(f"P&L de un largo en TPC por pb de subida del CTD: "
      f"{usd_pb.median():.1f} USD (DV01 medio "
      f"{d01['TPC'].mean():.1f})")
```
```output
P&L de un largo en TPC por pb de subida del CTD: -70.1 USD (DV01 medio 70.4)
```

Un largo en `TPC` pierde de mediana 70,1 USD por cada punto básico que sube el rendimiento, y el DV01 medio de la
serie es 70,4. Con eso, el empinador:

```python
yld = dv.pivot(index="fecha", columns="mercado",
               values="rendimiento_ctd")

def empinador(corto, largo):
    """Largo en h contratos del plazo corto y corto en 1 del largo,
    h = DV01 largo / DV01 corto de la sesión anterior."""
    h = (d01[largo] / d01[corto]).shift(1)
    p = (h * pyg(corto) - pyg(largo)).dropna()
    nivel = yld[largo].diff().reindex(p.index) * 100       # pb
    pendiente = (yld[largo] - yld[corto]).diff().reindex(
        p.index) * 100
    return p, nivel, pendiente

p, nivel, pend = empinador("TPA", "TPC")
dp = (yld["TPC"] - yld["TPA"]).iloc[[0, -1]].diff().iloc[-1]
print(f"P&L acumulado 2010-2025: {p.sum():,.0f} USD por contrato "
      "de TPC")
print(f"Cambio de la pendiente CTD en el periodo: {100 * dp:+.0f} pb")
print(f"Correlación del P&L diario con el cambio de pendiente: "
      f"{p.corr(pend):.2f}; con el de nivel: {p.corr(nivel):.2f}")
```
```output
P&L acumulado 2010-2025: -29,452 USD por contrato de TPC
Cambio de la pendiente CTD en el periodo: -193 pb
Correlación del P&L diario con el cambio de pendiente: 0.99; con el de nivel: 0.49
```

La figura de la cabecera lo resume: entre 2010 y 2025 la pendiente sintética (rendimiento del bono de referencia del
10 años menos el del 2) pasó de unos 200 pb a valores negativos, con un cambio total de −193 pb, y el empinador perdió
29.452 USD por contrato de `TPC`. Su P&L diario tiene una correlación de 0,99 con el cambio de la pendiente. El P&L
acumulado no es exactamente la pendiente por el DV01, porque a lo largo de 16 años cambian los DV01, el bono de
referencia de cada contrato y la financiación de las dos patas; pero el día a día sí lo es.

La correlación con el nivel (0,49) no es cero. ¿Es neutral la posición al nivel o no? Para separar las dos cosas, una
regresión del P&L diario sobre el cambio del rendimiento a 10 años («nivel»), sola y junto al cambio de la pendiente:

$$
\text{PyG}_t = a + \beta_{\text{nivel}} \, \Delta y^{10}_t + \beta_{\text{pend}} \, \Delta\left(y^{10}_t - y^{2}_t\right) + \varepsilon_t .
$$

```python
def betas(p, nivel, pend):
    filas = {}
    for per, (a, b) in {"2010-2015": ("2010", "2015"),
                        "2016-2025": ("2016", "2025")}.items():
        y, l, s = p.loc[a:b], nivel.loc[a:b], pend.loc[a:b]
        sola = np.polyfit(l, y, 1)[0]
        X = np.column_stack([np.ones(len(y)), l, s])
        _, b_niv, b_pend = np.linalg.lstsq(X, y, rcond=None)[0]
        filas[per] = {"nivel_sola": sola, "nivel_con_pend": b_niv,
                      "pendiente": b_pend}
    return pd.DataFrame(filas).T.round(1)

pd.concat({"2s10s": betas(p, nivel, pend),
           "NOB": betas(*empinador("TPC", "TPD"))})
```
```output
                 nivel_sola  nivel_con_pend  pendiente
2s10s 2010-2015        34.0            -0.2       71.7
      2016-2025        15.1             1.1       69.5
NOB   2010-2015        13.0             0.1      156.6
      2016-2025        14.2             1.0      158.2
```

*Fig. — Exposición al nivel de los spreads de tipos neutrales en DV01: beta del P&L diario al cambio del rendimiento largo, sola y con la pendiente en la regresión.* Barras horizontales por spread y periodo, en USD por punto básico. Con la pendiente en la regresión, la beta al nivel es casi cero en todos los casos (−0,2, 1,1, 0,1 y 1,0). Sola, es positiva: 34,0 en el 2s10s de 2010-2015 (destacada), 15,1 en el de 2016-2025, 13,0 y 14,2 en el NOB.

Con la pendiente en la regresión, la beta al nivel es casi cero (−0,2 y 1,1 USD por pb en el 2s10s; 0,1 y 1,0 en el
NOB) y la beta a la pendiente es casi el DV01 de la pata del plazo largo: 69,5-71,7 USD por pb en el 2s10s (DV01 del
10 años, 70-71) y 156,6-158,2 en el NOB (DV01 del bono, 155-163). Es la **respuesta conocida** del README de los datos,
y la regresión la recupera. La posición es neutral a un desplazamiento paralelo. Pero la beta al nivel sola, sin la
pendiente, es de 34 USD por pb en el 2s10s de 2010-2015 y de 13-15 en los demás casos. La explicación está en cómo se movían los dos
plazos:

```python
dy = yld.diff() * 100
vol = dy.groupby(dy.index.year >= 2016)[["TPA", "TPC", "TPD"]].std()
vol.index = ["2010-2015", "2016-2025"]
vol.round(2)
```
```output
mercado     TPA   TPC   TPD
2010-2015  4.00  6.22  6.33
2016-2025  6.95  7.13  7.30
```

En 2010-2015, con los tipos a corto cerca de cero, el rendimiento a 2 años se movía 4,00 pb al día de desviación
típica frente a 6,22 del de 10 años. Una subida del 10 años era casi siempre un empinamiento, así que, en la práctica,
el empinador se comportaba en buena parte como un corto en la nota a 10 años. Neutral en DV01 quiere decir neutral a
un movimiento paralelo, no neutral a lo que de verdad hace la curva. Desde 2016, con el 2 años tan volátil como el 10
(6,95 frente a 7,13 pb), la beta al nivel sola baja a 15.

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

Un empinador «neutral» que se combina con una cartera larga en bonos no la cubre cerca de tipos cero: le añade un
corto en el plazo largo. Antes de sumar posiciones, mide la beta al nivel con los datos del régimen en que estás, no
la que dice la fórmula.

</aside>

## NQ/ES: un índice frente a otro

El spread de índices más operado en EE. UU. es el del Nasdaq-100 frente al S&P 500 (NQ/ES): una apuesta por las
tecnológicas frente al mercado amplio. En los datos, `RVB` imita al E-mini Nasdaq-100 y `RVA` al E-mini S&P 500. En
el modelo, el rendimiento logarítmico de cada futuro es su deriva propia (7,0 % anual en `RVA`, 9,5 % en `RVB`), más
una beta por un factor de mercado común (1,00 y 1,15) y un ruido propio. Con los mismos contratos de un día a otro:

```python
r = pd.DataFrame({m: cambio(m, log=True)
                  for m in ["RVA", "RVB", "RVE"]}).dropna()
beta = r.cov().loc["RVB", "RVA"] / r["RVA"].var()
print(f"Beta de RVB a RVA: {beta:.3f}; correlación: "
      f"{r['RVB'].corr(r['RVA']):.2f}")
for nombre, s in {"nominal (1:1)": r["RVB"] - r["RVA"],
                  "beta": r["RVB"] - beta * r["RVA"]}.items():
    media, vol = s.mean() * 252, s.std() * 252 ** 0.5
    t = media / vol * (len(s) / 252) ** 0.5
    print(f"Neutral por {nombre}: deriva {media:+.1%}/año, "
          f"vol {vol:.1%}, t = {t:.2f}, "
          f"correlación con RVA {s.corr(r['RVA']):+.2f}")
```
```output
Beta de RVB a RVA: 1.151; correlación: 0.91
Neutral por nominal (1:1): deriva +3.2%/año, vol 10.4%, t = 1.21, correlación con RVA +0.28
Neutral por beta: deriva +1.4%/año, vol 10.0%, t = 0.56, correlación con RVA +0.00
```

La beta medida (1,151) recupera la plantada (1,15). Hay dos formas habituales de construir el spread:

- **Neutral por nominal** (un dólar largo por un dólar corto): es la que describe CME con su *spread ratio*, el
  cociente de los nominales de los dos contratos calculados con el índice al contado. Conserva la diferencia de betas:
  1,15 − 1 = 0,15 del mercado. En los datos, su correlación con `RVA` es 0,28 y su deriva, +3,2 % anual.
- **Neutral por beta** (1,15 dólares de `RVA` por dólar de `RVB`): elimina el factor de mercado. Su correlación con
  `RVA` es 0,00 y su deriva es la relativa pura, que en el modelo vale $9{,}5 - 1{,}15 \cdot 7{,}0 = 1{,}45$ % al año.
  La medida es +1,4 %.

*Fig. — Spread RVB/RVA (imitan al Nasdaq-100 y al S&P 500): rendimiento relativo acumulado neutral por nominal y neutral por beta, 2010–2025.* Dos líneas de 2010 a 2025 en porcentaje logarítmico acumulado. El spread neutral por nominal (un dólar largo en RVB por un dólar corto en RVA) acaba en +50 %, con caídas en las fases de bajada del mercado. El neutral por beta, destacado (1,15 dólares de RVA por dólar de RVB), acaba en +22 % con un recorrido más plano, entre −25 y +29 %, y una t de 0,56.

La estimación de la deriva neutral por beta es casi exacta, y aun así no significa nada: con una volatilidad del 10 %
anual y 16 años, el error típico de la media es $10/\sqrt{16} = 2{,}5$ puntos, y $t = 0{,}56$. El spread neutral por
nominal parece mejor (t = 1,21, +50 % acumulado en la figura), pero su ventaja viene casi toda del 0,15 de mercado que
lleva dentro, que gana mientras la bolsa sube y pierde cuando cae (el tramo de 2016 de la figura es el más visible). Es
el mismo punto de la lección 3.2.1 con el calendario de crudo: lo que se llama «spread» puede ser, en parte, una
posición direccional.

Pasar a contratos:

```python
idx = pd.read_csv("futuros3_indices_contado.csv",
                  parse_dates=["fecha"])
s = idx[idx["fecha"] == "2025-12-31"].set_index("indice")["contado"]
nominal = s[["RVA", "RVB"]] * esp.loc[["RVA", "RVB"], "multiplicador"]
print(nominal.round(0).to_string())
n_b = 1e6 / nominal["RVB"]
print(f"Largo en RVB: {n_b:.1f} contratos; corto en RVA neutral por "
      f"nominal: {n_b * nominal['RVB'] / nominal['RVA']:.1f}; "
      f"por beta: {beta * n_b * nominal['RVB'] / nominal['RVA']:.1f}")
```
```output
indice
RVA    335966.0
RVB    435294.0
Largo en RVB: 2.3 contratos; corto en RVA neutral por nominal: 3.0; por beta: 3.4
```

Un millón de USD en `RVB` son 2,3 contratos (435.294 USD de nominal cada uno a 2025-12-31); el lado corto, 3,0
contratos de `RVA` neutral por nominal o 3,4 neutral por beta. Con contratos grandes, un spread de un millón no se
puede ajustar con precisión: los micros (`RVAM`, `RVBM`, una décima parte del multiplicador, lección 3.1.1) existen,
entre otras cosas, para eso. Y la beta no es fija: el segundo ejercicio la mide año a año.

## Europa frente a EE. UU.: la divisa

El spread de Europa frente a EE. UU. añade una dificultad: las patas cotizan en monedas distintas. En los datos, `RVE`
imita al Euro Stoxx 50 y cotiza en QEV (el evro de Vesperia, que imita al euro); `RVA`, en USD. Si un inversor compra
las acciones europeas con dólares, tiene el índice europeo y además la divisa: su rendimiento en USD es el del índice
en QEV más el del QEV frente al USD. Con un futuro no hace falta cambiar el nominal: se deposita un margen y se liquida
cada día el P&L, en QEV. El riesgo de divisa queda limitado a ese P&L acumulado y al margen.

```mermaid
flowchart LR
  C[Contado europeo] --> N[Nominal en QEV]
  N --> X1[Expuesto entero]
  F[Futuro RVE] --> P[Resultado en QEV]
  P --> X2[Solo el resultado]
```

```python
fx = pd.read_parquet("fx3_diario.parquet")
x = fx[fx["divisa"] == "QEV"].set_index("fecha")["usd_por_unidad"]
r_fx = np.log(x).diff().reindex(r.index)
contado_usd = r["RVE"] + r_fx          # índice europeo pasado a USD
futuro_usd = np.expm1(r["RVE"]) * x.reindex(r.index) / x.shift(
    1).reindex(r.index)                # P&L del futuro, en USD
for nombre, s in {"RVE en QEV": r["RVE"],
                  "RVE en USD (contado)": contado_usd,
                  "futuro RVE, P&L en USD": futuro_usd}.items():
    print(f"{nombre:24s} vol {s.std() * 252 ** 0.5:.1%}  "
          f"correlación con RVA {s.corr(r['RVA']):.2f}")
```
```output
RVE en QEV               vol 20.9%  correlación con RVA 0.86
RVE en USD (contado)     vol 22.9%  correlación con RVA 0.78
futuro RVE, P&L en USD   vol 20.9%  correlación con RVA 0.86
```

En QEV, el índice europeo tiene una volatilidad del 20,9 % y una correlación de 0,86 con `RVA`. Pasado a USD como
contado, la volatilidad sube al 22,9 % y la correlación baja a 0,78: la divisa añade ruido que no tiene nada que ver
con la bolsa. El P&L del futuro convertido a USD cada día se queda como el índice en QEV (20,9 % y 0,86). Un spread de
Europa frente a EE. UU. con futuros es, por tanto, casi un spread en moneda local; con contado, es además una posición
en la divisa. Cómo gestionar ese riesgo en una cartera multimoneda es el tema de la lección 3.3.3.

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

En los datos, todas las series usan las sesiones de la NYSE (simplificación del generador). En real, los futuros
europeos y los de EE. UU. tienen horarios y precios de liquidación a horas distintas, así que las correlaciones
diarias calculadas con liquidaciones subestiman la relación real y un backtest que «ejecuta» las dos patas al cierre
mezcla precios de momentos distintos. Además, cada pata se compensa en su cámara (Eurex Clearing y CME Clearing):
no hay compensación de márgenes entre ellas, a diferencia de un spread dentro de la misma cámara.

</aside>

## Lo que esto cambia en un sistema

- **El ratio decide la apuesta.** Neutral en DV01, la posición apuesta por la pendiente; con otro ratio, también por
  el nivel. Neutral por nominal, un spread de índices apuesta también por el mercado; neutral por beta, no.
- **Neutral a un movimiento no es neutral a todos.** Cerca de tipos cero, un empinador neutral en DV01 tiene una beta
  al nivel de 34 USD por pb. La exposición residual se mide en los datos del régimen, con una regresión.
- **Los ratios se mueven.** El DV01 y la beta cambian con el tiempo; los spreads listados con ratio fijo son cómodos,
  pero no neutrales siempre. Rehacer el ratio cada día tiene un coste de ejecución (lección 3.2.5).
- **Una deriva relativa no se valida con 16 años.** Con un 10 % de volatilidad, hace falta una deriva de más de 5
  puntos al año para que la t pase de 2.
- **La divisa, solo en el P&L.** Con futuros, el riesgo de divisa es el del P&L y el margen; con contado, el del
  nominal.

## Ejercicios

1. Construye el 2s10s con el ratio fijo de 2:1 (dos contratos de `TPA` por uno de `TPC`) y repite la regresión de
   betas. ¿Qué exposición al nivel queda con la pendiente en la regresión y por qué tiene ese signo?

**Solución.**

```python
p_fijo = (2 * pyg("TPA") - pyg("TPC")).dropna()
betas(p_fijo, nivel.reindex(p_fijo.index),
      pend.reindex(p_fijo.index))
```
```output
           nivel_sola  nivel_con_pend  pendiente
2010-2015        23.8           -19.6       91.1
2016-2025         1.0           -16.6       87.7
```

Con 2:1, la beta al nivel con la pendiente en la regresión ya no es cero: −19,6 USD por pb en 2010-2015 y −16,6 en
2016-2025. El signo es negativo porque dos contratos de `TPA` tienen más DV01 que uno de `TPC` (2 × 42,55 = 85,1 frente
a 64,47 a finales de 2025): la posición está neta larga en duración y pierde cuando los tipos suben en paralelo. La
beta a la pendiente sube a 88-91 USD por pb porque el lado corto en plazo, con más contratos, pesa más. Con el ratio
fijo se apuesta por la pendiente y, además, por una bajada de los tipos.

2. Estima la beta de `RVB` a `RVA` en cada año de 2010 a 2025. ¿Cuánto varía y qué consecuencia tiene para un spread
   neutral por beta que se calibra con un año de datos?

**Solución.**

```python
por_ano = r.groupby(r.index.year).apply(
    lambda g: g["RVB"].cov(g["RVA"]) / g["RVA"].var())
print(por_ano.round(2).to_frame("beta").T.to_string())
print(f"De {por_ano.min():.2f} a {por_ano.max():.2f}")
```
```output
fecha  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  2025
beta   1.15  1.21  1.15  1.12  1.13  1.15  1.14  1.15  1.17  1.06  1.15   1.1  1.15  1.19  1.16  1.17
De 1.06 a 1.21
```

La beta anual va de 1,06 (2019) a 1,21 (2011), alrededor de la verdadera de 1,15, que en el modelo no cambia: toda la
variación es error de estimación con unas 250 sesiones. Un spread calibrado con la beta de 2019 habría quedado un 8 %
corto en `RVA` (1,06 frente a 1,15), con una exposición residual de 0,09 al mercado. En datos reales la beta además
cambia de verdad, así que la estimación con ventanas cortas mezcla los dos efectos: más ruido con ventanas cortas,
más retraso con ventanas largas (el filtro de Kalman de la lección 2.1.6 es una forma de elegir).

3. Un gestor con una cartera de acciones europeas en USD quiere apostar por que Europa lo hará mejor que EE. UU. sin
   añadir riesgo de divisa. Compara hacerlo con futuros (largo en el futuro europeo, corto en el estadounidense) y con
   contado (comprar acciones europeas y vender un ETF de EE. UU.).

**Solución.**

Con futuros, el nominal no se cambia de moneda: el gestor deposita margen en QEV (o en USD, según su bróker) y recibe o
paga cada día el P&L de la pata europea en QEV. Su exposición a la divisa es la del P&L acumulado y el margen, una
fracción pequeña del nominal; en los datos, el P&L del futuro convertido a USD tiene la misma volatilidad que el índice
en QEV (20,9 %). Con contado, compra acciones en QEV con todo el nominal y queda expuesto a la divisa por el importe
entero: el índice europeo en USD tiene un 22,9 % de volatilidad y una correlación menor con EE. UU. (0,78 frente a
0,86). Para tener solo la apuesta relativa con contado tendría que cubrir la divisa aparte (con un forward, lección
3.3.3). El coste de la versión con futuros está en otro sitio: dos cámaras sin compensación de márgenes, horarios
distintos y el roll de las dos patas cada trimestre.

## Autoevaluación

1. Un empinador 2s10s neutral en DV01 está largo en notas a 2 años y corto en notas a 10. ¿Cuándo gana?

   - A. Cuando todos los tipos suben lo mismo
   - B. Cuando la pendiente de la curva sube: el rendimiento a 10 años sube más (o baja menos) que el de 2
   - C. Cuando los tipos bajan
   - D. Cuando la curva se aplana

   *Respuesta B: Cuando la pendiente de la curva sube: el rendimiento a 10 años sube más (o baja menos) que el de 2.* Con los mismos dólares por punto básico en las dos patas, un desplazamiento paralelo se cancela. Lo que queda es la pendiente: en los datos, la beta del P&L a la pendiente es 69,5-71,7 USD por pb, casi el DV01 de la nota a 10 años (70-71), y la correlación diaria con el cambio de pendiente, 0,99.

2. En 2010-2015, una regresión del P&L del empinador sobre el cambio del rendimiento a 10 años da una beta de 34 USD por pb; con la pendiente en la regresión, −0,2. ¿Qué indica?

   - A. Que la cobertura por DV01 está mal calculada
   - B. Que la posición no es neutral al nivel
   - C. Que es neutral a un desplazamiento paralelo, pero el nivel y la pendiente no se movían igual: cerca de tipos cero el 2 años apenas se movía, y una subida del 10 años era casi siempre un empinamiento
   - D. Que el 2 años se movía más que el 10

   *Respuesta C: Que es neutral a un desplazamiento paralelo, pero el nivel y la pendiente no se movían igual: cerca de tipos cero el 2 años apenas se movía, y una subida del 10 años era casi siempre un empinamiento.* La beta sola mezcla nivel y pendiente. En 2010-2015 la desviación típica diaria del rendimiento a 2 años era de 4,00 pb frente a 6,22 del de 10: cuando el 10 años subía, la curva se empinaba. Con la pendiente en la regresión, la beta al nivel es −0,2: la posición sí es neutral a un movimiento paralelo.

3. CME lista el NOB (notas a 10 años frente al bono) con un ratio fijo de 2:1. En los datos, el ratio por DV01 va de 1,94 a 2,93. ¿Qué implica operar con el ratio fijo?

   - A. Nada: los dos son neutrales
   - B. Que la posición solo es neutral en DV01 cuando el ratio de los DV01 está cerca de 2; el resto del tiempo queda una exposición al nivel
   - C. Que el ratio fijo siempre tiene menos riesgo
   - D. Que el ratio por DV01 es un error de los datos

   *Respuesta B: Que la posición solo es neutral en DV01 cuando el ratio de los DV01 está cerca de 2; el resto del tiempo queda una exposición al nivel.* El DV01 de cada futuro cambia con el nivel de los tipos y con el bono más barato de entregar. Un ratio fijo es cómodo para ejecutar en un solo instrumento, pero deja exposición al nivel cuando se aleja del de DV01. El primer ejercicio lo mide en el 2s10s con un ratio de 2:1: −17 a −20 USD por pb de exposición al nivel.

4. El spread RVB/RVA neutral por beta (1,15) tiene una deriva medida de +1,4 % anual con una volatilidad del 10 % en 16 años (t = 0,56). La deriva plantada es del 1,45 %. ¿Qué se concluye?

   - A. Que no hay deriva
   - B. Que hay deriva y es significativa
   - C. Que la estimación es casi exacta, pero 16 años no bastan para distinguirla de cero: el error típico de la media es de unos 2,5 puntos al año
   - D. Que la beta está mal estimada

   *Respuesta C: Que la estimación es casi exacta, pero 16 años no bastan para distinguirla de cero: el error típico de la media es de unos 2,5 puntos al año.* Con una volatilidad del 10 % anual, el error típico de una media anual estimada con 16 años es 10/√16 = 2,5 puntos. Una deriva real del 1,45 % está a 0,6 errores típicos de cero. En datos reales no se conoce la verdad: un spread de índices con una deriva así no se puede validar con su propia historia.

5. Un spread largo en el futuro del índice europeo RVE (en QEV) y corto en RVA (en USD). ¿Qué riesgo de divisa tiene?

   - A. El del nominal entero de la pata europea, como si se hubieran comprado las acciones
   - B. Ninguno
   - C. Solo el del P&L acumulado y el margen en QEV: un futuro no invierte el nominal, así que su P&L en USD tiene la volatilidad del índice en QEV (20,9 %), no la del índice pasado a USD (22,9 %)
   - D. El doble que el del contado

   *Respuesta C: Solo el del P&L acumulado y el margen en QEV: un futuro no invierte el nominal, así que su P&L en USD tiene la volatilidad del índice en QEV (20,9 %), no la del índice pasado a USD (22,9 %).* Con futuros no se cambia el nominal a QEV: se depositan márgenes y se liquida el P&L. El P&L en USD es el P&L en QEV por el tipo de cambio del día, y su volatilidad es la del índice en QEV. El contado europeo pasado a USD tiene más volatilidad (22,9 %) y menos correlación con RVA (0,78 frente a 0,86).

## Ideas clave

- Un spread de tipos neutral en DV01 iguala los dólares por punto básico de las dos patas: no gana ni pierde con un desplazamiento paralelo y su P&L sigue a la pendiente (beta de 70 USD por pb, correlación de 0,99).
- Neutral en DV01 no es neutral al nivel en una regresión simple: cerca de tipos cero el 2 años apenas se mueve, y un empinador se comporta en parte como un corto en el 10 años (beta de 34 USD por pb en 2010-2015).
- El ratio por DV01 se mueve (1,41-1,87 en el 2s10s, 1,94-2,93 en el NOB de los datos); los spreads listados usan ratios fijos y dejan exposición al nivel cuando se alejan.
- Un spread de índices neutral por nominal conserva la diferencia de betas (correlación de 0,28 con el mercado); neutral por beta, no (0,00). Su deriva, aun plantada, no se distingue de cero con 16 años.
- Con futuros, un spread entre índices de distintas monedas solo tiene riesgo de divisa en el P&L y el margen, no en el nominal.

## Recursos

### Research

- [Impacto del factor estacional sobre los bonos americanos](https://pythonparatrading.com/estacionalidad-usa-yields/) · Research-0017 · 3 min

### Documentación

- [CME Group: Interest Rate Futures Inter-Commodity Spreads (ratios fijos del TUT, NOB y demás spreads de Treasury)](https://www.cmegroup.com/trading/interest-rates/intercommodity-spread.html) · cmegroup.com
- [CME Group Client Systems Wiki: Spreads and Combinations Available on CME Globex (precio de los spreads inter-commodity)](https://cmegroupclientsite.atlassian.net/wiki/spaces/EPICSANDBOX/pages/457089763/Spreads+and+Combinations+Available+on+CME+Globex) · cmegroupclientsite.atlassian.net
- [CME Group: Stock Index Spread Opportunities (ratio de un spread entre índices por valor nominal)](https://www.cmegroup.com/education/whitepapers/stock-index-spread-opportunities.html) · cmegroup.com
- [CME Group: Trading Opportunities in Equity Index Futures (spread Nasdaq-100 frente a S&P 500)](https://www.cmegroup.com/education/courses/introduction-to-equity-index-products/trading-opportunities-in-equity-index-futures.html) · cmegroup.com

### Datos

- [Datos del nivel 3: DV01 y rendimiento del bono de referencia de cada futuro de tipos (CSV)](https://pythonparatrading.com/curso/datos/nivel-3/tipos3_dv01.csv) · Descarga · tipos3_dv01.csv
- [Datos del nivel 3: índices al contado, dividendos y tipos (CSV)](https://pythonparatrading.com/curso/datos/nivel-3/futuros3_indices_contado.csv) · Descarga · futuros3_indices_contado.csv

Lección anterior: [3.2.2 · Spreads intercommodity: crack, spark y crush](https://pythonparatrading.com/curso-python-trading/nivel-3/spreads-intercommodity-crack-spark-y-crush/)

Lección siguiente: [3.2.4 · Ratios de cobertura: por nominal, por DV01 y por volatilidad](https://pythonparatrading.com/curso-python-trading/nivel-3/ratios-de-cobertura-nominal-dv01-y-volatilidad/)
