English 日本語
preview
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 56): Bill Williams Fraktale

MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 56): Bill Williams Fraktale

MetaTrader 5Handelssysteme |
122 0
Stephen Njuki
Stephen Njuki

Einführung

Der Fraktalindikator von Bill Williams ist ein zentraler und wichtiger Indikator unter den Sammlungsgewohnheiten, für die er bekannt ist. Es identifiziert in erster Linie Umkehrpunkte in der Preisentwicklung gehandelter Symbole. Basierend auf dem Konzept der Fraktale wird ein sich wiederholendes 5-Balken-Muster oft als abwärts bezeichnet, wenn der mittlere von 5 Balken das höchste Hoch, oder als aufwärts, wenn der mittlere Balken das niedrigste Tief darstellt. Wir sehen uns einige der Muster dieses Indikators an, die von Händlern genutzt werden können, wie wir es in der Vergangenheit mit Artikeln über den MQL5-Assistenten getan haben.


Aufeinanderfolgende Fraktale in dieselbe Richtung

Für unser erstes Muster, pattern-0, wird eine Aufwärts-Formation definiert, wenn sich eine Reihe von tiefen Aufwärts-Fraktalen am oder in der Nähe des vorherigen Tiefs bilden. Dies wird in der Regel so interpretiert, dass der Markt zu diesem Zeitpunkt Unterstützung findet. Es ist wichtig zu beachten, dass mit aufeinanderfolgenden fraktalen Tiefs gemeint ist, dass es kein fraktales Hoch zwischen den Tiefs gibt. Dies ist ein wichtiger Indikator, denn typische Muster sind fraktale Hochs, die auf fraktale Tiefs folgen, die sich abwechseln. Für das Aufwärts-Muster wird jedoch angenommen, dass verschiedene Käufer auf ähnlichen Kursniveaus in den Markt eintreten, was die These einer Akkumulationsphase, die einer Aufwärtsbewegung vorausgeht, untermauert.

Umgekehrt können mehrere aufeinander folgende hohen Abwärts-Fraktalen ein Widerstandsniveau abbilden, das der Kurs nicht durchbrechen kann. Diese starke Ablehnung (oder wiederholte Ablehnung auf großen Zeitrahmen) deutet oft auf einen starken Verkaufsdruck und eine wahrscheinliche Fortsetzung oder den Beginn eines Abwärtstrends hin.

Wir implementieren pattern-0 in MQL5 wie folgt:

//+------------------------------------------------------------------+
//| Check for Pattern 0.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_0(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalLow(X() + 1) != 0.0 && FractalLow(X()) != 0.0)
   {  return(true);
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 1) != 0.0 && FractalHigh(X()) != 0.0)
   {  return(true);
   }
   return(false);
}

Standardmäßig ist ein Bill-Williams-Fraktal-Indikator in der Reihe der eingebauten Indikatoren enthalten. Es erfordert auch einige Anpassungen, da viele seiner Werte für die Puffer Upper/Highs und Lower/Lows bei der ersten Verwendung NaNs erzeugen. Wir erstellen daher eine modifizierte Version davon, indem wir 2 Funktionen einführen: FractalHigh und FractalLow. Der Code für beide ist unten aufgeführt:

double            FractalHigh(int ind)
{  //
   m_high.Refresh(-1);
   if(m_high.MaxIndex(ind, 5) == ind)
   {  return(m_high.GetData(ind));
   }
   return(0.0);
}

double            FractalLow(int ind)
{  //
   m_low.Refresh(-1);
   if(m_low.MinIndex(ind, 5) == ind)
   {  return(m_low.GetData(ind));
   }
   return(0.0);
}

In der Funktion des Musters pattern-0 rufen wir einfach die Funktion Fractallow auf 2 aufeinanderfolgenden Balken auf, wenn wir ein Aufwärtssignal suchen, oder das fraktale Hoch desselben Balkens, wenn wir ein Abwärts-Muster suchen. Die Anzahl der aufeinanderfolgenden Balken kann vom Leser angepasst werden, indem sie erhöht wird, wenn mehr falsche Signale herausgefiltert werden sollen. Wie so oft müssen jedoch weniger Handels-Setups über längere Zeiträume getestet werden, bevor sie verlässlich sind. Wir führen alle Tests für die Muster dieses Indikators für das Symbol GBPUSD auf dem 4-Stunden-Zeitrahmen für das Jahr 2024 durch, nachdem wir die Muster für das Jahr 2023 optimiert haben. Der Vorwärtstest für pattern-0 liefert uns den folgenden Bericht.

r0

pattern-0 zeigt eine starke Trendfortsetzung an. Er kann daher bei der Wiedereröffnung von Positionen in einem vorherrschenden Trend helfen, wenn Gewinnmitnahmen stattgefunden haben.


Fraktaler Trenddurchbruch

