Problemas com iCustom

Michel Angelucci  

Olá pessoal. Será que algum de vocês sabe me dizer o porquê não consigo obter o valor do indicador quando rodo esse EA no histórico completo em um Time Frame menor do M12, quando o input é H1? Detalhe: o problema só aparece quando não há barras suficientes para o cálculo do indicador. Estou usando o ATR da pasta Examples, mas podem usar qual quiserem. Eu não consegui puxar o valor correto. O EA acessa o indicador antes dos buffers serem calculados, causando esse erro. Apesar de saber qual é o erro, não consigo saber qual a causa, e nem como contorná-la. Fico grato se alguém me der uma luz...

//+------------------------------------------------------------------+
//|                                           Testando Indicador.mq5 |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property link      "https://www.mql5.com"
#property version   "1.00"

input int Periodo=20;   //Período do Indicador
input ENUM_TIMEFRAMES timeframe=PERIOD_H1;

int handle=INVALID_HANDLE;

double array[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   handle=iCustom(Symbol(),timeframe,"Examples\\ATR",Periodo);
   if(handle==INVALID_HANDLE)
     {
      IndicatorRelease(handle);
      return(INIT_FAILED);
     }
   Sleep(10000);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   IndicatorRelease(handle);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!IsNewBar())
      return;
   
   if(Bars(Symbol(),timeframe)<Periodo)
     {
      return;
     }
   
   int copy=CopyBuffer(handle,0,1,1,array);
   if(copy<=0)
     {
      return;
     }
   
   printf("O valor de array[0] = %.2f - TimeCurrent: %s",array[0],TimeToString(TimeCurrent()));
   
  }
//+------------------------------------------------------------------+
//| Is New Bar Function                                              |
//+------------------------------------------------------------------+
bool IsNewBar(void)
  {
//--- memorize the time of opening of the last bar in the static variable
   static datetime last_time=0;
//--- current time
   datetime lastbar_time=(datetime)SeriesInfoInteger(_Symbol,Period(),SERIES_LASTBAR_DATE);

//--- if it is the first call of the function
   if(last_time==0)
     {
      //--- set the time and exit
      last_time=lastbar_time;
      return(false);
     }

//--- if the time differs
   if(last_time!=lastbar_time)
     {
      //--- memorize the time and return true
      last_time=lastbar_time;
      return(true);
     }
//--- if we passed to this line, then the bar is not new; return false
   return(false);
  }
Ricardo Rodrigues Lucca  
Michel Angelucci:

Olá pessoal. Será que algum de vocês sabe me dizer o porquê não consigo obter o valor do indicador quando rodo esse EA no histórico completo em um Time Frame menor do M12, quando o input é H1? Detalhe: o problema só aparece quando não há barras suficientes para o cálculo do indicador. Estou usando o ATR da pasta Examples, mas podem usar qual quiserem. Eu não consegui puxar o valor correto. O EA acessa o indicador antes dos buffers serem calculados, causando esse erro. Apesar de saber qual é o erro, não consigo saber qual a causa, e nem como contorná-la. Fico grato se alguém me der uma luz...

Antes do copybuffer ja pensou em fazer um barsCalculated no handle do atr pra ver se ele ja tem dados disponiveis?

Michel Angelucci  
Ricardo Rodrigues Lucca #:

Antes do copybuffer ja pensou em fazer um barsCalculated no handle do atr pra ver se ele ja tem dados disponiveis?

Olá Ricardo. Sim já tentei. Ele informa o número de barras correto. Uma vez que o EA tenta acessar os dados do indicador quando o mesmo ainda não foi calculado, o próprio indicador seta o buffer com um EMPTY_VALUE (que na verdade é um value). Nas próximas chamadas do OnCalculate, esse valor que foi setado no buffer continua retornando para todas as demais barras. Creio que como o ATR, em específico, utiliza o valor de Buffer[i-1] para calcular o Buffer[i], é onde que gera toda a confusão. No indicador que eu estava usando, onde me deparei com o problema, também uso o i-1 para calcular na barra i.
Ricardo Rodrigues Lucca  
Michel Angelucci #:
Olá Ricardo. Sim já tentei. Ele informa o número de barras correto. Uma vez que o EA tenta acessar os dados do indicador quando o mesmo ainda não foi calculado, o próprio indicador seta o buffer com um EMPTY_VALUE (que na verdade é um value). Nas próximas chamadas do OnCalculate, esse valor que foi setado no buffer continua retornando para todas as demais barras. Creio que como o ATR, em específico, utiliza o valor de Buffer[i-1] para calcular o Buffer[i], é onde que gera toda a confusão. No indicador que eu estava usando, onde me deparei com o problema, também uso o i-1 para calcular na barra i.
Verifica se tu tem um limite no grafico de numero de velas que ele pode carregar (Opcoes -> Graficos -> Numero maximo de barras). Se tiver, o indicador esta limitado a esse numero e acredito nem dispara o calculo colocando um numero maior que esse.
Michel Angelucci  
Ricardo Rodrigues Lucca #:
Verifica se tu tem um limite no grafico de numero de velas que ele pode carregar (Opcoes -> Graficos -> Numero maximo de barras). Se tiver, o indicador esta limitado a esse numero e acredito nem dispara o calculo colocando um numero maior que esse.

Olá Ricardo, infelizmente não deve ser isso... Veja que configurei o maxbar para Unlimited.

Arquivos anexados:
Op1zes.png  7 kb
Michel Angelucci  
Você já tentou rodar o código aí no seu terminal pra ver como fica?
Ricardo Rodrigues Lucca  
Michel Angelucci #:
Você já tentou rodar o código aí no seu terminal pra ver como fica?

Não tinha testado não, eu testei agora inicialmente com a pomo3 e tinha dado tudo certo. Troquei pra petz3 pra verificar como ficaria no IPO e deu o mesmo problema quando não retorna dados suficientes. Pode ser bug da ferramenta que teria que reportar em algum lugar que não sei.

Fiquei brincando com o exemplo e parece ser relacionado com o PLOT_DRAW_BEGIN. Se ele esta com valor igual ao periodo selecionado o indicador não consegue calcular. Já se retiro o acesso ao i-1 plota o grafico. Se troco o valor pra periodo - 1 mesmo com o acesso ao i-1, da certo o plot. Outra forma de solucionar seria nao chamar o PLOT_DRAW_BEGIN e definir como zero o EMPTY_VALUE. Nesse caso especifico seria possivel porque o ATR é sempre maior que zero.

Michel Angelucci  
Ricardo Rodrigues Lucca #:

Não tinha testado não, eu testei agora inicialmente com a pomo3 e tinha dado tudo certo. Troquei pra petz3 pra verificar como ficaria no IPO e deu o mesmo problema quando não retorna dados suficientes. Pode ser bug da ferramenta que teria que reportar em algum lugar que não sei.

Fiquei brincando com o exemplo e parece ser relacionado com o PLOT_DRAW_BEGIN. Se ele esta com valor igual ao periodo selecionado o indicador não consegue calcular. Já se retiro o acesso ao i-1 plota o grafico. Se troco o valor pra periodo - 1 mesmo com o acesso ao i-1, da certo o plot. Outra forma de solucionar seria nao chamar o PLOT_DRAW_BEGIN e definir como zero o EMPTY_VALUE. Nesse caso especifico seria possivel porque o ATR é sempre maior que zero.

Olá Ricardo. Tudo indica que seja isso mesmo: problema no PLOT_DRAW_BEGIN. Andei mexendo aqui e, em alguns casos, resolveu.

Valeu pela ajuda!

Razão: