En una entrada reciente de este blog describí un sistema para la generación automática de
sistemas de trading. Este sistema giraba en torno al concepto de
“Evolución Gramatical”, optimizadores avanzados, y el lenguaje
de análisis estadístico R. Degraciadamente R no dispone de ningún
paquete específicamente diseñado para la optimización de sistemas
basado en evoluciones gramaticales. Sin embargo, implementar los
fundamentos de este sistema no es complicado. En esta serie de
entradas vamos a revisar brevemente qué es eso de la evolución
gramatical, cómo puede ser implementada en R, y qué tiene que ver
con los sistemas de trading.
Las gramáticas son una herramienta muy
conocida en el mundo de la ingeniería informática, y más
concretamente, en el área de compiladores. Las gramáticas nos
permiten definir de manera rigurosa los lenguajes de programación
(como por ejemplo C++ o java), y por tanto, nos permite determinar si
un determinado código fuente está correctamente escrito según el
estándar del lenguaje. Además, las gramáticas también son útiles
a la hora de compilar los programas, es decir, de transformar el
código fuente de un programa en código máquina entendido por el
ordenador.
Sin embargo, en el caso que nos ocupa,
la generación de estrategias de trading, le vamos a dar la vuelta a
la tortilla. Es decir, no utilizamos las gramáticas para decidir si
una estrategia es (léxica y sintácticamente) correcta, sino para
generar automáticamente el código de dicha estrategia. Podríamos,
por ejemplo, definir una gramática que nos permita generar
estrategias basadas en el cruce de medias móviles, y dejar que sea
el propio ordenador el que “pruebe” distintas formas de combinar
las medias móviles en una estrategia. Por ejemplo, el sistema que
utilizamos en Entropycs generaría sistemas como los siguientes:
* SMA(simbolo,6)>SMA(simbolo,4+1)
| SMA(simbolo,92)>SMA(simbolo,90)
* SMA(simbolo,10)>SMA(simbolo,30)
& SMA(simbolo,2)>SMA(simbolo,36)
* SMA(simbolo,116)>SMA(simbolo,99)
Evidentemente la mayoría de los
sistemas así creados no tienen mucho sentido, pero si pensamos que
el ordenador genera y evalúa varios centenares de sistemas por
segundo, podemos hacernos una idea del potencial de este método.
Para describir las gramáticas se
utiliza la denominada la notación Backus-Naur (BNF).
Técnicamente la gramática se compone de un conjunto de símbolos
terminales, un conjunto de símbolos no terminales, unas reglas de
producción, y un símbolo inicial. Aunque suene muy complejo, la
idea es muy sencilla. Veamos un ejemplo. Supongamos que queremos
definir una gramática que genere números enteros de cualquier
longitud. Un número se compone de uno o más dígitos, y los dígitos
son los números de 0 a 9. Por tanto, la gramática sería
<número> := <número><dígito>
| <dígito>
<dígito> := 0 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9
Los símbolos no terminales son
<número> y <dígito>; los símbolos terminales sería de
0 al 9, y el símbolo inicial sería <número>. Las reglas de
producción son las vistas más arriba y transforman un símbolo no
terminal, a la izquierda del :=, por cualquiera de los símbolos
(terminales o no) de la derecha, que vienen separados por '|'. Notese
que en la generación de sistemas de trading seleccionaríamos al
azar (o según nuestro algoritmo de búsqueda) el símbolo de la
derecha a utilizar.
Por ejemplo, una posible evolución de
la gramática sería:
Paso 1: <número>
Paso 2: <número><dígito>
Paso 3: <número><dígito>5
Paso 4: <dígito>35
Paso 5: 135
Y al ser todos los símbolos ya
terminales, acabaría el proceso. Dejo propuesto al lector como
ejercicio crear una gramática que sume dos números enteros.
¿Y cómo se hace esto en R? Pues eso
es el tema del que tratará nuestra siguiente entrada de blog.
No hay comentarios:
Publicar un comentario