Discusión sobre el artículo "Trabajando con las series temporales en la biblioteca DoEasy (Parte 39): Indicadores basados en la biblioteca - Preparación de datos y eventos de la series temporales"

 

Artículo publicado Trabajando con las series temporales en la biblioteca DoEasy (Parte 39): Indicadores basados en la biblioteca - Preparación de datos y eventos de la series temporales:

En el presente artículo, analizaremos la aplicación de la biblioteca DoEasy para crear indicadores de periodo y símbolo múltiples. Hoy, vamos a preparar las clases de la biblioteca para trabajar con indicadores y poner a prueba la correcta creación de series temporales para su posterior uso como fuentes de datos en los indicadores. Asimismo, organizaremos la creación y el envío de los eventos de series temporales.

Compilamos el indicador y lo iniciamos en el gráfico de un símbolo con el que no hemos trabajado durante mucho tiempo, estableciendo previamente en los ajustes el trabajo con el símbolo actual; luego, seleccionamos el trabajo con la lista de marcos temporales establecida. El inicio en símbolos que no hemos utilizado durante mucho tiempo, obligará al indicador a cargar los datos que le faltan y comunicarlo en el diario y en el gráfico:


Aquí, podemos ver cómo una nueva serie temporal vacía se sincronizaba y creaba con cada tick. En el diario, en este caso, se mostraban las siguientes entradas:

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, MetaTrader 5 demo
--- Initializing "DoEasy" library ---
Working with the current symbol only: "USDCAD"
Working with the specified timeframe list:
"M1"  "M5"  "M15" "M30" "H1"  "H4"  "D1"  "W1"  "MN1"
USDCAD symbol timeseries: 
- Timeseries "USDCAD" M1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M5: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M15: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M30: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" H1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" H4: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" D1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" W1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" MN1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
Library initialization time: 00:00:01.406
"USDCAD" M1 timeseries created successfully:
- Timeseries "USDCAD" M1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5001
"USDCAD" M5 timeseries created successfully:
- Timeseries "USDCAD" M5: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5741
"USDCAD" M15 timeseries created successfully:
- Timeseries "USDCAD" M15: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5247
"USDCAD" M30 timeseries created successfully:
- Timeseries "USDCAD" M30: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5123
"USDCAD" H1 timeseries created successfully:
- Timeseries "USDCAD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6257
"USDCAD" H4 timeseries created successfully:
- Timeseries "USDCAD" H4: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6232
"USDCAD" D1 timeseries created successfully:
- Timeseries "USDCAD" D1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5003
"USDCAD" W1 timeseries created successfully:
- Timeseries "USDCAD" W1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 1403
"USDCAD" MN1 timeseries created successfully:
- Timeseries "USDCAD" MN1: Requested: 1000, Actual: 323, Created: 323, On the server: 323
New bar on USDCAD M1: 2020.03.19 12:18
New bar on USDCAD M1: 2020.03.19 12:19
New bar on USDCAD M1: 2020.03.19 12:20
New bar on USDCAD M5: 2020.03.19 12:20

Autor: Artyom Trishkin

 

¿Hay algún error en el artículo?

La biblioteca funciona en el temporizador si el indicador se ejecuta en el gráfico de símbolos, y en OnCalculate() en ticks - si el indicador se ejecuta en el probador.

¿O he entendido mal?
 
Сергей Таболин:

¿Hay algún error en el artículo?

La biblioteca funciona en el temporizador si el indicador se ejecuta en el gráfico de símbolos, y en OnCalculate() en ticks - si el indicador se ejecuta en el probador.

¿O he entendido mal?
Es correcto. Es así.
 

Hola,

Estoy intentando imprimir algunos parámetros de la última barra "completa" en el diario, pero supongo que no he actualizado los datos de la serie almacenados, o no los he ordenado (pero tampoco puedo averiguar cómo ordenarlos por tiempo y obtener la barra que quiero), mi resultado es siempre la 2ª barra del histórico, nunca datos actualizados en tiempo real de la barra completa anterior... A continuación quiero comparar el tamaño de la barra completa más reciente contra las 10-20 barras anteriores, ¡cualquier empujón en la dirección correcta será apreciado!

