Lección 424 min60 XPGratis
Ejecución y slippage: el precio que ves no es el que pagas
Al terminar sabrás
- Definir y medir el slippage con tus propios fills
- Descomponer el coste total de una operación (spread, comisión, slippage, impacto)
- Ver cómo un supuesto de un tick cambia el signo de una estrategia
Antes de esta conviene haber hecho El libro y la profundidad: cuánto hay detrás del precio que ves.
Una estrategia con ventaja real de medio tick por operación pierde dinero en cuanto le pones costes realistas. No porque la ventaja sea falsa: porque medio tick es menos que lo que cuesta cruzar el spread y pagar la comisión. La diferencia entre el precio que veías y el precio al que te ejecutaste se llama slippage, y es la variable que más backtests convierte en ficción.
El problema
El backtest opera a los precios de las barras. La cuenta real opera a los precios de los fills. Entre ambos hay spread, slippage, comisión e impacto, y la mayoría de la gente los mete en el backtest como un número inventado ("un tick") o no los mete. Esta lección te enseña a medirlos con tus propias operaciones y a ver qué le hacen a una estrategia.
Tres capas
Intuición
Vas a comprar un coche de segunda mano anunciado por 10.000 €. Cuando llegas, el vendedor te dice que hay otro interesado y son 10.200. Además hay que pagar transferencia (200 €) y el coche necesita ruedas (300 €). El coche te ha costado 10.700, un 7 % más de lo que veías en el anuncio. Si tu plan era revenderlo por 10.500, el plan era bueno con el precio del anuncio y malo con el precio real.
El slippage es esos 200 € de más: la diferencia entre el precio que viste al decidir y el precio al que de verdad cerraste. La comisión es la transferencia. El spread es lo que el vendedor pide de más solo por ser él quien tiene el coche ahora. Y el impacto es lo que sube el precio si vas a comprarle los tres coches que tiene en vez de uno. Todos son costes reales; ninguno sale en el anuncio.
Ejemplo numérico
Ocho operaciones en MES (datos de ejemplo del entregable; abajo el código que los analiza). Slippage medido como (fill − precio visto) con el signo de la operación, en ticks:
| Tipo de orden | Operaciones | Slippage medio (ticks) | Máximo (ticks) | Coste total ($) |
|---|---|---|---|---|
| Límite | 1 | 0,0 | 0,0 | 0,00 |
| Mercado | 5 | 1,6 | 3,0 | 20,00 |
| Stop | 2 | 2,5 | 3,0 | 6,25 |
Total: 26,25 $ en 8 operaciones, 3,28 $ por operación en MES, unos 2,6 ticks. El peor fill de mercado fue a las 3:15 de la madrugada (3 ticks); los mejores, en plena sesión (1 tick).
Ahora, qué hace eso con una estrategia. Estrategia sintética con 500 operaciones al año en MES y una ventaja bruta real de 0,62 $ por operación (medio tick). Cuatro supuestos de coste:
| Supuesto | Neto por operación | Total anual |
|---|---|---|
| Sin costes | +0,62 $ | +309 $ |
| Solo comisión (0,62 $/lado) | −0,62 $ | −311 $ |
| Comisión + 1 tick de spread | −1,87 $ | −936 $ |
| Comisión + 2 ticks (spread + slippage) | −3,12 $ | −1.561 $ |
La misma estrategia. La ventaja era real. El signo del resultado lo decide un supuesto que casi nadie escribe.
Formal
Sea el precio de referencia en el momento de la decisión (mid, last, o el cierre de la barra en un backtest) y el precio medio de ejecución. Para una operación de signo ( compra, venta):
Es positivo cuando te cuesta (compras más caro o vendes más barato de lo visto) y ocasionalmente negativo (mejora de precio). Se mide en ticks o en puntos básicos del nocional, por tipo de orden y por tramo horario, porque no es una constante: es una distribución con media positiva y cola gorda.
El coste total de transacción por operación completa (entrada + salida) se descompone en:
- Spread: medio spread por lado si cruzas ( respecto al mid); cero si eres pasivo y te ejecutan (pero entonces asumes riesgo de no ejecución y selección adversa).
- Comisión y fees: broker + bolsa + NFA; en micros del orden de 0,5-1 $ por lado, en ES 2-5 $.
- Slippage: la parte del coste que depende del momento (volatilidad, liquidez) y del tipo de orden. Stops y órdenes de mercado fuera de RTH lo concentran.
- Impacto: desplazamiento del precio causado por tu propio tamaño; crece aproximadamente con la raíz del tamaño relativo al volumen (la "ley de la raíz cuadrada", documentada empíricamente por Almgren et al., 2005, entre otros). Irrelevante para 1-5 micros; decisivo para institucionales.
En el backtest, hay tres niveles de honestidad: (a) coste fijo por operación (comisión + ticks), con medido en tus fills, no supuesto; (b) coste dependiente del tipo de orden y del tramo horario; (c) simulación de ejecución contra el libro (requiere datos de profundidad; Nivel 4). El nivel (a) con medido es obligatorio desde el Nivel 2; usar o "porque sí" es la forma más común de fabricar un backtest falso. Y una regla que no falla: si la estrategia es sensible a la diferencia entre y , la estrategia no tiene edge suficiente para operarse.
Para órdenes límite el slippage medido es cero o negativo, pero eso esconde el coste real: las operaciones que no se ejecutaron porque el precio se fue a favor. Un backtest que asume que las límites siempre se ejecutan al tocar el precio (fill al toque) es tan falso como uno sin costes. El supuesto conservador es exigir que el precio atraviese el límite, no que lo toque.
Ejemplo trabajado con código
Primero la estrategia bajo cuatro supuestos:
# numpy 2.4 · pandas 3.0 — Slippage: cómo tres supuestos distintos cambian el resultado de la misma estrategia
import numpy as np, pandas as pd
rng = np.random.default_rng(42)
# Estrategia sintética: 500 operaciones/año en MES, cada una con retorno bruto ~ N(+0,6 ticks, 8 ticks).
# Tiene ventaja ANTES de costes: +0,6 ticks = 0,75 $ por operación de media.
n_ops = 500
bruto_ticks = rng.normal(0.6, 8.0, n_ops)
valor_tick, comision_por_lado = 1.25, 0.62 # MES: 1,25 $/tick; comisión típica ~0,62 $/lado (ilustrativa)
escenarios = {"sin costes": 0.0, "solo comisión": 0.0, "comisión + 1 tick de spread": 1.0, "comisión + 2 ticks (spread + slippage)": 2.0}
print(f"{'supuesto':42s} {'neto/op ($)':>12s} {'total año ($)':>14s}")
for nombre, ticks_coste in escenarios.items():
comision = 0 if nombre == "sin costes" else 2 * comision_por_lado
neto = bruto_ticks * valor_tick - ticks_coste * valor_tick - comision
print(f"{nombre:42s} {neto.mean():>+12.2f} {neto.sum():>+14,.0f}")
print("La ventaja bruta era real. El resultado neto depende de un supuesto de un tick que la mayoría no escribe.")
np.save("slip_bruto.npy", bruto_ticks)supuesto neto/op ($) total año ($)
sin costes +0.62 +309
solo comisión -0.62 -311
comisión + 1 tick de spread -1.87 -936
comisión + 2 ticks (spread + slippage) -3.12 -1,561
La ventaja bruta era real. El resultado neto depende de un supuesto de un tick que la mayoría no escribe.Y el entregable del módulo: analiza tus fills reales. El CSV de ejemplo trae ocho operaciones; tú sustituyes por las tuyas.
# pandas 3.0 — Entregable M0.3: analiza tus fills reales frente al precio que veías al enviar la orden
# CSV esperado (uno por operación): fecha,instrumento,lado,tipo_orden,precio_visto,precio_fill,contratos
import pandas as pd, sys
ruta = sys.argv[1] if len(sys.argv) > 1 else "fills_ejemplo.csv"
df = pd.read_csv(ruta, parse_dates=["fecha"])
TICK = {"MES": 0.25, "ES": 0.25, "MNQ": 0.25, "MGC": 0.10, "MCL": 0.01}
VALOR_TICK = {"MES": 1.25, "ES": 12.5, "MNQ": 0.5, "MGC": 1.0, "MCL": 1.0}
signo = df.lado.map({"compra": 1, "venta": -1})
df["slip_pts"] = signo * (df.precio_fill - df.precio_visto) # positivo = te ha costado
df["slip_ticks"] = df.slip_pts / df.instrumento.map(TICK)
df["slip_usd"] = df.slip_ticks * df.instrumento.map(VALOR_TICK) * df.contratos
print(df[["fecha","instrumento","lado","tipo_orden","precio_visto","precio_fill","slip_ticks","slip_usd"]].to_string(index=False))
print()
res = df.groupby("tipo_orden").agg(n=("slip_ticks","size"), slip_medio_ticks=("slip_ticks","mean"), slip_max_ticks=("slip_ticks","max"), coste_total_usd=("slip_usd","sum"))
print(res.round(2).to_string())
print(f"\nSlippage total: {df.slip_usd.sum():+.2f} $ en {len(df)} operaciones = {df.slip_usd.sum()/len(df):+.2f} $/op. "
f"Usa este número en tu backtest, no un supuesto.")fecha instrumento lado tipo_orden precio_visto precio_fill slip_ticks slip_usd
2026-09-15 09:31:00 MES compra mercado 5401.00 5401.25 1.0 2.50
2026-09-15 10:05:00 MES venta mercado 5406.50 5406.25 1.0 2.50
2026-09-15 11:20:00 MES compra limite 5398.75 5398.75 0.0 0.00
2026-09-15 14:02:00 MES venta stop 5395.00 5394.50 2.0 2.50
2026-09-16 09:30:00 MES compra mercado 5410.25 5410.75 2.0 7.50
2026-09-16 15:10:00 MES venta mercado 5412.00 5411.75 1.0 3.75
2026-09-17 03:15:00 MES compra mercado 5405.00 5405.75 3.0 3.75
2026-09-17 09:45:00 MES venta stop 5399.00 5398.25 3.0 3.75
n slip_medio_ticks slip_max_ticks coste_total_usd
tipo_orden
limite 1 0.0 0.0 0.00
mercado 5 1.6 3.0 20.00
stop 2 2.5 3.0 6.25
Slippage total: +26.25 $ en 8 operaciones = +3.28 $/op. Usa este número en tu backtest, no un supuesto.Figura

