executive programme in algorithmic trading epat 500x500 1

El objetivo de Quantinsti es formar a su alumnos en el trading algorítmico. Pertenece a iRageCapital Advisory, empresa conocida por sus servicios relacionados con la creación de mesas de trading algorítmico.
Quantinsti

 

Este proyecto construye y evalúa una estrategia de pairs trading market-neutral centrada en 25 acciones large cap del NSE pertenecientes a los sectores de banca, tecnología, farma, cemento y automoción. Los pares se seleccionan mediante una prueba de estacionariedad de residuos, concretamente el ADF(0) con p-value de MacKinnon, sobre una muestra de entrenamiento. Para garantizar robustez estadística y controlar los falsos descubrimientos, se aplica la False Discovery Rate (FDR) de Benjamini–Hochberg al 5%.

La estrategia opera la reversión a la media a través de z-scores del spread utilizando una división train/test tipo walk-forward. Representa una implementación académica limpia y defendible, sin look-ahead bias, con costes de transacción explícitos (5 bps por pata y por lado), capital igual por cada par activo (₹5,00,000) y métricas de riesgo completas a nivel de cartera.

Introducción y motivación del proyecto

El pair trading es una estrategia clásica de arbitraje estadístico que busca explotar divergencias temporales de precio entre dos activos relacionados, manteniendo al mismo tiempo una postura neutral al mercado. Este proyecto aplica ese concepto al mercado de renta variable indio entre el 1 de enero de 2015 y el 30 de junio de 2025.

La motivación principal fue construir un prototipo riguroso que abordara errores comunes del trading algorítmico, como el look-ahead bias, cálculos incompletos de Profit and Loss (PnL) y controles insuficientes sobre el problema de múltiples pruebas.

Estrategia y metodología de implementación (desglose técnico)

La estrategia se apoya en una metodología walk-forward rodante que utiliza una ventana de entrenamiento de 252 días de trading y un paso de prueba de 21 días.

1. Selección de pares y cointegración: Durante la fase de entrenamiento, la ratio de cobertura (β) se estima mediante Ordinary Least Squares (OLS). Después se prueba la estacionariedad de los residuos usando el estadístico t de ADF(0) para generar un p-value de MacKinnon. La FDR de Benjamini–Hochberg se aplica al 5% para limitar falsos positivos. Del marco surgieron tres pares altamente cointegrados: HDFCBANK.NS vs KOTAKBANK.NS, HEROMOTOCO.NS vs ULTRACEMCO.NS y HCLTECH.NS vs ICICIBANK.NS.

2. Lógica de generación de señales: Para evitar look-ahead bias, las variables rodantes de media y desviación estándar se desplazan estrictamente 1 día.

Cálculo del spread: St = At – β × Bt
Cálculo del Z-Score: zt = (St – μt-1) / σt-1
Reglas de ejecución: Entrar cuando |zt| > 1,5 y salir cuando zt cruce 0.

Código de implementación en Python

A continuación se muestra un fragmento conceptual de Python que demuestra la lógica matemática central utilizada en la estrategia de Shant:

