Lección 1.2.3 · 65 min

Futuros: especificaciones, margen, roll y contango

Un futuro es un compromiso estandarizado de comprar o vender un activo en una fecha a un precio fijado hoy. No se paga al entrar: se deposita una garantía y cada día se cobran o pagan las diferencias. Esta lección desmonta un contrato ficticio sobre un índice, FIX, con siete años de precios de liquidación de todos sus vencimientos.

Fig. — Vida de cada contrato FIX en 2024 y 2025: cotizan unos nueve meses y son el cercano (barra) solo los tres últimos
Lecciones del nivel 1
  1. 1.1 · Cómo funcionan los mercados

    1. 1.1.1 Participantes y centros de negociación
    2. 1.1.2 Sesiones, subastas, festivos y calendarios
    3. 1.1.3 Libro de órdenes: bid, ask, spread y profundidad
    4. 1.1.4 Tipos de órdenes
    5. 1.1.5 Costes, liquidación, apalancamiento y margen
  2. 1.2 · Clases de activos

    1. 1.2.1 Acciones: splits, dividendos y eventos corporativos
    2. 1.2.2 ETFs: réplica, tracking error, apalancados y UCITS
    3. 1.2.3 Futuros: especificaciones, margen, roll y contango
    4. 1.2.4 Forex: pares, pips, lotes, rollover y CFD
    5. 1.2.5 Opciones: call, put, valor intrínseco y valor temporal
    6. 1.2.6 Cripto: spot, perpetuos, funding y custodia
    7. 1.2.7 Renta fija y tipos de interés; CFDs y productos apalancados
  3. 1.3 · Fuentes de datos de mercado

    1. 1.3.1 Tipos de datos de mercado: EOD, barras, ticks, libro y referencia
    2. 1.3.2 Fuentes de datos gratuitas
    3. 1.3.3 APIs de datos retail y prosumer
    4. 1.3.4 Proveedores de datos profesionales
    5. 1.3.5 Datos de cripto y on-chain
    6. 1.3.6 Brókeres como fuente de datos
    7. 1.3.7 Licencias y términos de uso de datos
    8. 1.3.8 Cómo elegir proveedor de datos
  4. 1.4 · Ingeniería de datos financieros

    1. 1.4.1 Descarga por REST y websockets: paginación, límites y reintentos
    2. 1.4.2 Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias
    3. 1.4.3 Ajustes por splits y dividendos: precios ajustados y sin ajustar
    4. 1.4.4 Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo
    5. 1.4.5 Construcción de barras: tiempo, ticks, volumen, dólar y desequilibrio
    6. 1.4.6 Series continuas de futuros: reglas de roll, ajuste por diferencia y ajuste por ratio
    7. 1.4.7 Almacenamiento: CSV, Parquet, particionado, DuckDB, TimescaleDB y ArcticDB
    8. 1.4.8 Pipeline reproducible: descarga, validación, actualización incremental y tests de calidad
  5. 1.5 · Datos fundamentales y macro

    1. 1.5.1 Estados financieros, ratios, XBRL y SEC EDGAR
    2. 1.5.2 Datos macro, calendarios económicos, estimaciones y transcripciones
  6. 1.6 · Análisis exploratorio financiero

    1. 1.6.1 Rentabilidades, volatilidad, correlaciones móviles y drawdown
    2. 1.6.2 Hechos estilizados: colas gruesas, agrupamiento, autocorrelación y apalancamiento
    3. 1.6.3 Estacionalidad: día de la semana, mes, cambio de mes y sesiones intradía
  7. 1.7 · Análisis técnico programado

    1. 1.7.1 Indicadores técnicos en Python
    2. 1.7.2 Implementación propia frente a TA-Lib: validar resultados
    3. 1.7.3 Patrones de velas y soportes y resistencias
    4. 1.7.4 Multi-timeframe sin anticipación

Un contrato estandarizado

Un futuro es un contrato por el que dos partes se comprometen a comprar y vender un activo (el subyacente) en una fecha futura (el vencimiento) a un precio que se fija hoy. A diferencia de un contrato a plazo privado (forward, lección 1.2.4), un futuro se negocia en una bolsa, con condiciones idénticas para todos, y una cámara de contrapartida se interpone entre comprador y vendedor (lección 1.1.1). Lo único que se negocia es el precio; todo lo demás lo fija la ficha del contrato.

Los datos del curso incluyen un futuro ficticio, FIX, sobre un índice de acciones de precios (sin dividendos). Su ficha:

