martes, 5 de marzo de 2013

Trabajar con Datos de Forex con R y SQLite (4/5)


En la entrada anterior de este blog vimos como crear barras de cualquier longitud utilizando SQLite. Sin embargo, nos encontramos con el problema de que el tiempo de respuesta de las consultas era demasiado elevado. Esto nos puede crear ciertos problemas en operativa real para estrategias que trabajen en barras muy cortas (por ejemplo de un minuto), y sobre todo, supone un gran problema cuando queremos realizar análisis de tipo walk forward, ya que este tipo de análisis requiere de múltiples consultas.

Pero aquí es donde entra en juego las optimizaciones que permite SQLite, y sobre todo, ese misterioso atributo unix que hemos añadido a nuestra tabla.

Utilizando el Tiempo Unix

Para poder mejorar el rendimiento utilizando el atributo unix, lo primero que tenemos que hacer es crear un índice sobre esta columna:

CREATE INDEX unix_index ON eurusd (unix);

Y a continuación veamos cómo podemos consultar el máximo y el mínimo en barras de 8 minutos utilizando este nuevo campo:

SELECT MAX(high) AS High, MIN(low) as Low, date as Date
FROM eurusd
WHERE date > '2010-01-01' AND date < '2011-01-01'
GROUP BY round(unix / (8 * 60));

Y de igual manera se podrían consultar los precios de apertura y de cierre.

Consulta Final

En este momento ya tenemos todo lo que necesitamos para crear barras de cualquier longitud, para cualquier periodo de tiempo, y de una manera eficiente. La consulta final para barras de 8 minutos (8*60=480) sería:

SELECT STRFTIME('%Y-%m-%d %H %M', MIN(date)) AS Date,
    (SELECT open FROM eurusd e2
         WHERE e2.unix >= e1.unix / 480 * 480
         ORDER BY e2.unix ASC LIMIT 1) AS Open,
    MAX(high) as High,
    MIN(low) as Low,
    (SELECT close FROM eurusd e3
         WHERE e3.unix < (e1.unix / 480 + 1) * 480
         ORDER BY e3.unix DESC LIMIT 1) AS Close
FROM eurusd e1
WHERE date > '2010-01-01' AND date < '2011-01-01'
GROUP BY e1.unix / 480;

Otras optimizaciones

Estas consultas se pueden optimizar aun más, pero para ello habría que entrar a programar directamente en el API C de SQLite, un API que nos permite extender la funcionalidad del lenguaje SQL. SQLite dispone de las funciones agregadas MAX y MIN que nos permiten calcular el máximo y el mínimo alcanzado en una barra, pero no dispone de nada equivalente para calcular los precios de apertura y cierre de dicha barra. Es por ello que tenemos que realizar complejas sub-queries que nos retrasan mucho todo el proceso. Este problema se podría solucionar creando nuestras propias funciones agregadas OPEN y CLOSE utilizando el mencionado API de SQLite. Pero esto es un tema demasiado complejo, y que a menos que los lectores demuestren interés, no lo cubriré en este blog.

No hay comentarios:

Publicar un comentario