pattern-1, unser zweites, definiert seine Aufwärts-Formation zunächst durch ein Abwärts-Fraktal, das als Widerstand diente. Eine Aufwärts-Formation entsteht, wenn der Kurs sich gegen die Erwartung entwickelt und dieses fraktale Hoch entscheidend übersteigt. Dieser Ausbruch wird dann so interpretiert, dass die Käufer die Verkäufer übertrumpfen, sodass das ehemalige Widerstandsniveau in eine Unterstützung umschlägt, was eine Trendumkehr signalisiert. Es könnte sich auch um eine starke Trendfortsetzung handeln, wenn sie innerhalb eines viel breiteren Aufwärtstrends stattfände, der auf kleinen Zeitrahmen weniger deutlich geworden ist.

Eine Abwärts-Version von pattern-1 würde erwartungsgemäß das Gegenteil bewirken. Auf ein tiefes Aufwärts-Fraktal würde ein Kursdurchbruch unter das Tief des Fraktals folgen. Dieser Durchbruch wird als Anzeichen dafür gewertet, dass die Verkäufer die Kontrolle übernehmen und die Weichen für einen Abwärtstrend stellen. Wir implementieren dies wie folgt in MQL5:

//+------------------------------------------------------------------+
//| Check for Pattern 1.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_1(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalHigh(X() + 1) != 0.0 && Close(X()) > FractalHigh(X() + 1))
   {  return(true);
   }
   else if(T == POSITION_TYPE_SELL && FractalLow(X() + 1) != 0.0 && Close(X()) < FractalLow(X() + 1))
   {  return(true);
   }
   return(false);
}

In unserem obigen Code suchen wir nach Fraktalpunkten auf dem vorherigen Balken und vergleichen dann den aktuellen Schlusskurs mit diesem Fraktalpreis. Wie in der Logik dargelegt, ist das fraktale Hoch (das Abwärts-Fraktal) für das Abwärts-Muster von Bedeutung, und das fraktale Tief ist ebenfalls für das Abwärts-Muster von Bedeutung.

Der Vorwärtstest für das Jahr 2024, der sich aus der Optimierung der Öffnungs- und Schließungsschwellen für das Jahr 2023 ergibt, führt zu dem folgenden Bericht:

r1

pattern-1 zeichnet sich dadurch aus, dass es im Gegensatz zu pattern-0, das eine Fortsetzung ist, als Umkehrung dienen kann. Aus diesem Grund ist es immer eine gute Idee, ihn zusammen mit anderen Indikatoren zu verwenden.


Innerhalb von Fraktalen (tiefere Hochs, höhere Tiefs)

Bei pattern-2 wird die Aufwärts-Formation definiert, wenn sich Aufwärts-Fraktale (Swing-Lows) in der Nähe der Spanne eines vorhergehenden breiteren Fraktals bilden. Innerhalb dieser Spanne verdichten sich die Kurse häufig, wobei die tiefen Fraktale fast eine gerade Linie bilden. Wenn also eine Bewegung oberhalb dieser engen Spanne erfolgt, würde dies eine Aufwärts-Tendenz bestätigen, da die Käufer den Preis aus einer Konsolidierungszone herausdrücken würden.

Umgekehrt würde eine fraktale Abwärts-Formation, wenn die Schwunghochs einen Cluster innerhalb der Grenzen einer früheren rückläufigen fraktalen Spanne bilden, ebenfalls eine Phase der Unentschlossenheit markieren. Sobald der Kurs unter die untere Begrenzung dieser Spanne fällt und die Unterstützung versagt, würde dieser Ausbruch nach unten eine Abwärts-Bewegung bestätigen. So implementieren wir dies in MQL5:

//+------------------------------------------------------------------+
//| Check for Pattern 2.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_2(ENUM_POSITION_TYPE T)
{  CArrayDouble _buffer;
   if(T == POSITION_TYPE_BUY)
   {  for(int i = 0; i < m_periods; i++)
      {  if(FractalLow(X() + i) != 0.0)
         {  _buffer.Add(FractalLow(X() + i));
         }
      }
      if(_buffer[_buffer.Maximum(0, _buffer.Total())] - _buffer[_buffer.Minimum(0, _buffer.Total())] <= fabs(Close(X()) - Close(X() + 10)))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL)
   {  for(int i = 0; i < m_periods; i++)
      {  if(FractalHigh(X() + i) != 0.0)
         {  _buffer.Add(FractalHigh(X() + i));
         }
      }
      if(_buffer[_buffer.Maximum(0, _buffer.Total())] - _buffer[_buffer.Minimum(0, _buffer.Total())] <= fabs(Close(X()) - Close(X() + 10)))
      {  return(true);
      }
   }
   return(false);
}

Die Implementierung dieses Musters erfordert, wie in unserem Ansatz, die Verwendung einer Array-Standardklasse. Der Grund dafür ist, dass wir nach fraktalen Punkten innerhalb eines bestimmten Zeitraums suchen und die Anzahl der Punkte, die wir finden werden, ungewiss ist. Dazu müssen wir auch ein Gefühl für die Standardabweichung dieser fraktalen Punkte bekommen.

Da unsere Array-Klasse keine Standardabweichungsfunktion wie der Vektor-Datentyp bietet und diese auch rechenintensiv ist, entscheiden wir uns stattdessen für den Bereich dieser Punkte. Um ein Gefühl dafür zu bekommen, dass ihre Spanne komprimiert ist, vergleichen wir sie mit dem Ausmaß des Trends im Schlusskurs, und wenn sie geringer ist, haben wir eine Bestätigung.

