[Os indicadores não são devidamente instanciados quando chamados/criados a partir de um Indicador de tempo de trabalho diferente. - página 3

 
Stanislav Korotky:
Postar pergunta mais específica com um código de amostra. Pode ser um buggy. A abordagem funciona para mim.

Aqui está um exemplo de código de acesso indicador de falha. Mesmo depois de looping, refrescante, espera (dois métodos diferentes de espera).

//+------------------------------------------------------------------+
//|                                                    THROWAWAY.mq5 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property indicator_chart_window

#include <Indicators\Trend.mqh>
#include <errordescription.mqh>

CiMA ima;
int m_bufferSize = -1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   static int iCnt = 0;
//--- indicator buffers mapping
      Print("-----------------------",TimeCurrent(),"--------------------------");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   static int tickCnt = 0;
   tickCnt++;
//---
   if(rates_total != prev_calculated || m_bufferSize < 1 ){
      ResetLastError();
      datetime createTime = TimeCurrent();
      ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
      ima.Refresh(); //no wait time!
          
      CIndicatorBuffer *buff = ima.At(0);
      m_bufferSize = buff.Total();
      int call = 0;
      int sleep = 200;
      // try with Sleep function ...
      while(buff.Total() <= 0 && call < 10){
         Sleep(sleep);
         ima.Refresh(); // Refreshed 10x since create
         m_bufferSize = buff.Total();
         call++;
         Print(__LINE__," ",__FUNCTION__," ",buff.Name(),
               " Buffer size = ",m_bufferSize," | Call (",
               call,")"," Sleep(",sleep,")"
               );
         sleep+=100;
        
      }
      // try wait with looping  
      if(buff.Total() <=0){
         datetime waitTime = timeLoop(createTime);
         Print("Time Between Create and Refresh() = ",TimeToString(waitTime,TIME_SECONDS));
         ima.Refresh();
         m_bufferSize = buff.Total();
      }
      if(m_bufferSize < 1){
         Print(ErrorDescription(GetLastError()));
         return(rates_total);
      } else {
         for(int i=0;i<m_bufferSize;i++){
            if(i>2return(rates_total);
            else{
               Print(__LINE__," ",__FUNCTION__,buff.Name(),
                     " Buffer size = ",m_bufferSize,
                     " | ",ima.PeriodDescription()," iMA(",i,") value = ",
                     DoubleToString(ima.Main(i),_Digits),
                     " | Tick-count = ",tickCnt
                     );  
            }
         }
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason){

}

datetime timeLoop(datetime timeIn){
   int cnt = 0;
   while(TimeCurrent() - timeIn < 10 && !IsStopped()){
      Comment("Time looping i = ",cnt);
      cnt++;
   }
   return TimeCurrent() - timeIn;
}

E aqui está o ouput:

-----------------------2017.01.31 23:48:03--------------------------


60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (1) Sleep(200)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (2) Sleep(300)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (3) Sleep(400)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (4) Sleep(500)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (5) Sleep(600)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (6) Sleep(700)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (7) Sleep(800)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (8) Sleep(900)

60 OnCalculate MAIN_LINE tamanho do buffer = -1 | Call (9) Sleep(1000)

60 OnCalculate MAIN_LINE Tamanho do buffer = -1 | Call (10) Sleep(1100)

Tempo entre Criar e Refrescar() = 00:00:11

Dados solicitados não encontrados

81 OnCalculateMAIN_LINE Tamanho do buffer = 1024 | H1 iMA(0) valor = 113.227 | Tick-count = 2

81 OnCalculateMAIN_LINE Tamanho do buffer = 1024 | H1 iMA(1) valor = 113.269 | Tick-count = 2

81 OnCalculateMAIN_LINE Tamanho do buffer = 1024 | H1 iMA(2) valor = 113.313 | Tick-count = 2

















 
nicholishen:

Aqui está um exemplo de código de acesso indicador de falha. Mesmo depois de looping, refrescante, espera (dois métodos diferentes de espera).

         Sleep(sleep);


Dormir não vai funcionar em um indicador; não se pode interromper o fio da interface.

Tente-o com OnTimer() em vez disso.

 
honest_knave:

Dormir não vai funcionar em um indicador; não se pode interromper o fio da interface.

Tente-o com OnTimer() em vez disso.

É isso aí! É isso que funciona! Eu poderia beijá-lo, cara!

Isto permite que o OnInit() retorne à plataforma e o OnTimer() pule sobre ela e chame para o segundo passe. Eu defini o EventSetMillisecondTimer para apenas 1ms e o chamei apenas uma vez e agora está funcionando.

//+------------------------------------------------------------------+
//|                                                    THROWAWAY.mq5 |
//|                                                      nicholishen |
//|                                   www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "www.reddit.com/u/nicholishenFX"
#property version   "1.00"
#property indicator_chart_window

#include <Indicators\Trend.mqh>
#include <errordescription.mqh>

CiMA ima;
int m_bufferSize = -1;
bool timedEvent = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
      int waitMS = 1;
      Print("-----------------------",TimeCurrent(),"--------------------------");
  
      ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
      EventSetMillisecondTimer(waitMS);
      Print("OnTimer set to ",waitMS," ms");
      
//---
   return(INIT_SUCCEEDED);
  }

void OnTimer()
  {
//---
   ima.Refresh();
   EventKillTimer();
   timedEvent = true;
  
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

   static int tickCnt = 0;
   tickCnt++;
  
   if(!timedEvent)return rates_total;
//---
   if(rates_total != prev_calculated || m_bufferSize < 1 ){
      ResetLastError();
      CIndicatorBuffer *buff = ima.At(0);
      m_bufferSize = buff.Total();
      if(m_bufferSize <=0) ima.Refresh();
      // try wait with looping  
      
      if(m_bufferSize < 1){
         Print(ErrorDescription(GetLastError()));
        
      } else {
         for(int i=0;i<m_bufferSize;i++){
            if(i>2) break;
            else{
               Print(__LINE__," ",__FUNCTION__,buff.Name(),
                     " Buffer size = ",m_bufferSize,
                     " | ",ima.PeriodDescription()," iMA(",i,") value = ",
                     DoubleToString(ima.Main(i),_Digits),
                     " | Tick-count = ",tickCnt
                     );  
            }
         }
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+


Saída:

-----------------------2017.02.01 01:31:01--------------------------

OnTimer ajustado para 1 ms

75 OnCalculateMAIN_LINE Tamanho do buffer = 1024 | H1 iMA(0) valor = 113.142 | Tick-count = 2

75 OnCalculateMAIN_LINE Tamanho do buffer = 1024 | H1 iMA(1) valor = 113.181 | Contagem de carrapatos = 2

 
nicholishen:

É isso aí! É a solução! Eu poderia beijá-lo, cara!

Sem problemas, aceito transferências bancárias e todos os principais cartões de crédito... 100 dólares, não é verdade?
 
nicholishen:

É isso aí! É a solução! Eu poderia beijá-lo, cara!

Legal!

Eu sugeri que você usasse um temporizador. Você respondeu que não funcionava para você. Eu perguntei por um exemplo do que você tentou. Mas você disse que não podia postar mais detalhes do que já tinha feito.

Agora outro homem lhe sugeriu o cronômetro e você parece feliz com ele. ;-)

 
Stanislav Korotky:

Legal!

Eu sugeri que você usasse um temporizador. Você respondeu que não funcionava para você. Eu perguntei por um exemplo do que você tentou. Mas você disse que não podia postar mais detalhes do que já tinha feito.

Agora outro homem lhe sugeriu o cronômetro e você parece feliz com ele. ;-)

Ei! Pare de tentar ganhar $150!
 
Stanislav Korotky:

Legal!

Eu sugeri que você usasse um temporizador. Você respondeu que não funcionava para você. Eu perguntei por um exemplo do que você tentou. Mas você disse que não podia postar mais detalhes do que já tinha feito.

Agora outro homem lhe sugeriu o cronômetro e você parece feliz com ele. ;-)

E agora temos um bug MT5 corrigido...
 
honest_knave:
Sem problemas, aceito transferências bancárias e todos os principais cartões de crédito... 100 dólares, não é verdade?

$100?! ...Pensei ter oferecido mais...

Fórum sobre negociação, sistemas automatizados de negociação e teste de estratégias de negociação

[MQL5 BUG] [SOLVED] Os indicadores não são devidamente instanciados quando chamados/criados a partir de um Indicador de tempo de trabalho diferente.

Stanislav Korotky, 2017.02.01 09:27

Legal!

Eu sugeri o uso de um temporizador. Você respondeu que ele não funcionava para você. Eu perguntei por um exemplo do que você tentou. Mas você disse que não podia postar mais detalhes do que já tinha feito.

Agora outro homem lhe sugeriu o cronômetro e você parece feliz com ele. ;-)


Desculpe-me por não ter entendido o que você quis dizer com isso, até agora. Vou considerá-lo parceiro do knave, e como ninguém postou um modelo de trabalho, vou decidir que a recompensa será de 50% - divididos em dois sentidos: Então isso é...mm...levar os dois... Que tal eu comprar uma cerveja para vocês dois? A sério, me dêem um endereço BTC e eu me certificarei de que ambos sejam compensados :)

Quero agradecer especialmente por toda sua ajuda... se não fosse por sua condescendência, não sei onde eu teria encontrado a motivação para lutar! /s

 
nicholishen:

Sério, me dê um endereço BTC e eu me certificarei de que ambos sejam compensados :)

uma oferta generosa, mas desnecessária. Fico feliz que você a tenha organizado.
 
Vou fechar isto com o balcão de serviço, mas caso a MetaQuotes esteja lendo isto, ainda considero isto como uma grande falha na plataforma. Se este é um problema com o threading, deve haver uma maneira melhor de lidar com este tipo de eventos do que lançando arbitrariamente (uma quantidade adivinhada) o tempo de espera no código.