Documentación
Aplicaciones
Última actualización el 21. 6. 2022 by Mark Fric
Carga de datos históricos en fragmentos
Contenido de la página
Notas importantes
- Este ejemplo sólo funcionará en SQ Build 136 Dev 2 o posterior
- La carga de datos no funcionará para los datos protegidos (SQ Futures y SQ Equities), donde no se nos permite dar acceso a los datos en bruto a los usuarios por contrato con el proveedor de datos.
Este ejemplo mostrará cómo puede acceder a datos históricos mediante programación desde sus fragmentos. Esto es útil si desea comparar, por ejemplo, las órdenes resultantes con algunas tendencias de los datos históricos.
Esta funcionalidad utiliza un nuevo Cargador de datos históricos que sólo está disponible desde SQ Build 136 Dev2.
Este ejemplo está realizado en un snippet de Análisis Personalizado, pero puede utilizar esta funcionalidad en cualquier snippet. Sólo tenga en cuenta que la carga de los datos puede ser lenta, la llamada de la función de carga puede tardar varios segundos.
Por lo tanto, no es aconsejable utilizarlo en fragmentos que se llamen muy a menudo y deban ser rápidos, por ejemplo, las métricas de columna del banco de datos.
Cómo utilizar HistoryDataLoader para cargar datos
El uso es muy sencillo. La clase Cargador de datos históricos sólo tiene un método get(símbolo, timframe, dateFrom, dateTo, sesión).
Sólo tienes que llamarlo con los parámetros correctos y devolverá el objeto HistoriaOHLCData con los datos solicitados.
try { Log.info("Carga iniciada ..."); HistoryDataLoader loader = new HistoryDataLoader(); HistoryOHLCData data = loader.get("EURUSD_M1", TimeframeManager.TF_H1, SQTime.toLong(2007,1, 1), SQTime.toLong(2020, 12, 31), Session.NoSession); } catch(HistoryDataNotAvailableExeption e) { Log.error("Error al cargar datos.", e); }
Es importante rodear este método con try-catch, porque puede devolver HistoryDataNotAvailable excepción.
Acceso a los datos del objeto HistoryOHLCData
Los datos se devuelven en HistoriaOHLCData objeto. Es un objeto simple, donde los datos se almacenan en matrices primitivas que normalmente se pueden recorrer.
Un ejemplo:
// usamos esto para obtener la longitud de los datos int longituddatos = datos.Tiempo.longitud; Log.info("Longitud de datos cargados: {}", dataLength); Log.info("Imprimiendo los 5 primeros registros: Índice, Hora, Apertura, Máximo, Mínimo, Cierre"); // recorrer los datos for(int i=0; i<longituddatos; i++) { long time = datos.Hora[i]; float open = data.Open[i]; float high = datos.High[i]; float low = data.Low[i]; float close = data.Close[i]; float volumen = data.Volumen[i]; if(i<5) { Log.info("#{} - {}, {}, {}, {}, {}", i, SQTime.toDateMinuteString(time), open, high, low, close); } }
Puede ver que el objeto de datos tiene matrices para Hora, Apertura, Máximo, Mínimo, Cierre y Volumen. Todas las matrices tienen el mismo tamaño.
Y eso es todo, muy sencillo.
Cómo obtener el símbolo y el marco temporal de la estrategia
Una cosa útil que se puede hacer es recuperar el símbolo, el marco temporal y los intervalos de fechas de la última prueba retrospectiva de la estrategia (Grupo de resultados ) para saber qué datos cargar.
Es igualmente sencillo, un ejemplo:
/** * Ejemplo de cómo recuperar el símbolo, el TF y los rangos de fechas desde-hasta de la estrategia. * Posteriormente se puede utilizar para cargar datos históricos. * @param resultsGroup */ private void reconocerSímboloTFFdesdeEjemploEstrategia(GrupoResultados) { if(resultsGroup == null) { return; } try { SettingsMap settings = resultsGroup.specialValues(); String symbol = resultsGroup.mainResult().getString(SpecialValues.Symbol, "N/A"); String tf = resultsGroup.mainResult().getString(SpecialValues.Timeframe, "N/A"); long from = settings.getLong(SpecialValues.HistoryFrom); long to = settings.getLong(SpecialValues.HistoryTo); Log.info("Ejemplo - Última configuración de backtest de la estrategia: {} / {}, desde: {}, hasta: {}", symbol, tf, SQTime.toDateString(from), SQTime.toDateString(to)); } catch(Exception e) { Log.error("Excepción", e); } }
A continuación, puede utilizar estos valores en el método HistoryDataLoader.get() para recuperar exactamente los datos que se utilizaron en el backtest de la estrategia.
Código completo del fragmento de ejemplo LoadHistoryData
paquete SQ.CustomAnalysis; importar com.strategyquant.lib.*; import java.util.ArrayList; import com.strategyquant.tradinglib.results.SpecialValues; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.strategyquant.datalib.*; import com.strategyquant.tradinglib.*; import com.strategyquant.datalib.session.*; public class LoadHistoryData extends CustomAnalysisMethod { //------------------------------------------------------------------------ //------------------------------------------------------------------------ //------------------------------------------------------------------------ public CargarHistorialDatos() { super("LoadHistoryData", TYPE_PROCESS_DATABANK); } //------------------------------------------------------------------------ @Override public boolean filterStrategy(String project, String task, String databankName, ResultsGroup rg) throws Exception { return true; } //------------------------------------------------------------------------ @Override public ArrayList processDatabank(String project, String task, String databankName, ArrayList databankRG) throws Exception { // ejemplo sencillo de uso de HistoryDataLoader para cargar datos históricos para un símbolo y un marco temporal dados try { HistoryDataLoader loader = new HistoryDataLoader(); Log.info("Carga iniciada ..."); HistoryOHLCData data = loader.get("EURUSD_M1", TimeframeManager.TF_H1, SQTime.toLong(2007,1, 1), SQTime.toLong(2020, 12, 31), Session.NoSession); // usamos esto para obtener la longitud de los datos int dataLength = data.Time.length; Log.info("Longitud de datos cargados: {}", dataLength); Log.info("Imprimiendo los 5 primeros registros: Índice, Hora, Apertura, Máximo, Mínimo, Cierre"); // recorrer los datos for(int i=0; i<longituddatos; i++) { long time = datos.Hora[i]; float open = data.Open[i]; float high = datos.High[i]; float low = data.Low[i]; float close = data.Close[i]; float volumen = data.Volumen[i]; if(i 0) { recognizeSymbolTFFromStrategyExample(databankRG.get(0)); } return databankRG; } //------------------------------------------------------------------------ /** * Ejemplo de cómo recuperar el símbolo, el TF y los rangos de fechas desde-hasta de la estrategia. * Posteriormente se puede utilizar para cargar datos históricos. * @param resultsGroup */ private void reconocerSímboloTFFdesdeEjemploEstrategia(GrupoResultados) { if(resultsGroup == null) { return; } try { SettingsMap settings = resultsGroup.specialValues(); String symbol = resultsGroup.mainResult().getString(SpecialValues.Symbol, "N/A"); String tf = resultsGroup.mainResult().getString(SpecialValues.Timeframe, "N/A"); long from = settings.getLong(SpecialValues.HistoryFrom); long to = settings.getLong(SpecialValues.HistoryTo); Log.info("Ejemplo - Última configuración de backtest de la estrategia: {} / {}, desde: {}, hasta: {}", symbol, tf, SQTime.toDateString(from), SQTime.toDateString(to)); } catch(Exception e) { Log.error("Excepción", e); } } }
¿Le ha resultado útil este artículo? El artículo era útil El artículo no era útil
Fantástico Mark.
Excelente !! realmente lo necesitabamos !!!
¡¡¡¡Muchas gracias Mark !!!!