IN [01]python
import numpy as np
import pandas as pd

esp = pd.read_csv("fix_especificaciones.csv").iloc[0]
print(esp.drop("regla_vencimiento").to_string())
print(esp["regla_vencimiento"])
OUT [01]Especificaciones de FIX
multiplicador                50
tick                       0.25
valor_tick                 12.5
margen_inicial            16500
margen_mantenimiento      15000
meses                   H,M,U,Z
tercer viernes del mes del contrato (si no hay sesión, la anterior); liquidación final en efectivo al cierre del índice ese día; último día de negociación = vencimiento

Cada campo responde a una pregunta:

CampoPreguntaFIX
Subyacente¿Sobre qué?Índice FIX de precios
Multiplicador¿Cuánto vale un punto?50 USD
Tick¿Cuál es la variación mínima del precio?0,25 puntos
Valor del tick¿Cuánto se gana o pierde por tick y contrato?0,25 × 50 = 12,50 USD
Meses¿Qué vencimientos hay?Marzo, junio, septiembre, diciembre (H, M, U, Z)
Vencimiento¿Qué día?Tercer viernes del mes (o la sesión anterior)
Liquidación final¿Cómo se cierra?En efectivo, al cierre del índice ese día
Márgenes¿Qué garantía se deposita?16.500 USD iniciales, 15.000 de mantenimiento

Los códigos de mes (H marzo, M junio, U septiembre, Z diciembre) son la convención de las bolsas de EE. UU.; el contrato FIXH24 es el de marzo de 2024. Con un precio y la ficha se calcula todo lo demás:

IN [02]python
indice = pd.read_csv("fix_indice_diario.csv", parse_dates=["fecha"],
                     index_col="fecha")["indice"]
S = indice["2025-06-02"]
nominal = S * esp["multiplicador"]
print(f"Índice: {S:.2f}  nominal de un contrato: {nominal:,.0f} USD")
print(f"Margen inicial: {esp['margen_inicial']:,} USD"
      f" = {esp['margen_inicial'] / nominal:.1%} del nominal")
print(f"Apalancamiento: {nominal / esp['margen_inicial']:.1f} a 1")
print(f"Un 1 % del índice: {0.01 * nominal:,.0f} USD por contrato")
OUT [02]Nominal, tick y apalancamiento
Índice: 6359.10  nominal de un contrato: 317,955 USD
Margen inicial: 16,500 USD = 5.2% del nominal
Apalancamiento: 19.3 a 1
Un 1 % del índice: 3,180 USD por contrato

Un contrato controla 317.955 USD de índice con 16.500 de garantía: un apalancamiento de 19,3 a 1. Un movimiento del 1 % del índice son 3.180 USD, casi una quinta parte del margen. Para dimensionar una posición en futuros hay que pensar siempre en el nominal, nunca en el margen (lección 0.1.2).

Los contratos reales siguen el mismo esquema. Algunas cifras de sus fichas oficiales:

ContratoMultiplicadorTickVencimiento y liquidación final
E-mini S&P 500 (CME)50 USD × índice0,25 puntos = 12,50 USDEfectivo; cotización especial de apertura del índice el tercer viernes del mes
Futuro IBEX 35 (MEFF)10 EUR × índicePor circularTercer viernes; media del índice de 16:15 a 16:45, un valor por minuto
Futuro Mini IBEX 35 (MEFF)1 EUR × índice5 puntos = 5 EURTercer viernes; igual que el IBEX 35

FIX imita al E-mini S&P 500 en multiplicador y tick. La diferencia está en la liquidación final: en el E-mini no es el cierre del índice sino una cotización especial calculada con los precios de apertura de sus acciones el día del vencimiento (regla 35803.A del capítulo 358), y la negociación del contrato que vence termina al empezar la sesión de la NYSE ese día. En MEFF, la liquidación diaria del primer vencimiento es la media ponderada por volumen de las operaciones del libro entre las 17:29 y las 17:30. Detalles así importan cuando se compara un futuro con su índice en la fecha de vencimiento.

Muchos contratos vivos a la vez

Cada día cotizan varios vencimientos del mismo futuro. fix_contratos.parquet tiene una fila por sesión y contrato, con el precio de liquidación diario (el que fija la cámara al cierre para calcular pérdidas y ganancias), el volumen y el interés abierto (contratos vivos, no cerrados):

