Larry Williams Marktgeheimnisse (Teil 1): Aufbau eines Swing-Struktur-Indikators in MQL5
Einführung
Die Finanzmärkte bewegen sich in Wellen. Die Preise steigen und fallen jeden Tag, und diese Bewegungen können wichtige Umkehrpunkte (swing-points) markieren. Larry Williams erklärt, wie man diese Punkte auf einfache Weise mechanisch lesen kann. Mit diesem Verständnis können wir Instrumente entwickeln, die die Marktstruktur hervorheben und den Händlern helfen, zu entscheiden, wann sie in den Handel einsteigen oder ihn vermeiden sollten.
In diesem Artikel erstellen wir einen Marktstrukturindikator in MQL5. Es basiert auf den Ideen von Larry Williams über Marktschwankungen. Der Indikator erkennt kurzfristige Umkehrpunkte. Er unterteilt sie in mittel- und langfristige Punkte. So entsteht ein klares Bild der Preisentwicklung.
Dieser Artikel ist Teil einer größeren Serie über die Marktkonzepte von Larry Williams. In jedem Artikel dieser Reihe wird eine Idee nach der anderen untersucht und in praktische MQL5-Tools umgesetzt. Das macht das Lernen einfach und hilft Ihnen, der Logik Schritt für Schritt zu folgen.
Wer ist Larry Williams?
Larry Williams ist einer der angesehensten Namen im Handel. Er ist ein Aktien- und Rohstoffhändler mit einer langen Erfolgsgeschichte. Er ist auch Autor zahlreicher Handelsbücher. Eine seiner bekanntesten Veröffentlichungen ist „Long-Term Secrets to Short-Term Trading“ (Langfristige Geheimnisse für den kurzfristigen Handel). Viele Händler studieren dieses Buch wegen seiner praktischen Herangehensweise an die Marktstruktur und Umkehr-Analyse, die als Grundlage für diesen Artikel dient.
Larry Williams erlangte große Anerkennung, nachdem er 1987 den World Cup Championship of Futures Trading gewonnen hatte. In diesem Wettbewerb machte er innerhalb von zwölf Monaten aus zehntausend Dollar (10.000 $) mehr als eine Million Dollar (1.000.000 $). Dieser Rekord wurde seither noch nie gebrochen. Zehn Jahre später nahm seine Tochter Michelle Williams an demselben Wettbewerb teil und gewann ebenfalls. Dies zeigte, dass seine Ideen von anderen gelernt und erfolgreich angewendet werden konnten.
Seine Arbeit hat weiterhin Einfluss auf den modernen technischen Handel. Dies macht ihn zu einem perfekten Bezugspunkt für die Entwicklung strukturierter Instrumente wie dieses Marktstrukturindikators.
Die Logik der Williams-Marktstruktur verstehen
Die Marktstruktur, wie sie von Larry Williams gelehrt wird, basiert darauf, wie sich Preisschwankungen im Laufe der Zeit bilden. Diese Umkehrpunkte treten ganz natürlich auf, wenn sich der Markt nach oben und unten bewegt. Wenn wir diese Umkehrpunkte verstehen, können wir den Trend sicherer verfolgen und beurteilen, ob der Markt dreht oder sich weiterbewegt. Bei dieser Methode wird das Rätselraten durch einen einfachen mechanischen Rahmen ersetzt.
Larry Williams teilt die Umkehrpunkte in drei Gruppen ein. Dabei handelt es sich um kurzfristige, mittelfristige und langfristige Umkehrpunkte. Jede Gruppe baut auf der darunterliegenden auf, sodass wir sehen können, wie sich die Struktur Schicht für Schicht aufbaut. Mit ein paar Regeln können wir Charts auf eine saubere, organisierte Weise lesen.
Kurzfristige Umkehrpunkte
Ein kurzfristiger Umkehr entsteht, wenn der Kurs eine kleine Bewegung vollzieht und dann wieder in die entgegengesetzte Richtung dreht. Ein kurzfristiges Tief liegt beispielsweise vor, wenn der Kurs auf einen neuen Tiefstand fällt, nicht weiter sinkt und dann wieder steigt. Vereinfacht ausgedrückt, liegt der niedrigste Balken zwischen zwei Balken mit höheren Tiefs. Dies zeigt uns, dass die Abwärtsbewegung vorerst beendet ist.

Ein kurzfristiges Hoch bildet sich in umgekehrter Weise. Der Preis steigt bis zu einem Hoch, steigt dann nicht weiter an und fällt stattdessen. Das mittlere Hoch wird zu einem kurzfristigen Hoch, da die Balken auf beiden Seiten niedrigere Hochs aufweisen. Kurzfristige Umkehrpunkte markieren die kleinsten Umkehrpunkte, aber sie sind die Grundlage für alles, was wir später aufbauen.

Mittelfristige Umkehrpunkte
Wenn sich genügend kurzfristige Umkehrpunkte bilden, können wir einen Ausschlag der nächsten Stufe erkennen. Ein mittelfristiges Hoch ist ein kurzfristiges Hoch, das über zwei anderen kurzfristigen Hochs liegt.

Ebenso bildet sich ein mittelfristiges Tief, wenn auf ein kurzfristiges Tief höhere kurzfristige Tiefs auf beiden Seiten folgen.

Diese Umkehrpunkte stellen einen bedeutsameren Umkehrpunkt dar, weil sie bestätigen, dass der Kurs länger als eine normale kurzfristige Schwankung die Richtung geändert hat.
Durch diese Umkehrpunkte können wir leichte Störungen entfernen und die Struktur deutlicher erkennen. Das Chart beginnt Wellen zu bilden, die leichter zu verfolgen sind. Der Markt sieht nicht mehr zufällig aus, denn wir können eine Abfolge erkennen: Kurzfristige Hochs und Tiefs verbinden sich zu mittelfristigen Umkehrpunkten.
Langfristige Umkehrpunkte
Sobald sich mittelfristige Umkehrpunkte bilden, können wir eine Stufe höher gehen. Ein langfristiger Umkehrpunkt tritt auf, wenn ein mittelfristiger Umkehrpunkt über oder unter anderen mittelfristigen Umkehrpunkten in der Umgebung liegt. Ein langfristiges Hoch entsteht, wenn auf ein mittelfristiges Hoch kurzfristige Hochs auf beiden Seiten liegen.

Ein langfristiges Tief bildet sich, wenn die umgebenden mittelfristigen Tiefs darüber liegen.

