En la
entrada anterior de esta serie vimos como hacer algunas
consultas sobre nuestros datos de Forex. En esta entrada lo que vamos
a ver es cómo hacer otras consultas más avanzadas, y más útiles.
Si
por ejemplo queremos ver el máximo y el mínimo de barras de 8
minutos (sí, sí, de 8 minutos), podemos hacer:
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(STRFTIME('%s', date) / (8 * 60));
Es
decir, podemos agrupar los datos en barras de cualquier longitud, y
no sólo las longitudes estándar de 5 minutos, 15 minutos, 1 hora,
etc. que ofrecen la mayoría de las plataformas de trading.
Uniendo
el ejemplo anterior con las consultas de apertura, máximo, mínimo y
cierre de la entrada anterior de este blog, lo que podemos
conseguir es agrupar nuestros datos sobre barras de cualquier
longitud. Esto nos permite hacer trading en barras de longitudes no
convencionales, lo que nos puede suponer una importante ventaja sobre
otros traders. Además, también podemos identificar mejor el tamaño
de barra óptimo para nuestras estrategias de trading, optimizándolas
para cada una las longitudes de barra, desde 1 minuto, hasta por
ejemplo 1440 minutos (1 día).
Por
ejemplo, para ver los datos agrupados en barras de 13 minutos
utilizamos:
SELECT
STRFTIME('%Y-%m-%d %H %M', MIN(date)) as Date,
MAX(CASE WHEN STRFTIME('%s', date) % (13 * 60) = 0 THEN open ELSE 0 END) AS Open,
MAX(high) as High,
MIN(low) as Low,
MAX(CASE WHEN STRFTIME('%s', date) % (13 * 60) = 4 * 60 THEN close ELSE 0 END) AS Close
FROM eurusd
MAX(CASE WHEN STRFTIME('%s', date) % (13 * 60) = 0 THEN open ELSE 0 END) AS Open,
MAX(high) as High,
MIN(low) as Low,
MAX(CASE WHEN STRFTIME('%s', date) % (13 * 60) = 4 * 60 THEN close ELSE 0 END) AS Close
FROM eurusd
WHERE date > '2010-01-01' AND date < '2011-01-01'
GROUP BY STRFTIME('%s', date) / (13 * 60);
GROUP BY STRFTIME('%s', date) / (13 * 60);
Desgraciadamente
esta consulta sólo funciona si nuestros datos no tienen huecos, lo
cual no siempre se cumple. Para conseguir el mismo resultado pero con
datos que potencialmente pueden tener huecos, tendríamos que
utilizar otra consulta algo más compleja:
SELECT
STRFTIME('%Y-%m-%d %H %M', MIN(date)) AS Date,
(SELECT open from eurusd e2
where CAST(STRFTIME('%s', e2.date) AS INTEGER) >=
CAST(STRFTIME('%s', e1.date) AS INTEGER) / (13 * 60) * 13 * 60
order by e2.date asc limit 1) AS Open,
MAX(high) as High,
MIN(low) as Low,
(SELECT open from eurusd e2
where CAST(STRFTIME('%s', e2.date) AS INTEGER) >=
CAST(STRFTIME('%s', e1.date) AS INTEGER) / (13 * 60) * 13 * 60
order by e2.date asc limit 1) AS Open,
MAX(high) as High,
MIN(low) as Low,
(SELECT close from eurusd e3
where CAST(STRFTIME('%s', e3.date) AS INTEGER) <
(CAST(STRFTIME('%s', e1.date) AS INTEGER) / (13 * 60) + 1) * 13 * 60
where CAST(STRFTIME('%s', e3.date) AS INTEGER) <
(CAST(STRFTIME('%s', e1.date) AS INTEGER) / (13 * 60) + 1) * 13 * 60
order by
e3.date desc limit 1) AS Close
FROM eurusd e1
FROM eurusd e1
WHERE
date > '2010-01-01' AND date < '2011-01-01'
GROUP BY CAST(STRFTIME('%s', e1.date) / (13 * 60) AS INTEGER);
GROUP BY CAST(STRFTIME('%s', e1.date) / (13 * 60) AS INTEGER);
Sin
embargo, el lector habrá notado que el tiempo de respuesta de esta
última consulta es demasiado elevado. Esto puede crear ciertos
problemas en operativa real para estrategias que trabajen en barras
muy cortas (de por ejemplo un minuto), y sobre todo, cuando queramos
realizar análisis de tipo walk forward, que requieren de múltiples
consultas.
Pero
aquí es donde entra en juego las optimizaciones que permite SQLite,
y sobre todo, ese misterioso atributo unix de nuestra tabla. Pero
este es tema para otra entrada de blog.
No hay comentarios:
Publicar un comentario