Schau, wie man Roboter kostenlos herunterladen kann
Finden Sie uns auf Twitter!
und werden Sie Mitglied unserer Fangruppe
Interessantes Skript?
Veröffentliche einen Link auf das Skript, damit die anderen ihn auch nutzen können
Hat Ihnen das Skript gefallen?
Bewerten Sie es im Terminal MetaTrader 5
Ansichten:
23
Rating:
(6)
Veröffentlicht:
2025.06.14 11:57
fiboZigZag.mq5 (13.54 KB) ansehen
MQL5 Freelance Benötigen Sie einen Roboter oder Indikator, der auf diesem Code basiert? Bestellen Sie ihn im Freelance-Bereich Zum Freelance

Der Aufbau

Wir benötigen :

  • 1 Zickzackkurve
  • 2 Datenpuffer für die Höchst- und Tiefstwerte
  • Eingabeparameter
  • eine laufende Reihe von Systemvariablen, die bei jeder Neuberechnung des Indikators zurückgesetzt werden

#property indicator_buffers 2
#property indicator_plots 1
input double retracement=23.6;//Retracement-Betrag
input double minSizeInAtrUnits=0.0;//min Größe der Wellen in atr-Einheiten
input int rollingAtrPeriod=14;//Rollende Atr-Periode
input color Color=clrDodgerBlue;//Wellenfarbe
input int Width=3;//Wellenbreite
input ENUM_LINE_STYLE Style=STYLE_SOLID;//wave style
//+------------------------------------------------------------------+




//| Benutzerdefinierte Initialisierungsfunktion für Indikatoren |
//+------------------------------------------------------------------+
//--- die Aufwärtswellen und die Abwärtswellen
  double upWaves[],dwWaves[];

Das upWaves-Array speichert die Hochs und das dwWaves-Array die Tiefs

Systemvariablen:

Wir müssen den Typ der letzten Welle kennen, wo sie begann, wo sie endete, den Abstand in Takten zwischen dem Beginn und dem Ende.

Dann brauchen wir eine lokale Hoch- und Tiefstwertvariable sowie die Abstände in Takten von jedem Punkt.

//--- Verfolgung des Zickzackkurses
  //--- die Art der Welle, die wir haben [0] keine [1] oben [2] unten
    int wave_type=0;
  //--- der Preis von der Welle (Startpreis) 
    double wave_start_price=0.0;
  //--- der Preis bis zum Ende der Welle (Endpreis)
    double wave_end_price=0.0;
  //--- der Abstand in Balken vom Startkurs
    int wave_start_distance=0;
  //--- der Abstand in Balken vom Endpreis
    int wave_end_distance=0;
  //--- Hochpreisiges Tracking
    double high_mem=0.0;
    int distance_from_high=0;
  //--- niedrige Preisverfolgung
    double low_mem=0.0;
    int distance_from_low=0;
  //--- rollende atr
    double rollingAtr=0.0;
       int rollingAtrs=0;

Schließlich die Rolling-Atr-Einheit und wie viele berechnet wurden.

Dann erstellen wir eine System-Reset-Funktion:

void resetSystem(){
ArrayFill(upWaves,0,ArraySize(upWaves),0.0);
ArrayFill(dwWaves,0,ArraySize(dwWaves),0.0);
wave_type=0;
wave_start_price=0.0;
wave_end_price=0.0;
wave_start_distance=0;
wave_end_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
}

Standard-Zeug, füllt die Arrays mit Nullen und setzt die Systemvariablen zurück.

Oninit richten wir die Puffer ein, den Plot, und wir rufen reset zum ersten Mal auf:

  SetIndexBuffer(0,upWaves,INDICATOR_DATA);
  SetIndexBuffer(1,dwWaves,INDICATOR_DATA);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Color);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,Width);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,Style);
  resetSystem();

Lassen Sie uns also gleich mit der Berechnung beginnen.

Als erstes müssen wir uns um die rollende Atr kümmern.

Solange wir nicht mehr Balken gesammelt haben, als die Atr-Periode beträgt, werden wir nichts anderes tun.

Der Teil, der die rollierende Atr verwaltet, ist wie folgt:

  • Wenn wir nicht mehr als die Periode gesammelt haben, addieren wir den Bereich der gefundenen Balken zu einer Summierung
  • sobald wir die Periode erreicht haben, führen wir die erste Division (Durchschnitt) durch
  • Danach schneiden wir einen Teil der gleitenden Atr ab, nämlich Atr/Periode, und fügen dann einen neuen Teil hinzu, der die Spanne von Balken/Periode ist.
