Lección 1.2.5 · 60 min
Opciones: call, put, valor intrínseco y valor temporal
Una opción es un derecho con fecha de caducidad, y su precio se divide en lo que vale ejercerla hoy y lo que vale esperar. La lección lo mide sobre la cadena completa de opciones del índice ficticio FIX de un día: 584 contratos, cuatro vencimientos.
- Módulo
- 1.2 · Clases de activos
- Duración
- 60 min
Lecciones del nivel 1
1.1 · Cómo funcionan los mercados
1.2 · Clases de activos
- 1.2.1 Acciones: splits, dividendos y eventos corporativos
- 1.2.2 ETFs: réplica, tracking error, apalancados y UCITS
- 1.2.3 Futuros: especificaciones, margen, roll y contango
- 1.2.4 Forex: pares, pips, lotes, rollover y CFD
- 1.2.5 Opciones: call, put, valor intrínseco y valor temporal
- 1.2.6 Cripto: spot, perpetuos, funding y custodia
- 1.2.7 Renta fija y tipos de interés; CFDs y productos apalancados
1.3 · Fuentes de datos de mercado
- 1.3.1 Tipos de datos de mercado: EOD, barras, ticks, libro y referencia
- 1.3.2 Fuentes de datos gratuitas
- 1.3.3 APIs de datos retail y prosumer
- 1.3.4 Proveedores de datos profesionales
- 1.3.5 Datos de cripto y on-chain
- 1.3.6 Brókeres como fuente de datos
- 1.3.7 Licencias y términos de uso de datos
- 1.3.8 Cómo elegir proveedor de datos
1.4 · Ingeniería de datos financieros
- 1.4.1 Descarga por REST y websockets: paginación, límites y reintentos
- 1.4.2 Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias
- 1.4.3 Ajustes por splits y dividendos: precios ajustados y sin ajustar
- 1.4.4 Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo
- 1.4.5 Construcción de barras: tiempo, ticks, volumen, dólar y desequilibrio
- 1.4.6 Series continuas de futuros: reglas de roll, ajuste por diferencia y ajuste por ratio
- 1.4.7 Almacenamiento: CSV, Parquet, particionado, DuckDB, TimescaleDB y ArcticDB
- 1.4.8 Pipeline reproducible: descarga, validación, actualización incremental y tests de calidad
1.5 · Datos fundamentales y macro
1.6 · Análisis exploratorio financiero
1.7 · Análisis técnico programado
Un derecho con fecha de caducidad
Una opción es un contrato que da a quien la compra el derecho, pero no la obligación, de comprar o vender un activo (el subyacente) a un precio fijado de antemano (el strike o precio de ejercicio) hasta una fecha (el vencimiento). Hay dos tipos:
- Una call da el derecho a comprar el subyacente al strike. Le interesa a quien espera que suba.
- Una put da el derecho a vender el subyacente al strike. Le interesa a quien espera que baje o quiere protegerse de una caída.
Por ese derecho, el comprador paga una prima al vendedor en el momento de la compra. El vendedor (también llamado emisor o writer) cobra la prima y asume la obligación contraria: si el comprador ejerce, tiene que vender (en la call) o comprar (en la put) al strike. La asimetría es la clave de todo lo que sigue: el comprador arriesga como mucho la prima; el vendedor cobra poco y seguro a cambio de un riesgo que puede ser grande.
Fuente Mermaid
flowchart TB
C[Comprador] -- prima --> V[Vendedor]
C --> X{¿Acaba dentro?}
X -- sí --> E[Ejerce]
X -- no --> N[Expira sin valor]
E --> L[Vendedor paga]Al vencimiento, el comprador ejerce solo si le conviene: una call si el subyacente está por encima del strike, una put si está por debajo. La liquidación puede ser física (se entregan las acciones o el futuro subyacente) o en efectivo (se paga la diferencia entre el precio de liquidación y el strike). Las opciones sobre índices, como las de esta lección, se liquidan en efectivo: no se puede entregar un índice.
Cada contrato tiene un multiplicador: cuántas unidades de dinero vale un punto de prima. En las opciones de la lección es de 100 USD por punto, como en las opciones SPX de Cboe sobre el S&P 5001Nota 1 · Especificaciones de las opciones SPX en la página de Cboe enlazada en los recursos: multiplicador de 100 USD, estilo europeo y liquidación en efectivo.: una prima de 174,05 puntos cuesta 17.405 USD por contrato. Olvidar el multiplicador es el error más barato de cometer en un notebook y el más caro en una cuenta real.
La cadena de FIX
Los datos son una foto de la cadena de opciones de un índice ficticio, FIX, al cierre del 2 de junio de 2025:
todas las calls y puts cotizadas, para cuatro vencimientos y decenas de strikes, con su mejor precio de compra (bid) y
de venta (ask), el volumen del día y el interés abierto (contratos vivos). Son opciones europeas con liquidación en
efectivo. El índice cerró ese día en 6.359,10 (fix_indice_diario.csv, el mismo índice de los futuros de la lección
1.2.3).
import numpy as np
import pandas as pd
cad = pd.read_csv("opciones_cadena_fix.csv",
parse_dates=["fecha", "vencimiento"])
indice = pd.read_csv("fix_indice_diario.csv", parse_dates=["fecha"])
S = indice.set_index("fecha").loc["2025-06-02", "indice"]
print(f"{len(cad)} opciones; FIX al cierre: {S}")
cad.groupby(["vencimiento", "tipo"]).agg(
strikes=("strike", "size"), desde=("strike", "min"),
hasta=("strike", "max"), interes=("interes_abierto", "sum"))584 opciones; FIX al cierre: 6359.1
strikes desde hasta interes
vencimiento tipo
2025-06-20 call 50 5675 6900 412880
put 50 5675 6900 621931
2025-07-18 call 82 5275 7300 574545
put 82 5275 7300 863427
2025-09-19 call 66 4700 7950 414879
put 66 4700 7950 622741
2025-12-19 call 94 4150 8800 497606
put 94 4150 8800 746209Cuatro vencimientos, el tercer viernes de junio, julio, septiembre y diciembre, y en cada uno el mismo número de calls y de puts: cada strike tiene su pareja. Cuanto más largo es el plazo, más amplio es el abanico de strikes, porque el índice puede alejarse más. El interés abierto de las puts es mayor que el de las calls: en un índice de acciones, las puts son el seguro de las carteras, y hay más demanda de seguro que de apuestas al alza.
Un listado así es poco legible. La forma habitual de mirar una cadena es la que usan las plataformas de los brokers: una fila por strike, las calls a la izquierda y las puts a la derecha.
cad["medio"] = (cad["bid"] + cad["ask"]) / 2
jul = cad[cad["vencimiento"] == "2025-07-18"]
tabla = jul.pivot(index="strike", columns="tipo",
values=["bid", "ask"])
tabla.columns = [f"{t}_{c}" for c, t in tabla.columns]
tabla = tabla[["call_bid", "call_ask", "put_bid", "put_ask"]]
tabla.loc[6200:6500:2] call_bid call_ask put_bid put_ask
strike
6200 274.0 275.2 92.1 92.6
6250 238.4 239.5 106.1 106.7
6300 204.9 205.8 122.3 122.9
6350 173.6 174.5 140.7 141.4
6400 144.9 145.6 161.5 162.3
6450 118.8 119.4 185.1 185.9
6500 95.5 96.0 211.4 212.4La figura de la cabecera dibuja la misma cadena como una escalera de strikes: cada peldaño es un strike, con el bid y el ask de su call a la izquierda y los de su put a la derecha, y la línea ámbar marca dónde está el índice. Las zonas sombreadas son las opciones dentro del dinero: las calls con strike por debajo del índice (arriba a la izquierda) y las puts con strike por encima (abajo a la derecha). Al bajar por la escalera, hacia strikes más altos, las calls se abaratan y las puts se encarecen. Cada peldaño de 50 puntos cambia el precio medio de la call en menos de 50 puntos: unos 41 entre 6.050 y 6.100, unos 29 entre 6.350 y 6.400 y unos 15 entre 6.600 y 6.650. Esa sensibilidad de la prima al strike se relaciona con la probabilidad de acabar dentro del dinero (nivel 3).
Lo que paga cada posición al vencimiento
Al vencimiento, una opción ya no tiene incertidumbre: vale lo que da ejercerla. Con el subyacente al vencimiento y el strike:
Ese es el payoff. El resultado de la posición (P&L) resta lo pagado por la prima, o suma lo cobrado si se ha vendido. Con las cuatro combinaciones —call o put, comprada o vendida— salen las cuatro posiciones básicas, y todas las estrategias con opciones (diferenciales, straddles, cóndores) son sumas de ellas. Se calculan con las opciones del dinero de julio, strike 6.350, compradas o vendidas al precio medio:
def pnl_vencimiento(s_t, strike, prima, tipo, lado=1):
"""P&L por unidad de subyacente; lado 1 compra, -1 venta."""
s_t = np.asarray(s_t, dtype=float)
if tipo == "call":
payoff = np.maximum(s_t - strike, 0)
else:
payoff = np.maximum(strike - s_t, 0)
return lado * (payoff - prima)
K = 6350
prima = jul[jul["strike"] == K].set_index("tipo")["medio"]
print(prima.to_dict())
escenarios = [6000, 6200, 6350, 6500, 6700]
pd.DataFrame({
"call comprada": pnl_vencimiento(escenarios, K,
prima["call"], "call"),
"call vendida": pnl_vencimiento(escenarios, K,
prima["call"], "call", -1),
"put comprada": pnl_vencimiento(escenarios, K,
prima["put"], "put"),
"put vendida": pnl_vencimiento(escenarios, K,
prima["put"], "put", -1),
}, index=pd.Index(escenarios, name="FIX al vencimiento")){'call': 174.05, 'put': 141.05}
call comprada call vendida put comprada put vendida
FIX al vencimiento
6000 -174.05 174.05 208.95 -208.95
6200 -174.05 174.05 8.95 -8.95
6350 -174.05 174.05 -141.05 141.05
6500 -24.05 24.05 -141.05 141.05
6700 175.95 -175.95 -141.05 141.05Cada columna es la imagen especular de su vecina: lo que gana el comprador lo pierde el vendedor, punto por punto. Conviene reconocer las cuatro formas a simple vista:
| Posición | Visión | Ganancia máxima | Pérdida máxima | Punto muerto |
|---|---|---|---|---|
| Call comprada | Alcista | Ilimitada | La prima | |
| Call vendida | No alcista | La prima | Ilimitada | |
| Put comprada | Bajista | La prima | ||
| Put vendida | No bajista | La prima |
mult = 100 # USD por punto de prima
print(f"Punto muerto de la call: {K + prima['call']:.2f}")
print(f"Punto muerto de la put: {K - prima['put']:.2f}")
print(f"Una call cuesta {prima['call'] * mult:,.0f} USD")
subida = (K + prima["call"]) / S - 1
print(f"La call gana si FIX sube más de un {subida:.2%}")Punto muerto de la call: 6524.05
Punto muerto de la put: 6208.95
Una call cuesta 17,405 USD
La call gana si FIX sube más de un 2.59%Comprar la call del dinero solo da beneficio si el índice sube más de un 2,59 % en las seis semanas que quedan hasta el vencimiento. Esa es la otra cara de la pérdida limitada: la prima hay que recuperarla antes de ganar nada. El vendedor de la call gana mientras el índice no pase de 6.524,05: en la mayoría de los escenarios gana poco, como mucho la prima; en unos pocos pierde mucho más de lo que podía ganar.
Valor intrínseco y valor extrínseco
Antes del vencimiento, la prima de una opción es mayor que su payoff inmediato. Se divide en dos partes:
- Valor intrínseco: lo que daría ejercerla ahora, en una call y en una put. Nunca es negativo.
- Valor extrínseco o valor temporal: el resto, prima menos valor intrínseco. Es lo que se paga por la posibilidad de que el subyacente se mueva a favor antes del vencimiento.
La relación entre strike y subyacente se llama moneyness y da tres categorías:
| Categoría | Call | Put | Valor intrínseco |
|---|---|---|---|
| Dentro del dinero (ITM) | Positivo | ||
| En el dinero (ATM) | Casi cero | ||
| Fuera del dinero (OTM) | Cero |
def moneyness(tipo, strike, s, banda=0.005):
"""ITM, ATM (a menos de un 0,5 % del índice) u OTM."""
dist = (s - strike) / s if tipo == "call" else (strike - s) / s
if abs(dist) < banda:
return "ATM"
return "ITM" if dist > 0 else "OTM"
es_call = cad["tipo"] == "call"
cad["intrinseco"] = np.where(es_call, S - cad["strike"],
cad["strike"] - S).clip(min=0)
cad["extrinseco"] = cad["medio"] - cad["intrinseco"]
cad["moneyness"] = [moneyness(t, k, S) for t, k in
zip(cad["tipo"], cad["strike"])]
cols = ["tipo", "strike", "medio", "intrinseco", "extrinseco",
"moneyness"]
jul = cad[cad["vencimiento"] == "2025-07-18"]
jul[jul["strike"].isin([6000, 6350, 6700])][cols].round(2) tipo strike medio intrinseco extrinseco moneyness
158 call 6000 433.75 359.1 74.65 ITM
159 put 6000 52.65 0.0 52.65 OTM
186 call 6350 174.05 9.1 164.95 ATM
187 put 6350 141.05 0.0 141.05 ATM
214 call 6700 31.15 0.0 31.15 OTM
215 put 6700 346.20 340.9 5.30 ITMLas seis filas resumen la idea. La call de 6.000 está dentro del dinero: de su prima de 433,75 puntos, 359,10 son valor intrínseco y 74,65, valor temporal. La de 6.700 está fuera: toda su prima es valor temporal. Las dos del strike 6.350 están en el dinero, con un intrínseco de 9,10 puntos en la call y cero en la put, y son las que más valor temporal tienen de las seis.
La figura lo extiende a todas las calls de julio. La zona gris es el valor intrínseco, la recta que sale del strike igual al índice; la línea, la prima. Lo que queda entre las dos es el valor extrínseco, y tiene forma de campana centrada en el índice. Muy dentro del dinero la call se comporta casi como el propio índice; muy fuera, casi no vale nada; cerca del dinero, el resultado final es más incierto, y la incertidumbre es lo que se paga.
idx = cad.groupby(["vencimiento", "tipo"])["extrinseco"].idxmax()
maximos = cad.loc[idx].set_index(["vencimiento", "tipo"])
maximos[["strike", "extrinseco"]].round(2) strike extrinseco
vencimiento tipo
2025-06-20 call 6350 94.40
put 6350 85.05
2025-07-18 call 6350 164.95
put 6350 141.05
2025-09-19 call 6350 280.35
put 6350 223.95
2025-12-19 call 6350 414.10
put 6350 311.30En los cuatro vencimientos y en los dos tipos, el máximo cae en el strike 6.350, el más próximo al índice. Las calls y las puts del mismo strike no tienen el mismo valor extrínseco: en julio, 164,95 puntos la call y 141,05 la put. La diferencia viene del forward, que está por encima del índice (sección de la paridad), pero la forma de campana es la misma en las dos.
El valor temporal se va acelerando
El valor extrínseco depende del plazo. Más tiempo es más margen para que el subyacente se mueva, y por tanto más valor. Pero la relación no es lineal: con un modelo de precios con movimientos aleatorios independientes, la dispersión del subyacente al vencimiento crece con la raíz cuadrada del plazo (lección 0.7.1), y el valor temporal de una opción del dinero, aproximadamente también.
Para medirlo sin la distorsión del forward, se toma la media del valor extrínseco de la call y de la put del strike 6.350: la call tiene más valor extrínseco que la put porque el forward está por encima del índice (la call ya está dentro del dinero respecto al forward), y la media de las dos compensa ese efecto.
del_dinero = cad[cad["strike"] == 6350]
atm = del_dinero.pivot(index="vencimiento", columns="tipo",
values="extrinseco")
atm["medio"] = (atm["call"] + atm["put"]) / 2
atm["dias"] = (atm.index - pd.Timestamp("2025-06-02")).days
atm["por_raiz_dia"] = atm["medio"] / np.sqrt(atm["dias"])
atm.round(2)tipo call put medio dias por_raiz_dia
vencimiento
2025-06-20 94.40 85.05 89.72 18 21.15
2025-07-18 164.95 141.05 153.00 46 22.56
2025-09-19 280.35 223.95 252.15 109 24.15
2025-12-19 414.10 311.30 362.70 200 25.65Si el valor temporal fuera proporcional al plazo, la última columna se multiplicaría por 3,3 del primer vencimiento al último (); en cambio, pasa de 21 a 26 puntos por raíz de día. Que suba algo con el plazo se debe a que la volatilidad implícita de esta cadena crece con el vencimiento, algo que se estudia en el nivel 3. Con una sola constante ajustada a los cuatro puntos, la curva permite ver cómo se gasta el valor temporal de una opción del dinero de 200 días si nada más cambia:
a = (atm["medio"] * np.sqrt(atm["dias"])).sum() / atm["dias"].sum()
print(f"a = {a:.2f} puntos por raíz de día")
inicial = a * np.sqrt(200)
for desde, hasta in [(200, 170), (90, 60), (60, 30), (30, 0)]:
perdida = a * (np.sqrt(desde) - np.sqrt(hasta))
print(f"de {desde:>3} a {hasta:>3} días: pierde {perdida:6.1f}"
f" puntos ({perdida / inicial:.0%} del valor inicial)")a = 24.61 puntos por raíz de día
de 200 a 170 días: pierde 27.2 puntos (8% del valor inicial)
de 90 a 60 días: pierde 42.8 puntos (12% del valor inicial)
de 60 a 30 días: pierde 55.8 puntos (16% del valor inicial)
de 30 a 0 días: pierde 134.8 puntos (39% del valor inicial)Con la curva ajustada a la cadena, una opción del dinero de 200 días pierde en su primer mes 27 puntos, un 8 % de su valor temporal; en el último mes pierde los 135 puntos que le quedan, un 39 % del valor inicial. Esa erosión diaria del valor temporal tiene nombre, theta, y forma parte de las «griegas», las sensibilidades de la prima al subyacente, a la volatilidad, al tiempo y al tipo de interés. Las griegas y la volatilidad implícita son materia del nivel 3; aquí basta la intuición: el comprador de una opción paga el paso del tiempo y el vendedor lo cobra.
La paridad put-call
Una call comprada y una put vendida del mismo strike y vencimiento dan, al vencimiento, en todos los escenarios: es lo mismo que un futuro comprado a . Si dos carteras pagan lo mismo en el futuro, hoy tienen que costar lo mismo, y de ahí sale la paridad put-call de las opciones europeas:
con el tipo de interés, el rendimiento por dividendo del índice (los dos en tasa continua) y el forward, el precio teórico de un futuro con el mismo vencimiento (lección 1.2.3). Para la fecha de los datos, = 4,354 % y = 1,350 % (README de los datos).
En una cadena real hay que comprobarla con precios ejecutables. Comprar la call y vender la put cuesta ; vender la call y comprar la put ingresa . Si el valor teórico cae entre los dos, no hay arbitraje posible después de pagar las horquillas:
r, q = 0.04354, 0.01350
ancho = cad.pivot_table(index=["vencimiento", "strike"],
columns="tipo", values=["bid", "ask"])
ancho.columns = [f"{t}_{c}" for c, t in ancho.columns]
venc = ancho.index.get_level_values("vencimiento")
k = ancho.index.get_level_values("strike")
T = (venc - pd.Timestamp("2025-06-02")).days / 365
F = S * np.exp((r - q) * T)
ancho["teorico"] = np.exp(-r * T) * (F - k)
ancho["minimo"] = ancho["call_bid"] - ancho["put_ask"]
ancho["maximo"] = ancho["call_ask"] - ancho["put_bid"]
dentro = ancho["teorico"].between(ancho["minimo"], ancho["maximo"])
print(f"Strikes que cumplen la paridad: {dentro.sum()} de "
f"{len(ancho)}")
ancho.loc[("2025-07-18", 6350),
["minimo", "teorico", "maximo"]].round(2)Strikes que cumplen la paridad: 292 de 292
minimo 32.20
teorico 33.04
maximo 33.80
Name: (2025-07-18 00:00:00, 6350), dtype: float64Los 292 pares cumplen la paridad dentro de la horquilla. En el strike del dinero de julio, el valor teórico de es de 33,04 puntos y el intervalo ejecutable, de 32,20 a 33,80, mide 1,6. La paridad también funciona al revés: con los precios medios de la call y de la put se puede deducir el forward que descuenta el mercado, sin necesidad de un futuro. Es una forma habitual de estimar el dividendo implícito o de detectar datos defectuosos:
ancho["medio_cp"] = ((ancho["call_bid"] + ancho["call_ask"])
- (ancho["put_bid"] + ancho["put_ask"])) / 2
ancho["F_implicito"] = k + ancho["medio_cp"] * np.exp(r * T)
resumen = ancho.groupby(level="vencimiento")["F_implicito"].median()
pd.DataFrame({"F implícito": resumen,
"F teórico": S * np.exp((r - q) *
(resumen.index - pd.Timestamp("2025-06-02"))
.days.values / 365)}).round(2) F implícito F teórico
vencimiento
2025-06-20 6368.52 6368.53
2025-07-18 6383.22 6383.22
2025-09-19 6416.42 6416.40
2025-12-19 6464.65 6464.64El forward implícito coincide con el teórico a menos de 0,02 puntos en los cuatro vencimientos, y está por encima del índice porque el tipo de interés supera al rendimiento por dividendo: el mismo contango de los futuros de FIX.
Americanas y europeas
La diferencia es cuándo se puede ejercer:
- Una opción europea solo se ejerce al vencimiento. Son europeas, por ejemplo, las opciones SPX sobre el S&P 500, las de esta lección y muchas opciones sobre índices.
- Una opción americana se puede ejercer cualquier día hasta el vencimiento. Lo son, por regla general, las opciones sobre acciones individuales y sobre ETFs cotizadas en EE. UU., que al ejercerse se liquidan entregando las acciones2Nota 2 · Cboe, en la página de especificaciones de las SPX: las opciones sobre índices (europeas) solo se ejercen al vencimiento; las opciones sobre acciones y ETFs (americanas) pueden ejercerse en cualquier momento antes del vencimiento. En su comparativa, las opciones sobre ETFs se liquidan con entrega de las acciones..
Poder ejercer antes nunca resta valor, así que una americana vale al menos lo que la europea equivalente. Y, sobre todo, una americana nunca puede valer menos que su valor intrínseco: si costara menos, bastaría con comprarla y ejercerla en el acto. Una europea sí puede, y la cadena de FIX lo muestra:
bajo = cad[(cad["tipo"] == "put") & (cad["extrinseco"] < 0)]
print(f"Puts con prima menor que el intrínseco: {len(bajo)}")
print(bajo.groupby("vencimiento")["strike"].min())
peores = bajo.nsmallest(3, "extrinseco").set_index("vencimiento")
peores[["strike", "medio", "intrinseco", "extrinseco"]].round(2)Puts con prima menor que el intrínseco: 93
vencimiento
2025-06-20 6625
2025-07-18 6750
2025-09-19 6900
2025-12-19 7050
Name: strike, dtype: int64
strike medio intrinseco extrinseco
vencimiento
2025-12-19 8800 2280.35 2440.9 -160.55
2025-12-19 8750 2231.55 2390.9 -159.35
2025-12-19 8700 2182.75 2340.9 -158.15Las 93 puts afectadas están todas muy dentro del dinero: desde el strike 6.625 en junio, un 4 % por encima del índice, y desde el 7.050 en diciembre, un 11 % por encima. En los vencimientos largos hace falta estar más dentro del dinero porque queda más valor temporal que compensar. La razón del fenómeno es el tipo de interés. Una put muy dentro del dinero casi seguro se ejercerá, y lo que paga entonces es : el strike se cobra al vencimiento, no hoy. Descontado con un tipo del 4,35 %, ese cobro futuro vale menos que su importe nominal. La put de strike 8.800 de diciembre vale unos 160 puntos menos que si se pudiera ejercer hoy.
Con una put americana, ese descuento es una razón para ejercer antes: cobrar el strike hoy y colocarlo al tipo de interés vale más que esperar. Por eso el ejercicio anticipado tiene sentido sobre todo en dos casos:
Fuente Mermaid
flowchart TB
A[Opción americana] --> T{¿Tipo?}
T -- put --> P{¿Muy dentro?}
P -- sí --> PI[Ejercer ya]
P -- no --> NO[Esperar]
T -- call --> D{¿Dividendo antes?}
D -- sí --> CD[Ejercer la víspera]
D -- no --> NO- Put muy dentro del dinero: los intereses del strike cobrado hoy superan el valor temporal que queda.
- Call justo antes de un dividendo: el poseedor de la call no cobra dividendos. Si el dividendo es mayor que el valor temporal, compensa ejercer el día antes de la fecha ex para tener las acciones y cobrarlo (lección 1.2.1). Sin dividendos, ejercer una call americana antes de tiempo nunca compensa: venderla rinde más que ejercerla.
Para un sistema que vende opciones americanas, esto es un riesgo operativo: la contraparte puede ejercer contra la posición en cualquier momento (la asignación), y el vendedor se encuentra con acciones compradas o vendidas que no esperaba. Para un backtest, significa que una opción americana no puede valorarse con la fórmula de una europea.
Lo que hay que vigilar en los datos de opciones
Una cadena tiene cientos de contratos por subyacente y día, y la mayoría apenas negocian. La liquidez se concentra en unos pocos:
jul = cad[cad["vencimiento"] == "2025-07-18"].copy()
jul["redondo"] = np.where(jul["strike"] % 100 == 0,
"múltiplo de 100", "resto")
jul["horquilla_pct"] = 100 * (jul["ask"] - jul["bid"]) / jul["medio"]
print(jul.groupby("redondo")["interes_abierto"].mean().round(0))
jul[jul["tipo"] == "call"].set_index("strike").loc[
[6000, 6400, 6800, 7000, 7200],
["bid", "ask", "horquilla_pct"]].round(2)redondo
múltiplo de 100 17177.0
resto 5873.0
Name: interes_abierto, dtype: float64
bid ask horquilla_pct
strike
6000 432.80 434.70 0.44
6400 144.90 145.60 0.48
6800 14.40 14.70 2.06
7000 1.75 1.90 8.22
7200 0.00 0.15 200.00Los strikes múltiplos de 100 acumulan unas tres veces más interés abierto que los intermedios: es donde se concentra la negociación. Y la horquilla, medida en porcentaje de la prima, se dispara lejos del dinero: en la call de 7.200 el bid es cero y el ask, 0,15. En una opción así el «precio medio» no significa nada, y un backtest que compre y venda al medio subestima los costes por completo.
Los errores más comunes al trabajar con datos de opciones:
- Usar el último precio. Una opción poco negociada puede tener su última operación de hace días, con el subyacente en otro sitio. Para valorar, bid y ask del mismo instante.
- Mezclar horas. El índice al cierre y las opciones a las 15:45 no son simultáneos. En la paridad, un minuto de diferencia con el subyacente moviéndose rompe la igualdad.
- Olvidar el multiplicador o el estilo. 100 USD por punto en la mayoría de opciones de EE. UU., otros valores en otros mercados; europea o americana; efectivo o entrega física. Todo está en la especificación del contrato.
- Sesgo de supervivencia de contratos. Las cadenas históricas solo tienen los strikes que existieron; los que se añadieron tras un movimiento fuerte no estaban antes. Y los contratos vencidos desaparecen de muchas APIs gratuitas.
Para cadenas reales, yfinance da la foto actual de la cadena de un subyacente de EE. UU., sin histórico (lección 1.3.2). No se ejecuta aquí porque necesita red:
import yfinance as yf
spy = yf.Ticker("SPY")
print(spy.options[:4]) # vencimientos disponibles
cadena = spy.option_chain(spy.options[0])
calls, puts = cadena.calls, cadena.puts
calls[["strike", "bid", "ask", "lastPrice", "volume",
"openInterest", "impliedVolatility", "inTheMoney"]]option_chain devuelve dos tablas, calls y puts, con una fila por strike: precio, volumen, interés abierto y una
volatilidad implícita calculada por Yahoo. Las opciones de SPY son americanas y sobre un ETF que paga dividendos, así
que ni la paridad exacta ni la comprobación de puts por debajo del intrínseco se aplican tal cual.
Ejercicios
- Un straddle comprado es una call y una put compradas del mismo strike y vencimiento. Calcula, con los precios medios del strike 6.350 de julio, la prima total y los dos puntos muertos. ¿Cuánto tiene que moverse el índice, en porcentaje, para que la posición gane?
Solución
coste = prima["call"] + prima["put"]
arriba, abajo = K + coste, K - coste
print(f"Prima total: {coste:.2f} puntos "
f"({coste * mult:,.0f} USD)")
print(f"Puntos muertos: {abajo:.2f} y {arriba:.2f}")
print(f"Movimiento necesario: {arriba / S - 1:+.2%} "
f"o {abajo / S - 1:+.2%}")Prima total: 315.10 puntos (31,510 USD)
Puntos muertos: 6034.90 y 6665.10
Movimiento necesario: +4.81% o -5.10%El straddle paga si el índice se mueve mucho en cualquier dirección, y pierde la prima entera si acaba justo en el strike. Hace falta que el índice suba más de un 4,81 % o baje más de un 5,10 % en seis semanas. Es una apuesta a que la volatilidad realizada será mayor que la que el mercado ha puesto en las primas.
- Usa la paridad put-call para deducir, en cada vencimiento, qué rendimiento por dividendo descuenta la cadena (supón que = 4,354 % es conocido). Pista: con el forward implícito, .
Solución
dias = (resumen.index - pd.Timestamp("2025-06-02")).days.values
t = dias / 365
q_impl = r - np.log(resumen.values / S) / t
pd.Series(100 * q_impl, index=resumen.index,
name="q implícito (%)").round(3)vencimiento
2025-06-20 1.353
2025-07-18 1.350
2025-09-19 1.349
2025-12-19 1.350
Name: q implícito (%), dtype: float64Los cuatro vencimientos dan el 1,35 % con el que se generaron los datos, con diferencias de milésimas que salen del redondeo de las primas al tick (0,05 o 0,10 puntos) y que pesan más cuando es pequeño, como en junio. Con datos reales, el dividendo implícito varía por vencimiento porque los dividendos no se reparten uniformemente a lo largo del año.
- Un compañero calcula el valor extrínseco de las opciones de una cadena con el último precio negociado y encuentra varias calls fuera del dinero con valor extrínseco negativo. ¿Qué explicaciones darías antes de pensar en un arbitraje?
Solución
Una call fuera del dinero tiene valor intrínseco cero, así que un extrínseco negativo significa un precio negativo, lo que es imposible: el error está en los datos o en el cálculo. Las causas habituales: el último precio es de una operación antigua (o de otro contrato con el mismo símbolo tras un ajuste), el subyacente usado para calcular el intrínseco no es del mismo instante, el strike está ajustado por un evento corporativo, o se ha mezclado call y put. Con bid y ask simultáneos del mismo instante que el subyacente, la comprobación se repite y el problema suele desaparecer.
Footnotes
-
Especificaciones de las opciones SPX en la página de Cboe enlazada en los recursos: multiplicador de 100 USD, estilo europeo y liquidación en efectivo. ↩
-
Cboe, en la página de especificaciones de las SPX: las opciones sobre índices (europeas) solo se ejercen al vencimiento; las opciones sobre acciones y ETFs (americanas) pueden ejercerse en cualquier momento antes del vencimiento. En su comparativa, las opciones sobre ETFs se liquidan con entrega de las acciones. ↩
Respuesta plegada en cada pregunta
Autoevaluación
El índice está en 6.359,10. Una call de strike 6.300 cuesta 205,35 puntos. ¿Cuánto de esa prima es valor extrínseco?
- A205,35 puntos: toda la prima
- B59,10 puntos
- C146,25 puntos
- DCero, porque está dentro del dinero
Ver respuesta
Respuesta C. 146,25 puntos
El valor intrínseco de la call es lo que daría ejercerla ahora: 6.359,10 − 6.300 = 59,10. El resto de la prima, 205,35 − 59,10 = 146,25 puntos, es valor extrínseco: lo que el mercado paga por la posibilidad de que el índice suba más antes del vencimiento.
¿Qué posición tiene pérdida máxima ilimitada al vencimiento?
- ACall comprada
- BPut comprada
- CCall vendida
- DPut vendida
Ver respuesta
Respuesta C. Call vendida
Quien vende una call se obliga a pagar
S − Ksi el subyacente acaba por encima del strike, y el subyacente no tiene techo. La put vendida también puede perder mucho, pero como máximoKmenos la prima, porque el precio no baja de cero.¿Dónde es mayor el valor extrínseco de las opciones de un mismo vencimiento?
- AEn las más dentro del dinero
- BEn las más fuera del dinero
- CEs igual en todos los strikes
- DCerca del dinero, con el strike próximo al subyacente
Ver respuesta
Respuesta D. Cerca del dinero, con el strike próximo al subyacente
Lejos del strike, el resultado está casi decidido: muy dentro del dinero la opción se comporta como el subyacente y muy fuera casi no vale nada. La incertidumbre sobre si acabará dentro o fuera, que es lo que se paga como valor extrínseco, es máxima cuando el strike está cerca del precio actual.
En la cadena de FIX, varias puts europeas muy dentro del dinero cotizan por debajo de su valor intrínseco. ¿Por qué no hay arbitraje?
- APorque los datos están mal
- BPorque una opción europea solo se ejerce al vencimiento: el strike se cobra más tarde y hay que descontarlo con el tipo de interés
- CPorque las puts no tienen valor intrínseco
- DPorque el multiplicador es 100
Ver respuesta
Respuesta B. Porque una opción europea solo se ejerce al vencimiento: el strike se cobra más tarde y hay que descontarlo con el tipo de interés
El valor de una put europea muy dentro del dinero se acerca a
K·e^(−rT) − S·e^(−qT), no aK − S. Con tipos del 4,35 %, cobrar el strike dentro de unos meses vale menos que cobrarlo hoy. Una put americana sí podría ejercerse ya, y por eso nunca vale menos que su valor intrínseco.Para comprobar la paridad put-call en una cadena real, ¿qué precios hay que usar?
- ALos de compra y venta:
C_bid − P_askyC_ask − P_bidacotan lo que se puede hacer de verdad - BEl último precio negociado de la call y de la put
- CSolo el precio medio de la call
- DEl precio de cierre del índice
Ver respuesta
Respuesta A. Los de compra y venta:
C_bid − P_askyC_ask − P_bidacotan lo que se puede hacer de verdadEl último precio puede tener horas de antigüedad y no ser simultáneo en la call y en la put. Lo ejecutable son el bid y el ask: comprar la call y vender la put cuesta
C_ask − P_bid; lo contrario ingresaC_bid − P_ask. Si el valor teórico cae entre los dos, no hay arbitraje después de horquillas.- ALos de compra y venta:
Ideas clave
- Una call da el derecho a comprar y una put el derecho a vender, a un precio fijado (strike) y hasta una fecha. El comprador paga la prima; el vendedor la cobra y asume la obligación.
- La prima se divide en valor intrínseco (lo que daría ejercer ahora) y valor extrínseco (lo que vale esperar). El extrínseco es máximo cerca del dinero y crece con el plazo.
- El valor temporal no se pierde a ritmo constante: crece más o menos con la raíz cuadrada del plazo, así que el último mes es el que más se lleva.
- En una cadena europea,
C − P = e^(−rT)(F − K): la paridad put-call liga calls y puts del mismo strike y sirve para validar los datos y para deducir el forward. - Una opción americana se puede ejercer cualquier día y nunca vale menos que su valor intrínseco; una europea, solo al vencimiento, y puede valer menos.
- Los datos de opciones engañan con facilidad: último precio antiguo, horquillas anchas lejos del dinero, multiplicador y estilo de ejercicio distintos según el contrato.