Quant500 Academy

2. La escalera: simulación, papel y capital real

Nivel 12: Probar, desplegar y dar el paso

Ya sabes probar el sistema contra un doble. Eso demuestra que el código hace lo que dijiste, no que la estrategia gane dinero ni que el conjunto sobreviva al contacto con un mercado de verdad. Entre ambas cosas hay una escalera de cuatro peldaños, y la forma más común de perder dinero con un sistema automático no es un fallo de programación: es saltarse peldaños porque el backtest era muy bonito.

La regla de la escalera

Cada peldaño valida una cosa concreta y miente sobre las demás. Estar en un peldaño sin saber qué valida es tan inútil como no haberlo pisado. Y no se sube por tiempo cumplido ni por impaciencia: se sube cuando la diferencia entre lo que esperabas y lo que ha pasado está medida, y está explicada.

Peldaño 1: la simulación valida la lógica, no la ejecución

Es el backtest y la reproducción de datos históricos contra el sistema completo, con el mismo orquestador y el mismo calendario. Valida el tratamiento de los huecos, la idempotencia, las transiciones de estado y el comportamiento en los días raros del calendario. No valida absolutamente nada de la ejecución: ni el precio al que se llena, ni la latencia, ni el impacto, ni los rechazos.

Su trampa característica es sutil: un simulador que ejecuta al precio que usaste para decidir convierte cualquier estrategia de reversión intradía en una máquina de imprimir dinero. Duración razonable, la que haga falta, con el tramo fuera de muestra sin tocar.

Peldaño 2: la cuenta de papel valida la tubería y miente en el precio

Aquí se valida todo lo que hay entre tu decisión y el mercado: credenciales, formato de las órdenes, husos horarios, tipos de orden que el bróker acepta de verdad, comportamiento fuera de sesión, reconexión, y que tu reconciliación cuadre contra una cuenta real. Es el peldaño que descubre que tu bróker redondea el tamaño distinto de como creías.

Miente en dos sitios muy concretos:

Duración razonable: semanas, no días. Al menos un ciclo completo de la estrategia, suficientes operaciones para que un fallo raro tenga ocasión de asomar, y que el periodo incluya un festivo, un cambio de hora o un vencimiento.

Peldaño 3: el capital pequeño es el primer dato honesto

Aquí aparece por fin lo que ningún simulador te iba a dar: el deslizamiento y las comisiones reales, con tu bróker, tu tipo de orden y tu horario. Pequeño significa dos cosas a la vez: que perderlo entero no cambie tu vida, y que el tamaño de orden siga siendo representativo. Si la comisión mínima se come el 3% de cada operación, el resultado no mide la estrategia, mide la comisión mínima.

Lo que hay que medir ya lo registra el nivel 10: para cada orden, el precio de referencia en el instante de decidir y el precio medio de ejecución.

import numpy as np, pandas as pd

ops = pd.read_parquet("ejecuciones.parquet")
# fecha, lado, precio_decision, precio_medio_ejecucion, comision, nominal

signo = np.where(ops["lado"] == "compra", 1.0, -1.0)
ops["deslizamiento_pb"] = 1e4 * signo * (
    ops["precio_medio_ejecucion"] - ops["precio_decision"]
) / ops["precio_decision"]
ops["coste_total_pb"] = ops["deslizamiento_pb"] + 1e4 * ops["comision"] / ops["nominal"]

n = len(ops)
media = ops["coste_total_pb"].mean()
error_tipico = ops["coste_total_pb"].std(ddof=1) / np.sqrt(n)
print(n, round(media, 2), round(error_tipico, 2))

Con veinte operaciones no sabes nada: el error típico de esa media es comparable a la propia media. El criterio de subida no es "el coste medio parece bajo", sino que el coste medio más dos errores típicos siga dejando margen, y eso suele exigir del orden de un centenar de operaciones.

Peldaño 4: capital real, por tramos y con un criterio escrito

import math

def puede_subir(ops, coste_supuesto_pb, margen_bruto_pb, minimo=100):
    if len(ops) < minimo:
        return False, "faltan operaciones para medir con sentido"
    media = ops["coste_total_pb"].mean()
    et = ops["coste_total_pb"].std(ddof=1) / math.sqrt(len(ops))
    if media - 2 * et > coste_supuesto_pb:
        return False, "el coste real supera al supuesto del backtest"
    if margen_bruto_pb - (media + 2 * et) <= 0:
        return False, "no queda margen despues de costes"
    return True, "adelante, y por tramos"

De capital pequeño a capital real no se pasa de golpe: se multiplica por dos o por tres, se dejan pasar operaciones suficientes para volver a medir con el tamaño nuevo y solo entonces se repite. El deslizamiento no es una constante, crece con el tamaño relativo a la liquidez disponible. Y una condición que no es estadística: no se sube de peldaño y se toca la estrategia la misma semana, porque entonces ninguna diferencia de resultado tiene ya explicación única.

Escenario trabajado

Ejemplo construido con cifras, no un caso histórico. El backtest suponía 5 puntos básicos de coste por operación y un margen bruto esperado de 18. La cuenta de papel confirmó la tubería durante seis semanas sin sorpresas. Con capital pequeño, 120 operaciones dieron un coste medio de 11 puntos básicos con desviación típica de 9: error típico de 0,82, así que el coste está entre 9,4 y 12,6 con holgura. El margen sigue siendo positivo, pero se ha comido dos tercios del previsto. Al multiplicar el tamaño por cinco, el coste medio subió a 19 puntos básicos y el margen se volvió negativo. Nada de esto era visible en los dos primeros peldaños, y saltárselos habría llevado ese tamaño directamente a la cuenta real.

El resto de Quant500

Lo que estás aprendiendo, aplicado al índice todos los días:

La cartera del modelo, cada semana en tu correo

Cada sábado, su semana en un minuto: cómo fue, lo mejor y lo peor, y qué directivos compraron con su dinero. Y el día que el modelo se rehace, qué entra y qué sale. Es una simulación, no un consejo. Como mucho un correo a la semana, sin publicidad y sin cuenta; te das de baja con un clic. Lo hace una persona: Pol Gracia.

Cartera modelo con resultados simulados, no una recomendación personalizada. Tu correo se usa solo para esto: privacidad.

Detrás de la Academia y del resto de Quant500 hay una sola persona: Pol Gracia Serrahima.