Wir setzen den letzten Teil an die erste Stelle, weil er häufiger vorkommt und wir nicht auf 2 if-Anweisungen zugreifen müssen.

     //--- verwaltung der atr
       rollingAtrs++;
       if(rollingAtrs>rollingAtrPeriod){
       double new_portion=((high[i]-low[i])/_Point)/((double)rollingAtrPeriod);
       //--- wir entfernen einen alten Teil und fügen einen neuen Teil hinzu
       rollingAtr=(rollingAtr)-(rollingAtr/((double)rollingAtrPeriod))+new_portion;
       }
       else if(rollingAtrs<=rollingAtrPeriod){
         rollingAtr+=(high[i]-low[i])/_Point;
         if(rollingAtrs==rollingAtrPeriod){
           rollingAtr/=((double)rollingAtrs);
           //--- Starten Sie den Speicher für Hochs und Tiefs und das System
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
         }

Toll, jetzt gibt es ein weiteres Problem.

Die Grundlage für diesen Zickzackkurs ist ein Retracement.

Aber damit ein Retracement stattfinden kann, muss es mindestens eine Welle geben.

Aber was wird die erste Welle zurückgehen? xD

Aus diesem Grund werden wir das Folgende tun:

  • sobald sich der atr füllt (atr gesammelt = Periode), werden wir das Hoch und das Tief in unseren Systemvariablen erfassen
  • welche Seite es schafft, eine Welle zu bilden, die eine gültige Größe in atr-Einheiten hat, und ein neues Hoch (Aufwärtswelle) oder ein neues Tief (Abwärtswelle) bildet, gewinnt

Auf diese Weise haben wir kein Retracement als Anfangswelle, aber wir müssen die Sequenz irgendwie beginnen.

Wir hätten uns auch für einen klassischen fraktalen Ansatz entscheiden können, nur für die erste Welle, und dann mit Retracements weitermachen.

Genau das tun wir, solange wir keine Welle haben:

   //--- wenn wir noch keinen Wellentyp haben
     else{
       //--- wenn wir das Hoch und nicht das Tief gebrochen haben
         if(high[i]>high_mem&&low[i]>=low_mem){
         double new_wave_size_in_atr_units=((high[i]-low_mem)/_Point)/rollingAtr;
         //--- wenn die neue Wellengröße gültig ist
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
           //--- Start einer neuen Aufwärtswelle 
             wave_type=1;
           //--- Startpreis ist der niedrigste Wert 
             wave_start_price=low_mem;
             wave_start_distance=distance_from_low;
           //--- Endpreis ist der neue Höchststand
             wave_end_price=high[i];
             wave_end_distance=0;
           //--- die Welle zeichnen 
             dwWaves[i-wave_start_distance]=low_mem;
             upWaves[i]=high[i];
           //--- den Höchstwert ändern
             high_mem=high[i];
             distance_from_high=0;
           //--- den Tiefpunkt ändern 
             low_mem=low[i];
             distance_from_low=0;
           }
           } 
       //--- wenn wir das Tief und nicht das Hoch gebrochen haben
         else if(low[i]<low_mem&&high[i]<=high_mem){
         double new_wave_size_in_atr_units=((high_mem-low[i])/_Point)/rollingAtr;
         //--- wenn die neue Wellengröße gültig ist
         if(new_wave_size_in_atr_units>=minSizeInAtrUnits){         
           //--- Beginn einer neuen Abwärtswelle 
             wave_type=-1;
           //--- Der Startpreis ist der höchste Mem 
             wave_start_price=high_mem;
             wave_start_distance=distance_from_high;
           //--- Endpreis ist das neue Tief
             wave_end_price=low[i];
             wave_end_distance=0;
           //--- die Welle zeichnen 
             upWaves[i-wave_start_distance]=high_mem;
             dwWaves[i]=low[i];
           //--- den Höchstwert ändern
             high_mem=high[i];
             distance_from_high=0;
           //--- den Tiefpunkt ändern 
             low_mem=low[i];
             distance_from_low=0;
           }
           }
       //--- wenn wir beides kaputt machen
         else if(low[i]<low_mem&&high[i]>high_mem){
           //--- ändern Sie sie
             high_mem=high[i];
             low_mem=low[i];
             distance_from_high=0;
             distance_from_low=0;
           }
       }

Großartig. Nun das letzte Stück.

  • Wenn wir eine Aufwärtswelle haben :
  1. Wenn ein neues Hoch erreicht wird, verschieben wir das Zickzack vom vorherigen Hoch zum neuen Hoch, was wir tun können, da wir die Balkenabstände beibehalten, und aktualisieren auch das Tief und den Abstand vom Tief.
  2. Wenn ein neuer Tiefpunkt erreicht wird oder ein neuer Tiefpunkt gesetzt wird, berechnen wir den Abstand zwischen dem Höchststand und dem Tiefpunkt und teilen ihn durch die Wellengröße. Wenn also die Wellengröße 100 Punkte und das Retracement 24 Punkte beträgt, erhalten wir 24/100 0,24, also x 100 24%. Wenn die Größe der neuen "Möchtegern"-Welle, die die vorherige Welle zurückzieht, auch für die ATR-Einheiten gültig ist, starten wir eine neue Abwärtswelle, setzen die neuen lokalen Hochs und Tiefs und die Balkenabstände fest.