IN [03]python
fut = pd.read_parquet("fix_contratos.parquet")
fut["dias"] = (fut["vencimiento"] - fut["fecha"]).dt.days
dia = fut[fut["fecha"] == "2025-06-02"]
dia[["contrato", "vencimiento", "dias", "liquidacion", "volumen",
     "interes_abierto"]]
OUT [03]Los contratos vivos un día
     contrato vencimiento  dias  liquidacion  volumen  interes_abierto
4867   FIXM25  2025-06-20    18      6367.75   315854           786283
4868   FIXU25  2025-09-19   109      6419.00     4406            24548
4869   FIXZ25  2025-12-19   200      6462.50      729             3201

El 2 de junio de 2025 hay tres vencimientos vivos. El de junio, a 18 días, concentra casi todo: 786.283 contratos de interés abierto frente a 24.548 del de septiembre. Es el contrato cercano (front month). Los demás existen, pero casi nadie los negocia hasta que se acerca su turno.

La figura de la cabecera es la «escalera» de 2024 y 2025: cada contrato cotiza unos nueve meses, pero solo es el cercano durante los tres últimos. La línea gruesa marca cuándo cada uno tiene el mayor interés abierto. Todos vencen en viernes:

IN [04]python
venc = fut.groupby("contrato")["vencimiento"].first()
venc = venc[venc.dt.year == 2025]
pd.DataFrame({"vencimiento": venc.dt.date,
              "dia": venc.dt.day_name()})
OUT [04]Fechas de vencimiento
         vencimiento     dia
contrato
FIXH25    2025-03-21  Friday
FIXM25    2025-06-20  Friday
FIXU25    2025-09-19  Friday
FIXZ25    2025-12-19  Friday

Margen y liquidación diaria

Comprar un futuro no cuesta su nominal. El comprador y el vendedor depositan una garantía, el margen inicial, y a partir de ahí la cámara liquida cada día la diferencia entre el precio de liquidación de hoy y el de ayer (mark to market): la parte que gana cobra y la que pierde paga, en efectivo, antes de la sesión siguiente. El ejemplo de la ficha de MEFF lo resume: comprar 30 futuros IBEX 35 a 10.000 con una liquidación de 10.020 al final de la sesión da (10.020 − 10.000) × 30 × 10 = +6.000 euros ese día.

liquidación diarialiquidación diariaCompradorMiembroVendedorMiembroCámara
Fuente Mermaid
flowchart LR
  C[Comprador] --> MC[Miembro]
  V[Vendedor] --> MV[Miembro]
  MC -- liquidación diaria --> K[Cámara]
  MV -- liquidación diaria --> K

Si las pérdidas dejan el saldo de la cuenta por debajo del margen de mantenimiento, el bróker hace una llamada de margen: hay que aportar efectivo hasta volver al margen inicial. Si no se aporta, el bróker cierra la posición.

saldo bajo mínimoaporta efectivono aportavende o venceAbiertaLlamadaCerrada
Fuente Mermaid
stateDiagram-v2
  [*] --> Abierta
  Abierta --> Llamada: saldo bajo mínimo
  Llamada --> Abierta: aporta efectivo
  Llamada --> Cerrada: no aporta
  Abierta --> Cerrada: vende o vence
  Cerrada --> [*]

Con los precios de liquidación de FIX se puede simular la cuenta de margen de un largo en el contrato de marzo de 2025, abierto el 16 de diciembre de 2024 y mantenido hasta el vencimiento:

IN [05]python
def cuenta_margen(precios, contratos=1, lado=1):
    """Saldo de la cuenta de margen con liquidación diaria.

    lado = 1 para un largo, -1 para un corto. Si el saldo baja del
    margen de mantenimiento, se aporta lo necesario para volver al
    margen inicial.
    """
    saldo, filas = float(esp["margen_inicial"]) * contratos, []
    anterior = precios.iloc[0]
    for fecha, precio in precios.items():
        puntos = lado * (precio - anterior)
        pyg = puntos * esp["multiplicador"] * contratos
        saldo += pyg
        aporte = 0.0
        if saldo < esp["margen_mantenimiento"] * contratos:
            aporte = esp["margen_inicial"] * contratos - saldo
            saldo += aporte
        filas.append((fecha, precio, pyg, aporte, saldo))
        anterior = precio
    cols = ["liquidacion", "pyg", "aporte", "saldo"]
    tabla = pd.DataFrame(filas, columns=["fecha"] + cols)
    return tabla.set_index("fecha")