Streng genommen handelt es sich hierbei um eine grobe Einschätzung, da man leicht erkennen kann, dass in Märkten, die sich im Trend befinden, wenn die Größenordnung der Schlusskursveränderung recht groß wird, jede Reihe von fraktalen Punkten diesen Test bestehen wird. Deshalb kann es für die Leser eine gute Idee sein, Änderungen vorzunehmen, die besagen, dass der Bereich der fraktalen Punkte oder ihre Standardabweichung mit einem absoluten Wert zu vergleichen ist. Dieser Wert kann durch Optimierung angepasst werden.

Ein Vorwärtstest nach der Optimierung unseres von einem Assistenten zusammengestellten Expert Advisor mit dem Paar USD JPY auf dem 4-Stunden-Zeitrahmen liefert uns diese Ergebnisse:

r2

pattern-2 ist ein Kompressionsmuster, das auf ein Ausbruchspotenzial hinweist. Wenn sich in mehreren Zeitrahmen kleinere Fraktale innerhalb größerer Fraktale bilden, deutet dies in der Regel auf einen Verengung vor einer Expansion hin.


Fraktale Divergenz mit einer Preisbewegung

Divergenz mit einer Preisbewegung ist unser pattern-3. Bei diesem Muster wird eine Aufwärts-Divergenz festgestellt, wenn der Kurs ein tieferes Tief erreicht (ein Anzeichen für anhaltenden Abwärtsdruck), die entsprechenden Aufwärts-Fraktale (die Tiefs des Umschwungs) jedoch über denen des vorherigen Umschwungs liegen. Diese Divergenz wird als aufwärts interpretiert, mit dem Argument, dass trotz fallender Kurse die zugrunde liegende Unterstützung zunimmt, was auf eine bevorstehende Aufwärts-Wende hindeutet.

Eine Abwärts-Divergenz liegt hingegen vor, wenn der Kurs ein höheres Hoch bildet, während die hohen Abwärts-Fraktale niedriger sind als die vorherigen. Diese Konstellation signalisiert in der Regel, dass, obwohl der Kurs steigt, der Widerstand den Kurs drückt, was eine Vorwarnung für den Verlust der Kaufkraft und eine Umkehr nach unten sein könnte. Wir setzen dies in MQL5 wie folgt um:

//+------------------------------------------------------------------+
//| Check for Pattern 3.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_3(ENUM_POSITION_TYPE T)
{  CArrayDouble _buffer;
   if(T == POSITION_TYPE_BUY)
   {  for(int i = 0; i < m_periods; i++)
      {  if(FractalLow(X() + i) != 0.0)
         {  _buffer.Add(FractalLow(X() + i));
         }
         if(_buffer.Total() >= 2)
         {  break;
         }
      }
      if(_buffer[0] > _buffer[1] && Low(X()) < Low(X() + 1))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL)
   {  for(int i = 0; i < m_periods; i++)
      {  if(FractalHigh(X() + i) != 0.0)
         {  _buffer.Add(FractalHigh(X() + i));
         }
         if(_buffer.Total() >= 2)
         {  break;
         }
      }
      if(_buffer[0] < _buffer[1] && High(X()) > High(X() + 1))
      {  return(true);
      }
   }
   return(false);
}

Die Codierung unseres pattern-3 erfordert auch die Verwendung der Standard-Array-Klasse, die in der MQL5-IDE verfügbar ist. Dies hat vor allem Gründe, die bereits in pattern-2 genannt wurden, allerdings suchen wir in diesem Fall nur nach 2 fraktalen Punkten und nicht nach einer Sammlung über einen durch den Eingabeparameter „m_periods“ festgelegten Zeitraum. Wir verwenden die 2 fraktalen Punkte zusammen mit den 2 extremen Kurspunkten, um unser potenzielles Signal zu ermitteln, wie bereits oben dargelegt.

Ein Vorwärtstest nach der Optimierung für ein ähnliches Symbol, einen ähnlichen Zeitrahmen und einen ähnlichen Testzeitraum wie bei den vorherigen Mustern liefert uns den folgenden Bericht:

r3



Gegensätzliche Zwillingsfraktale (Umkehrzonen)

Gegensätzliche Zwillingsfraktale bilden unser pattern-4. Die Aufwärts-Formation für dieses Muster umfasst zwei identisch platzierte Fraktale, ein aufwärtsgerichtetes (bei Tiefstständen) und ein abwärtsgerichtetes (bei Höchstständen). Durch die Überschneidung dieser beiden Bereiche entsteht eine Zone der Unentschlossenheit. Wenn der Kurs vom Aufwärts-Fraktal abprallt und über das Abwärts-Fraktal ansteigt, wird ein Aufwärtssignal bestätigt.

Bei der Abwärts-Formation ist die Sequenz ein Aufwärts-Fraktal, auf das unmittelbar ein Abwärts-Fraktal folgt.  Wenn der Kurs vom (hohen) Abwärts-Fraktal abprallt und unter das Aufwärts-Fraktal fällt, wird ebenfalls ein Verkaufssignal bestätigt. Wir codieren dies in MQL5 wie folgt:

