High-Performance Backtest Engines
How to build a backtest engine that runs hundreds of times faster without changing a single PnL number — data layout, caching, adaptive resolution, and architecture, from first speedups to production internals.
- 01
Jun 26, 2026 #algotradingLa escalera de velocidad del backtest: 298x en la CPU de un portátil, PnL idéntico hasta la última operación
Cinco implementaciones del mismo barrido de 80 combinaciones de parámetros, todas verificadas para producir el mismo PnL: pandas rolling.apply tarda 69,9 segundos, numpy 3,1, numba 2,0, numba paralelo 0,23 — una aceleración medida de 298x en un Apple M2 Max sin ningún cambio de hardware, y aun así ~13x sobre una base vectorizada competente. Qué compra cada peldaño, por qué una GPU no es la pieza que falta, y dónde vive el verdadero cuello de botella en la búsqueda masiva de parámetros.
- 02
Jul 2, 2026 #algotradingEl impuesto del framework: cuando tu librería de backtest es más lenta que un bucle ingenuo de pandas
Comparamos ocho motores de backtest en un mismo barrido de parámetros idéntico: 150k barras, 80 combinaciones de cruce de HMA, con la paridad de número de operaciones fijada en 2707. Dos de los frameworks orientados a eventos más populares resultaron más lentos que un bucle de pandas escrito a mano, mientras que un motor vectorizado/compilado ejecutó el mismo trabajo unas 13,000× más rápido. Un estudio de la sobrecarga por barra que las librerías populares nunca fueron diseñadas para amortizar.
- 03
Mar 16, 2026 #algotradingCache Parquet Agregado: Cómo Acelerar Backtests Multi-Timeframe Cientos de Veces
Cómo precalcular timeframes e indicadores a partir de velas de un minuto, guardarlos en parquet y usarlos para pruebas masivas de estrategias sin recálculos redundantes.
- 04
Jul 3, 2026 #algotradingEl espacio de parámetros de dos ejes: por qué la mayor parte de tu barrido debería ser casi gratis
No todos los parámetros cuestan lo mismo al buscar. Los parámetros de una estrategia se dividen en un eje costoso (indicadores, recalculados sobre toda la serie) y un eje barato (umbrales de decisión, un recorrido O(n) sobre señales precalculadas). Como los indicadores son invariantes a los umbrales, los calculas una vez y barres miles de configuraciones de umbrales a ~5.600 cfg/s, aproximadamente 1.600 veces más barato que recalcular por configuración. Una re-tasación de la maldición de la dimensionalidad.
- 05
Mar 17, 2026 #algotradingDrill-down adaptativo: backtest con granularidad variable, de minutos a operaciones individuales
Cómo la granularidad adaptativa de los datos acelera los backtests y ahorra almacenamiento: drill-down de 1m a 1s, 100ms y operaciones individuales solo donde el precio se movió de forma significativa o el volumen se disparó, no en toda la serie histórica.
- 06
Jul 5, 2026 #algotradingLa Puerta de Fidelidad: el Backtesting de Grueso a Fino te Engaña Más Rápido, a Menos que el Proxy Barato Clasifique Igual que el Costoso
La búsqueda de profundización progresiva / multi-fidelidad (ASHA, eliminación sucesiva, Hyperband) filtra miles de configuraciones de forma barata y solo asciende a los supervivientes a la evaluación completa y costosa. Es una aceleración genuina, pero colapsa en silencio si la clasificación de baja fidelidad no coincide con la de alta fidelidad. Medimos la correlación de rango entre pliegues: en un solo pliegue, la ρ de Spearman puede ser 0.03 (clasifica casi al azar), subiendo a 0.43, 0.67, 0.78, 0.91 a medida que se acumulan los pliegues. La solución es una puerta obligatoria: medir primero ρ(barato, completo) y elevar automáticamente la fidelidad mínima hasta el primer escalón donde ρ ≥ 0.5.
- 07
Jul 4, 2026 #algotradingBúsqueda aleatoria vs. inteligente: el cruce es el costo de evaluación, no el algoritmo
Cuando un backtest es barato, un Sobol scrambled y tonto gana en throughput puro — los samplers inteligentes (TPE, CMA-ES, ASHA) pagan un impuesto de ask/tell en Python que los frena 20 veces, por lo que evalúan muchos menos puntos al mismo wall-clock y pierden. Haz que cada evaluación sea costosa (multi-TF + folds de walk-forward) y el cruce se invierte. Medimos ambos regímenes, y por qué la fidelidad de rank por fold (ρ@1 subiendo 0.03→0.43) es la condición previa para que el pruning valga la pena.
- 08
Jul 6, 2026 #trading algorítmicoLa trampa de precisión de la GPU: cómo un backtest en fp32 sobre Apple Metal devuelve basura en silencio
La GPU Metal de Apple no tiene float64. Porta un backtest vectorizado a ella de forma ingenua y la tentadora WMA por suma de prefijos desborda fp32 —error relativo máximo de 211×— y aun así se ejecuta y devuelve números de aspecto plausible. La solución no es más precisión; es una formulación distinta: una convolución directa por ventanas, segura en fp32 hasta 8×10⁻⁷ y 55.9× más rápida que numba de un solo hilo. La trampa, la aritmética y cómo demostrar que no caíste en ella.
- 09
Jul 7, 2026 #algotradingCuándo Compensa la GPU: El Roofline del Sweep de Parámetros, Donde un Titular de 167x Es en Realidad 27x de Algoritmo por 6.2x de Hardware
La ventaja de la GPU sobre la CPU crece con el tamaño del batch — de 54.5x con un combo por llamada hasta 359.6x con 61 en nuestro precómputo de indicadores multi-timeframe — porque un sweep pequeño no puede amortizar el overhead de lanzamiento de kernels y de transferencia. Descomponemos un titular de 167x en una victoria algorítmica de 27x que también ayuda a la CPU y una victoria de hardware de 6.2x, mostramos que la ventaja real de la GPU frente a la mejor CPU es solo 3.2x en single-timeframe y 6.2x en multi, y damos una guía de decisión sobre cuán ancho debe ser un sweep antes de que valga la pena apostar por una GPU.
- 10
Jun 30, 2026 #algotradingEl impuesto IPC: pon el motor de backtesting detrás de un socket y pierde un 13% — casi nada de eso es del socket
Portamos un kernel de backtesting de numba línea por línea a Rust y lo llamamos a través de un límite de proceso de cuatro formas, con una puerta de equivalencia que confirma un PnL idéntico hasta el último trade. Enviar toda la serie de precios de 1.2 MB por un socket Unix cuesta ~2 ms — alrededor del 0.1% del trabajo. Codificar el mismo payload en JSON cuesta 1348 veces más que los bytes crudos, las llamadas charlatanas por combinación reenvían los datos 80 veces, y un patrón de llamada por barra pagaría 2.1 s de IPC pura en un trabajo de 2.0 s. El límite es barato; el impuesto está en cómo lo cruzas.