h25 = fut[fut["contrato"] == "FIXH25"].set_index("fecha")["liquidacion"]
cm = cuenta_margen(h25.loc["2024-12-16":])
cm.loc["2025-02-26":"2025-03-07"]
OUT [05]Liquidación diaria de un largo
            liquidacion     pyg  aporte    saldo
fecha
2025-02-26      5836.25 -1150.0  2500.0  16500.0
2025-02-27      5757.50 -3937.5  3937.5  16500.0
2025-02-28      5753.75  -187.5     0.0  16312.5
2025-03-03      5601.25 -7625.0  7812.5  16500.0
2025-03-04      5618.25   850.0     0.0  17350.0
2025-03-05      5503.50 -5737.5  4887.5  16500.0
2025-03-06      5334.50 -8450.0  8450.0  16500.0
2025-03-07      5234.75 -4987.5  4987.5  16500.0

A finales de febrero de 2025 el índice empieza a caer con fuerza. Cada día de pérdidas grandes deja el saldo por debajo de 15.000 USD y obliga a aportar hasta volver a 16.500: 2.500 USD el 26 de febrero, 3.937,50 el 27, 7.812,50 el 3 de marzo y, del 5 al 7 de marzo, 4.887,50, 8.450 y 4.987,50. En los seis días de la tabla con aportación, la cuenta pide 32.575 USD: casi el doble del margen inicial entero.

IN [06]python
llamadas = cm[cm["aporte"] > 0]
print("Llamadas de margen:", len(llamadas))
print(f"Efectivo aportado: {llamadas['aporte'].sum():,.2f} USD")
print(f"Resultado de la posición: {cm['pyg'].sum():,.2f} USD")
print(f"Saldo final de la cuenta: {cm['saldo'].iloc[-1]:,.2f} USD")
OUT [06]Resumen de las llamadas de margen
Llamadas de margen: 12
Efectivo aportado: 64,112.50 USD
Resultado de la posición: -65,332.50 USD
Saldo final de la cuenta: 15,280.00 USD
Fig. — Un largo en FIXH25 del 16 de diciembre de 2024 al vencimiento: resultado acumulado y efectivo aportado en llamadas de margen

La posición pierde 65.332,50 USD: cuatro veces el margen inicial. El inversor ha tenido que aportar 64.112,50 USD en 12 llamadas, y al vencimiento le quedan 15.280 en la cuenta. Las cuentas cuadran: 16.500 + 64.112,50 − 65.332,50 = 15.280. El margen inicial no es la pérdida máxima: es solo lo que la cámara pide para cubrir uno o dos días malos.

Base, coste de mantenimiento y convergencia

¿Por qué un futuro cotiza a un precio distinto del contado? Porque comprar el futuro y comprar el índice no son lo mismo. Quien compra el índice paga hoy todo su valor (y deja de cobrar intereses por ese dinero) y cobra los dividendos; quien compra el futuro no paga nada hoy y no cobra dividendos. Para que no haya arbitraje, el futuro tiene que compensar esa diferencia, el coste de mantenimiento (cost of carry):

Ft=St e(r−q) τF_t = S_t \, e^{(r - q)\,\tau}

donde StS_t es el índice, rr el tipo de interés, qq el rendimiento por dividendo del índice y τ\tau el tiempo al vencimiento en años. La diferencia Ft−StF_t - S_t es la base. El 2 de junio de 2025, con el tipo a tres meses de la curva del curso y un rendimiento por dividendo del 1,35 %:

IN [07]python
curva = pd.read_csv("curva_tipos_diaria.csv", parse_dates=["fecha"],
                    index_col="fecha")
r = curva.loc["2025-06-02", "3m"] / 100
q = 0.0135
dia = dia.assign(teorico=S * np.exp((r - q) * dia["dias"] / 365))
dia["base"] = dia["liquidacion"] - S
print(f"Índice {S}, r = {r:.3%}, q = {q:.2%}")
dia[["contrato", "dias", "liquidacion", "teorico", "base"]].round(2)
OUT [07]Precio teórico frente a liquidación
Índice 6359.1, r = 4.354%, q = 1.35%
     contrato  dias  liquidacion  teorico    base
4867   FIXM25    18      6367.75  6368.53    8.65
4868   FIXU25   109      6419.00  6416.40   59.90
4869   FIXZ25   200      6462.50  6464.64  103.40