//+------------------------------------------------------------------+
//| Check for Pattern 4.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_4(ENUM_POSITION_TYPE T)
{  bool _1 = (FractalHigh(X() + 1) != 0.0 && FractalLow(X() + 1) != 0.0);
   bool _2 = (FractalHigh(X() + 2) != 0.0 && FractalLow(X() + 2) != 0.0);
   if(_1 || _2)
   {  if(T == POSITION_TYPE_BUY)
      {  if((_1 && Close(X()) > FractalHigh(X() + 1)) || (_2 && Close(X()) > FractalHigh(X() + 2)))
         {  return(true);
         }
      }
      else if(T == POSITION_TYPE_SELL)
      {  if((_1 && Close(X()) < FractalLow(X() + 1)) || (_2 && Close(X()) < FractalLow(X() + 2)))
         {  return(true);
         }
      }
   }
   return(false);
}

Unser Code verwendet zwei Booleans, um das fraktale Zwillingsmuster zu erkennen. Wir haben uns für die Verwendung von 2 Booleschen Werten entschieden, weil die Auswirkungen dieses einzigartigen Musters leicht verlangsamt sein könnten (im Gegensatz zu verzögert). Jeder Wert markiert entweder den letzten vollständigen Balken oder den Balken davor. Wenn das Muster gefunden wird, prüfen wir einfach, ob der Schlusskurs eines der oben erläuterten Schlüsselniveaus durchbrochen hat. 

Ein Vorwärtstest nach der Optimierung für dieses Muster liefert uns den folgenden Bericht:

r4

Das aufeinanderfolgende Auftreten von Aufwärts- und Abwärts-Fraktalen verdeutlicht auch einen weiteren Unentschlossenheitspunkt an den Märkten. Ausbrüche auf beiden Seiten werden also als Signale für pattern-4 verwendet.


Fraktale Bestätigung von Swing-Hochs und -Tiefs

Bei diesem Muster, pattern-5, betrachten wir die Kursentwicklung über eine Reihe von Balken im Verhältnis zu den fraktalen Benchmarks. Die Aufwärts-Formation ist definiert, wenn ein Aufwärts-Fraktal (das oft ein potenzielles Unterstützungsniveau darstellt) festgestellt wird und die anschließende Kursentwicklung nicht deutlich unter dieses Niveau fällt. Wenn der Kurs weiterhin von diesem Niveau abprallt, bestätigt dies die These, dass es sich um eine Aufwärts-Unterstützungszone handelt.

Umgekehrt entsteht eine Abwärts-Swing-/Formation, wenn ein fraktales Hoch erreicht wird und der Kurs nach der anschließenden Kursbewegung das Hoch des Fraktals nicht überschreitet. Das Argument hier ist, dass die anhaltende Unfähigkeit, aus dem Fraktal nach oben auszubrechen, seine Rolle als Widerstandsbereich und somit als Signal für eine rückläufige Stimmung verstärkt. Wir setzen dies in MQL5 wie folgt um:

//+------------------------------------------------------------------+
//| Check for Pattern 5.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_5(ENUM_POSITION_TYPE T)
{  vector _std;
   _std.Init(5);
   _std.Fill(0.0);
   if(T == POSITION_TYPE_BUY && FractalLow(X() + m_periods) != 0.0)
   {  if(_std.CopyRates(m_symbol.Name(), m_period, 4, 0, m_periods) && _std.Std() <= fabs(Close(X()) - Close(X() + m_periods)))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X() + m_periods))
   {  if(_std.CopyRates(m_symbol.Name(), m_period, 2, 0, m_periods) && _std.Std() <= fabs(Close(X()) - Close(X() + m_periods)))
      {  return(true);
      }
   }
   return(false);
}

Unser obiger Code verwendet einen Vektor nicht nur zum Kopieren des Puffers mit den von uns benötigten Raten, sondern auch zum effizienten Abrufen ihrer Standardabweichung. Wir vergleichen diese Abweichung mit der Größe des vorherrschenden Trends im Schlusskurs, wie wir es bei pattern-2 getan haben. Die in pattern-2 angesprochenen Nachteile und Vorsichtsmaßnahmen gelten daher auch hier, sodass es dem Leser freisteht, den beigefügten Code zu ändern.

Ein Vorwärtstest nach der Optimierung mit dem gleichen Symbol, den gleichen Fenstern und dem gleichen Zeitrahmen wie oben ergibt den folgenden Bericht:

r5

Ich hatte in dieser Artikelserie keine Vorwärtstest gemacht, aber, da die Testfenster sehr klein sind, nehmen wir sie jetzt standardmäßig auf. Was fehlen wird, sind die Optimierungsläufe während des Trainingszeitraums, denn beides würde den Artikel zu voll machen.


Scheitern am Fraktal

pattern-6 konzentriert sich auf das „Scheitern“ von Kursbewegungen, die Fraktale zu überwinden. Wenn der Kurs nach einem Aufwärts-Fraktal versucht, nach darunter auszubrechen, und dieser Versuch scheitert, d. h. wenn das neue Tief durch eine schnelle Umkehr nach oben abgelehnt wird, deutet dies häufig darauf hin, dass die Verkäufer erschöpft sind und die Käufer einspringen müssen.

