Início Indicador técnico Postagem

Ideal ZigZag: O Indicador Perfeito para MetaTrader 4

Anexo
10671.zip (2.71 KB, Baixar 0 vezes)



Vantagens do Ideal ZigZag:

  • A função mais custosa, iBarShift, é totalmente substituída por ciclos no código para recuperação de picos.
  • Todas as informações necessárias para construir o ZigZag em cada barra estão acessíveis de forma contínua, além de serem utilizadas em códigos externos.
  • Não há picos suspensos.
  • Método eficiente para encontrar picos disponível.
  • Extremamente rápido.
  • Funciona corretamente em inserções históricas e ao trocar de períodos gráficos.
  • Perfeito para uso em EAs.

Desvantagens:

1. Requisitos de memória: Este indicador utiliza 5 buffers em vez de 2 (ou até 1) como em outras implementações. Mas, na minha opinião, isso é um bom preço a pagar pelas vantagens mencionadas nos pontos 6 e 7. Nenhum ZigZag rápido que conheço consegue processar inserções históricas sem uma reconstrução completa. O meu faz isso de maneira eficiente.

2. Linhas adicionais são geradas: Isso é necessário para tornar os dados visíveis para qualquer código externo, mas essas linhas nunca devem ser exibidas.

Princípio:

O ZigZag é desenhado pelo princípio de canalização.

A largura do canal pode ser definida em Pontos (XLab_ZZ) ou em Porcentagem (XLab_ZZP).

Recuperação de picos:

extern int ChannelWidth = 100;

#property indicator_chart_window
#property indicator_buffers 1

#property indicator_color1 Red
#property indicator_width1 3

datetime LastTime;

int init()
{
   LastTime = 0;
   
   return(0);
}

bool GetValue(double dir, int bar, int prevBar, double& peak, int& peakBar, datetime& peakTime)
{
   if (dir < 0)
   {
      datetime t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 2, bar);
      int i = iBarShift(Symbol(), 0, t);

      if (i == prevBar)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 2, bar + 1);
         i = iBarShift(Symbol(), 0, t);
      }

      double v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 1, i);
      
      if (v == EMPTY_VALUE)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 2, bar + 1);
         i = iBarShift(Symbol(), 0, t);
         v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 1, i);
      }
      
      peak = v;
      peakBar = i;
      peakTime = t;
   }
   else if (dir > 0)
   {
      t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 3, bar);
      i = iBarShift(Symbol(), 0, t);

      if (i == prevBar)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 3, bar + 1);
         i = iBarShift(Symbol(), 0, t);
      }

      v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 0, i);
      
      if (v == EMPTY_VALUE)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 3, bar + 1);
         i = iBarShift(Symbol(), 0, t);
         v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 0, i);
      }
      
      peak = v;
      peakBar = i;
      peakTime = t;
   }
   else 
   {
      return (false);
   }
   
   return (true);
}

int start()
{
   if (LastTime == Time[0]) return (0);
   LastTime = Time[0];
   
   double dir = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 4, 1);
   double rdir = -dir;

   if (dir == EMPTY_VALUE) return (0);
   
   double v1, v2, v3, v4, v5;
   int    i1, i2, i3, i4, i5;
   datetime t1, t2, t3, t4, t5;
   
   GetValue(dir, 1, 0, v1, i1, t1);
   GetValue(rdir, i1, 0, v2, i2, t2);
   GetValue(dir, i2, i1, v3, i3, t3);
   GetValue(rdir, i3, i2, v4, i4, t4);
   GetValue(dir, i4, i3, v5, i5, t5);

   SetPt("1", v1, t1);
   SetPt("2", v2, t2);
   SetPt("3", v3, t3);
   SetPt("4", v4, t4);
   SetPt("5", v5, t5);
   
   Print(v1, "   ", v2, "  ", v3, "  ", v4, " ", v5, " ", i1, "  ", i2, "  ", i3, " ", i4, " ", i5);

   return(0);
}

void SetPt(string name, double price, datetime time)
{
   ObjectCreate(name, OBJ_ARROW, 0, time, price);
   ObjectSet(name, OBJPROP_ARROWCODE, 108);
   ObjectSet(name, OBJPROP_PRICE1, price);
   ObjectSet(name, OBJPROP_TIME1, time);
}

Este exemplo é um indicador que marca (uma vez por barra) os cinco primeiros picos (incluindo o que está se formando atualmente).

Atenção! Este código pode funcionar incorretamente se o modo de barra 0 estiver ativado.

Modo de Barra 0:

É configurado com a variável DrawZeroBar, que está desativada por padrão.

Não é recomendável usar essa opção, especialmente se o indicador estiver sendo utilizado em um EA.


Aproveite a utilização do indicador! ;) Sinta-se à vontade para perguntar qualquer coisa.

Se encontrar algum bug, por favor, me avise. Obrigado!

Publicações relacionadas

Comentário (0)