Los tres precios de liquidación están a menos de tres puntos de su valor teórico: la diferencia es el redondeo al tick y un pequeño ruido. La base crece con el plazo: 8,65 puntos a 18 días, 59,90 a 109 y 103,40 a 200. Y como el plazo se acorta cada día, la base de un contrato se va consumiendo hasta desaparecer:

IN [08]python
z25 = fut[fut["contrato"] == "FIXZ25"].set_index("fecha")
base = (z25["liquidacion"] - indice.reindex(z25.index)).rename("base")
pd.concat([z25["dias"], base.round(2)], axis=1).iloc[[0, 50, 100,
                                                      150, -2, -1]]
OUT [08]La base del FIXZ25 hasta su vencimiento
            dias    base
fecha
2025-03-19   275  109.70
2025-05-30   203  103.12
2025-08-12   129   63.00
2025-10-22    58   27.06
2025-12-18     1    0.65
2025-12-19     0    0.00
Fig. — Base del futuro FIXZ25 frente al índice, de su primer día de cotización a su vencimiento

El FIXZ25 empieza a cotizar en marzo de 2025 con una base de 109,70 puntos a 275 días y termina el 19 de diciembre con base cero: su liquidación final es el cierre del índice. Por eso un futuro sobre índice «pierde» frente al índice cuando el tipo supera al dividendo: no es una mala rentabilidad, es el interés que el comprador del futuro no paga y que sí cobra el dinero que no ha gastado.

Contango y backwardation

La estructura temporal es el precio de cada vencimiento en un mismo día. Tiene dos formas básicas:

  • Contango: los vencimientos lejanos cotizan más caros que los cercanos (y que el contado). En un índice, cuando r>qr > q.
  • Backwardation: los lejanos cotizan más baratos. En un índice, cuando r<qr < q.
IN [09]python
def curva_futuros(fecha):
    d = fut[(fut["fecha"] == fecha) & (fut["dias"] > 0)]
    s = indice[fecha]
    return d.assign(sobre_contado_pct=100 * (d["liquidacion"] / s - 1))

for fecha in ["2021-06-01", "2025-06-02"]:
    print(fecha, f"tipo 3m: {curva.loc[fecha, '3m']:.2f} %")
    print(curva_futuros(fecha)[["contrato", "dias", "liquidacion",
                                "sobre_contado_pct"]].round(2))
OUT [09]Estructura temporal en dos fechas
2021-06-01 tipo 3m: 0.16 %
     contrato  dias  liquidacion  sobre_contado_pct
1836   FIXM21    17      4040.75              -0.07
1837   FIXU21   108      4022.25              -0.52
1838   FIXZ21   199      4010.75              -0.81
2025-06-02 tipo 3m: 4.35 %
     contrato  dias  liquidacion  sobre_contado_pct
4867   FIXM25    18      6367.75               0.14
4868   FIXU25   109      6419.00               0.94
4869   FIXZ25   200      6462.50               1.63
Fig. — Estructura temporal de los futuros FIX en dos fechas: backwardation en 2021 y contango en 2025

El 1 de junio de 2021, con el tipo a tres meses en el 0,16 %, por debajo del rendimiento por dividendo, la curva baja: backwardation. El 2 de junio de 2025, con el tipo en el 4,35 %, sube: contango. Para medir los periodos con todos los datos, basta comparar cada día los dos vencimientos más cercanos y anualizar la diferencia:

IN [10]python
vivos = fut[fut["dias"] > 0].sort_values(["fecha", "vencimiento"])
dos = vivos.groupby("fecha").head(2)
par = dos.groupby("fecha").agg(f1=("liquidacion", "first"),
                               f2=("liquidacion", "last"),
                               d1=("dias", "first"),
                               d2=("dias", "last"))
par["carry"] = np.log(par["f2"] / par["f1"]) / ((par["d2"] - par["d1"])
                                                 / 365)
anual = par.groupby(par.index.year)["carry"]
pd.DataFrame({"contango_pct_dias": 100 * anual.apply(lambda x:
                                                     (x > 0).mean()),
              "carry_medio_pct": 100 * anual.mean()}).round(1)
OUT [10]Contango y backwardation año a año
       contango_pct_dias  carry_medio_pct
fecha
2019                62.7              0.2
2020                 0.0             -1.4
2021                 0.0             -1.4
2022                62.5              0.7
2023               100.0              3.5
2024               100.0              3.5
2025               100.0              2.7