Umgekehrt gilt: Wenn sich ein fraktales Hoch bildet und der Kurs versucht, über dieses Fraktal hinaus zu steigen, aber scheitert, wird dieser „Swing Failure“ als Zeichen dafür gewertet, dass die Verkäufer das Sagen haben und der Kurs wahrscheinlich auf einen Abwärtstrend zusteuert. Implementierung in MQL5 wie folgt:

//+------------------------------------------------------------------+
//| Check for Pattern 6.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_6(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalLow(X() + 2) != 0.0)
   {  if(Low(X() + 1) <= FractalLow(X() + 2) && Close(X()) >= High(X() + 2))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 2) != 0.0)
   {  if(High(X() + 1) >= FractalHigh(X() + 2) && Close(X()) <= Low(X() + 2))
      {  return(true);
      }
   }
   return(false);
}

Dies ist eines unserer einfachsten Muster, was die Kodierung betrifft. Wie oben dargelegt, vergleichen wir einfach frühere Tiefs mit dem fraktalen Tiefs davor und dann den Schlusskurs mit dem Hochs 2 Balken davor. Wir verfolgen den umgekehrten Weg bei einem Abwärts-Trend. Wie weit man in der Historie zurückgeht, kann der Leser selbst entscheiden.

Ein Vorwärtstest nach der Optimierung, wie bei den patterns-0 bis -5 für die Schwellen von Open und Close dieses Musters, liefert uns den folgenden Bericht:

r6

Ein fraktales Hoch (oder Tief), das von nachfolgenden Kerzen nicht überschritten wird, dient oft als Ablehnung. Dies ist ein starkes Signal für die Erschöpfung des Trends.



Fraktale Häufungen um gleitende Durchschnitte

Unser 8. Muster, pattern-7, kombiniert den fraktalen Indikator mit dem gleitenden Durchschnitt. Wenn sich eine Reihe von fraktalen Tiefs in der Nähe eines gleitenden Durchschnitts (z. B. 50-MA) bündelt, wird dies als Hinweis darauf gewertet, dass der gleitende Durchschnitt als starke Unterstützung fungiert. Diese fraktalen Tiefs bieten daher in der Regel Einstiegsmöglichkeiten für Käufer, und sobald der Kurs entscheidend über das nächstgelegene Widerstandsniveau oder sogar den gleitenden Durchschnitt selbst steigt, bestätigt dies die Aufwärtsthese.

Eine Abwärts-Formation liegt ebenfalls vor, wenn sich mehrere hohe Fraktale um den gleitenden Durchschnitt scharen, der zu diesem Zeitpunkt als Widerstand dient. Die wiederholte Ablehnung des Preises auf diesen Niveaus und eine entscheidende Bewegung unter die Unterstützung oder den MA, würde eine Abwärts-Tendenz bestätigen. Die Umsetzung in MQL5 sieht folgendermaßen aus:

//+------------------------------------------------------------------+
//| Check for Pattern 7.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_7(ENUM_POSITION_TYPE T)
{  CArrayDouble _buffer;
   if(T == POSITION_TYPE_BUY)
   {  for(int i = 1; i < m_periods; i++)
      {  if(FractalLow(X() + i) != 0.0)
         {  _buffer.Add(fabs(FractalLow(X() + i) - MA(X() + i)));
         }
      }
      if(_buffer[_buffer.Maximum(0, _buffer.Total())] <= fabs(Close(X() + 1) - Close(X() + m_periods)) && Close(X() + 1) <= MA(X() + 1) && Close(X()) > MA(X()))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL)
   {  for(int i = 1; i < m_periods; i++)
      {  if(FractalHigh(X() + i) != 0.0)
         {  _buffer.Add(fabs(FractalHigh(X() + i) - MA(X() + i)));
         }
      }
      if(_buffer[_buffer.Maximum(0, _buffer.Total())] <= fabs(Close(X() + 1) - Close(X() + m_periods)) && Close(X() + 1) >= MA(X() + 1) && Close(X()) < MA(X()))
      {  return(true);
      }
   }
   return(false);
}

pattern-7 verwendet wie pattern-2 und pattern-3 ebenfalls die Array-Klasse, aber dieses Mal, um die Größe des Abstands zwischen dem Fraktalpunkt und dem gleitenden Durchschnitt zu sichern. Wie oben dargelegt, suchen wir nach Situationen, in denen diese Lücke so klein wie möglich ist, und deshalb nehmen wir ihren maximalen Wert aus allen Lückenpunkten, die in den Puffer gehen. Wir vergleichen diese Größenordnung wiederum mit dem vorherrschenden Trend, sodass der Leser daran erinnert wird, Anpassungen vorzunehmen, wie bereits oben bei anderen Mustern wie Muster 6 erwähnt.

Das Vorwärtsgehen mit den Eingabeeinstellungen aus der Optimierung desselben Symbols, das in den obigen Mustern verwendet wurde, liefert uns den folgenden Bericht:

r7

