Ideal ZigZag: L'indicatore veloce per MetaTrader 5 che ogni trader deve conoscere

Mike 2012.07.20 23:07 16 0 0
Allegato

Se sei un trader in cerca di un indicatore ZigZag semplice ma super veloce, sei nel posto giusto!

Questo indicatore ha ottimizzato il recupero dei picchi, evitando picchi sospesi o errati. Scopriamo insieme perché è così interessante.

Ideal ZigZag

Vantaggi:

  • Grazie all'ottimizzazione, la funzione di calcolo più costosa, iBarShift, è stata sostituita con ArrayBSearch. Questo rende l'indicatore molto più efficiente rispetto al suo equivalente MQL4;
  • Tutti i dati necessari per ogni barra sono accessibili non solo in tempo reale, ma anche storicamente per un EA;
  • Assenza di picchi sospesi;
  • Metodo efficace per trovare i picchi senza dover cercare nei valori dell'indicatore;
  • Velocità impressionante;
  • Funziona correttamente anche con l'inserimento di dati storici e quando si cambia timeframe;
  • Perfetto da usare in Expert Advisors.

Svantaggi:

  • Richiesta di memoria. Il ZigZag richiede 2 buffer (uno non basta a causa dei ritardi) per un disegno corretto, mentre qui ne vengono utilizzati 5. Tuttavia, ritengo che questo svantaggio sia ampiamente superato dal vantaggio di cui al punto 6. Nessun ZigZag veloce può gestire correttamente l'inserimento di dati storici su due buffer.
  • Linee aggiuntive disponibili. Queste sono necessarie per rendere i dati visibili a un Expert Advisor. Queste linee non dovrebbero mai essere visibili.

Principio:

Il ZigZag viene tracciato secondo il principio del canale. La larghezza del canale può essere definita in punti (IdealZZ) o in termini percentuali (IdealZZP).

Recupero dei picchi:

input int ChannelWidth=100;

#property indicator_chart_window

datetime LastTime;
int ZZHandle;
//+------------------------------------------------------------------+
//| Funzione di inizializzazione dell'indicatore personalizzato           |
//+------------------------------------------------------------------+
void OnInit()
  {
   LastTime = 0;
   ZZHandle = iCustom(_Symbol, Period(), "IdealZZ", ChannelWidth);
  }
//+------------------------------------------------------------------+
//| GetValue                                                      |
//+------------------------------------------------------------------+
bool GetValue(double dir,int bar,int prevBar,double &peak,
             int &peakBar,datetime &peakTime,const datetime &T[])
  {
   if(dir<0)
     {
      double t[1];
      if(0>=CopyBuffer(ZZHandle,2,bar,1,t)) return false;
      int i= ArrayBsearch(T, (datetime)t[0]);

      if(i==prevBar)
        {
         if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
        }

      double v[1];
      if(0>=CopyBuffer(ZZHandle,1,i,1,v)) return false;

      if(v[0]==EMPTY_VALUE)
        {
         if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
         if(0>=CopyBuffer(ZZHandle,1,i,1,v)) return false;
        }

      peak=v[0];
      peakBar=i;
      peakTime=(datetime)t[0];
   }
   else if(dir>0)
     {
      double t[1];
      if(0>=CopyBuffer(ZZHandle,3,bar,1,t)) return false;
      int i= ArrayBsearch(T, (datetime)t[0]);

      if(i==prevBar)
        {
         if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
        }

      double v[1];
      if(0>=CopyBuffer(ZZHandle,0,i,1,v)) return false;

      if(v[0]==EMPTY_VALUE)
        {
         if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
         if(0>=CopyBuffer(ZZHandle,0,i,1,v)) return false;
        }

      peak=v[0];
      peakBar=i;
      peakTime=(datetime)t[0];
     }
   else
     {
      return(false);
     }

   return(true);
  }
//+------------------------------------------------------------------+
//| GetValue                                                      |
//+------------------------------------------------------------------+
void SetPt(string name,double price,datetime time)
  {
   ObjectCreate(0,name,OBJ_ARROW,0,time,price);
   ObjectSetInteger(0,name,OBJPROP_ARROWCODE,108);
   ObjectSetDouble(0,name,OBJPROP_PRICE,price);
   ObjectSetInteger(0,name,OBJPROP_TIME,time);
  }
//+------------------------------------------------------------------+
//| Funzione di iterazione dell'indicatore personalizzato            |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &T[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(LastTime==T[0]) return(rates_total);
   LastTime=T[0];

   ArraySetAsSeries(T,true);

   double dir_[1];
   if(0>=CopyBuffer(ZZHandle,4,1,1,dir_)) return rates_total;
   double dir=dir_[0];
   double rdir=-dir;

   if(dir==EMPTY_VALUE) return(rates_total);

   double v1,v2,v3,v4,v5;
   int    i1,i2,i3,i4,i5;
   datetime t1,t2,t3,t4,t5;

   if(
      GetValue(dir,1,0,v1,i1,t1,T) && 
      GetValue(rdir,i1,0,v2,i2,t2,T) && 
      GetValue(dir,i2,i1,v3,i3,t3,T) && 
      GetValue(rdir,i3,i2,v4,i4,t4,T) && 
      GetValue(dir,i4,i3,v5,i5,t5,T)
      )
     {
      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);
     }
     else
     {
      Print("Sembra ci sia un errore...");
     }

     return(rates_total);
  }
//+------------------------------------------------------------------+

Questo esempio è un indicatore che segna (una volta per barra) i primi cinque picchi (incluso quello attualmente in formazione).

Attenzione! Il codice potrebbe funzionare in modo errato se è attivata la modalità zero bar.

Modalità Zero Bar:

Questa modalità può essere attivata nel codice della variabile DrawZeroBar. È disabilitata per impostazione predefinita. Non è consigliabile attivarla, specialmente se l'indicatore è utilizzato in un Expert Advisor.

Divertiti a usarlo! Ti prego di farmi sapere se trovi qualche altro difetto.

Elenco
Commento 0