Hier ist der entsprechende Code für die oben genannten:

       //--- wenn wir eine Aufwärtswelle haben 
         if(wave_type==1){
           //--- wenn sich die Welle nach oben ausdehnt 
             if(high[i]>wave_end_price){
               //--- den vorherigen Endpreis von seiner Array-Position entfernen (0.0=leer)
                upWaves[i-wave_end_distance]=0.0;
               //--- an der neuen Position platzieren
                upWaves[i]=high[i];
                wave_end_price=high[i];
                wave_end_distance=0;
               //--- den Höchstwert ändern
                high_mem=high[i];
                distance_from_high=0;
               //--- den Tiefpunkt ändern 
                low_mem=low[i];
                distance_from_low=0;
               }
           //--- Prüfung auf Retracement
             if(low[i]<low_mem||distance_from_low==0){
               low_mem=low[i];
               distance_from_low=0;
               double size_of_wave=(wave_end_price-wave_start_price)/_Point;
               double size_of_retracement=(wave_end_price-low_mem)/_Point;
               if(size_of_wave>0.0){
                 double retraced=(size_of_retracement/size_of_wave)*100.0;
                 double new_wave_size_in_atr_units=((wave_end_price-low_mem)/_Point)/rollingAtr;
               //--- wenn die neue Wellengröße gültig ist
               if(new_wave_size_in_atr_units>=minSizeInAtrUnits){
                 //--- wenn der Rückschritt signifikant ist, eine Abwärtswelle starten
                   if(retraced>=retracement){
                    //--- Beginn einer neuen Abwärtswelle 
                      wave_type=-1;
                    //--- Der Startpreis ist der höchste Mem 
                      wave_start_price=high[i-distance_from_high];
                      wave_start_distance=distance_from_high;
                    //--- Endpreis ist das neue Tief
                      wave_end_price=low[i];
                      wave_end_distance=0;
                    //--- die Welle zeichnen 
                      upWaves[i-wave_start_distance]=high_mem;
                      dwWaves[i]=low[i];
                    //--- den Höchstwert ändern
                      high_mem=high[i];
                      distance_from_high=0;
                    //--- den Tiefpunkt ändern 
                      low_mem=low[i];
                      distance_from_low=0;                     
                     }
                   }
                 }
               }
           }

Wir machen das Gegenteil, wenn wir eine Abwärtswelle haben.

Das war's, unser Retracement-Zickzack ist fertig.

Hier ist das Zickzack mit 23,6% Retracement und 0,0 min Größe der Wellen in atr Einheiten


und hier ist derselbe Zickzackkurs mit einer 3-Min-Wellengröße in ATR-Einheiten






Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalpublikation: https://www.mql5.com/en/code/56619

TradeReportExporter TradeReportExporter

Das Skript TradeReportExporter wurde entwickelt, um die Historie der Handelsgeschäfte (Trades) in eine praktische CSV-Datei zu exportieren. Es sammelt automatisch die Daten aller Geschäfte des letzten Jahres für das Instrument, auf dem es installiert ist. Die Datei enthält Daten wie Datum und Uhrzeit, Transaktionsart (Kauf/Verkauf), Preis, Volumen, Provision und Gewinn/Verlust. Das Ergebnis wird in einer Datei gespeichert, die in Excel oder einem anderen Tabellenkalkulationsprogramm geöffnet werden kann.

Swaps Monitor for a Single Symbol Swaps Monitor for a Single Symbol

Ein einfaches Dienstprogramm zur Überwachung von Long- und Short-Swaps für ein einzelnes Symbol. Wenn die Swaps Ihres Broker-Dealers in Punkten statt in der Kontowährung angegeben sind, konvertiert dieses Dienstprogramm automatisch Punkte in die Kontowährung. Die Swaps werden am Mittwoch verdreifacht. Die horizontale und vertikale Ausrichtung kann in den Eingaben angepasst werden.

Autoscaling Zigzag Autoscaling Zigzag

Ein Zickzack-Indikator, der mit einer einzigen Eingabe die Schrittweite für die Erkennung von Wellenrichtungsänderungen einstellt

Telegram integration made easy. Telegram integration made easy.

Das Ziel ist es, die Funktion für jede Telegram-Integrationsaufgabe in der MQL5-Entwicklung leicht verfügbar zu machen. Wenn Sie diese Datei zu Ihrer CodeBase hinzufügen, können Sie sie einfach in Ihre Expert Advisors einbinden und die Funktion direkt aus dem enthaltenen Modul aufrufen. Damit entfällt die Notwendigkeit, den Code immer wieder von Grund auf neu zu entwickeln, und die Wiederverwendbarkeit über mehrere Projekte hinweg ist gewährleistet.