Wenn sich viele Fraktale in der Nähe eines gleitenden Durchschnitts festsetzen, deutet dies auf eine Umkehr-Zone hin, wobei ein Ausbruch aus dem Anhäufung eine Fortsetzung oder Umkehr bestätigt.



Muster von Lücken der Fraktale

Bei pattern-8 liegt ein Aufwärtssignal vor, wenn sich ein tiefes Aufwärts-Fraktal in der Nähe einer Kurslücke befindet (in der Regel bei hoher Volatilität oder nachrichtengetriebener Kursentwicklung). In diesem Fall dient die Lücke als Unterstützungszone. Das Vorhandensein eines Fraktals nahe der Lücke wird dann so interpretiert, dass die Käufer diesen Bereich als Chance betrachten. Sobald die Lücke „gefüllt“ ist oder gehalten wird, ist eine Aufwärtsbewegung wahrscheinlich.

Eine Abwärts-Formation liegt auch vor, wenn das Hoch eines Abwärts-Fraktals in der Nähe oder an der Stelle einer Kurslücke erscheint, die sich nach oben geöffnet hat. In diesem Szenario würde die Lücke ein Widerstandsniveau darstellen. Das Vorhandensein des Fraktals würde darauf hindeuten, dass die Verkäufer das Niveau verteidigen, und sollte der Preis einen Abwärtstrend beginnen, wäre der Abwärtstrend festgeschrieben. Wir setzen dies in MQL5 wie folgt um:

//+------------------------------------------------------------------+
//| Check for Pattern 8.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_8(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalLow(X() + 2) != 0.0)
   {  if(Low(X() + 1) > High(X() + 2) && Close(X()) >= High(X() + 2))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 2) != 0.0)
   {  if(High(X() + 1) < Low(X() + 2) && Close(X()) <= Low(X() + 2))
      {  return(true);
      }
   }
   return(false);
}

Bei pattern-8 sind wir lediglich an einer Preislücke interessiert, sodass unsere obige Implementierung fast so einfach ist wie bei pattern-6.

Nachfolgend sehen Sie einen Vorwärtstest mit ähnlichen Symbol- und Testumgebungseinstellungen, wie wir sie oben für den 4-Stunden-Zeitrahmen USD JPY im Jahr 2023 hatten:

r8

Das Zusammentreffen von Kurslücken und fraktalen Ausbrüchen verstärkt immer die Kursbewegung. Diese Konstellationen sind jedoch häufiger bei nachrichtenorientierten Ereignissen anzutreffen.



Fraktale Ausrichtung mit Fibonacci-Levels

Unser letztes Muster kombiniert das Fraktal mit den Fibonacci-Levels. Eine Aufwärts-Ausrichtung entsteht, wenn ein tiefes Fraktal mit einem wichtigen Fibonacci-Rückfall-Level zusammenfällt. Dieses Zusammentreffen von fraktal identifizierter Unterstützung und dem Fibo-Level verstärkt die Stärke des Unterstützungsbereichs. Diese doppelte Bestätigung dient daher als robustes Aufwärtssignal, sollte der Kurs auf diesem Niveau halten. In der Regel könnte dies ein Signal für einen Abprall oder eine Trendfortsetzung sein.

Bei einer Abwärts-Formation steht das hohe Fraktal in einer Linie mit einem kritischen Fibonacci-Rückfall-Level. Diese Ausrichtung verstärkt dann den Widerstand an diesem Punkt. Gelingt es dem Kurs dann nicht, die Fibonacci-Zone zu durchbrechen, und kehrt er stattdessen von dieser Zusammenflusszone aus nach unten um, bestätigt dies ein Abwärtssignal. Beide Setups sind in MQL5 wie folgt kodiert:

//+------------------------------------------------------------------+
//| Check for Pattern 9.                                             |
//+------------------------------------------------------------------+
bool CSignalFractals::IsPattern_9(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && FractalLow(X()) != 0.0)
   {  if(Is_Fibo_Level(X()))
      {  return(true);
      }
   }
   else if(T == POSITION_TYPE_SELL && FractalHigh(X()) != 0.0)
   {  if(Is_Fibo_Level(X()))
      {  return(true);
      }
   }
   return(false);
}

Der Code für unser endgültiges Muster war etwas schwierig zu konzipieren, da das, was beim manuellen Handel immer offensichtlich und klar ist, bei der Automatisierung kaum der Fall ist. Wie würden wir Fibonacci-Levels „zeichnen“ und markieren? Wir entwickeln eine rudimentäre Funktion, die uns dabei helfen soll, und die wir „Is_Fibo_Level()“ nennen. Sein Code ist unten angegeben:

bool Is_Fibo_Level(int ind)
{  double _r=0.0;
   vector _h,_l;
   int _size = 3 * PeriodSeconds(PERIOD_MN1) / PeriodSeconds(m_period);
   _h.Init(_size);
   _l.Init(_size);
   if(_h.CopyRates(m_symbol.Name(),m_period,2,0,_size) && _l.CopyRates(m_symbol.Name(),m_period,4,0,_size))
   {  _r = _h.Max()-_l.Min();
      if(_l.Min()-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+ATR(ind))
      {  return(true);
      }
      else if(_l.Min()+(0.236*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.236*_r)+ATR(ind))
      {  return(true);
      }
      else if(_l.Min()+(0.382*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.382*_r)+ATR(ind))
      {  return(true);
      }
      else if(_l.Min()+(0.5*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.5*_r)+ATR(ind))
      {  return(true);
      }
      else if(_l.Min()+(0.618*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.618*_r)+ATR(ind))
      {  return(true);
      }
      else if(_h.Max()-ATR(ind) <= Close(ind) && Close(ind) <= _h.Max()+ATR(ind))
      {  return(true);
      }
   }
   return(false);
}

