Documentación

Aplicaciones

Última actualización el 21. 6. 2022 by Mark Fric

Carga de datos históricos en fragmentos

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

Suscríbase a
Notificar a
3 Comentarios
Más antiguo
Más reciente Más votados
Feedbacks de Inline
Ver todos los comentarios
Comerciante de abejas
21. 6. 2022 12:02 pm

Fantástico Mark.

Emmanuel
22. 6. 2022 12:56 pm

Excelente !! realmente lo necesitabamos !!!

Emmanuel
22. 6. 2022 12:56 pm

¡¡¡¡Muchas gracias Mark !!!!

Puestos relacionados