El error típico
Poner "1 tick de slippage" en el backtest porque es lo que dice todo el mundo, y no volver a mirarlo. Tres problemas: (1) no es una constante, es una distribución que depende del tipo de orden y de la hora, y los stops fuera de sesión te cuestan tres veces más que las órdenes de mercado en RTH; (2) las límites tienen slippage cero pero un coste de no ejecución que el backtest suele ignorar; (3) nadie mide el suyo. El entregable de este módulo existe para eso: durante las próximas semanas, cada operación que hagas (en simulado o real) va a un CSV con el precio que viste y el precio que te dieron. Al final del Nivel 0 tendrás tu propia distribución de slippage, y ese es el número que va en tus backtests. No el de nadie más.
Quiz
5 preguntas · se aprueba con 60 %
1.Compras MES viendo 5.401,00 y te ejecutan a 5.401,25. Slippage:
2.Una estrategia obtiene 0,5 ticks brutos por operación en MES. Con comisión de 0,62 $/lado y 1 tick de spread:
3.Tu backtest asume que las órdenes límite se ejecutan cuando el precio toca el nivel. ¿Problema?
4.¿Qué tipo de orden concentra más slippage según los fills de ejemplo?
5.Si una estrategia pasa de rentable a perdedora al cambiar el supuesto de costes de 1 a 2 ticks:
0 de 5 respondidas
Ejercicio (entregable del módulo)
Abre una cuenta de simulación (TradingView paper, o la de tu broker/prop firm) y durante al menos 15 operaciones en MES, en distintas horas y con distintos tipos de orden, registra en un CSV con el formato de fills_ejemplo.csv: fecha y hora, instrumento, lado, tipo de orden, precio que veías al enviar y precio del fill. Pasa fills.py sobre tu CSV.
Resultado verificable: tu slippage medio en órdenes de mercado en RTH debería estar entre 0,5 y 1,5 ticks; en stops, más; fuera de RTH, más. Si te sale cero en órdenes de mercado, la simulación de tu plataforma no modela el spread y no sirve para esto (anótalo: también es un dato). El número que obtengas es el que usarás en el Nivel 2.
Qué te llevas
- Slippage = signo × (fill − precio visto). Se mide, no se supone, y depende del tipo de orden y de la hora.
- El coste total (spread + comisión + slippage + impacto) puede cambiar el signo de una estrategia con ventaja bruta real.
- Si tu estrategia no sobrevive a un tick más de coste, no tiene edge operable. Mide el tuyo desde hoy.
Siguiente lección: De tu clic al fill: latencia y por qué (casi nunca) te importa. Cuánto se mueve el precio mientras tu orden viaja a Chicago, y a qué tipo de estrategia le duele.