Estoy realizando esta acción en el evento "Nueva Barra":

   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //--- Evento "Nueva barra
      if(idx==SERIES_EVENTS_NEW_BAR)
        {
         Print(TextByLanguage("Новый бар на ","New Bar on "),sparam," ",TimeframeDescription((ENUM_TIMEFRAMES)dparam),": ",TimeToString(lparam));

        
//--- imprimir el tamaño de la última barra completa en cada nueva barra 
         // Obtener el objeto Symbol a partir de la cadena pasada param 
         CSymbol *symbol=engine.GetSymbolObjByName(sparam);
         if(symbol==NULL)
            return;
         // Obtener la última barra completa (actual -1 desde la derecha del gráfico) para este timeframe
         CBar *bar=engine.SeriesGetBar(symbol.Name(),(ENUM_TIMEFRAMES)dparam,1);
         if(bar==NULL)
            return;            
         //--- Mostrar los datos recibidos del objeto barra
         Print(TextByLanguage("Бар \"","Data from Bar \"")+symbol.Name()+"\" "+TimeframeDescription((ENUM_TIMEFRAMES)dparam)+": "+TimeToString(bar.Time(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+
            " H: "+DoubleToString(bar.High(),symbol.Digits())+
            " L: "+DoubleToString(bar.Low(),symbol.Digits())+
            " Size: "+DoubleToString(bar.Size(),symbol.Digits()));        
        
        }
     }

Adjunto captura de pantalla de los resultados del diario

Archivos adjuntos:
Example.jpg  102 kb
 
iabbott :

Hola,

Estoy intentando imprimir algunos parámetros de la última barra "completa" en el diario, pero supongo que no he actualizado los datos de la serie almacenados, o no los he ordenado (pero tampoco puedo averiguar cómo ordenarlos por tiempo y obtener la barra que quiero), mi resultado es siempre la 2ª barra del historial, nunca datos actualizados en tiempo real de la barra completa anterior... A continuación quiero comparar el tamaño de la barra completa más reciente contra las 10-20 barras anteriores, ¡cualquier empujón en la dirección correcta será apreciado!

Estoy realizando esta acción en el evento "Nueva Barra":

Adjunto captura de pantalla de los resultados del diario

Adjunta aquí el código fuente del programa en el que obtienes dichos resultados, por favor.

¿Qué barras de timeframe quiere recibir en la apertura de una nueva barra?

 

Hola,

Acabo de añadir este bloque de código al evento de nueva barra del EA TestDoEasy Pt39, sin otros cambios (línea 544 en el adjunto)

En la apertura de una nueva barra, quiero comprobar el historial de barras del timeframe que activó el evento - ya que el evento se activa en cada timeframe por separado, pensé que sería más fácil poner esta comprobación como parte del evento.

Gracias

Archivos adjuntos:
 

Hola, ¿alguna novedad?

¿Es algo que no estoy haciendo bien? Me parece que si fuera un problema con la biblioteca que alguien habría encontrado mucho antes que esto :)

Gracias.

 
iabbott:

¿Alguna novedad?

¿Es algo que no estoy haciendo bien? Me parece que si fuera un problema con la biblioteca que alguien habría encontrado mucho antes que esto :)

Gracias.

Pido disculpas. Estaba ocupado. Pronto veré cuál es tu problema.
 

Hola Artyom, ¿tienes ideas concretas para que la librería escriba en los comentarios del gráfico, utilizando ::Comment() como se hace en CEngine::SeriesSync()?

void CEngine::SeriesSync(SDataCalculate &data_calculate,const uint required=0)
  {
//...
      //--- Muestre los datos de la serie de tiempo vacía como un comentario del gráfico e intente sincronizar la serie de tiempo con los datos del servidor
      ::Comment(series.Header(),": ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC));
      ::ChartRedraw(::ChartID());

//...
            //--- mostrar el comentario del gráfico y el asiento con los datos de las series temporales recreadas
            ::Comment(series.Header(),": OK");
            ::ChartRedraw(::ChartID());
            Print(series.Header()," ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_CREATED_OK),":");
            series.PrintShort();

//...
     //--- Borrar todos los comentarios
      ::Comment("");
      ::ChartRedraw(::ChartID());
  }

En mi humilde opinión, probablemente sea mejor dejar esto al usuario de la librería... Tengo mi propia librería que manipula los comentarios de los gráficos para dar salida a aspectos operativos clave de mis EAs, por lo que preferiría evitar la interferencia de la librería DoEasy. ¿Cuáles son sus planes futuros al respecto?

 
Dima Diall :

Hola Artyom, ¿tienes ideas concretas para que la librería escriba en los comentarios del gráfico, utilizando ::Comment() como se hace en CEngine::SeriesSync()?

En mi humilde opinión, probablemente sea mejor dejar esto al usuario de la librería... Tengo mi propia librería que manipula los comentarios de los gráficos para dar salida a aspectos operativos clave de mis EAs, por lo que preferiría evitar la interferencia de la librería DoEasy. ¿Cuáles son sus planes futuros al respecto?

Si en el futuro se trabaja con gráficos, no habrá comentarios estándar.

 

En algunos casos se basa en el parámetro de identificación del evento gráfico de OnChartEvent() mientras que en otros lo extrae del parámetro lparam mediante engine.EventSource(lparam) -- ¿hay alguna razón en particular por la que sea diferente en cada caso?

void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
//--- Recuperar (1) el tiempo del evento en milisegundos, (2) la razón y (3) la fuente desde lparam, así como (4) establecer el tiempo exacto del evento
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- Manejo de eventos de símbolos
   if(source==COLLECTION_SYMBOLS_ID)
     {
      //...
     }
//--- Handling account events
   else if(source==COLLECTION_ACCOUNT_ID)
     {
      //...
     }
//--- Handling market watch window events
   else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling timeseries events
   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling trading events
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      //...
     }