Startseite Technischer Indikator Beitrag

Ideal ZigZag: Der schnelle Indikator für MetaTrader 5

Anhang
925.zip (3.53 KB, Herunterladen 0 mal)

Der Ideal ZigZag ist ein einfacher, aber blitzschneller ZigZag-Indikator.

Es gibt keine unterbrochenen oder falschen Spitzen, da die Spitzenabfrage zeitoptimiert wurde.

Ideal ZigZag

Vorteile:

  • Die rechenintensivste Funktion iBarShift wurde durch ArrayBSearch ersetzt, was bedeutet, dass der Indikator effizienter ist als seine MQL4-Entsprechung;
  • Alle notwendigen Daten für jede Kerze sind nicht nur in jedem Moment zugänglich, sondern auch für EAs zu jedem Zeitpunkt in der Geschichte verfügbar;
  • Keine unterbrochenen Spitzen;
  • Effiziente Methode zur Spitzenfindung ohne Suche nach Indikatorwerten;
  • Sehr schnell;
  • Funktioniert korrekt bei Geschichtseinfügungen und beim Wechseln der Zeitrahmen;
  • Perfekt für die Verwendung in EAs.

Nachteile:

  • Speicheranforderungen: ZigZag benötigt zwei Puffer (einer reicht nicht aus wegen Verzögerungen) für eine korrekte Darstellung, hier werden fünf Puffer verwendet. Dieser Nachteil wird meiner Meinung nach durch den Vorteil #6 mehr als aufgewogen. Kein schneller ZigZag kann Geschichtseinfügungen auf zwei Puffern korrekt verarbeiten.
  • Zusätzliche Linien sind vorhanden. Diese sind erforderlich, um die Daten für einen Expert Advisor sichtbar zu machen. Diese Linien sollten jedoch niemals sichtbar sein.

Prinzip:

Der ZigZag wird nach dem Kanalprinzip gezeichnet. Die Kanalbreite kann in Punkten (IdealZZ) oder in Prozent (IdealZZP) definiert werden.

Spitzenabfrage:

input int ChannelWidth=100;

#property indicator_chart_window

datetime LastTime;
int ZZHandle;
//+------------------------------------------------------------------+
//| Initialisierungsfunktion des benutzerdefinierten Indikators                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   LastTime = 0;
   ZZHandle = iCustom(_Symbol, Period(), "IdealZZ", ChannelWidth);
  }
//+------------------------------------------------------------------+
//| Wertabfrage                                                         |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Funktion zum Setzen von Punkten                               |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Iterationsfunktion des benutzerdefinierten Indikators                               |
//+------------------------------------------------------------------+
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("Es scheint ein Fehler vorzuliegen...");
     }

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

Dieses Beispiel ist ein Indikator, der die ersten fünf Spitzen (einschließlich der aktuell entstehenden) markiert (einmal pro Kerze).

Achtung! Der Code kann fehlerhaft arbeiten, wenn der Null-Bar-Modus aktiviert ist.

Null-Bar-Modus:

Der Modus kann im Code der DrawZeroBar-Variablen aktiviert werden. Er ist standardmäßig deaktiviert. Es wird nicht empfohlen, ihn zu aktivieren, insbesondere wenn der Indikator in einem Expert Advisor verwendet wird.

Viel Spaß bei der Nutzung! Bitte informiert mich über eventuelle entdeckte Mängel.

Verwandte Beiträge

Kommentar (0)