Discussão do artigo "Trabalhando com séries temporais na biblioteca DoEasy (Parte 39): indicadores com base na biblioteca - preparação de dados e eventos das séries temporais"

 

Novo artigo Trabalhando com séries temporais na biblioteca DoEasy (Parte 39): indicadores com base na biblioteca - preparação de dados e eventos das séries temporais foi publicado:

No artigo, consideramos o uso da biblioteca DoEasy para criar indicadores multissímbolos e multiperíodos. Prepararemos as classes da biblioteca, para trabalhar como parte dos indicadores, e testaremos a criação correta de séries temporais para usá-los como fontes de dados em indicadores. Realizaremos a criação e o envio de eventos de séries temporais.

Compilaremos o indicador e o iniciaremos no gráfico do símbolo, com o qual não trabalhamos há muito tempo, depois definir o símbolo atual nas configurações e selecionar a lista de períodos gráficos desejada. A execução de símbolos longos não utilizados fará com que o indicador carregue os dados ausentes e relate isso no log e no gráfico:


Aqui vemos que, a cada novo tick, as próximas séries temporais vazias foram sincronizadas e criadas. Nesse caso, as seguintes entradas foram gravadas no log:

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

[Excluído]  

Há algum erro no artigo?

A biblioteca funciona no cronômetro se o indicador for executado no gráfico de símbolos, e em OnCalculate() em ticks - se o indicador for executado no testador.

Ou eu não entendi direito?
 
Сергей Таболин:

Há algum erro no artigo?

A biblioteca funciona no cronômetro se o indicador for executado no gráfico de símbolos, e em OnCalculate() em ticks - se o indicador for executado no testador.

Ou eu não entendi direito?
Está correto. É assim que funciona.
 

Hi,

Estou tentando imprimir alguns parâmetros da última barra "completa" no diário, mas acho que não atualizei os dados da série armazenada ou não os classifiquei (mas também não consigo descobrir como classificá-los por tempo e obter a barra que quero), meu resultado é sempre a segunda barra no histórico, nunca atualizei os dados em tempo real da barra completa anterior... Em seguida, quero comparar o tamanho da barra completa mais recente com as 10 a 20 barras anteriores .Qualquer sugestão na direção certa será bem-vinda!

Estouexecutando essa ação no evento "New Bar":

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

        
//--- imprimindo o tamanho da última barra completa em cada nova barra 
         // Obter o objeto Symbol a partir da string passada param 
         CSymbol *symbol=engine.GetSymbolObjByName(sparam);
         if(symbol==NULL)
            return;
         // Obter a última barra completa (atual -1 à direita do gráfico) para esse período de tempo
         CBar *bar=engine.SeriesGetBar(symbol.Name(),(ENUM_TIMEFRAMES)dparam,1);
         if(bar==NULL)
            return;            
         //--- Exibir os dados recebidos do objeto de 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()));        
        
        }
     }

Em anexo, a captura de tela dos resultados do diário

Arquivos anexados:
Example.jpg  102 kb
 
iabbott :

Hi,

Estou tentando imprimir alguns parâmetros da última barra "completa" no diário, mas acho que não atualizei os dados da série armazenada ou não os classifiquei (mas também não consigo descobrir como classificá-los por tempo e obter a barra que quero), meu resultado é sempre a segunda barra no histórico, nunca atualizei os dados em tempo real da barra completa anterior... Em seguida, quero comparar o tamanho da barra completa mais recente com as 10 a 20 barras anteriores. Qualquer sugestão na direção certa será bem-vinda!

Estou executando essa ação no evento "Nova barra":

Em anexo, a captura de tela dos resultados do diário

Anexe aqui o código-fonte do programa no qual você obtém esses resultados, por favor.

Que barras de período de tempo você deseja receber na abertura de uma nova barra?

 

Hi,

Acabei de adicionar esse bloco de código ao evento de nova barra do EA TestDoEasy Pt39, sem outras alterações (linha 544 no anexo)

Na abertura de uma nova barra, quero verificar o histórico de barras do timeframe que acionou o evento - como o evento é acionado em cada timeframe separadamente, achei que seria mais fácil colocar essa verificação como parte do evento

Agradecimentos

Arquivos anexados:
 

Alguma novidade?

É algo que não estou fazendo corretamente? Parece-me que, se fosse um problema com a biblioteca, alguém o teria encontrado muito antes disso :)

Obrigado!

 
iabbott:

Alguma novidade?

É algo que não estou fazendo corretamente? Parece-me que, se fosse um problema com a biblioteca, alguém o teria encontrado muito antes disso :)

Obrigado!

Peço desculpas. Eu estava ocupado. Verei qual é o seu problema em breve.
 

Oi Artyom, você tem ideias específicas para a biblioteca escrever nos comentários do gráfico, usando ::Comment() como você faz em CEngine::SeriesSync()?

void CEngine::SeriesSync(SDataCalculate &data_calculate,const uint required=0)
  {
//...
      //--- Exibir os dados da série temporal vazia como um comentário do gráfico e tentar sincronizar a série temporal com os dados do servidor
      ::Comment(series.Header(),": ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC));
      ::ChartRedraw(::ChartID());

//...
            //--- exibir o comentário do gráfico e o registro no diário com os dados recriados da série temporal
            ::Comment(series.Header(),": OK");
            ::ChartRedraw(::ChartID());
            Print(series.Header()," ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_CREATED_OK),":");
            series.PrintShort();

//...
     //--- Excluir todos os comentários
      ::Comment("");
      ::ChartRedraw(::ChartID());
  }

Na minha humilde opinião, provavelmente é melhor deixar isso para o usuário da biblioteca... Tenho minha própria biblioteca que manipula os comentários do gráfico para gerar aspectos operacionais importantes de meus EAs, portanto, prefiro evitar a interferência da biblioteca DoEasy. Quais são seus planos futuros com relação a isso?

 
Dima Diall :

Olá, Artyom, você tem ideias específicas para a biblioteca escrever nos comentários do gráfico, usando ::Comment() como você faz em CEngine::SeriesSync()?

Na minha humilde opinião, provavelmente é melhor deixar isso para o usuário da biblioteca... Tenho minha própria biblioteca que manipula os comentários do gráfico para gerar aspectos operacionais importantes de meus EAs, portanto, prefiro evitar a interferência da biblioteca DoEasy. Quais são seus planos futuros com relação a isso?

Se houver trabalho futuro com gráficos, não haverá comentários padrão.

 

Olá - ao revisar o código do manipulador de eventos mais de perto, notei que você usa métodos diferentes para analisar a origem do evento... em alguns casos, ele se baseia no parâmetro id do evento do gráfico de OnChartEvent(), enquanto em outros você o extrai do parâmetro lparam por meio de engine.EventSource(lparam) - há algum motivo específico para que seja diferente em cada caso?

void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
//--- Recuperar (1) milissegundos de tempo do evento, (2) motivo e (3) fonte de lparam, bem como (4) definir o tempo exato do evento
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- Manipulação de eventos de símbolo
   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)
     {
      //...
     }