¿Realmente, qué es una estrategia
consistente y robusta?
By TradingSys
AndrEAs Analyzer |
En el trading
de sistemas a menudo hablamos de consistencia y robustez como si estos dos
términos significasen lo mismo e hiciesen referencia al hecho de que nuestro
maravilloso y flamante algoritmo es capaz de ganar dinero de manera
consistente. Pues bien, deshagamos algunos equívocos:
Si por
"consistente" entendemos beneficios regulares y estables en el
tiempo, desde ya les digo que ningún sistema les proporcionará jamás esa
satisfacción. Los mercados son volátiles, erráticos, caprichosos y, en buena
medida, imprevisibles. Los sistemas casi siempre van de comparsas: les toca seguir
su pauta.
Existe
una consistencia fuerte, axiomática, formal, junto a otra más blanda y
operativa que se ha instalado en el ámbito de los problemas complejos, donde
aleatoriedad e incertidumbre son moneda común. De la primera nos habla la
lógica de Gödel, según la cual un teorema T es consistente si,
dado un conjunto de axiomas, operadores lógicos y reglas de transformación, no
podemos deducir de él una conclusión C y su contraria -C. Obviamente,
este no es el caso de las máquinas lógicas que los traders algorítmicos construimos, porque
muchas veces idénticas reglas aplicadas a distintos mercados o marcos
temporales darán resultados (C1, C2...Cn)
contradictorios e inconsistentes. Por otra parte, la definición blanda de
consistencia encuentra su mejor aliado en la lógica difusa, donde las
conclusiones derivadas de un proceso inferencial tienen un carácter
provisional, aproximativo, estadístico. Eso ya es más familiar para nosotros y
representa mucho mejor el ámbito en el que nos movemos.
De este
modo, podemos decir que un sistema es consistente cuando:
A)
Responde de manera previsible a los movimientos del mercado para los que ha
sido programado, aunque estos muestren ligeras variaciones.
B) Un
amplio rango de combinaciones paramétricas consecuentes la lógica de base, son
soluciones viables para un determinado activo.
Si además se
cumplen las dos siguientes condiciones, el sistema también es robusto:
C) Obtiene
resultados positivos en un número elevado de activos y time frames.
D)
Resiste el paso del tiempo, siendo pequeña la dispersión de resultados en
distintas ventanas temporales.
Veamos
todo esto con más detalle:
La condición
A hace referencia a una consistencia formal "modelo-mercado"
que responde a la pregunta de si el sistema hace lo que debe. Es decir:
- ¿Se colocan
las órdenes de entrada y salida en los puntos previstos por el modelo?
-
¿Observamos diferencias significativas entre operativa simulada y real?
- ¿Los stops
loss funcionan según lo previsto? ¿Cumplen su cometido? ¿Nos protegen
desde la primera barra?
- ¿Los
filtros de volatilidad y tendencia realmente filtran o son un coladero de
órdenes adversas según la situación del mercado?
- ¿Al
aplicar el sistema en otras compresiones horarias y mercados tampoco detectamos
fallo alguno en la lógica?
Ni que decir
tiene que esta primera condición es un requisito sine qua non para poder operar
un sistema. Una estrategia con reglas de difícil validación o que en algún
momento pueden fallar carece de consistencia interna y no se debe operar.
La condición
B es más escurridiza y difícil de calibrar. Todo sistema incorpora
variables implícitas y explicitas. Las primeras tienen valores fijos
incorporados a las reglas y no son optimizables. Estas variables, por lo
general, permanecen ocultas para quien no sea el desarrollador de la
estrategia, pero no por ello son menos problemáticas. Las variables explicitas
son parámetros cuyo rango específico de valores es susceptible de optimización.
Veamos un ejemplo:
if (ADX(14)[0] < ADX(14)[1]
&& EMA(Low, EmaPeriod)[0] <
Low[3])
{
EnterShortStop(1, Low[0]-3*TickSize, "");
}
En estas
líneas de código solo tenemos una variable explícita "EmaPeriod",
pero aparecen numerosas variables implícitas cuyos valores elegidos ad
hoc resultan cuando menos cuestionables:
- ¿Por qué
utilizar un ADX de 14 barras en lugar de uno de 10 o de 25?
-
¿Por qué estamos comparando el valor de la media de los mínimos en la barra
actual con el mínimo de hace 3 barras? ¿No sería quizá mejor comparar con el
mínimo de hace 2 barras o de hace 5?
- ¿Por qué
metemos la orden en stop 3 ticks por debajo del mínimo de la
última barra? ¿Qué nos impediría meterla unos cuantos ticks más
abajo o más arriba?
Todas
estas preguntas nos llevarán, sobre todo a los más suspicaces, inevitablemente
a otra: A menos que el desarrollador sea un genio en el antiguo arte de
la numerología, ¿No habrán salido dichos valores de optimizaciones previas?
Aquí,
el problema capital es que una optimización intensiva acabará enmascarando las
bondades de la lógica y resultará muy difícil determinar si un sistema es bueno
debido a la consistencia de sus reglas o a que, de manera casual, determinada
combinación de parámetros ofrece resultados excelentes en un determinado
activo. En definitiva, bien de manera implícita o explícita, el fantasma del curve
fitting se nos puede colar en cualquier estrategia, así que
acostumbrémonos a vivir con él. Y vaya por delante que yo no soy defensor
de los sistemas sin parámetros, ni de estrategias minimalistas de simplicidad
delirante, pero carentes de estructura.
Tanto los
parámetros optimizables como el diseño de lógicas alternativas y no trilladas
son herramientas del arsenal del trader que, administradas de
manera inteligente, pueden conducir a sistemas ganadores. En este mundillo se
repiten de manera recurrente -y bastante acrítica, por cierto- mantras como
"buscad siempre la belleza de lo simple", "evitad las reglas
complejas", "al mercado no le gustan los caminos laterales",
etc. Pero la realidad es que en este, como en muchos otros ámbitos de la
actividad humana, la innovación siempre acaba ganado la partida al "más de
lo mismo". Y ahí están los inmensos recursos que el trading de alta
frecuencia pone al servicio de unos pocos privilegiados para demostrarlo.
Algunos de
los problemas del curve fitting tienen que ver con la forma de
optimizar:
- Demasiados
parámetros y muy poco histórico.
- Demasiados
parámetros y pocas operaciones.
- Inadecuada
elección de los cortes in-sample / out-sample.
-
Optimización demasiado fina e intensiva.
Dado que las
tres primeras son sobradamente conocidas por cualquier trader con
una mínima experiencia, nos centraremos en la última:
Aparentemente,
cuanto más fina sea la optimización y mejores los resultados obtenidos en
función del ratio diana empleado, mejor preparado estará nuestro sistema para
afrontar el insondable arcano oculto tras la última barra. Cuesta mucho asumir
la idea de que una combinación de parámetros que conduce a un impresionante backtest en
un histórico largo y con muchas operaciones, no tiene por qué ser
necesariamente la mejor para la operativa real. Sin embargo, la experiencia nos
demuestra que casi siempre acaban funcionando mejor juegos paramétricos:
a) Que no
representan soluciones de caso límite. Es decir, valores que generan resultados
extraordinarios pero sin continuidad en los valores contiguos; o sea, las
consabidas cimas escarpadas en un gráficos de superficies.
b) Limpios,
sin tantos decimales, sin "forzar la máquina": ¿Por qué no 100 en
lugar de 97 o 0,5 en vez de 0,496?
En
definitiva, una "optimización gruesa" de la región in-sample suele
dar mejores resultados en el out-sample que otra demasiado fina.
Por ello recomiendo utilizar algoritmos genéticos en vez de optimizaciones de
"fuerza bruta", así como saltos generosos entre valores en lugar de
filigranas de ballet. Pongamos un ejemplo:
Nuestro punto
de partida será un sistema intradiario tipo VBO (volatility breakout) con 6 parámetros optimizables
cuyos rangos de valores son:
Una cantidad
tan descomunal de combinaciones paramétricas 1,8 x 108 (y les
aseguro que no es ni de lejos de las mayores que he visto) puede hacer estragos
cuando pulsamos el botón de fabricar sueños y realizamos una optimización
exhaustiva, o de fuerza bruta, en un histórico pequeño. En realidad lo que
estamos consiguiendo es un billete seguro al reverso tenebroso de la
sobreoptimización.
En el
gráfico inferior vemos el resultado de una sobreoptimización típica: Optimizamos la
región in-sample y aplicamos el juego de valores más rentable,
o el que satisfaga el criterio diana elegido, al tramo del histórico sin
optimizar:
El trazado de
la curva de beneficios en 2010 y 2011 es impecable, y nuestra primera tentación
bien podría haber sido comenzar a operar el sistema el primer día laborable de
2012 con esos valores. Pues bien, la sorpresa hubiera sido mayúscula al
comprobar el progresivo e inmisericorde deterioro de la estrategia
prácticamente desde el primer mes.
Afortunadamente,
hemos sido sensatos y optamos por un modelo de optimización más realista. En
lugar de una matriz de optimización tan monstruosa, optamos por reducir el espacio
de búsqueda. Esto lo podemos hacer de dos modos: aumentando el tamaño del salto
y/o ciñendo más las horquillas de máximos y mínimos a los valores centrales de
la distribución obtenida durante la construcción de la lógica:
Ahora ya
tenemos un número bastante más manejable. Aun así, optaremos por una
optimización genética más superficial, sin forzar demasiado el tamaño de la
población y el número de generaciones
El aspecto de
la región optimizada ahora no es tan vistoso como en el gráfico anterior. De
hecho resultará mucho menos apetecible comenzar a operar en 2012 con esta
combinación de parámetros viendo el trazado de la región in-sample.
Sin embargo, miren lo que ocurrió después y la fiesta que nos habríamos
perdido.
Naturalmente,
una combinación de parámetros, por muy rigurosos que hayamos sido en el proceso
de evaluación, no garantizará nunca resultados brillantes en operativa real: Se
puede producir algún sesgo no previsto en las formaciones de precios que
erosione lentamente el rendimiento de la estrategia; o peor aún, una transición
de fase a otra ventana temporal(cambio de mercado): Cuando un mercado cambia de manera abrupta el
sistema se rompe, con independencia de los parámetros elegidos.
Aclarado
este punto, veamos qué podemos hacer para acreditar la consistencia de una
lógica si el sistema, como suele ocurrir casi siempre, incorpora varios
parámetros.
Analicemos
un caso práctico:
Supongamos un
sistema intradiario, basado en ruptura de rangos que cuenta con un filtro de
volatilidad y un stop de pérdidas. En total 6 parámetros. Lo aplicamos a un instrumento financiero X
en compresión de 20 minutos. Para ello contamos con un histórico de 12 años
(2001-2012).
Nuestro
objetivo será determinar cuántas combinaciones paramétricas, en un espacio de
búsqueda previamente acotado generan resultados positivos, así como la
distribución de los mismos. Para ello lo primero que debemos hacer es delimitar
el terreno de juego, estableciendo una horquilla de valores máximos y mínimos
que sean consecuentes con la lógica a evaluar:
Así, para la
EMA larga seleccionamos valores entre 200 y 2000 en saltos de 50. Mientras que
para la EMA corta elegiremos el rango 10-150 en saltos de 10. El filtro de
volatilidad oscilará entre 0,5 y 2,5 con un salto de 0,1. El stop es de tipo
porcentual y no queremos que la peor operación rebase el 5%, por lo que
optimizaremos entre 0,5 y 5 con un salto de 0,1. Por último, nuestro
estimador del rango efectivo se aplicará a un número de sesiones comprendido
entre 10 y 50, siendo el salto de 5.
Como pueden
ver, incluso siendo cuidadosos al delimitar el espacio de búsqueda, el número
de combinaciones paramétricas posibles es inmenso. Por lo que procede, como ya
hemos señalado, tirar de algoritmos genéticos y optimización gruesa. Pero
ahora, en lugar de buscar las mejores operaciones, lo que queremos es evaluar
una muestra aleatoria de parámetros que sea representativa del conjunto de
combinaciones posibles.
Para ello
tenemos dos alternativas:
- Modificar
el código del sistema para que en cada iteración los valores paramétricos sean
diferentes. Un ejemplo de código de este tipo para NinjaScript sería:
-
También podemos recurrir a herramientas como el optimizador genético de NT7
para generar secuencias aleatorias de combinaciones paramétricas de manera
sencilla.
Supongamos
que queremos una muestra estadísticamente representativa (por ejemplo, 1.000
combinaciones) de un espacio de búsqueda muy grande, como el de las tablas
anteriores. En este caso lo único que tenemos que hacer es configurar el
optimizador del siguiente modo:
Así, el
algoritmo genético seleccionará una población de mil individuos (cada individuo
no es más que una matriz aleatoria de valores de los parámetros) y la aplicará
en una única generación, con lo que los procesos evolutivos de recombinación y
selección no serán aplicables y el resultado será una lista con los resultados
de esas combinaciones. Por ejemplo esta:
Exportamos a
Excel los resultados y procedemos a un análisis detallado. Para ello
necesitamos la estadística descriptiva y distribución del retorno, el drawdown y
el ratio diana elegido al optimizar. Nosotros normalmente utilizamos el SQN (system
quality number), si bien se pueden emplear también otros ratios como los de
Calmar, Sortino y Sharpe, o el profit factor. Finalmente obtenemos gráficos de este
tipo:
...Y las
estadísticas que delimitan el terreno de juego:
Bien, pues
ahora la cuestión será determinar si viendo una muestra representativa de los
múltiples caminos que puede tomar el equity curve podemos
acreditar la consistencia de esta estrategia. Lo ideal sería que todas las
combinaciones paramétricas condujesen a rendimientos positivos. Pero, con un
histórico largo y un espacio de búsqueda inmenso, esa situación la vamos a
encontrar en contadas ocasiones.
Lo
normal es que una lógica robusta deje un amplísimo sesgo positivo en la
distribución de resultados, de tal modo que podamos asegurar con una
probabilidad muy alta que el sistema es inherentemente ganador con
independencia de la configuración elegida.
En
cualquier caso, para el trader independiente y con recursos
limitados, la cuestión de qué combinación paramétrica debe elegir seguirá
siendo un problema embarazoso y una fuente de incertidumbre aun cuando
demostremos estadísticamente la consistencia de una estrategia: Como usuario
del sistema, no me importa tanto saber que dispongo de una máquina en promedio
muy rentable, sino asegurarme, hasta donde sea posible, de que la configuración
concreta que he elegido será también una apuesta ganadora.
Veamos
todo esto con un ejemplo:
·
AÑO 1:
Supongamos
que una vez optimizado el sistema XYZ los juegos de valores de las curvas
blanca, roja y azul son los que ofrecen los mejores resultados in-sample.
En consecuencia, el 2 de enero comenzamos a operar con la combinación
paramétrica de la línea blanca: ¡Genial! Hemos acertado y terminamos el año con
generosos beneficios. La curva roja también está en el mismo bombo. Sin
embargo, nunca sabremos de su peligroso trazado, ya que permanecerá oculto en
el universo de lo que pudo haber sido y no fue.
·
AÑO 2:
Alentados por
los buenos resultados del año anterior, y dado que nuestro sistema tuvo un
rally estupendo en los dos últimos meses, consideramos que no es necesario
modificar los parámetros y decidimos continuar con ellos un año más. Pues bien,
craso error, porque ahora son las curvas azul y roja quienes toman la
delantera, mientras que la curva blanca queda prácticamente clavada al suelo.
·
AÑO 3:
Con los
resultados del año anterior en la mano, pensamos que no nos queda otra que
reoptimizar el sistema. De las tres mejores combinaciones en backtest debemos
elegir una, y en esta ocasión optamos por el juego de valores correspondiente a
la línea azul. Nuevamente el insondable arcano quiere que volvamos a fallar,
pero esta vez incluso incurriendo en pérdidas. En vista de la traumática
experiencia, decidimos que quizá el sistema se ha roto y no vale la pena operar
con él: ¡Game Over! Fin de la partida.
Sin embargo
el sistema está muy vivo, y así lo entiende el gestor de un Hedge Fund para
quien no existe el problema de las combinaciones paramétricas, sencillamente
porque, habiendo comprobado de manera exhaustiva la robustez de la lógica, en
lugar de echar sus tablillas de apuestas sobre valores concretos, ha decidido
comprar la mesa de juego entera. En consecuencia, procede de manera muy
distinta: Selecciona una muestra aleatoria de combinaciones paramétricas cuyas
estadísticas sean análogas a las de la totalidad del espacio de búsqueda. El
tamaño de la muestra dependerá del capital disponible y del nivel de confianza
deseado. En fin, ahorrémonos los detalles, supongamos que ha llegado a la
conclusión de que 100 combinaciones son suficientes. Seguidamente lo que
hace es estimar el capital necesario, y ¡a jugar!
Ahora el
juego es bien distinto y su aspecto gráfico será de este tipo:
En realidad,
es como una simulación de Montecarlo, pero vista desde los parámetros en lugar
que desde la secuencia de operaciones. En este escenario la evolución de cada
curva concreta es irrelevante, lo que cuenta es que el rendimiento promedio año
a año se mantenga. En otras palabras, que la distribución empírica de
resultados se acomode a la distribución teórica del modelo. Así, mientras los
principales ratios no se alejen de un umbral preestablecido, consideraremos que
el sistema es consistente, aguanta y se puede confiar en él.
Valga
decir que con este enfoque la carga de la prueba recae en la calidad de la
lógica, y optimizar se convierte en un problema de pobres, de escasez de
recursos.
Y si además demostramos que el
sistema cumple las condiciones C (funcionar en muchos
mercados) y D (resistir sin achaques el paso del tiempo),
entonces estamos ante una rara joya que acreditará además de la consistencia su robustez,
alegrando la vida de su afortunado poseedor. No sueñen, estas gemas son bastante
infrecuentes.
No me denomiría trader si no hubiese encontrado a partir de darme golpes con el mercado soluciones para esto. Pero será para otra entrada y tal vez no pública.
AndrEAs
No hay comentarios.:
Publicar un comentario