Mit dieser Funktion werden einfach die Preise der letzten 3 Monate abgerufen, ein willkürlicher Zeitraum, der natürlich nicht die wichtigsten Preisniveaus erfasst, wie es bei einer manuellen Einstellung der Fall wäre. Man sagt immer, dass der Beweis des Puddings im Essen liegt. Wenn wir uns also zu sehr darauf konzentrieren, wie wir die Dinge manuell sehen, muss sich das nicht unbedingt in der Handelsperformance niederschlagen. Deshalb entwickeln wir dies zu einem pattern-9, bei dem wir einfach nach einer Übereinstimmung zwischen fraktalen Punkten und Ebenen dieser Funktion suchen. Die ATR wird auch in einer sehr rudimentären Art und Weise verwendet, um festzulegen, wie breit unsere Niveaus sind, sodass in dem Fall, dass das 3-Monats-Fenster eine niedrige Volatilität aufweist, eine Menge Überschneidungen auftreten werden. Dies könnte dann ein Ausgangspunkt für den interessierten Leser sein, um Änderungen vorzunehmen.

Ein Vorwärtsgang, wie wir ihn bei den anderen fünf Mustern gemacht haben, ergibt diesen Bericht:

r9

Dieses Muster dient daher als Bestätigung der wichtigsten Umkehrzonen. In diesen Serien haben wir immer, wenn wir uns mit Mustern befasst haben, auch die Möglichkeit in Betracht gezogen, nicht nur ein Muster zu verwenden, wie es bisher bei allen 10 Mustern oben der Fall war, sondern alle Muster zusammen zu verwenden.



Kombinieren von Mustern

Der beigefügte Code für alle unsere 9 Muster liegt in Form einer nutzerdefinierten Signalklasse vor. Wir verwenden diese Klasse in einem MQL5-Assistenten, um Expert Advisors zusammenzustellen. Hier und hier gibt es Anleitungen, wie man das macht.  Die oben durchgeführten Einzelmusteroptimierungen und Testläufe basierten auf der Zuordnung der Eingabeparameter maps-used zu einem speziellen Index, der die Form 2 hoch dem Musterindex hat. Bei Muster 5 war dies also 2^5, was 32 ergibt, bei 7 war es 128, und so weiter. Beim Handel mit mehreren Mustern dient diese Eingabe jedoch eher als Zuordnung denn als Verweis auf ein bestimmtes Muster. Wir haben 9 Muster, also ist der maximale Wert unseres Parameters für genutzte Zuordnungen 2^9, was 512 minus eins ist (da wir bei Null anfangen zu zählen).

Wenn wir für die beste Kombination von Mustern auf Standardschwellen der Eröffnungen und Schlusskurse optimieren, sind unsere besten Eingabeeinstellungen wie folgt:

i_o

Ein Testlauf mit den Trainingsdaten ergibt den folgenden Bericht:

r_oll

c_oll

Der Vorwärtstest bis zum Jahr 2024 führt zu folgenden Ergebnissen:

r_oll_

c_oll_

Diese Ergebnisse sprechen meiner Meinung nach für das, was in früheren Artikeln hervorgehoben wurde, nämlich dass die Kombination von Mustern Expertenwissen seitens des Händlers erfordert. Er muss bei der Kombination von Mustern sehr genau sein. Er sollte keine Antworten aus Optimierungsläufen suchen. Wir haben oben einzelne Muster, die in Vorwärtstests funktionierten. Dies war ein 1-Jahres-Test, sodass längere Testzeiträume sicherlich gerechtfertigt sind, und wie immer lassen vergangene Leistungen nicht auf zukünftige Ergebnisse schließen. Dies zeigt jedoch, wie wichtig es ist, bei der Auswahl von Mustern für ein Zeichen einen zielgerichteten Ansatz zu verfolgen, anstatt den Durchschnitt auslaufen zu lassen.



Bedeutung des Zeitrahmens

Die fraktale Interpretation ist je nach dem verwendeten Zeitrahmen sehr subjektiv. Die höheren Zeitrahmen H4, Daily und Weekly liefern stärkere und zuverlässigere Signale, da sie dazu neigen, eine Menge Marktrauschen herauszufiltern. Fraktale auf diesen Zeitrahmen markieren oft wichtige Unterstützungs- und Widerstandsniveaus, die von Institutionen und langfristigen Händlern beachtet werden. Die generierten Signale bilden sich sehr langsam, was für viele Händler frustrierend sein kann, aber wenn sie gebildet werden, sind sie oft sehr vertrauenswürdige Setups.