Todo 2020 y 2021 en backwardation, con un carry medio del −1,4 % anual: los tipos estaban casi a cero y el dividendo del índice pesaba más. Todo 2023, 2024 y 2025 en contango, con un carry de 2,7 a 3,5 puntos al año. 2019 y 2022 son años de transición, con un 63 % de las sesiones en contango.

¿Qué cambia para un inversor? Quien mantiene una posición larga en futuros y la renueva cada trimestre vende el contrato que vence (cerca del contado) y compra el siguiente (más caro en contango). Ese «coste del roll» no es una pérdida extra: es el mismo coste de mantenimiento que la base va consumiendo, y lo compensa el interés del efectivo que no se ha invertido. Comparar la rentabilidad de un futuro con la del índice sin sumar ese interés hace parecer que el futuro rinde peor de lo que rinde.

El roll: cuándo se mueve la liquidez

Unos días antes del vencimiento, la mayoría de las posiciones se trasladan al contrato siguiente: se cierra el cercano y se abre el siguiente, a menudo con una sola orden de spread de calendario. El volumen y el interés abierto migran:

IN [11]python
roll = fut[fut["contrato"].isin(["FIXM25", "FIXU25"])
           & fut["fecha"].between("2025-06-05", "2025-06-23")]
tabla = roll.pivot(index="fecha", columns="contrato",
                   values="interes_abierto")
cruce = tabla[tabla["FIXU25"] > tabla["FIXM25"]].index[0]
print("El siguiente supera al cercano el", cruce.date())
tabla
OUT [11]El roll de junio de 2025
El siguiente supera al cercano el 2025-06-13
contrato      FIXM25    FIXU25
fecha
2025-06-05  778177.0   34906.0
2025-06-06  764556.0   49050.0
2025-06-09  734660.0   79671.0
2025-06-10  672936.0  141139.0
2025-06-11  563376.0  247645.0
2025-06-12  413715.0  393825.0
2025-06-13  263789.0  540829.0
2025-06-16  153647.0  648266.0
2025-06-17   90019.0  709669.0
2025-06-18   58420.0  741939.0
2025-06-20   44111.0  763316.0
2025-06-23       NaN  805582.0
Fig. — El roll de junio de 2025: interés abierto (arriba) y volumen (abajo) del contrato que vence, FIXM25, y del siguiente, FIXU25

El 5 de junio, el FIXM25 tiene 778.177 contratos abiertos y el FIXU25, 34.906. Una semana después se cruzan: el 12 de junio casi se igualan (413.715 frente a 393.825) y el viernes 13 el de septiembre ya tiene más interés abierto. Ese mismo día el volumen del FIXU25 se dispara (807.106 contratos): es el día de más actividad del roll. El 20 de junio, el día del vencimiento, al FIXM25 le quedan 44.111 contratos, un 6 % del máximo, que se liquidan en efectivo al cierre del índice.

Para un sistema de trading, esto tiene dos consecuencias. Primera, quien opera el cercano durante la semana del roll lo hace en un contrato que se vacía: las horquillas se abren y el coste sube. Segunda, para tener una serie larga hay que encadenar contratos, y la regla para saltar de uno a otro (por fecha, por volumen, por interés abierto) y cómo se corrige el salto de precio entre ellos son decisiones que cambian los resultados de un backtest. Esa construcción es la lección 1.4.6.

Lo que esto cambia en tus datos

  • El precio de un futuro es un precio de liquidación. El dato diario estándar no es el último cruce, sino el precio que fija la cámara. Para comparar con el índice hay que saber a qué hora y cómo se calcula cada uno.
  • El tamaño se mide en nominal. Un contrato de FIX son unos 300.000 USD; el margen es una garantía, no el riesgo.
  • El efectivo de reserva es parte de la estrategia. Las llamadas de margen ocurren en los días malos y pueden sumar varias veces el margen inicial.
  • La base no es rentabilidad. Futuro e índice difieren en el coste de mantenimiento; la rentabilidad de un futuro se compara con la del índice menos el tipo de interés, no con la del índice a secas.
  • Las series continuas se construyen. No existe «el precio del futuro» de diez años: existe una regla de roll y un ajuste (lección 1.4.6).

Ejercicios

  1. Repite la simulación de la cuenta de margen para un corto en el FIXH25 desde el 16 de diciembre de 2024. ¿Cuántas llamadas de margen recibe y cuánto efectivo acumula la cuenta al vencimiento?
