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
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;
(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