«`html id=»47240″
import pandas as pd
import statsmodels.api as sm

def calculate_signals(train_data, test_data, stock_a, stock_b):
# 1. Estimate Hedge Ratio (Beta) using OLS on Training Window
model = sm.OLS(train_data[stock_a], train_data[stock_b]).fit()
beta = model.params

# 2. Calculate Out-of-Sample Spread
# Spread formula: S_t = A_t – beta * B_t
spread = test_data[stock_a] – (beta * test_data[stock_b])

# 3. Calculate Z-Score strictly avoiding look-ahead bias
# z_t = (S_t – mu_{t-1}) / sigma_{t-1}
rolling_mean = spread.rolling(window=30).mean().shift(1)
rolling_std = spread.rolling(window=30).std().shift(1)
z_score = (spread – rolling_mean) / rolling_std

# 4. Generate Trading Signals based on Z-Score Thresholds
# Enter when absolute z-score > 1.5, Exit when it crosses 0
long_entry = z_score < -1.5 short_entry = z_score > 1.5
exit_signal = (z_score.shift(1) * z_score <= 0)

return z_score, long_entry, short_entry, exit_signal

3. Cartera y gestión del riesgo:

Tamaño: asignación de capital equiponderada, asignando ₹5,00,000 por cada par activo.
Costes: los costes de transacción se modelizan explícitamente en 5 bps por pata y por lado para entrada y salida.
Cálculo del PnL: el PnL se asigna desde ambas patas. Cualquier posición abierta se cierra forzosamente en el último día del backtest para asegurar un reporting completo.

Hallazgos clave y rendimiento de la cartera

El backtest fuera de muestra generó las siguientes métricas de rendimiento a nivel de cartera durante el periodo de prueba:

Resumen de rendimiento de la estrategia
Base de capital    ₹15,00,000
Pares operados    3
Periodo de backtest    11 de enero de 2016 – 27 de junio de 2025
Total de operaciones    271
Ratio de acierto    63,47%
PnL total    ₹1,65,544.97
PnL / Capital    11,04%
Rentabilidad anualizada    0,30%
Volatilidad anualizada    13,34%
Ratio Sharpe    0,089
Máximo drawdown    -34,31%

Retos y limitaciones

Restricciones de tamaño: la asignación es educativa (igual capital por par); no modeliza dinámicamente límites de capacidad ni restricciones reales de margen.

Costes de transacción: se modelizan limpiamente a 5 bps por pata y por lado, pero el slippage real de ejecución y los spreads bid-ask pueden diferir.

Aproximación ADF(0): el modelo utiliza un ADF con rezago 0 por velocidad computacional. Para futuras iteraciones se recomienda una prueba ADF completa con rezagos optimizados.

Múltiples pruebas: aunque el método FDR reduce los falsos descubrimientos, no los elimina por completo.

Sesgo de supervivencia: el universo de 25 acciones es fijo y no tiene en cuenta dinámicamente los cambios históricos en la composición del índice.

Próximos pasos

Mejorar el rendimiento de la estrategia

Aunque la estrategia actual proporciona una base académica limpia, varias mejoras concretas pueden elevar de forma significativa su rentabilidad ajustada al riesgo y su aplicabilidad en el mundo real:

1. Optimizar la selección del rezago en el ADF

Sustituir el atajo actual de ADF(0) por un selector de rezagos basado en criterio de información (AIC o BIC). Esto reduce el riesgo de señales espurias de cointegración y mejora la calidad de la selección de pares, lo que lleva a entradas más estables y fiables.

2. Ampliar el universo y diversificar pares

La cartera actual de tres pares está muy concentrada. Extender el universo más allá de las 25 large caps para incluir mid caps del NSE en sectores adicionales (energía, FMCG, metales) generaría un conjunto más amplio de candidatos cointegrados, mejoraría la diversificación y reduciría el impacto de que un solo par deje de funcionar.

3. Introducir position sizing dinámico

La estrategia utiliza actualmente un tamaño fijo de ₹5,00,000 por par. Sustituirlo por un sizing escalado por volatilidad (por ejemplo, ponderación inversa a volatilidad o criterio de Kelly) permitiría asignar más capital a pares que muestren señales de reversión a la media más fuertes y spreads más ajustados, mejorando el Sharpe ratio global y reduciendo drawdowns.

4. Afinar de forma adaptativa los umbrales de entrada/salida

Los umbrales fijos de z-score de ±1,5 para la entrada y 0 para la salida son estáticos en todos los regímenes de mercado. Un modelo adaptativo de umbrales, donde los niveles de entrada y salida se calibran a la volatilidad rodante de cada par o a su clasificación de régimen (tendencial frente a mean-reverting), puede filtrar señales de baja calidad y mejorar la tasa de acierto por encima del actual 63,47%.

5. Incorporar reglas de stop-loss para controlar el drawdown

El drawdown máximo actual de -34,31% es elevado en relación con la rentabilidad anualizada del 0,30%. Añadir un stop-loss a nivel de par (por ejemplo, salir cuando el z-score supere ±3,0 o cuando la pérdida no realizada exceda un porcentaje fijo del capital asignado) limitaría el downside en eventos de ruptura de régimen y mejoraría sustancialmente el Sharpe ratio.

6. Corregir el sesgo de supervivencia con un universo rodante

El universo fijo de 25 acciones infla el rendimiento histórico al incluir solo compañías que sobrevivieron a todo el periodo 2015–2025. Utilizar una lista point-in-time de componentes del NSE Nifty 50 o Nifty 100 que refleje la composición real del índice en cada ventana de entrenamiento eliminaría este sesgo y produciría estimaciones de rendimiento futuro más realistas.