Diese langfristigen Umkehrpunkte zeigen oft wichtige Umkehrpunkte auf dem Markt an.
Wenn alle drei Ebenen sichtbar sind, ähnelt das Chart einer Treppe. Zunächst bemerkt man kleine Schritte, die durch kurzfristige Umkehrpunkte entstehen. Mehrere von ihnen werden zu einem mittelfristigen Umkehrpunkt kombiniert. Und mehrere mittelfristige Umkehrpunkte bilden einen langfristigen Umkehrpunkt. Diese verschachtelte Struktur zeigt die Trendrichtung, die Trendstärke und mögliche Umkehrpunkte mit großer Klarheit. Deswegen konzentriert sich Larry Williams stark auf die Umkehr-Logik.
Indikator-Design und visuelle Struktur
Bevor wir einen Code schreiben, müssen wir verstehen, wie dieser Indikator aussieht, wenn er in ein Chart geladen wird. Ziel ist es nicht nur, die Marktstruktur zu erkennen, sondern sie auch in einer visuell aussagekräftigen und leicht lesbaren Form darzustellen. Händler sollten in der Lage sein, einen Blick auf den Chart zu werfen und Marktschwankungen sofort zu erkennen, ohne sich mit der Interpretation von Rohwerten oder versteckter Logik abmühen zu müssen.
Dieser Indikator zeigt drei verschiedene Ebenen der Marktstruktur an. Diese Ebenen werden unterschiedlich gezeichnet, damit der Händler sie ohne Verwirrung unterscheiden kann.
1. Kurzfristige Umkehrpunkte
Kurzfristige Umkehrpunkte werden mit einzelnen Kreisen markiert.

Dies sind die kurzfristigen Umkehrpunkte, die am häufigsten auftreten. Sie helfen uns, den Rhythmus des Marktes Schritt für Schritt zu lesen. Wenn der Indikator ein kurzfristiges Tief findet, platziert er einen Kreis unter der Kerze. Wenn er ein kurzfristiges Hoch erreicht, erscheint ein weiterer Kreis über der Kerze.
2. Mittelfristige Umkehrpunkte
Mittelfristige Umkehrpunkte entstehen aus kurzfristigen Umkehrpunkten. Sie sind aussagekräftiger, weil sie seltener auftreten und eine Verschiebung des Marktdrucks darstellen. Diese Punkte werden mit einem Doppelkreis markiert, einem kleineren Ring in einem größeren.

Der äußere Ring zeigt, dass sich ein Umkehrpunkt gebildet hat, während der innere Ring dessen Bedeutung bestätigt. Wenn ein Händler dieses Symbol sieht, weiß er, dass der Kurs mit mehr Momentum gedreht hat als bei einem typischen kurzfristigen Umkehrpunkt.
3. Langfristige Umkehrpunkte
Die letzte und entscheidende Kategorie ist der langfristige Umkehrpunkt. Dies sind die wichtigsten Umkehrpunkte, die den allgemeinen Trend bestimmen. Es mag dauern, bis sie sich bilden, aber wenn sie einmal da sind, sind sie am wichtigsten. Langfristige Hochs und Tiefs werden durch Pfeile markiert.

