Prólogo
En el anterior artículo de sistemas de trading les explicábamos cómo diseñar la gestión de cierre por fin de sesión utilizando Visual Chart 5. Al final del artículo, reflexionamos sobre el problema de colocar la orden de liquidación justo en la última barra de cada sesión. Comentamos que una posible solución sería cerrar posiciones una barra antes del cierre de sesión para asegurar la ejecución de la orden. Pues bien, dedicaremos éste artículo a explicar cómo automatizar la búsqueda de ésta penúltima barra, en concreto, el horario asignado a dicha barra.
Cómo calcular el horario de la penúltima barra
Vamos a detectar el horario de la penúltima barra de cada sesión de modo que podamos asignar dicho horario a la variable endsession (ver artículo anterior). La idea es que realizando este único cambio, no tengamos que cambiar nada más del código fuente.
Pero, ¿cómo saber cuál será el horario de la penúltima barra? Tengamos en cuenta que esto puede variar en base a la compresión temporal. Estamos de acuerdo en que la hora de cierre es siempre la misma independientemente de si usamos gráficos de 5, 10, 30 o 60 minutos. Pero el valor cambia en cada una de estas compresiones cuando queremos referirnos a la barra anterior. Por ejemplo, para las acciones del Ibex35, la hora de cierre será las 17:30 horas, si el gráfico usado es de 5 minutos, el horario asignado a la barra anterior será las 17:25 (hora de cierre de la barra), si el gráfico es de 30, será las 17:00, si el gráfico es de 10, será las 17:20, etc…
La ecuación horaria
En realidad, se trata de resolver una ecuación con una única incógnita y dos variables. La incógnita sería la hora que queremos obtener y las dos variables serían la hora de cierre de la sesión y el tamaño de la compresión de minutos. La ecuación quedaría de la siguiente forma:
Hora_ant = Hora_cierre – Tama_compresion
Supongamos el ejemplo de antes (acciones del Ibex35) y una compresión de 5 minutos. Recordemos que el horario se especifica en formato militar, esto es, que las 17:30 horas se definen como 1730. Si sustituimos la Hora_Cierre por 1730 y el Tama_compresion por 5, obtenemos el horario de la barra anterior:
Hora_ant = 1730 – 5 = 1725
Si la compresión hubiera sido de 20 minutos:
Hora_ant = 1730 – 20 = 1710
Por lo tanto, podríamos pensar que basta añadir esta ecuación en el código fuente y ya tenemos el valor hora que buscamos. Sin embargo, la solución no es tan directa porque aunque se utilice un formato numérico, lo que se está calculando son horas, las cuales van de 60 en 60 minutos, es decir, que no usan el sistema decimal. De modo que si la compresión, por ejemplo, hubiera sido de 90 minutos quedaría así:
Hora_ant = 1730 – 90 = 1640
Resultado que no es correcto, porque si restamos 90 minutos a 17:30, el resultado debe ser las 16:00 horas (1 hora y media).
¿Cómo solucionarlo entonces? Pues lo más sencillo es aprovechar las funciones que ya incorpora Visual Basic para calcular fechas. Veamos a continuación cómo sería el proceso:
Las funciones temporales de Visual Basic
El módulo DateAndTime de Visual Basic contiene varias funciones que permiten jugar con un tipo de variables denominadas Date las cuales representan a fechas y horas.
Para no complicarnos, no vamos a entrar a detallar este módulo. Nos basta con saber que existe una función llamada DateAdd() con la cual podemos obtener el resultado de sumar o restar un valor a una fecha u hora.
Modificando la ecuación planteada antes, hacemos que la incógnita se obtenga a partir del valor devuelto por la función DateAdd(), de modo que lo que tendríamos que añadir a nuestro código fuente sería lo siguiente:
Hora_ant = DateAdd(“n”, -1 * Tama_Compresion, Hora_Cierre)
Donde “n” especifica que se están restando minutos y el menos uno sirve para restar el valor en lugar de sumarlo.
Una vez más volvemos a tener un problema: Y es que el valor de Hora_Cierre está en formato militar, es decir, que se trata de un valor de tipo numérico, mientras que la función espera que dicha variable sea un valor de tipo Date.
Asimismo, la función devuelve también un valor de tipo Date, mientras que lo que nosotros queremos obtener es un valor de tipo numérico para sustituirlo en la variable endsession. Como vemos, tenemos un doble problema de conversión de tipos.
Para arreglarlo, habría que, primero, transformar Hora_Cierre a un valor de tipo Date, y segundo, transformar el resultado de la función a un valor de tipo numérico.
Transformando un tipo numérico a un tipo Date
Si recordamos el anterior artículo, en la variable endsession guardábamos el valor numérico devuelto por la función GetSymbolInfo(). Esto nos generaba una hora en formato militar (por ejemplo, las 1730).
Lo que vamos a hacer con esta variable es extraer los minutos, extraer la hora y crear una cadena de texto que tenga la siguiente estructura: “hora : minutos”. Luego crearemos una variable auxiliar de tipo Date que recogerá la transformación. Veamos cómo quedaría:
En Visual Basic:
En la Plataforma Visual:
La Plataforma Visual no reconoce las variables de tipo Date ni tampoco las funciones de Visual Basic como Trim() o CDate(), por eso tenemos que poner todas las sentencias entrecomilladas. La variable auxiliar x recoge la transformación de la hora de cierre a formato Date, lo cual se consigue usando la función de Visual Basic CDate(número).
Transformando un tipo Date a un tipo numérico
Tras realizar este proceso, ya tenemos transformada la hora de cierre en tipo Date, así que ahora extraeremos la compresión temporal del gráfico y se lo restaremos a este valor. Una vez hecho esto, volveremos a realizar una transformación, en este caso, desde un valor de tipo Date a un valor de tipo numérico. Veamos cómo quedaría el código fuente:
En Visual Basic
Aquí vemos que hemos almacenado en la variable ncomp la compresión, y que luego lo hemos incluido en la función DateAdd() con signo negativo para que lo reste, tal y como habíamos comentado anteriormente.
En la Plataforma Visual
Como vemos, actualizamos la variable endsession con el valor devuelto por la función DateAdd() pero en formato numérico. Para definir este formato numérico, lo que hacemos es aplicar la siguiente ecuación:
Hora_Cierre = Minutos(Hora_ant) + 100 x Hora(Hora_ant)
Es decir, que si hora anterior ha resultado ser las 17:10 (por ejemplo), el valor de Hora_Cierre será 10 + (17 x 100) = 10 + 1700 = 1710.
Aplicando la estrategia a un gráfico
Tras haber añadido la actualización de la hora de cierre, compilamos la estrategia y podemos proceder a aplicarla a un gráfico.
En la siguiente imagen, observamos cómo efectivamente sobre la acción de Telefónica el último negocio cierra una barra antes del fin de sesión.
Gracias a esto, nos vamos a asegurar de que no queden posiciones abiertas fuera de sesión. Como la compresión era de 5 minutos, la orden se ejecutó a las 17:25. Si cambiamos a otro tipo de compresión, también lo hará correctamente. Para verificarlo, seleccionamos una compresión poco habitual, por ejemplo, de 102 minutos. En el siguiente gráfico vemos el resultado:
En este caso la orden se ejecutó a las 15:48, es decir, 1 hora y 42 minutos antes de las 17:30, acertando de pleno con la hora de la penúltima barra. ¡Perfecto!
Conclusiones
Dejar posiciones abiertas de un día para otro implica un alto riesgo no soportado por todos los bolsillos, por lo que aplicar una gestión de cierre de sesión es prácticamente obligatorio en cualquier estrategia automática. El código fuente que hemos visto en este artículo sirve como diseño estándar de la gestión de cierre sin tener que preocuparnos de cuál es la hora fin de sesión del producto financiero o de la compresión temporal, si bien es obvio que el diseño puede resultar algo complejo si tenemos pocas nociones de programación.
¿Existe un método más sencillo que éste? En cierto modo sí. Precisamente con la nueva versión de Visual Chart (Visual Chart 6) es posible definir un intervalo de operativa de forma mucho más sencilla gracias a las propiedades que se han incorporado como novedad en el diseño de estrategias.
En el próximo artículo hablaremos sobre ello.
Oscar Cuevas
Visual Chart Group