Solución
IN [12]python
corto = cuenta_margen(h25.loc["2024-12-16":], lado=-1)
print("Llamadas de margen:", (corto["aporte"] > 0).sum())
print(f"Aportado: {corto['aporte'].sum():,.2f} USD")
print(f"Resultado: {corto['pyg'].sum():,.2f} USD")
print(f"Saldo final: {corto['saldo'].iloc[-1]:,.2f} USD")
OUT [12]El corto en FIXH25
Llamadas de margen: 5
Aportado: 9,987.50 USD
Resultado: 65,332.50 USD
Saldo final: 91,820.00 USD

El corto gana exactamente lo que pierde el largo, 65.332,50 USD, y termina con 91.820 USD en la cuenta. Pero el camino no es cómodo: recibe 5 llamadas de margen, por 9.987,50 USD: cuatro en la segunda quincena de diciembre de 2024 y una el 19 de febrero de 2025, días en que el índice sube. Un futuro es un juego de suma cero entre comprador y vendedor antes de costes; la cámara solo traslada el efectivo de uno a otro cada día.

  1. Para cada vencimiento de 2024, encuentra el primer día en que el interés abierto del contrato siguiente supera al del que vence. ¿Cuántas sesiones antes del vencimiento ocurre?
Solución
IN [13]python
oi = fut.pivot(index="fecha", columns="contrato",
               values="interes_abierto")
sesiones = indice.index
pares = [("FIXH24", "FIXM24"), ("FIXM24", "FIXU24"),
         ("FIXU24", "FIXZ24"), ("FIXZ24", "FIXH25")]
for viejo, nuevo in pares:
    v = fut.loc[fut["contrato"] == viejo, "vencimiento"].iloc[0]
    x = oi[[viejo, nuevo]].dropna()
    x = x[x.index > v - pd.Timedelta(days=30)]  # el último mes
    dia_cruce = x[x[nuevo] > x[viejo]].index[0]
    antes = ((sesiones > dia_cruce) & (sesiones <= v)).sum()
    print(viejo, "->", nuevo, dia_cruce.date(), f"({antes} sesiones)")
OUT [13]Cruce del interés abierto en cada roll de 2024
FIXH24 -> FIXM24 2024-03-11 (4 sesiones)
FIXM24 -> FIXU24 2024-06-14 (4 sesiones)
FIXU24 -> FIXZ24 2024-09-16 (4 sesiones)
FIXZ24 -> FIXH25 2024-12-16 (4 sesiones)

En los cuatro rolls de 2024 el cruce ocurre a cuatro sesiones del vencimiento (contando el propio día del vencimiento), en la semana anterior. Una regla de roll «por interés abierto» cambiaría de contrato esos días; una regla «por fecha fija», por ejemplo ocho sesiones antes, lo haría antes, cuando el contrato nuevo aún tiene menos liquidez. El filtro del último mes hace falta: cuando el contrato nuevo empieza a cotizar, nueve meses antes, los dos son lejanos y su interés abierto, pequeño, puede cruzarse por casualidad.

  1. Un compañero dice que los ETF sobre futuros de índices «pierden dinero en cada roll por el contango». Explica qué parte de la frase es correcta y qué falta.
Solución

Es cierto que en contango el contrato nuevo cuesta más que el que vence, y que el precio de un futuro largo «baja» hacia el contado a medida que se acerca el vencimiento. Lo que falta es que ese contango es, en un futuro financiero, el coste de mantenimiento: el tipo de interés menos el dividendo. Quien compra el futuro en lugar del índice no desembolsa el nominal y cobra intereses por ese efectivo, que compensan la base. Si se suma el interés del efectivo (como hace un ETF bien gestionado), la rentabilidad se parece a la del índice de rentabilidad total, menos costes. En materias primas, donde la estructura temporal refleja almacenamiento y expectativas, el roll sí puede costar mucho más que el interés.

Respuesta plegada en cada pregunta