Ein Pfeil oberhalb des Kurses signalisiert einen starken, hohen Umkehrpunkt und eine mögliche Abwärtsbewegung. Ein Pfeil unterhalb des Kurses signalisiert ein starker, tiefer Umkehrpunkt und eine mögliche Aufwärtsbewegung. Wenn diese Pfeile erscheinen, heben sie sich deutlich ab und erregen sofortige Aufmerksamkeit.
Implementierung der Marktstrukturlogik in MQL5
In diesem Abschnitt beginnen wir mit der Umsetzung der Marktstrukturlogik in einen echten MQL5-Indikator. MQL5-Programme gibt es in vier Varianten: Skripte, Indikatoren, Expert Advisors und Dienstleistungen. Da unser Ziel darin besteht, Umkehrstrukturen auf dem Chart zu erkennen und zu zeichnen, werden wir dies als nutzerdefinierten Indikator implementieren.
Öffnen Sie zunächst MetaEditor 5, erstellen Sie eine neue Indikatordatei und benennen Sie sie:
larryWilliamsMarketStructureIndicator.mq5
Sobald die Datei erstellt ist, löschen Sie alles darin und fügen Sie den folgenden Startcode ein:
//+------------------------------------------------------------------+ //| larryWilliamsMarketStructureIndicator.mq5 | //| Copyright 2025, MetaQuotes Ltd. Developer is Chacha Ian | //| https://www.mql5.com/en/users/chachaian | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd. Developer is Chacha Ian" #property link "https://www.mql5.com/en/users/chachaian" #property version "1.00" //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int32_t rates_total, const int32_t prev_calculated, const datetime &time [], const double &open [], const double &high [], const double &low [], const double &close[], const long &tick_volume[], const long &volume[], const int32_t &spread[]) { //--- Return total bars processed return(rates_total); } //--- UTILITY FUNCTIONS //+------------------------------------------------------------------+
Aufschlüsseln des Codes
Im Folgenden wird erläutert, was die einzelnen Teile der Datei bedeuten und warum sie wichtig sind:
1. Datei Kopfzeilen
//+------------------------------------------------------------------+ //| larryWilliamsMarketStructureIndicator.mq5 | //| Copyright 2025, MetaQuotes Ltd. Developer is Chacha Ian | //| https://www.mql5.com/en/users/chachaian | //+------------------------------------------------------------------+
Der erste Kommentarblock am Anfang dient nur der Lesbarkeit. Sie enthält den Dateinamen, Angaben zum Autor und den Urheberrechtshinweis. Sie hat keinen Einfluss auf die Funktionsweise des Indikators – sie dokumentiert lediglich die Eigentumsverhältnisse.
2. Eigenschaftserklärungen
Die folgenden Zeilen mit #property legen Metadaten für den Indikator fest.
#property copyright "Copyright 2025, MetaQuotes Ltd. Developer is Chacha Ian" #property link "https://www.mql5.com/en/users/chachaian" #property version "1.00"
Hier werden das Copyright, der Link und die Versionsnummer angegeben. Weitere Eigenschaften werden später zu Regelkartenzeichnungen und Pufferplots hinzugefügt.
3. OnInit-Funktion
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ return(INIT_SUCCEEDED); }
Diese Funktion wird nur einmal ausgeführt, und zwar genau in dem Moment, in dem der Indikator startet. Wir werden diesen Abschnitt später verwenden, um Puffer zuzuweisen, Plots zu konfigurieren und Zeichenstile festzulegen. Für den Moment geben wir Erfolg zurück.
4. OnCalculate-Funktion
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int32_t rates_total, const int32_t prev_calculated, const datetime &time [], const double &open [], const double &high [], const double &low [], const double &close[], const long &tick_volume[], const long &volume[], const int32_t &spread[]) { //--- Return total bars processed return(rates_total); }
Diese Funktion wird jedes Mal ausgeführt, wenn der Chart aktualisiert wird oder sich eine neue Kerze bildet. Es empfängt Preis-Arrays (Open, High, Low, Close) und gibt die Anzahl der verarbeiteten Bars zurück. In Kürze werden wir hier die gesamte Logik zur Erkennung von Umkehrpunkten hinzufügen – kurz-, mittel- und langfristig.
5. Abschnitt Hilfsfunktionen
Am unteren Rand befindet sich ein Platzhalter für Hilfsfunktionen. Hier werden wir unsere Nutzenfunktionen unterbringen. Durch die Trennung von Hilfsfunktionen wird der Hauptcode sauberer und leichter lesbar.
Nun, da die Projektdatei vorhanden ist, müssen wir MetaTrader 5 mitteilen, wo unser Indikator erscheinen soll. Jeder Indikator muss angeben, ob er im Hauptpreischart oder in einem separaten Unterfenster angezeigt werden soll. Zu den Indikatoren in Unterfenstern gehören Instrumente wie RSI und MACD, während kursbasierte Indikatoren wie gleitende Durchschnitte in der Regel direkt auf dem Chart angezeigt werden.
In unserem Fall ist die Umkehrstruktur, die wir aufbauen, preisbasiert. Die Umkehrpunkte müssen mit den Kerzen übereinstimmen; daher müssen sie im Hauptfenster des Charts eingezeichnet werden. MQL5 ermöglicht es uns, dies mit einer einfachen Direktive zu spezifizieren.
Fügen Sie den folgenden Abschnitt direkt unter den Eigenschaftslinien am Anfang der Datei ein:
//+------------------------------------------------------------------+ //| Custom Indicator specific directives | //+------------------------------------------------------------------+ #property indicator_chart_window
Diese Zeile weist MetaTrader 5 an, die Ausgabe unseres Indikators im Hauptkerzenchart und nicht in einem separaten Unterfenster anzuzeigen. Sobald dies eingestellt ist, wird jedes grafische Element, das wir zeichnen, direkt an die Kursbalken angehängt, was genau das ist, was wir für die Identifizierung von Hochs und Tiefs der Umkehrpunkte wollen.
Nachdem der Anzeigeort festgelegt wurde, legen wir nun fest, wie umfangreich die Darstellung und wie viel Puffer unser Indikator verwenden soll. In MQL5 ist jede visuelle Ausgabe, die auf dem Chart gezeichnet wird, mit einem Indikatorpuffer verbunden. Ein Puffer ist ein Feld, in dem Kurswerte oder Signale gespeichert werden, die später als Formen oder Linien erscheinen. Die Anzahl der Darstellungen, die wir angeben, teilt MetaTrader 5 mit, wie viele unabhängige visuelle Elemente wir zu zeichnen beabsichtigen.
Für unseren Marktstrukturindikator gibt es sechs mögliche Umkehrpunkte, die jeweils mit einem eigenen Puffer versehen sind. Die sechs Umkehrpunkt-Typen, die wir aufspüren werden, sind:
- Kurzfristiges Tief
- Kurzfristiges Hoch
- Mittelfristiges Tief
- Mittelfristiges Hoch
- Langfristiges Tief
- Langfristiges Hoch
Jeder dieser Punkte wird separat in das Chart eingezeichnet. Da eine Darstellung einen Puffer benötigt, brauchen wir sechs Puffer und sechs Darstellungen. Wir fügen den folgenden Code unter den vorhandenen Eigenschaftsrichtlinien ein:
//+------------------------------------------------------------------+ //| Custom Indicator specific directives | //+------------------------------------------------------------------+ ... #property indicator_plots 6 #property indicator_buffers 6
Diese beiden Eigenschaften teilen MetaTrader 5 mit, dass der Indikator sechs grafische Ausgaben erzeugen wird und Speicher für sechs Puffer zum Speichern dieser Werte zugewiesen werden muss.
Nachdem wir nun die Gesamtzahl der Puffer festgelegt haben, die unser Indikator verwenden wird, besteht der nächste Schritt darin, die eigentlichen Speicherfelder zu deklarieren. Diese Arrays enthalten die Werte für die erste Kategorie von Umkehrpunkten: kurzfristige Hochs und kurzfristige Tiefs. Wir platzieren sie im globalen Bereich der Datei, sodass sie für den gesamten Indikator zugänglich sind. Fügen Sie die folgenden Zeilen direkt unter den Eigenschaftsanweisungen ein:
//+------------------------------------------------------------------+ //| Indicator buffers | //+------------------------------------------------------------------+ double shortTermLows []; double shortTermHighs[];
In diesem Stadium zeichnen die Arrays noch nichts. Sie dienen lediglich als Container für Umkehrpunkt-Werte.
Nachdem wir unsere Speicherfelder im globalen Bereich deklariert haben, besteht die nächste logische Aufgabe darin, sie als Indikatorpuffer zu registrieren. Dieser Schritt ermöglicht es MetaTrader 5, die Arrays als Teil des Darstellungssystems zu erkennen. Einmal registriert, können alle darin gespeicherten Werte in Echtzeit auf dem Chart dargestellt werden.
Wir führen diese Registrierung in der OnInit-Funktion mit SetIndexBuffer durch. Diese Funktion verknüpft ein bestimmtes Array mit einem Pufferindex innerhalb des Indikators. Die Plattform wird diese Verbindung später nutzen, um unsere Umkehrpunkte zu zeichnen.
Wir fügen den folgenden Code in die OnInit-Funktion ein:
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ //--- Bind arrays to indicator buffers SetIndexBuffer(0, shortTermLows, INDICATOR_DATA); SetIndexBuffer(1, shortTermHighs, INDICATOR_DATA); return(INIT_SUCCEEDED); }
Der nächste Schritt ist die Entwicklung eines Algorithmus, der die kurzfristigen Umkehrpunkte erkennt. Diese Logik wird in der Funktion OnCalculate untergebracht. Dies ist der Punkt, an dem der Indikator seine Arbeit tut. MetaTrader 5 ruft sie bei jeder Aktualisierung des Charts auf. Dazu gehören der Zeitpunkt, an dem Sie den Indikator zum ersten Mal anbringen, die Bildung einer neuen Kerze und das Eintreffen von Preis-Ticks.
Zwei Situationen sind besonders wichtig. Der erste ist der erste Lauf. Sie erkennen es, wenn prev_calculated gleich Null ist. Verwenden Sie diesen Fall, um den Indikator vorzubereiten. Initialisieren Sie z. B. Puffer, löschen Sie alle vorherigen Werte und füllen Sie historische Umkehrpunkte, wenn Sie beim Laden einen vollständigen Verlauf anzeigen lassen möchten.
Das zweite ist das Ereignis eines neuen Balkens. Dies ist der Fall, wenn prev_calculated kleiner ist als rates_total. In diesem Fall sollten Sie in der Lage sein, eine Logik zu implementieren, die einmal pro geschlossener Kerze ausgeführt wird. Dadurch wird verhindert, dass der Indikator bei jedem Tick wiederholt wird, und er bleibt effizient.
Könnten Sie nun Ihre OnCalculate-Funktion so aktualisieren, dass sie der unten gezeigten Struktur entspricht?
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int32_t rates_total, const int32_t prev_calculated, const datetime &time [], const double &open [], const double &high [], const double &low [], const double &close[], const long &tick_volume[], const long &volume[], const int32_t &spread[]) { //--- Start with clean buffers at first calculation if(prev_calculated == 0){ } //--- Recalculate structures only when a new bar is added if(prev_calculated < rates_total){ } //--- Return total bars processed return(rates_total); }
Wenn der Indikator zum ersten Mal gestartet wird, müssen wir sicherstellen, dass alle unsere Puffer mit sauberen Werten beginnen. Dadurch wird verhindert, dass die Arrays Datenreste enthalten, und es wird sichergestellt, dass nur tatsächlich vorhandene Umkehrpunkte angezeigt werden. Da Umkehrsignale nicht bei jedem Balken auftreten, ist es wichtig, mit leeren Puffern zu beginnen und diese während des Berechnungsprozesses mit neuen Werten zu füllen.
Um dies zu erreichen, fügen wir die Initialisierungslogik in den Block ein, die prüft, ob prev_calculated == 0 ist. Dieser Block wird nur einmal ausgeführt, wenn der Indikator zum ersten Mal an das Chart angehängt wird. Hier verwenden wir die Funktion ArrayInitialize, um beide Arrays mit EMPTY_VALUE zu füllen. EMPTY_VALUE ist ein spezieller Wert, der MetaTrader 5 anweist, für diesen Balken nichts zu zeichnen.
Aktualisieren Sie Ihren Code entsprechend der unten stehenden Struktur:
//--- Start with clean buffers at first calculation if(prev_calculated == 0){ ArrayInitialize(shortTermLows, EMPTY_VALUE); ArrayInitialize(shortTermHighs, EMPTY_VALUE); }
Dieser einfache Schritt bereitet den Indikator auf die nächste Phase vor, in der wir damit beginnen, kurzfristige Umkehrpunkte zu erkennen und aufzuzeichnen.
Erkennung von kurzfristigen Umkehrpunkte in OnCalculate
//--- Recalculate structures only when a new bar is added if(prev_calculated < rates_total){ ArrayInitialize(shortTermLows, EMPTY_VALUE); ArrayInitialize(shortTermHighs, EMPTY_VALUE); for(int32_t i = 1; i < rates_total - 2; i++){ //--- Identify a short-term low if(low[i] < low[i - 1] && low[i] < low[i + 1]){ shortTermLows[i] = low[i]; } //--- Identify a short-term high if(high[i] > high[i - 1] && high[i] > high[i + 1]){ shortTermHighs[i] = high[i]; } } }
Dieser Block wird ausgeführt, wenn der Indikator zum ersten Mal gestartet wird und wenn ein neuer Balken erscheint. Wir löschen die kurzfristigen Puffer und scannen dann den Kursverlauf, um kurzfristige Hochs und Tiefs zu ermitteln. Der Code verwendet eine einfache Regel aus drei Balken. Ein kurzfristiges Tief ist ein Balken, dessen Tief niedriger ist als das Tief des Balkens zu seiner Linken und niedriger als das Tief des Balkens zu seiner Rechten. Ein kurzfristiges Hoch ist das Gegenteil. Sein Hoch ist höher als das Hoch des linken Balkens und höher als das Hoch des rechten Balkens.
Im Folgenden wird erläutert, welche Aufgaben die einzelnen Teile haben und warum sie benötigt werden
ArrayInitialize(shortTermLows, EMPTY_VALUE); ArrayInitialize(shortTermHighs, EMPTY_VALUE);
Diese Aufrufe setzen beide Puffer auf leere Werte zurück. Die Konstante EMPTY_VALUE weist MetaTrader 5 an, für diesen Balken nichts anzuzeigen. Durch das Löschen der Felder wird sichergestellt, dass alte Markierungen nicht bestehen bleiben, sodass wir für den aktuellen Durchgang mit einer weißen Weste beginnen können.
for(int32_t i = 1; i < rates_total - 2; i++){ }
Die Schleife durchläuft jeden verwendbaren Balkenindex. Wir beginnen bei eins, weil wir einen linken Nachbarn bei Index i-1 brauchen. Wir enden vor den letzten Balken, sodass immer ein rechter Nachbar bei i+1 existiert. Dadurch wird verhindert, dass der Lesebereich überschritten wird und Fehler auftreten.
Innerhalb der Schleife wenden wir die Drei-Balken-Tests an.
if(low[i] < low[i - 1] && low[i] < low[i + 1]){ shortTermLows[i] = low[i]; }
Damit wird auf ein kurzfristiges Tief geprüft. Wenn die Bedingung erfüllt ist, schreiben wir das Tief in den Puffer shortTermLows bei Index i. Wenn wir einen echten Preis in den Puffer schreiben, wird das Symbol für diesen Balken dargestellt.
//--- Identify a short-term high if(high[i] > high[i - 1] && high[i] > high[i + 1]){ shortTermHighs[i] = high[i]; }
Damit wird ein kurzfristiges Hoch geprüft. Wenn dies der Fall ist, schreiben wir das Hoch in den Puffer shortTermHighs bei Index i. Wenn wir den Wert schreiben, zeigt das Chart den Höchstwert für diesen Balken an.
Durch die Neuinitialisierung und Neuberechnung, wenn sich eine neue Kerze bildet, spiegelt der Indikator die aktuelle Struktur wider. Ein Umkehrpunkt kann entstehen oder verschwinden, wenn neue Kursdaten eintreffen. Durch das Zurücksetzen der Puffer werden alle veralteten oder falschen Markierungen entfernt. Dadurch bleibt die sichtbare Struktur korrekt und konsistent.
Einrichten von grafischen Darstellungen für kurzfristige Umkehrpunkte
In diesem Stadium kann unser Indikator kurzfristige Hochs und Tiefs erkennen, und die Werte erscheinen bereits im Datenfenster. Wenn Sie den Indikator jedoch einem Preischart zuordnen, ist auf dem Chart noch nichts zu sehen. Das ist normal. In MQL5 wird ein Indikator erst sichtbar, nachdem wir eine oder mehrere grafische Darstellungen konfiguriert haben. Ein Plot teilt MetaTrader 5 mit, wie die in einem bestimmten Indikatorpuffer gespeicherten Daten dargestellt werden sollen. Ohne diesen Schritt weiß die Plattform nicht, welche Formen sie zeichnen soll und wie sie aussehen sollen.
Wir werden zwei Plots hinzufügen. Ein Plot zeigt die kurzfristigen Tiefs, das andere die kurzfristigen Hochs. Für beide Darstellungen wird ein kreisförmiges Wingdings-Symbol verwendet. Larry Williams beschreibt diese Punkte oft als „ringed swings“, sodass das kreisförmige Symbol perfekt dazu passt.
Sie können den folgenden Code in die OnInit-Funktion einfügen, direkt nach der Registrierung der Indikatorpuffer: Einrichten von grafischen Plots für kurzfristige Umkehrpunkte.
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... //--- Configure Graphic Plots PlotIndexSetInteger(0, PLOT_ARROW, 161); PlotIndexSetDouble (0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetString (0, PLOT_LABEL, "ShortTermLows"); PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_ARROW); PlotIndexSetInteger(1, PLOT_ARROW, 161); PlotIndexSetDouble (1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetString (1, PLOT_LABEL, "ShortTermHighs"); return(INIT_SUCCEEDED); }
Lassen Sie uns aufschlüsseln, was jede Zeile bewirkt.
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ARROW); ... PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_ARROW);
Damit wird der Zeichenstil festgelegt. Wir wählen DRAW_ARROW, weil die kreisförmigen Wingdings-Symbole zur Familie der Pfeile gehören. Auf diese Weise können wir einen kleinen Ring auf jeden Balken zeichnen, bei dem ein Umkehrpunkt auftritt.
PlotIndexSetInteger(0, PLOT_ARROW, 161); ... PlotIndexSetInteger(1, PLOT_ARROW, 161);
Hier wählen wir den Wingdings-Zeichencode. Code 161 ist ein kreisförmiges Symbol, das wie ein sauberer Ring auf dem Chart aussieht. Dies entspricht dem visuellen Stil, den Larry Williams für Umkehrpunkte verwendet.
PlotIndexSetDouble (0, PLOT_EMPTY_VALUE, EMPTY_VALUE); ... PlotIndexSetDouble (1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
Damit wird MetaTrader 5 mitgeteilt, das „nichts zu zeichnen“ ist. Da wir unbenutzte Balken mit EMPTY_VALUE initialisieren, wird der Indikator nur bei Balken ein Symbol zeichnen, bei denen wir einen echten Preis in den Puffer schreiben.
PlotIndexSetString (0, PLOT_LABEL, "ShortTermLows"); ... PlotIndexSetString (1, PLOT_LABEL, "ShortTermHighs");
Dadurch erhält jede Darstellung eine Bezeichnung. Diese Beschriftungen erscheinen im Datenfenster, sodass Sie leicht erkennen können, welche Serie welcher Art von Umkehrpunkt entspricht.
Um die Einrichtung zu vervollständigen, müssen wir auch das Erscheinungsbild des Plots mithilfe von Eigenschaftsanweisungen steuern. Fügen wir diese Zeilen direkt unter den bestehenden Direktiven von #property ein:
#property indicator_color1 clrGreen #property indicator_color2 clrBlack #property indicator_width1 1 #property indicator_width2 1
Diese Richtlinien haben folgende Funktion:
indicator_color1 und indicator_color2
Diese legen die Farben für die beiden Darstellungen fest. Die erste Farbe steht für kurzfristige Tiefs, die zweite für kurzfristige Hochs. Sie können diese später anpassen, wenn Sie ein anderes Farbschema wünschen.
indicator_width1 und indicator_width2
Damit wird die Dicke der gezeichneten Symbole festgelegt. Da wir runde Wingdings-Zeichen verwenden, sorgt die Breite 1 dafür, dass sie sauber und gut erkennbar sind.
Zu diesem Zeitpunkt verfügt der Indikator über eine grundlegende Erkennungslogik, Pufferregistrierung und Plot-Konfiguration. Es ist bereit für einen ersten Test. Speichern Sie Ihre Datei, drücken Sie in MetaEditor 5 auf Kompilieren und vergewissern Sie sich, dass keine Fehler aufgetreten sind. Dann fügen Sie den Indikator in ein beliebiges Chart ein. Verwenden Sie einen Zeitrahmen mit genügend Balken, z. B. täglich oder H1. Beobachten Sie nach dem Laden, wie kleine Kreise auf dem Chart erscheinen. Diese Kreise markieren die kurzfristigen Tiefs und Hochs der Umkehrpunkte. Blättern Sie durch die Historie oder warten Sie, bis sich ein neuer Balken bildet – Sie sollten sehen, dass die Umkehrpunkte automatisch aktualisiert werden. Damit wird die Dicke der gezeichneten Symbole festgelegt. Da wir runde Wingdings-Zeichen verwenden, sorgt die Breite 1 dafür, dass sie sauber und gut erkennbar sind.

Aufbau von mittelfristigen Umkehrpunkten
Da wir nun kurzfristige Umkehrpunkte erkennen können, besteht das nächste Ziel darin, daraus die mittelfristigen Umkehrpunkte zu bilden. Larry Williams lehrt, dass sich die Marktstruktur in Schichten bildet. Kurzfristige Umkehrpunkte bilden die Grundlage, aus denen sich größere Umkehrpunkte ableiten lassen, die ein deutlicheres Bild der Trendstärke vermitteln. Um diese nächste Phase zu unterstützen, deklarieren wir zunächst zwei weitere globale Arrays. Die eine speichert die Tiefs und die andere die Hochs der mittelfristigen Umkehrpunkte.
double intermediateTermLows []; double intermediateTermHighs[];
In der Funktion OnInit verknüpfen wir diese Arrays mit neuen Indizes der Indikatorpuffer, indem wir SetIndexBuffer aufrufen. Dies stellt sicher, dass MetaTrader 5 weiß, woher die Werte für diese Darstellungen kommen.
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... SetIndexBuffer(2, intermediateTermLows, INDICATOR_DATA); SetIndexBuffer(3, intermediateTermHighs, INDICATOR_DATA); ... return(INIT_SUCCEEDED); }
Sobald dies geschehen ist, können wir zwei kleine Nutzenfunktionen einführen. Ihr Zweck ist einfach. Wir scannen die kurzfristigen Umkehrpunkte, die wir bereits berechnet haben, und extrahieren nur die Punkte, die sich als mittelfristiger Umkehrpunkt qualifizieren.
//+------------------------------------------------------------------+ //| Build intermediate highs from short-term highs | //+------------------------------------------------------------------+ void BuildIntermediateHighs(const double &shortHighs[], const int32_t rates_total, double &intermediateHighs[]) { // ensure target array sized if(ArraySize(intermediateHighs) != rates_total) ArrayResize(intermediateHighs, rates_total); // clear intermediate buffer for(int32_t i = 0; i < rates_total; ++i) intermediateHighs[i] = EMPTY_VALUE; // collect indices of short-term highs int SH_idx[]; ArrayResize(SH_idx, 0); for(int32_t i = 0; i < rates_total; ++i) { if(shortHighs[i] != EMPTY_VALUE) { int newlen = ArraySize(SH_idx) + 1; ArrayResize(SH_idx, newlen); SH_idx[newlen - 1] = i; } } // compress: each short high with lower short highs on both sides becomes an intermediate high int count = ArraySize(SH_idx); if(count < 3) return; // need at least three short-highs for a middle one to qualify for(int k = 1; k < count - 1; ++k) { int prev_i = SH_idx[k - 1]; int cur_i = SH_idx[k]; int next_i = SH_idx[k + 1]; // strict comparison per Larry: current must be higher than neighbors if(shortHighs[cur_i] > shortHighs[prev_i] && shortHighs[cur_i] > shortHighs[next_i]) intermediateHighs[cur_i] = shortHighs[cur_i]; } } //+------------------------------------------------------------------+ //| Build intermediate lows from short-term lows | //+------------------------------------------------------------------+ void BuildIntermediateLows(const double &shortLows[], const int32_t rates_total, double &intermediateLows[]) { if(ArraySize(intermediateLows) != rates_total) ArrayResize(intermediateLows, rates_total); for(int32_t i = 0; i < rates_total; ++i) intermediateLows[i] = EMPTY_VALUE; int SL_idx[]; ArrayResize(SL_idx, 0); for(int32_t i = 0; i < rates_total; ++i) { if(shortLows[i] != EMPTY_VALUE) { int newlen = ArraySize(SL_idx) + 1; ArrayResize(SL_idx, newlen); SL_idx[newlen - 1] = i; } } int count = ArraySize(SL_idx); if(count < 3) return; for(int k = 1; k < count - 1; ++k) { int prev_i = SL_idx[k - 1]; int cur_i = SL_idx[k]; int next_i = SL_idx[k + 1]; // strict comparison: current low must be lower than neighbors if(shortLows[cur_i] < shortLows[prev_i] && shortLows[cur_i] < shortLows[next_i]) intermediateLows[cur_i] = shortLows[cur_i]; } }
Anhand der Funktion BuildIntermediateHighs wollen wir die Funktionsweise dieser Hilfsmittel erläutern. Die Funktion stellt zunächst sicher, dass das Zielarray genügend Platz hat, und leert es dann, indem sie es mit leeren Werten füllt. Anschließend durchläuft sie die kurzfristigen Hochs und sammelt die Balkenindizes, bei denen echte hohe Umkehrpunkte auftreten. Diese Indizes werden in einer kleinen temporären Liste gespeichert. Sobald wir diese Liste haben, prüft die Funktion jedes kurzfristige Hoch in der Mitte seiner Nachbarn. Ein Balken gilt nur dann als mittelfristige Umkehrpunkt, wenn sein Wert höher ist als der des kurzfristigen Hochs vor ihm und höher als der des Hochs nach ihm. Dies ist die klassische Drei-Punkte-Struktur. Eine linke Schulter, eine höhere mittelfristige Spitze und eine rechte Schulter, die niedriger ist. Wenn diese Bedingung erfüllt ist, wird der Wert in den Puffer für mittelfristige hohe Umkehrpunkte geschrieben.
Die Funktion zur Bildung von mittelfristiges Tief folgt den gleichen Schritten. Der einzige Unterschied besteht darin, dass sie auf Tiefstwerte statt auf Höchstwerte prüf. Während die eine Funktion also nach einem mittelfristigen Hoch sucht, sucht die andere nach einem mittelfristigen Tief. Abgesehen von diesem umgekehrten Vergleich ist die allgemeine Logik identisch.
Nach der Erstellung der Hilfsfunktionen, die mittelfristige Umkehrpunkte bilden, besteht der nächste Schritt darin, sie in den Arbeitsablauf des Indikators zu integrieren. Wie bei den kurzfristigen Puffern müssen auch die Puffer der mittelfristigen Umkehrpunkte in einem sauberen Zustand beginnen. Wir erreichen dies, indem wir sie beim ersten Start des Indikators im Chart auf EMPTY_VALUE initialisieren. Dies geschieht in der Funktion OnCalculate, in dem ausgeführten Abschnitt, wenn prev_calculated gleich Null ist.
//--- Start with clean buffers at first calculation if(prev_calculated == 0){ ... ArrayInitialize(intermediateTermLows, EMPTY_VALUE); ArrayInitialize(intermediateTermHighs, EMPTY_VALUE); }
Sobald die Initialisierung abgeschlossen ist, können wir die mittelfristigen Umkehrpunkte berechnen. Dies geschieht innerhalb des ausgeführten Blocks, wenn sich ein neuer Balken bildet oder wenn der Indikator zum ersten Mal geladen wird. Mit anderen Worten, dies geschieht, wenn prev_calculated kleiner ist als rates_total. Wir verwenden diesen Block bereits zur Berechnung der kurzfristigen Umkehrpunkte, also fügen wir unsere Funktionsaufrufe unterhalb dieses Abschnitts ein.
//--- Recalculate structures only when a new bar is added if(prev_calculated < rates_total){ ... BuildIntermediateLows(shortTermLows, rates_total, intermediateTermLows); BuildIntermediateHighs(shortTermHighs, rates_total, intermediateTermHighs); }
Diese beiden Aufrufe ermöglichen es dem Indikator, mittelfristige Umkehrpunkte direkt aus der aktualisierten kurzfristigen Struktur abzuleiten. Jedes Mal, wenn ein neuer Balken hinzugefügt wird, berechnet der Indikator zunächst die Basisschicht neu und wendet dann die zweite Schicht an. Auf diese Weise entsteht eine saubere und konsistente Hierarchie von Umkehrpunkten, die reibungslos aktualisiert wird, wenn sich der Markt bewegt.
Nachdem die Logik für den mittelfristigen Umkehrpunkt nun vollständig eingerichtet ist, besteht der nächste Schritt darin, diese Werte im Chart sichtbar zu machen. Die Berechnung allein ist nicht ausreichend. Genau wie bei den kurzfristigen Strukturen benötigen die mittelfristigen Umkehrpunkte eine eigene grafische Plot-Konfiguration innerhalb der OnInit-Funktion. Wir fügen die folgenden beiden Plot-Definitionen direkt unter den bestehenden kurzfristigen Plot-Einstellungen ein.
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_ARROW); PlotIndexSetInteger(2, PLOT_ARROW, 161); PlotIndexSetDouble (2, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetString (2, PLOT_LABEL, "intermediateTermLows"); PlotIndexSetInteger(3, PLOT_DRAW_TYPE, DRAW_ARROW); PlotIndexSetInteger(3, PLOT_ARROW, 161); PlotIndexSetDouble (3, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetString (3, PLOT_LABEL, "IntermediateTermHighs"); return(INIT_SUCCEEDED); }
Diese Zeilen folgen der gleichen Struktur wie die früheren Konfigurationen, sodass ihr Verhalten bereits bekannt sein sollte. Sie weisen das Terminal an, wie die in den mittelfristigen Puffern gespeicherten Werte zu zeichnen sind, wobei dasselbe kreisförmige Wingdings-Zeichen wie für die Kurzzeitpunkte verwendet wird. Der Unterschied wird deutlich, wenn wir die Anzeigeeigenschaften einführen.
Um dem Händler die visuelle Unterscheidung zwischen mittelfristigen und kurzfristigen Umkehrpunkten zu erleichtern, definieren wir eine zusätzliche Reihe von Eigenschaftsanweisungen:
#property indicator_color3 clrGreen #property indicator_color4 clrBlack #property indicator_width3 4 #property indicator_width4 4
Hier verwenden wir die gleichen Farben wie zuvor, vergrößern aber die Breite erheblich. Infolgedessen erscheinen die mittelfristigen Umkehrpunkte als größere, kreisförmige Markierungen. Wenn ein mittelfristiger Umkehrpunkt am gleichen Balken wie eine kurzfristige Umkehr auftritt, setzt sich der größere Kreis natürlich über den kleineren, wodurch ein Doppelringeffekt entsteht. Dies ist beabsichtigt und entspricht der Konvention von Larry Williams, dass höher gelegene Umkehrpunkte auf dem Chart visuell dominanter sind.
In diesem Stadium können Sie den Indikator neu kompilieren und ihn in ein beliebiges Chart einfügen, z. B. in den Stunden- oder Tageszeitrahmen. Wenn Sie alles richtig eingegeben haben, sollten Sie nun sowohl die kurzfristigen als auch die mittelfristigen Umkehrpunkte deutlich auf dem Bildschirm sehen. Dies ist ein guter Zeitpunkt, um sicherzustellen, dass Ihre Logik wie erwartet funktioniert und der Indikator die verschiedenen Ebenen der Marktstruktur korrekt identifiziert.

Aufbau langfristiger Umkehrpunkte
Nachdem die kurz- und mittelfristigen Strukturen bereits vorhanden sind, bilden die langfristigen Umkehrpunkte die letzte Ebene unserer Marktstrukturhierarchie. Diese langfristigen Umkehrpunkte werden aus den mittelfristigen Umkehrpunkten abgeleitet, so wie die mittelfristigen Umkehrpunkte aus den kurzfristigen Umkehrpunkten abgeleitet wurden. Da der Leser mit diesem Arbeitsablauf vertraut ist, werden wir uns nur auf die neuen Teile konzentrieren, die auf dieser Ebene eingeführt werden.
Wie zuvor beginnen wir mit der Deklaration von zwei Arrays im globalen Bereich. Diese Arrays enthalten die Werte der langfristigen Tiefs- und Hochs, die später auf ihre eigenen Indikatorpuffer abgebildet werden:
double longTermLows []; double longTermHighs[];
In der Funktion OnInit registrieren wir diese Arrays als Indikatorpuffer, damit das Terminal weiß, dass sie Plot-Daten enthalten werden:
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... SetIndexBuffer(4, longTermLows, INDICATOR_DATA); SetIndexBuffer(5, longTermHighs, INDICATOR_DATA); ... return(INIT_SUCCEEDED); }
Wenn der Indikator zum ersten Mal läuft, bereiten wir diese Puffer vor, indem wir sie innerhalb des Blocks prev_calculated == 0 mit EMPTY_VALUE füllen. Dadurch wird sichergestellt, dass nur die tatsächlichen langfristigen Umkehrpunkte aufgezeichnet werden:
//--- Start with clean buffers at first calculation if(prev_calculated == 0){ ... ArrayInitialize(longTermLows, EMPTY_VALUE); ArrayInitialize(longTermHighs, EMPTY_VALUE); }
Die Logik zur Ableitung der langfristigen Umkehrpunkte entspricht weitgehend dem, was wir bereits umgesetzt haben. Wir verwenden nach wie vor die gleichen Funktionen für die Ermittlung – BuildIntermediateLows und BuildIntermediateHighs. Der einzige Unterschied besteht darin, dass wir in dieser Phase keine kurzfristigen Umkehrpunkte, sondern mittelfristige Umkehrpunkte als Input verwenden. Dies ermöglicht es demselben Algorithmus, langfristige Pivots auf der nächsten Datenebene zu identifizieren. Innerhalb des Blocks, der die Neuberechnung durchführt, sehen die Aufrufe wie folgt aus:
//--- Recalculate structures only when a new bar is added if(prev_calculated < rates_total){ ... BuildIntermediateLows(intermediateTermLows, rates_total, longTermLows); BuildIntermediateHighs(intermediateTermHighs, rates_total, longTermHighs); }
Nachdem die langfristigen Umkehrpunkte berechnet wurden, muss als Nächstes ihr grafisches Erscheinungsbild konfiguriert werden. Diese Punkte sollten im Chart deutlich hervorgehoben werden. Daher verwenden wir keine kreisförmigen Wingdings (wie bei den kurzfristigen und mittelfristigen Umkehrpunkten), sondern Pfeilsymbole. Wir verschieben die Pfeile auch leicht über oder unter den Preis, damit sie sich nicht mit Kerzen oder früheren Umkehrpunkten überschneiden. Diese visuelle Trennung hilft dem Leser, langfristige Strukturen sofort von anderen zu unterscheiden.
In der Funktion OnInit konfigurieren Sie die Plots wie folgt:
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_ARROW); PlotIndexSetInteger(4, PLOT_ARROW, 233); PlotIndexSetInteger(4, PLOT_ARROW_SHIFT, +30); PlotIndexSetDouble (4, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetString (4, PLOT_LABEL, "LongTermHighs"); PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_ARROW); PlotIndexSetInteger(5, PLOT_ARROW, 234); PlotIndexSetInteger(5, PLOT_ARROW_SHIFT, -30); PlotIndexSetDouble (5, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetString (5, PLOT_LABEL, "LongTermHighs"); return(INIT_SUCCEEDED); }
Um die visuelle Konfiguration zu vervollständigen, fügen wir zwei weitere Direktiven #property hinzu, um Farben und Linienstärken zuzuweisen, die für langfristige Umkehrpunkte geeignet sind:
#property indicator_color5 clrGreen #property indicator_color6 clrBlack #property indicator_width5 2 #property indicator_width6 2
Bevor wir die Implementierung abschließen, gibt es noch eine weitere Verbesserung, die wir hinzufügen sollten. Da sich dieser Indikator stark auf die visuelle Interpretation der Umkehrpunkte stützt, ist es sehr hilfreich, wenn das Chart selbst sauber, konsistent und leicht zu lesen ist. Verschiedene Nutzer haben möglicherweise unterschiedliche Chartvorlagen geladen, und einige dieser Vorlagen – dunkle Themen, starke Gitternetzlinien, exotische Kerzenfarben – können die gezeichnete Umkehrstruktur schwer erkennbar machen.
Um sicherzustellen, dass der Indikator immer übersichtlich dargestellt wird, definieren wir eine kleine Hilfsfunktion, ConfigureChartAppearance.
//+------------------------------------------------------------------+ //| This function configures the chart's appearance. | //+------------------------------------------------------------------+ bool ConfigureChartAppearance() { if(!ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite)){ Print("Error while setting chart background, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_SHOW_GRID, false)){ Print("Error while setting chart grid, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_MODE, CHART_CANDLES)){ Print("Error while setting chart mode, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack)){ Print("Error while setting chart foreground, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrSeaGreen)){ Print("Error while setting bullish candles color, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBlack)){ Print("Error while setting bearish candles color, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CHART_UP, clrSeaGreen)){ Print("Error while setting bearish candles color, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrBlack)){ Print("Error while setting bearish candles color, ", GetLastError()); return false; } return true; }
Diese Funktion passt das Chart an ein einfaches, kontrastreiches Layout an, indem sie einen weißen Hintergrund einstellt, das Raster ausschaltet und einheitliche Vordergrund- und Kerzenfarben verwendet. Wir ändern hier keine Handelslogik; die Funktion standardisiert lediglich das Chart, sodass die Darstellungen der Umkehrpunkte sofort auffällt, wenn der Indikator geladen wird.
Sobald die Funktion definiert ist, rufen wir sie ganz am Anfang von OnInit auf.
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit(){ //--- To configure the chart's appearance if(!ConfigureChartAppearance()){ Print("Error while configuring chart appearance", GetLastError()); return INIT_FAILED; } ... }
Wenn die Konfiguration erfolgreich durchgeführt wurde, fährt der Indikator mit seiner normalen Initialisierung fort. Andernfalls wird ein Fehler gemeldet. Wenn Sie diesen Aufruf an den Anfang stellen, wird sichergestellt, dass das Chart vollständig vorbereitet ist, bevor irgendwelche Puffer oder Charts eingerichtet werden.
Mit dieser letzten Ergänzung berechnet der Indikator nicht nur zuverlässig die Struktur, sondern stellt sie auch in einem sauberen, professionellen visuellen Layout dar, sodass die zugrunde liegenden Umkehr-Levels auf einen Blick erkennbar sind.
Sie können den Indikator neu kompilieren und ihn dann in einem Chart starten. Wenn alle drei Ebenen implementiert sind, sollte die gesamte Umkehrstruktur – kurz-, mittel- und langfristig – nun auf einen Blick sichtbar und leicht zu erkennen sein.

Mit diesem letzten Schliff ist unser Indikator komplett. Alle Komponenten – von der Identifizierung kurzfristiger, mittelfristiger und langfristiger Umkehrpunkte bis hin zur Konfiguration des Charts für eine übersichtliche Visualisierung – sind nun vollständig implementiert. Um Ihnen die Arbeit zu erleichtern, haben wir den vollständigen Quellcode als „larryWilliamsMarketStructureIndicator.mq5“ beigefügt. Wenn Sie zu irgendeinem Zeitpunkt das Gefühl haben, dass etwas fehlt oder nicht wie erwartet funktioniert, vergleichen Sie Ihre Implementierung mit der beigefügten Referenzdatei.
Wie Sie den Indikator für Ihren Handel verwenden
Nachdem der Indikator nun voll funktionsfähig ist und kurzfristige und mittelfristige Umkehrpunkte auf dem Chart anzeigt, ist es wichtig zu erklären, wie ein Händler diese Informationen tatsächlich nutzen kann. Die Marktstruktur ist eines der wertvollsten Instrumente bei der Preisanalyse, und diese Umkehrpunkte helfen dem Händler, die Richtung des Marktes zu verstehen und zu erkennen, wo bedeutsame Verschiebungen stattfinden. Der Indikator generiert nicht von sich aus Kauf- oder Verkaufsaufträge. Stattdessen werden die Ebenen hervorgehoben, auf denen sich die Marktstruktur ändert, und der Händler kann diese Informationen in seinen allgemeinen Handelsansatz einbeziehen.
Ein Händler kann entweder mittelfristige Umkehrpunkte oder langfristige Umkehrpunkte als Grundlage für seine Entscheidungen verwenden. Die Idee ist einfach. Wenn sich ein mittelfristiges Tief bildet, deutet dies darauf hin, dass die Käufer in den Markt eingedrungen sind, um einen vorübergehenden Boden bei den Preisen zu schaffen. Ein Händler, der es vorzieht, dem Trend zu folgen, kann an diesem Punkt kaufen und halten, bis ein mittelfristiges Hoch die Struktur entkräftet. Die gleiche Logik gilt auch in umgekehrter Richtung. Wenn sich ein mittelfristiger hoher Umkehrpunkt bildet, kann dies ein Zeichen dafür sein, dass die Verkäufer eine Obergrenze erreicht haben. Ein Händler kann dann erwägen, eine Verkaufsposition einzugehen und in diesem Handel zu bleiben, bis ein neues mittelfristiges Tief erscheint.
Langfristige Umkehrpunkte können auf die gleiche Weise verwendet werden, liefern aber Signale, die seltener auftreten und breitere Verschiebungen in der Marktstruktur widerspiegeln. Dadurch eignen sie sich besser für Händler, die einen langsameren Handelsstil bevorzugen, oder für diejenigen, die auf höheren Zeitskalen arbeiten. Ein langfristiger tiefer Umkehrpunkt kann ein starkes Signal für eine potenzielle längere Aufwärtsphase sein, während ein langfristiger hoher Umkehrpunkt vor einer längeren Abwärtsbewegung warnen kann. Diese langfristigen Strukturen helfen Händlern, Positionen mit größerer Zuversicht zu halten, insbesondere wenn sie mit Trendfiltern oder Analysen auf höheren Zeitskalen kombiniert werden.
Der Indikator kann auch Entscheidungen des Handelsmanagements unterstützen, insbesondere in Bezug auf Ausstiege und die Platzierung von Stop-Loss. Wenn sich ein Händler beispielsweise in einer ausgedehnten Position befindet und der Kurs unter das vorherige mittelfristige Tief zurückgeht, kann dies darauf hindeuten, dass die Struktur durchbrochen wurde. In einem solchen Fall ist der Ausstieg aus dem Handel eine logische Entscheidung. In ähnlicher Weise kann eine Verkaufsposition geschlossen werden, wenn der Kurs über das vorherige mittelfristige Hoch klettert. Die Verwendung von Umkehrpunkten zur Verwaltung laufender Handelsgeschäfte hilft den Händlern, ihre Gewinne zu schützen und zu vermeiden, dass sie Positionen halten, wenn der Markt eindeutig gegen sie gerichtet ist.
Obwohl dieser Indikator wertvolle strukturbasierte Informationen liefert, sollte er immer als Ergänzung zu einem vollständigen Handelsplan verwendet werden. Umkehrpunkte allein reichen für eine konsistente Entscheidungsfindung nicht aus. Händler werden ermutigt, sie mit anderen Formen des Zusammenflusses zu kombinieren, z. B. mit der Trendrichtung, Liquiditätszonen, gleitenden Durchschnitten oder der Volumenanalyse. Ziel ist es, einen robusten Prozess aufzubauen, bei dem die Umkehrstruktur dazu beiträgt, das zu bestätigen, was der Händler bereits auf dem Markt sieht.
Zusammenfassend kann gesagt werden, dass dieser Indikator einen klaren und systematischen Weg zur Interpretation der Marktstruktur bietet. Er hebt Momentumverschiebungen hervor, hilft bei der Identifizierung von Trendfortsetzungs- und Trendumkehrpunkten und bietet einen unkomplizierten Ansatz für Ein- und Ausstiege. Bei richtiger Anwendung und in Kombination mit anderen zuverlässigen Instrumenten kann es die Fähigkeit eines Händlers, den Markt zu lesen und fundierte Entscheidungen zu treffen, erheblich verbessern.
Schlussfolgerung
Dieser Artikel zeigt, wie man die von Larry Williams in seinem Buch „Long-Term Secrets to Short-Term Trading“ vorgestellten Marktstrukturkonzepte in einen voll funktionsfähigen MQL5-Indikator umsetzt. Schritt für Schritt haben wir die Darstellungen entworfen, die Puffer vorbereitet und die Algorithmen entwickelt, die kurz- und mittelfristige Umkehrpunkte direkt aus den Kursdaten extrahieren. Das Endergebnis ist ein praktisches Instrument, das Händler auf ihren Charts platzieren können, um die Marktstruktur klar zu visualisieren.
Über den Indikator selbst hinaus hat der Leser praktische Erfahrungen mit den Kernkonzepten von MQL5 gesammelt, einschließlich Puffermanagement, Plotkonfiguration und strukturierter Indikatorlogik. Diese Fähigkeiten können als Ausgangspunkt für den Aufbau langfristiger Umkehrerkennungen, Warnungen, automatisierter Strategien oder anderer Verbesserungen dienen, die Sie hinzufügen möchten. Es handelt sich um ein reales Projekt mit einer realen Anwendung, das sowohl als Lernressource als auch als Grundlage für zukünftige Entwicklungen dienen soll.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/20511
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Implementierung von praktischen Modulen aus anderen Sprachen in MQL5 (Teil 06): Python-ähnliche Datei-IO-Operationen in MQL5
Erstellen von nutzerdefinierten Indikatoren in MQL5 (Teil 2): Bau eines RSI-Displays im Stil einer Messuhr mit Leinwand und Nadelmechanik
Eine alternative Log-datei mit der Verwendung der HTML und CSS
Datenwissenschaft und ML (Teil 47): Marktprognosen mithilfe des DeepAR-Modells in Python
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
können Sie auch Code für CRT UND ICT ALGO schreiben
können Sie auch Code für CRT UND ICT ALGO schreiben