Auf der anderen Seite erscheinen die niedrigeren Zeitrahmen von M15, M20 und M30 häufiger, können aber aufgrund kurzfristiger Preisschwankungen weniger zuverlässig sein. Sie eignen sich am besten für Scalping-Strategien, bei denen eine schnelle Reaktion besser belohnt wird. In der Regel sind sie jedoch anfälliger für falsche Ausbrüche und erfordern zusätzliche Filter zur Verbesserung der Genauigkeit.

Es gibt auch die mittleren Zeitrahmen H1 und H2, die auf dem Papier einen Kompromiss zwischen den beiden bieten sollten. Der Leser ist eingeladen, den Wahrheitsgehalt dieser Aussage zu überprüfen; die beste Praxis zeigt jedoch, dass sie gut funktionieren, wenn sie mit Fraktalen in höheren Zeiträumen kombiniert werden.



Schlussfolgerung

Fraktale tendieren dazu, sich auf Märkten mit hoher Liquidität und starkem institutionellen Interesse zu behaupten. Kursspitzen mit geringem Volumen führen zwangsläufig zu falschen Fraktalen, die schnell entkräftet werden. Deshalb können Volumenanalysen oder Footprint-Charts verwendet werden, um fraktalbasierte Entscheidungen zu untermauern.

Mit dieser sagte, wir haben 9 separate Muster dieses sehr Umkehr orientierten Indikator und während es hat große Nachteile auf kleineren Zeitrahmen, wenn geduldig an der größeren Zeitrahmen könnte es interessante Ergebnisse liefern, wie wir in der Lage gewesen, erfolgreiche Vorwärtstests über 1 Jahr auf einige der Muster durchzuführen.

Datei Beschreibung
SignalWZ_56.mqh Signalklassen-Datei
WZ_56.mq5 Expertendatei, die die enthaltenen Dateien vorstellt

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/17334

Beigefügte Dateien |
SignalWZ_56.mqh (23.11 KB)
WZ_56.mq5 (7.99 KB)
Installation von MetaTrader 5 und anderen MetaQuotes-Anwendungen auf HarmonyOS NEXT Installation von MetaTrader 5 und anderen MetaQuotes-Anwendungen auf HarmonyOS NEXT
Eine einfache Installation des MetaTrader 5 und andere MetaQuotes-Applikationen auf Geräten mit HarmonyOS NEXT mit DroiTong. Eine detaillierte Schritt-für-Schritt-Anleitung für Ihr Handy oder Ihren Laptop.
Analyse mehrerer Symbole mit Python und MQL5 (Teil 3): Dreieck der Wechselkurse Analyse mehrerer Symbole mit Python und MQL5 (Teil 3): Dreieck der Wechselkurse
Händler sehen sich oft mit Drawdowns aufgrund falscher Signale konfrontiert, während das Warten auf eine Bestätigung zu verpassten Chancen führen kann. In diesem Artikel wird eine dreieckige Handelsstrategie vorgestellt, die den Silberpreis in Dollar (XAGUSD) und Euro (XAGEUR) zusammen mit dem EURUSD-Wechselkurs verwendet, um das Rauschen herauszufiltern. Durch die Nutzung marktübergreifender Beziehungen können Händler versteckte Stimmungen aufdecken und ihre Eingaben in Echtzeit verfeinern.
Der Kalman-Filter für Forex-Strategien der Rückkehr zur Mitte Der Kalman-Filter für Forex-Strategien der Rückkehr zur Mitte
Der Kalman-Filter ist ein rekursiver Algorithmus, der im algorithmischen Handel verwendet wird, um den wahren Zustand einer Finanzzeitreihe durch Herausfiltern von Rauschen aus den Preisbewegungen zu schätzen. Er aktualisiert die Vorhersagen dynamisch auf der Grundlage neuer Marktdaten, was ihn für adaptive Strategien wie Mean Reversion wertvoll macht. In diesem Artikel wird zunächst der Kalman-Filter vorgestellt und seine Berechnung und Anwendung erläutert. Als nächstes wenden wir den Filter auf eine klassische Devisenstrategie, der Rückkehr zur Mitte, als Beispiel an. Schließlich führen wir verschiedene statistische Analysen durch, indem wir den Filter mit einem gleitenden Durchschnitt für verschiedene Devisenpaare vergleichen.
Handel mit dem MQL5 Wirtschaftskalender (Teil 6): Automatisierung des Handelseinstiegs mit der Analyse von Nachrichtenereignissen und Countdown-Timern Handel mit dem MQL5 Wirtschaftskalender (Teil 6): Automatisierung des Handelseinstiegs mit der Analyse von Nachrichtenereignissen und Countdown-Timern
In diesem Artikel implementieren wir einen automatischen Handelseinstieg mit dem MQL5-Wirtschaftskalender, indem wir nutzerdefinierte Filter und Zeitverschiebungen anwenden, um qualifizierte Nachrichtenereignisse zu identifizieren. Wir vergleichen die prognostizierten und die vorherigen Werte, um zu entscheiden, ob ein KAUF oder VERKAUF eröffnet werden soll. Dynamische Countdown-Timer zeigen die verbleibende Zeit bis zur Veröffentlichung von Nachrichten an und werden nach einem Handel automatisch zurückgesetzt.