Autoevaluación

  1. El futuro FIX cotiza a 6.400 puntos con un multiplicador de 50 USD y un tick de 0,25. ¿Cuánto gana o pierde un contrato por cada tick y cuál es su nominal?

    • A0,25 USD por tick; nominal de 6.400 USD
    • B12,50 USD por tick; nominal de 320.000 USD
    • C50 USD por tick; nominal de 320.000 USD
    • D12,50 USD por tick; nominal de 16.500 USD
    Ver respuesta

    Respuesta B. 12,50 USD por tick; nominal de 320.000 USD

    Valor del tick = 0,25 × 50 = 12,50 USD; nominal = 6.400 × 50 = 320.000 USD. Los 16.500 USD son el margen inicial: lo que se deposita, no lo que se controla.

  2. Una cuenta tiene un margen inicial de 16.500 USD y uno de mantenimiento de 15.000. Tras una pérdida diaria, el saldo queda en 14.200 USD. ¿Qué ocurre?

    • ANada: todavía hay saldo positivo
    • BLlamada de margen: hay que aportar 800 USD para volver al mantenimiento
    • CLlamada de margen: hay que aportar 2.300 USD para volver al margen inicial
    • DLa posición se cierra automáticamente
    Ver respuesta

    Respuesta C. Llamada de margen: hay que aportar 2.300 USD para volver al margen inicial

    Al caer por debajo del mantenimiento, la cuenta tiene que volver al margen inicial: 16.500 − 14.200 = 2.300 USD. Si no se aporta a tiempo, el bróker puede cerrar la posición.

  3. Con un tipo de interés del 4,35 % y un rendimiento por dividendo del índice del 1,35 %, ¿qué estructura temporal se espera en los futuros sobre ese índice?

    • ABackwardation: los vencimientos lejanos más baratos
    • BContango: los vencimientos lejanos más caros, en torno a un 3 % anual por encima del contado
    • CPlana: todos los vencimientos al mismo precio
    • DNo se puede saber sin conocer la opinión del mercado
    Ver respuesta

    Respuesta B. Contango: los vencimientos lejanos más caros, en torno a un 3 % anual por encima del contado

    Por no arbitraje, F = S·e^((r−q)τ). Con r − q = 3 %, cada vencimiento cotiza aproximadamente un 3 % anual por encima del contado. En un futuro financiero la curva la fija el coste de mantenimiento, no una previsión.

  4. ¿Qué pasa con la base (futuro − contado) el día del vencimiento?

    • AEs igual al dividendo pendiente
    • BVale cero: el precio de liquidación final se fija con el propio índice
    • CEs igual al margen inicial
    • DDepende del volumen de ese día
    Ver respuesta

    Respuesta B. Vale cero: el precio de liquidación final se fija con el propio índice

    En FIX, la liquidación final es el cierre del índice ese día, así que la base se anula. En los contratos reales cambia la referencia (la cotización especial de apertura en el E-mini S&P 500, una media del IBEX 35 entre las 16:15 y las 16:45 en MEFF), pero la idea es la misma.

  5. En la semana del roll de junio de 2025, el interés abierto del FIXU25 supera al del FIXM25 el 13 de junio. ¿Por qué importa para un sistema de trading?

    • ANo importa: los dos contratos son el mismo activo
    • BPorque a partir de ahí la liquidez está en el siguiente vencimiento: seguir en el cercano encarece la ejecución, y una serie continua tiene que decidir cuándo cambiar
    • CPorque el contrato cercano deja de cotizar ese día
    • DPorque el margen se duplica
    Ver respuesta

    Respuesta B. Porque a partir de ahí la liquidez está en el siguiente vencimiento: seguir en el cercano encarece la ejecución, y una serie continua tiene que decidir cuándo cambiar

    El cercano sigue cotizando hasta el vencimiento (20 de junio), pero con cada vez menos interés abierto. El momento y la forma de pasar de un contrato a otro es la decisión central de una serie continua (lección 1.4.6).

Ideas clave

  • El contrato fija todo salvo el precio: subyacente, multiplicador, tick, meses, último día y forma de liquidación. En FIX, 50 USD por punto y 12,50 USD por tick: un nominal de más de 300.000 USD con 16.500 de margen.
  • La liquidación diaria convierte cada movimiento en efectivo. Un largo en el FIXH25 desde mediados de diciembre de 2024 perdió 65.332 USD hasta el vencimiento y recibió 12 llamadas de margen: el margen inicial no es la pérdida máxima.
  • En un futuro financiero, F = S·e^((r−q)τ): la base es el coste de mantenimiento y se anula al vencimiento.
  • Contango (lejanos más caros) cuando el tipo supera al dividendo; backwardation cuando no. En FIX, backwardation todo 2020 y 2021, con tipos casi a cero; contango desde 2023.
  • En las ~8 sesiones antes del vencimiento, el volumen y el interés abierto pasan al contrato siguiente. Quién hace el roll y cuándo condiciona cualquier serie continua.

Recursos