Download MetaTrader 5

Bovespa. Problemas com funções e manipuladores de indicadores (iBands, etc)

Para adicionar comentários, por favor Conecte-se ou registrar
Drmqlbrazil5
11
Drmqlbrazil5  

(publiquei inicialmente este tópico em assuntos Gerais. Peço aos moderadores para deixar aqui)

Prezados,

Saudações a todos os participantes do forum. Esta é minha primeira participação.
Não sou programador profissional,  mas entendo algo de programação e estou me arriscando a fazer algumas coisas no mql5. Estou com alguns problemas num indicador que estou desenvolvendo para mini índice bovespa (conta real), que parecem bruxaria.

O indicador é para construir barras de TimeFrames maiores no gráfico de 1min. Aproveitando, serão mostradas as Bandas de Bollinger para esses períodos maiores.

O primeiro problema que gostaria de comentar é com o indicador iBands. Este indicador retorna dados, através da função CopyBuffer para a linha base(0), superior(1) e inferior(2) das Bandas de Bollinger. Na seguinte linha, que fica na função OnInit(), é criado o manipulador, como variável global.

BB_handle= iBands(NULL, TimeFrame, InpMaPeriod, Desviacao, Shift, InpPreco);
SMA_handle= iMA(NULL, TimeFrame, InpMaPeriod, Shift, InpTipoMedia, InpPreco);
STD_handle= iStdDev(NULL, TimeFrame, InpMaPeriod, Shift, InpTipoMedia, InpPreco);

Agora na função OnCalculated, tentando obter os dados das tres linhas, apenas os dados da linha base(0) são recuperados. Ou seja, as 3 funções CopyBufer retornam o mesmo valor (da linha base) para as três linhas, independentemente de qual é chamada primeiro:

if (CopyBuffer(BB_handle, 0, time[bar], 1, array_buffer_med) <= 0) {...
if (CopyBuffer(BB_handle, 1, time[bar], 1, array_buffer_sup) <= 0) {...
if (CopyBuffer(BB_handle, 2, time[bar], 1, array_buffer_inf) <= 0) {...

Desta forma as 3 linhas ficam juntas no gráfico, uma em cima da outra (ou seja, vejo apenas uma linha (a base)).
Alguém sabe por que isso acontece?

Eu contornei essa dificuldade calculando as bandas de bollinger, através da média e o desvio padrão (algo nada agradável para um "programador"), por isso os outros dois manipuladores mostrados acima.

Bom, a segunda parte dos problemas está relacionada com a localização de parte do código do programa, na função OnCalculate ou em uma função independente (chamada desde OnCalculate).

Quando o código está na função OnCalculate, seja no horário do pregão ou não, o indicador funciona bem. Porém, quando o código é colocado em uma função independente (textualmente), o indicador pára de funcionar. Novamente o problema dá na função CopyBuffer. Veja-se o exemplo:

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[]) {...
  ArraySetAsSeries(time, true);
  double array_buffer_med[1];
  int limit;
  if((prev_calculated <= 0) || (prev_calculated > rates_total))
     limit= 500;  //exemplo para 500 barras, mas com o total funciona OK
  else
      limit= rates_total - prev_calculated;
  for (int bar= limit; bar >= 0; bar--) {
      if (CopyBuffer(SMA_handle, 0, time[bar], 1, array_buffer_med) <= 0) {
            Print("Erro na média", GetLastError());
          return(0); }

Dessa forma o indicador funcionam bem.
Agora passando o código para uma função (nomeada Grafico), o programa não tem erro, porém nem as bandas nem as barras aparecem.

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[]) {...
  ArraySetAsSeries(time, true);
  if (!Grafico(rates_total, prev_calculated, time, open, high, low, close) {
      Print("Erro na função ", GetLastError());
      return(0); }


bool Grafico(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[],
         const double &high[], const double &low[], const double &close[], const int bar) {
  ArraySetAsSeries(time, true); //pode ou nao estar aqui e o problema continua
  double array_buffer_med[1];
  int limit;
  if((prev_calculated <= 0) || (prev_calculated > rates_total))
     limit= 500;
  else
      limit= rates_total - prev_calculated;
  for (int bar= limit; bar >= 0; bar--) {
      if (CopyBuffer(SMA_handle, 0, time[bar], 1, array_buffer_med) <= 0) {
            Print("Erro na média desde a função ", GetLastError());
          return(0); }
  ....
  return(true); } //fim da função

Eu não pretendo "desaparecer" a função OnCalculate. Não todo seu código estará na função Grafico. Acontece que parte do código utilizarei em várias funções do programa, por isso tive a ideia de independizá-lo em uma função (aqui chamada de Grafico).

Eu fiz a função com essa parte do código e o indicador parou de funcionar, e então, para descartar causas passei 100% do código de OnCalculate para a função, e o problema continua.

Eu nem fiz aquelas outras funções ainda, mas com apenas isto o indicador não desenha, porque o CopyBuffer(SMA_handle...) retorna -1 (acho) e minha função retorna 0 para OnCalculate. Mas veja-se que é exatamente o mesmo código que estava em OnCalculate, onde não dá problemas.
 
Qual a explicação, por que isso acontece?

Saudações novamente.

Felipe
Para adicionar comentários, por favor Conecte-se ou registrar