English Русский 日本語
preview
Vom Neuling zum Experten: Programmieren von Kerzen

Vom Neuling zum Experten: Programmieren von Kerzen

MetaTrader 5Beispiele |
138 1
Clemence Benjamin
Clemence Benjamin

Inhalt



Einführung

Im Laufe der Zeit haben wir zahlreiche Kerzenmuster gelernt und auswendig gelernt. Sie mit dem Auge auf einer Karte zu erkennen, ist jedoch schwierig und kann durch Parallaxenfehler beeinträchtigt werden. Die Illusion einer Fehlinterpretation ist aufgrund der Art und Weise, wie die Logik von Kerzenmustern in der Regel definiert ist, sehr gut möglich.

Das Muster „Bullish Engulfing“ besteht beispielsweise aus einer Abwärtskerze, auf die eine Aufwärtskerze folgt. Die Aufwärtskerze öffnet unterhalb des Schlusskurses der Abwärtskerze und schließt oberhalb ihres Schlusskurses, wodurch der Körper der Abwärtskerze in einer Zeitreihe vollständig abgedeckt wird. Die Herausforderung besteht darin, die Position des Eröffnungskurses der Aufwärtskerze im Verhältnis zum Schlusskurs der Abwärtskerze richtig einzuschätzen. Das menschliche Auge neigt zu gelegentlichen Fehleinschätzungen, insbesondere bei der visuellen Analyse von Charts.

Stellen Sie sich nun vor, dieses Muster manuell anhand historischer Daten zu testen - das wäre schwierig und fehleranfällig. Wenn jedoch ein Algorithmus richtig kodiert ist, um diese Muster zu erkennen und strategische Markierungen auf dem Chart zu setzen, werden Identifizierung und die Backtests wesentlich einfacher und genauer.

Zweck dieses Artikels

In dieser Diskussion möchte ich die Programmierung von Kerzenmustern und die grundlegende Mathematik dahinter in MQL5 ermitteln und schließlich eine Kerzenmuster-Bibliothek entwickeln, die auf bereits vorhandenen Mustern aufbaut.

Viele Investment-Websites listen eine große Anzahl von Kerzenmustern in natürlicher Sprache auf, aber nur wenige gehen einen Schritt weiter und ermittle ihre algorithmische Struktur. Manch einer mag behaupten, dass alle möglichen Kerzenmuster bereits definiert worden sind. Ich glaube jedoch, dass es noch Raum für Innovationen gibt - neue Muster können entdeckt und benannt werden.

In dieser Diskussion werden wir einige bekannte Muster behandeln und Ihnen die Möglichkeit geben, jedes Kerzenmuster, das Sie auf einem Chart beobachten, zu kodieren und es auf Ihre eigene Weise zu benennen. Der Einfachheit halber werden wir uns zum besseren Verständnis auf gängige Muster konzentrieren.

Es ist wichtig zu erkennen, dass das Programmieren und Erfinden neuer Muster ein mühsamer Prozess sein kann, aber die Belohnung ist beträchtlich - die Entwicklung eines Algorithmus, der die Mustererkennung automatisiert, befreit Sie für immer von der wiederholten manuellen Analyse.

Was kommt als Nächstes?

Der nächste Abschnitt ist vollgepackt mit meinen Forschungsergebnissen und Schlüsselkonzepten, die ich zusammengestellt habe, um dieser Diskussion Struktur zu verleihen. Ich bin zuversichtlich, dass diese Lektüre für Sie von großem Nutzen sein wird. 



Verstehen der Kerzendaten und ihrer grundlegenden Programmiervorgänge

Ich gehe davon aus, dass Sie bereits mit den Grundlagen der Kerzenmuster aus verschiedenen Quellen, einschließlich der MQL5-Community, anderen Websites und Büchern, vertraut sind. Wenn Sie eine Auffrischung benötigen, können Sie sich unter diesem Link einige Hintergrundinformationen holen, bevor Sie fortfahren. Mein Ziel ist es nicht, das Rad neu zu erfinden, sondern zu zeigen, wie wir die MQL5-Sprache anwenden können, um die traditionelle Kerzen-Analyse in einen algorithmischen Rahmen zu übertragen. Dieser Ansatz hilft denjenigen, die Kerzenmuster konzeptionell verstehen, eine strukturiertere, algorithmische Denkweise zu entwickeln - was sie möglicherweise in die Lage versetzt, ihre eigenen Handelsstrategien in MQL5 zu automatisieren.

Für einen Anfänger ist es wichtig, mit einfachen Konzepten zu beginnen und seine Programmierkenntnisse schrittweise auszubauen. Beginnen wir mit der Definition von Aufwärts- und Abwärtskerze unter Verwendung grundlegender relationaler Operatoren. Sobald Sie mit diesen Vergleichen vertraut sind, können Sie zu Einzel-Kerzenmustern übergehen, indem Sie Rechenoperationen zum Messen von Körpergrößen und Dochtlängen integrieren. Nachdem wir die Analyse von Einzelkerzen gemeistert haben, fahren wir mit der Analyse von Mehrkerzenmustern fort, bei der wir darlegen, wie die Indexierung zu verwenden ist, um Daten von mehreren Kerzen zu vergleichen. Das Testen Ihrer Arbeit mit Funktionen wie Print() hilft Ihnen zu überprüfen, ob Ihre Logik wie erwartet funktioniert.

Ein kurzer Überblick: Kerzen sind ein visuelles Instrument, das beim Handel verwendet wird, um zu zeigen, wie sich die Kurse über einen bestimmten Zeitraum, z. B. eine Stunde oder einen Tag, bewegen. Jede Kerze wird durch vier Schlüsselpreise definiert: den Eröffnungskurs (der Preis zu Beginn der Zeitperiode), den Höchstkurs (der maximale Preis während der Zeitperiode), den Tiefstkurs (der minimale Preis) und den Schlusskurs (der Preis am Ende der Zeitperiode). Der Körper, „body“, der Kerze stellt die Spanne zwischen dem Eröffnungs- und dem Schlusskurs dar, während sich die Dochte oder Schatten („wicks” oder shadows) vom Körper zum Höchst- und Tiefstkurs erstrecken. Diese Struktur ermöglicht es Ihnen, die Marktstimmung schnell einzuschätzen. Wenn beispielsweise der Schlusskurs höher ist als der Eröffnungskurs, wird die Kerze als Aufwärtskerze betrachtet, was auf eine Aufwärtsdynamik hindeutet. Liegt der Schlusskurs dagegen unter dem Eröffnungskurs, ist er fallend und deutet auf einen Abwärtstrend hin.

Ich möchte Ihnen einige Schlüsselbegriffe vorstellen, die meiner Meinung nach für die Arbeit mit Zeitreihendaten unerlässlich sind. Diese Konzepte sind grundlegend für das Verständnis und die Implementierung der Kerzenmustererkennung in MQL5. Ich habe sie mit meinen eigenen Worten und auf der Grundlage meiner Recherchen erläutert, um eine klare und praktische Interpretation zu ermöglichen:

    1. Relationale Operatoren

    Dies sind Vergleichsoperatoren, ähnlich wie die Ungleichungen, die Sie vielleicht in der Schule gelernt haben. In MQL5 werden sie jedoch aus einer anderen Perspektive innerhalb der Programmierlogik angewendet. Sie werden in der MQL5-Dokumentation ausführlich erläutert, ebenso wie andere häufig verwendete Operationen. Im Folgenden finden Sie eine Liste der relationalen Operatoren, die wir in unserer Diskussion verwenden.

    • < (kleiner als)
    • > (größer als)
    • == (gleich)
    • != (ungleich)
    • <= (kleiner oder gleich)
    • >= (größer oder gleich)

    Es ist wichtig zu wissen, dass diese Operatoren nicht nur auf die Programmierung von Kerzenmustern beschränkt sind. Sie können auch zum Vergleich verschiedener Marktwerte verwendet werden und spielen eine entscheidende Rolle bei der Entscheidungsfindung im algorithmischen Handel.

    2. Kerzen-Index

    Bei Zeitreihendaten wird jede Kerzen (oder Balken) durch einen Index referenziert. Der jüngste Balken hat einen Index von 0, während ältere Balken mit aufsteigenden Indexwerten referenziert werden (z. B. 1, 2, 3 usw.). Dieses Verständnis hilft bei der korrekten Iteration durch historische Preisdaten.

    3. Zeitreihe

    Eine Zeitreihe ist ein spezieller Array-Typ, der zum Speichern historischer Preis- oder Indikatordaten verwendet wird, wobei die Indexierung umgekehrt ist. In einer Zeitreihe wird auf die neuesten Daten (z. B. den aktuellen oder jüngsten Balken) bei Index 0 zugegriffen, während ältere Daten bei höheren Indexnummern folgen.

    4. Average True Range (ATR)

    ATR ist ein Volatilitätsindikator, der dynamische Schwellenwerte für Kerzenmuster definiert und so die Anpassungsfähigkeit an die Marktbedingungen gewährleistet. Das Muster „Hammer“ beispielsweise erfordert einen kleinen Körper (weniger als 30 % der ATR) und einen unteren Docht, der mindestens doppelt so groß ist wie der Körper, was eine flexible Erkennung über verschiedene Vermögenswerte und Zeitrahmen hinweg ermöglicht.

    Die Herausforderung besteht darin zu definieren, was „klein“, „lang“ oder „groß“ bedeutet. Ein fester Wert (z. B. 10 Pips für einen kleinen Körper) funktioniert nicht konsistent für verschiedene Vermögenswerte oder Marktbedingungen. Eine Bewegung von 10 Pips kann für ein Paar mit geringer Volatilität wie EUR/USD auf einem 5-Minuten-Chart von Bedeutung sein, ist aber für ein volatiles Paar wie GBP/JPY auf einem Tages-Chart belanglos. Hier glänzt der ATR - er bietet einen dynamischen, volatilitätsangepassten Richtwert, der auf den Vermögenswert und den Zeitrahmen zugeschnitten ist.

    Durch die Verwendung des ATR werden die Bedingungen für die Erkennung von Kerzenmustern adaptiv:

    • Auf Märkten mit hoher Volatilität (hohe ATR) kann ein „kleiner Körper“ absolut gesehen größer sein, aber im Verhältnis zu den jüngsten Kursschwankungen immer noch klein.
    • Auf Märkten mit geringer Volatilität (niedrige ATR) kann selbst eine winzige absolute Bewegung als signifikant angesehen werden.

    5. MathAbs

    MathAbs ist eine integrierte Funktion in MQL5, die den Absolutwert einer Zahl berechnet. Der Absolutwert ist einfach der Abstand der Zahl von Null, der immer einen nicht-negativen (positiven oder Null) Wert ergibt.

    Wie es in diesem Zusammenhang funktioniert: 

    • Wenn Sie eine negative Zahl eingeben, wird diese in eine positive Zahl umgewandelt. MathAbs(-5) gibt zum Beispiel 5 zurück.
    • Wenn die Zahl bereits positiv oder Null ist, bleibt sie gleich. MathAbs(5) gibt zum Beispiel 5 zurück, MathAbs(0) 0.

    In einem Kerzenmuster wird MathAbs verwendet, um die Größe des Kerzenkörpers zu messen, d. h. die Differenz zwischen dem Schlusskurs (Close[1]) und dem Eröffnungskurs (Open[1]), d. h. Close[1] - Open[1].

    Warum MathAbs verwenden?

    1. Da die Körpergröße ein positiver Wert sein muss, ist es egal, ob es eine Aufwärts- (close > open) oder Abwärtskerze (close < open) ist. Zum Beispiel:

    • Aufwärtskerze: Close[1] = 10, open[1] = 8 → 10 - 8 = 2.
    • Abwärtskerze: Close[1] = 8, open[1] = 10 → 8 - 10 = -2, aber MathAbs(8 - 10) = 2.

    2. Dadurch wird sichergestellt, dass die Größe des Körpers immer positiv ist, um einen konsistenten Vergleich in den Musterregeln zu ermöglichen.

    Vergleichen von Preisen mit relationalen Operatoren in MQL5

    In MQL5 sind relationale Operatoren wichtige Hilfsmittel, mit denen Sie Werte vergleichen können, z. B. den Eröffnungs- und den Schlusskurs einer Kerze. Die oben erwähnten Operatoren <, >, ==, !=, <= und >= geben entweder wahr (1) oder falsch (0) zurück und helfen bei der Feststellung, ob es eine Auf- oder Abwärtskerze ist.

    Zum Beispiel,

    • Eine Aufwärtskerze wird identifiziert, wenn die Bedingung close[0] > open[0] erfüllt ist, wobei sich [0] auf den letzten Kerzenindex bezieht.

    Andererseits,

    • eine Abwärtskerze wird durch close[0] < open[0] angezeigt. 

    Dieser grundlegende Vergleich ist der Eckpfeiler der Kerzenmustererkennung. Betrachten Sie diese Vergleiche als einfache Fragen nach dem Preis: „Liegt der Schlusskurs der Kerze über ihrem Eröffnungskurs?“ Wenn ja, handelt es sich um ein Aufwärtssignal.

    Kerzenmuster

    Auf der Grundlage meiner Forschung können wir Kerzenmuster in zwei Haupttypen einteilen: einzelne Kerzenmuster und mehrere Kerzenmuster. Jetzt wird alles, was wir bisher besprochen haben, zusammenkommen. Zum besseren Verständnis wollen wir die beiden Begriffe kurz miteinander vergleichen. Ich habe zwei Tabellen mit detaillierten Informationen vorbereitet, um ihre Unterschiede hervorzuheben

    Einzel-Kerzenmuster

    Bei der Arbeit mit Einzel-Kerzenmustern sind arithmetische Operationen unerlässlich, um verschiedene Aspekte einer Kerze zu messen, z. B. die Größe des Körpers, die Länge des Dochts und den Gesamtbereich. Ein-Kerzenmuster, wie das Doji, das auftritt, wenn der Eröffnungs- und der Schlusskurs nahezu gleich sind, sind von Bedeutung, da sie Unentschlossenheit des Marktes oder potenzielle Umkehrungen signalisieren. Durch die Analyse der Unterschiede zwischen dem Eröffnungs-, Hoch, Tief und Schlusskurs können wir diese Muster ableiten und Einblicke in wichtige Marktveränderungen gewinnen.

    Doji-Kerze

    Kerzen-NameLogische BeschreibungReferenzbild
    DojiEin Doji-Kerzenmuster wird erkannt, wenn der Eröffnungs- und der Schlusskurs sehr nahe beieinander liegen oder gleich sind, was auf eine Unentschlossenheit des Marktes hinweist. Das bedeutet: open[1] ≈ close[1], wobei der Höchst- und der Tiefstkurs erheblich variieren können. Ein Doji kann in verschiedenen Formen auftreten, z. B. als Long-Legged Doji, Dragonfly Doji oder Gravestone Doji, abhängig von der Platzierung der Dochte.


    // Check for Doji pattern
    
    if( MathAbs(Open[1] - Close[1]) < Point * 2 ) 
    // Open and close are almost equal
    {
        Print("Doji pattern detected");
    }
    Doji

    Multi-Kerzenmuster

    Bei Multi-Kerzenmustern müssen wir die Beziehungen zwischen aufeinanderfolgenden Kerzen analysieren. In MQL5 verwenden wir die Indizierung, um auf vergangene Kerzen zu verweisen: close[1] steht für den Schlusskurs der vorherigen Kerze, während close[2] für die Kerze davor steht. Ein beliebtes Multi-Kerzenmuster ist das Bullish Engulfing, bei dem auf eine kleine Abwärtskerze eine größere Aufwärtskerze folgt, die die vorherige Kerze vollständig „verschlingt“.

    Um dieses Muster zu kodieren, müssen wir überprüfen, ob die vorherige Kerze eine Abwärtskerze ist (mit close[1] < open[1]), und dann überprüfen, ob die aktuelle Kerze eine Aufwärtskerze ist (mit close[0] > open[0]), während wir auch bestätigen, dass der Körper der aktuellen Kerze über die Grenzen der vorherigen Kerze hinausgeht. Die Bedingungen in unserem Code stellen sicher, dass das Muster den erwarteten Sequenz- und Größenverhältnissen folgt, was für die genaue Erkennung eines Aufwärts-Engulfing-Musters entscheidend ist.

    KerzenmusterLogische BeschreibungReferenzbild
    Bullish EngulfingDas Muster des „Bullish Engulfing“ liegt vor, wenn die Kerze bei Index 2 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h. Close[2] < Open[2]) und die Kerze bei Index 1 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h. Close[1] > Open[1]). Außerdem muss die Kerze bei Index 1 den Körper der Kerze bei Index 2 verschlingen, indem sie unter ihrem Schlusskurs öffnet (Open[1] < Close[2]) und über ihrem Open schließt (Close[1] > Open[2])


    // Check for bullish engulfing pattern
    if( Close[2] < Open[2] && // Candle at index 2 is bearish
        Close[1] > Open[1] && // Candle at index 1 is bullish
        Open[1] < Close[2] && // Candle at index 1 opens below candle at index 2 close
        Close[1] > Open[2] )  // Candle at index 1 closes above candle at index 2 open
    {
        Print("Bullish engulfing pattern detected");
    }

    Bullish engulfing


    Aufbau einer Sammlung bekannter Kerzenmuster und einer wiederverwendbaren Funktionsbibliothek für Kerzenmuster

    Um den Prozess zu vereinfachen, habe ich zwei Tabellen mit einer Sammlung bekannter Kerzenmuster zusammengestellt und eine umfassende Referenztabelle mit einer Beschreibungsspalte und einer Referenzbildspalte erstellt. Diese Tabelle wird sowohl während der Entwicklung als auch für künftige Leser als wertvolle Ressource dienen. Außerdem kann es im Laufe der Zeit durch neue Entdeckungen erweitert und verfeinert werden, was den Aufbau einer umfassenderen und anspruchsvolleren Kerzenmuster-Bibliothek erleichtert.

    Sammlung von Einzel-Kerzenmustern

    KerzenmusterLogische BeschreibungReferenzbild
    HammerDas Muster „Hammer“ wird identifiziert, wenn die Kerze bei Index 1 einen kleinen Körper (die absolute Differenz zwischen Close und Open ist kleiner als das 0,3-fache der ATR, d.h. MathAbs(Close[1] - Open[1]) < 0,3 * ATR), einen langen unteren Docht (der Abstand vom unteren von Open oder Close zum Low ist mindestens doppelt so groß wie der Körper, d.h., MathMin(Open[1], Close[1]) - Low[1] >= 2 * MathAbs(Close[1] - Open[1])), und ein kleiner oder kein oberer Docht (der Abstand vom höheren Open oder Close zum High ist kleiner oder gleich der halben Körpergröße, d.h. High[1] - MathMax(Open[1], Close[1]) <= 0,5 * MathAbs(Close[1] - Open[1]))


    // Check for Hammer pattern
    if( MathAbs(Close[1] - Open[1]) < 0.3 * ATR[1] &&     // Small body
    // Long lower wick
        (MathMin(Open[1], Close[1]) - Low[1]) >= 2 * MathAbs(Close[1] - Open[1]) && 
    // Small or no upper wick
        (High[1] - MathMax(Open[1], Close[1]) <= 0.5 * MathAbs(Close[1] - Open[1])) 
    {
        Print("Hammer pattern detected");
    }

    Hammer
    Shooting StarDas Muster „Shooting Star“ wird erkannt, wenn die Kerze bei Index 1 einen kleinen Körper (die absolute Differenz zwischen Close und Open ist kleiner als das 0,3-fache der ATR, d.h. MathAbs(Close[1] - Open[1]) < 0,3 * ATR), einen langen oberen Docht (der Abstand vom höheren Open oder Close zum High ist mindestens doppelt so groß wie der Körper, d.h., High[1] - MathMax(Open[1], Close[1]) >= 2 * MathAbs(Close[1] - Open[1])) und ein kleiner oder kein unterer Docht (der Abstand vom unteren Open- oder Close-Wert zum Low-Wert ist kleiner oder gleich der halben Körper-Größe, d. h. MathMin(Open[1], Close[1]) - Low[1] <= 0,5 * MathAbs(Close[1] - Open[1]))


    // Check for Shooting Star pattern
    if( MathAbs(Close[1] - Open[1]) < 0.3 * ATR[1] &&     // Small body
     // Long upper wick
        (High[1] - MathMax(Open[1], Close[1]) >= 2 * MathAbs(Close[1] - Open[1]) &&    
    // Small or no lower wick
        (MathMin(Open[1], Close[1]) - Low[1]) <= 0.5 * MathAbs(Close[1] - Open[1]) ) 
    {    
        Print("Shooting Star pattern detected");
    }

    Shooting Star
    Standard-DojiDas Muster „Standard-Doji“ wird identifiziert, wenn die Kerze bei Index 1 einen minimalen Körper hat, d.h., dass der Eröffnungs- und der Schlusskurs fast gleich sind (die absolute Differenz zwischen dem Schlusskurs und dem Eröffnungskurs ist kleiner als das 0,1-fache der ATR, d.h. MathAbs(Close[1] - Open[1]) < 0,1 * ATR)


    // Check for Standard Doji pattern
    if( MathAbs(Close[1] - Open[1]) < 0.1 * ATR[1] )     // Open and close are nearly equal
    {
        Print("Standard Doji pattern detected");
    }

    Dragonfly DojiDas Muster „Dragonfly Doji“ wird identifiziert, wenn die Kerze bei Index 1 einen kleinen Körper (die absolute Differenz zwischen dem Schlusskurs und dem Eröffnungskurs ist kleiner als das 0,1-fache der ATR, d.h. MathAbs(Close[1] - Open[1]) < 0,1 * ATR), einen langen unteren Docht (der Abstand vom niedrigeren Eröffnungs- oder Schlusskurs zum Tief ist größer als das 0,5-fache der ATR, d.h., MathMin(Open[1], Close[1]) - Low[1] > 0,5 * ATR), und wenig bis kein oberer Docht (der Abstand vom höheren Open oder Close zum High ist kleiner als das 0,1-fache der ATR, d.h. High[1] - MathMax(Open[1], Close[1]) < 0,1 * ATR)


    // Check for Dragonfly Doji pattern
    if( MathAbs(Close[1] - Open[1]) < 0.1 * ATR[1] &&     // Small body
        (MathMin(Open[1], Close[1]) - Low[1]) > 0.5 * ATR[1] &&     // Long lower wick
        (High[1] - MathMax(Open[1], Close[1]) < 0.1 * ATR[1] )     // Little to no upper wick
    {
        Print("Dragonfly Doji pattern detected");
    }

    Gravestone DojiDas Muster „Gravestone Doji“ wird identifiziert, wenn die Kerze bei Index 1 einen kleinen Körper hat (die absolute Differenz zwischen dem Schlusskurs und dem Eröffnungskurs ist kleiner als das 0,1-fache der ATR, d.h. MathAbs(Close[1] - Open[1]) < 0,1 * ATR), einen langen oberen Docht (der Abstand zwischen dem höheren Eröffnungs- oder Schlusskurs und dem Hoch ist größer als das 0,5-fache der ATR, d.h., High[1] - MathMax(Open[1], Close[1]) > 0,5 * ATR), und wenig bis gar kein unterer Docht (der Abstand vom niedrigeren Wert von Open oder Close zum Low ist kleiner als das 0,1-fache der ATR, d. h. MathMin(Open[1], Close[1]) - Low[1] < 0,1 * ATR)


    // Check for Gravestone Doji pattern
    if( MathAbs(Close[1] - Open[1]) < 0.1 * ATR[1] &&     // Small body
        (High[1] - MathMax(Open[1], Close[1]) > 0.5 * ATR[1] &&     // Long upper wick
        (MathMin(Open[1], Close[1]) - Low[1]) < 0.1 * ATR[1] )     // Little to no lower wick
    {
        Print("Gravestone Doji pattern detected");
    }

    Gravestone
    Bullish MarubozuDas Muster „Bullish-Marubozu“ liegt vor, wenn die Kerze bei Index 1 stark steigend ist (der Schlusskurs ist höher als der Eröffnungskurs, d. h. Close[1] > Open[1]) und fast keine Dochte aufweist, d. h. der Eröffnungskurs liegt sehr nahe am Tief (Open[1] - Low[1] < 0,1 * ATR) und der Schlusskurs sehr nahe am Hoch (High[1] - Close[1] < 0,1 * ATR).


    // Check for Bullish Marubozu pattern
    if( Close[1] > Open[1] &&     // Bullish candle
        (High[1] - Close[1]) < 0.1 * ATR[1] &&     // Close is very close to high
        (Open[1] - Low[1]) < 0.1 * ATR[1] )     // Open is very close to low
    {
        Print("Bullish Marubozu pattern detected");
    }

    Bullish Marubozu
    Bearish MarubozuDas Muster „Bearish Marubozu“ wird erkannt, wenn die Kerze bei Index 1 eine starke Abwärtskerze ist (der Schlusskurs ist niedriger als der Eröffnungskurs, d.h. Close[1] < Open[1]) und fast keine Dochte aufweist, d.h. der Eröffnungskurs liegt sehr nahe am Hochkurs (High[1] - Open[1] < 0,1 * ATR) und der Schlusskurs liegt sehr nahe am Tiefkurs (Close[1] - Low[1] < 0,1 * ATR)


    // Check for Bearish Marubozu pattern
    if( Close[1] < Open[1] &&     // Bearish candle
        (High[1] - Open[1]) < 0.1 * ATR[1] &&     // Open is very close to high
        (Close[1] - Low[1]) < 0.1 * ATR[1] )     // Close is very close to low
    {
        Print("Bearish Marubozu pattern detected");
    }

    Bearish Marubozu
    Spinning TopDas Muster „Spinning Top“ wird identifiziert, wenn die Kerze bei Index 1 einen kleinen Körper (die absolute Differenz zwischen ihrem Schlusskurs und ihrem Eröffnungskurs ist kleiner als das 0,3-fache der ATR, d.h. MathAbs(Close[1] - Open[1]) < 0,3 * ATR) und lange obere und untere Dochte (der Abstand vom höheren Eröffnungs- oder Schlusskurs zum Hoch ist größer als das 0,5-fache der ATR, d.h., High[1] - MathMax(Open[1], Close[1]) > 0,5 * ATR, und der Abstand vom Lower von Open oder Close zum Low ist größer als das 0,5-fache der ATR, d.h. MathMin(Open[1], Close[1]) - Low[1] > 0,5 * ATR)


    // Check for Spinning Top pattern
    if( MathAbs(Close[1] - Open[1]) < 0.3 * ATR[1] &&     // Small body
        (High[1] - MathMax(Open[1], Close[1]) > 0.5 * ATR[1] &&     // Long upper wick
        (MathMin(Open[1], Close[1]) - Low[1]) > 0.5 * ATR[1] )     // Long lower wick
    {
        Print("Spinning Top pattern detected");
    }

    Spinning Top

    Sammlung von Multi-Kerzenmustern

    KerzenmusterLogische BeschreibungReferenzbild
    Morning StarDas Muster des „Morning Star“ wird erkannt, wenn die Kerze bei Index 3 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h. Close[3] < Open[3]), die Kerze bei Index 2 einen kleinen Körper hat (die absolute Differenz zwischen ihrem Schlusskurs und ihrem Eröffnungskurs ist kleiner als das 0,3-fache der ATR, d.h., MathAbs(Close[2] - Open[2]) < 0.3 * ATR), und die Kerze bei Index 1 eine Aufwärtskerze ist (ihr Close ist höher als ihr Open, d.h. Close[1] > Open[1]). Zusätzlich muss der Schlusskurs der Kerze 1 über dem Mittelpunkt der Kerze 3 liegen (Close[1] > (Open[3] + Close[3]) / 2)


    // Check for Morning Star pattern
    if( Close[3] < Open[3] &&     // Candle at index 3 is bearish
        MathAbs(Close[2] - Open[2]) < 0.3 * ATR[1] && // Candle at index 2 has a small body
        Close[1] > Open[1] &&     // Candle at index 1 is bullish
        Close[1] > (Open[3] + Close[3]) / 2 ) // Candle at index 1 closes above midpoint of candle 3
    {
        Print("Morning Star pattern detected");
    }

    Morgenstern
    Evening StarDas Muster des „Evening Star“ wird erkannt, wenn die Kerze bei Index 3 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h. Close[3] > Open[3]), die Kerze bei Index 2 einen kleinen Körper hat (die absolute Differenz zwischen ihrem Schlusskurs und ihrem Eröffnungskurs ist kleiner als das 0,3-fache der ATR, d.h., MathAbs(Close[2] - Open[2]) < 0,3 * ATR), und die Kerze bei Index 1 ist eine Abwärtskerze (ihr Close ist niedriger als ihr Open, d.h. Close[1] < Open[1]). Zusätzlich muss der Schluss der Kerze 1 unter dem Mittelpunkt der Kerze 3 liegen (Close[1] < (Open[3] + Close[3]) / 2)


    // Check for Evening Star pattern
    if( Close[3] > Open[3] &&     // Candle at index 3 is bullish
        MathAbs(Close[2] - Open[2]) < 0.3 * ATR[1] && // Candle at index 2 has a small body
        Close[1] < Open[1] &&     // Candle at index 1 is bearish
        Close[1] < (Open[3] + Close[3]) / 2 ) // Candle at index 1 closes below midpoint of candle 3
    {
        Print("Evening Star pattern detected");
    }

    Three White SoldiersDas Muster der „Three White Soldiers)“ wird erkannt, wenn drei aufeinanderfolgende Aufwärtskerzen auftreten: Kerze bei Index 3 (Close[3] > Open[3]), Kerze bei Index 2 (Close[2] > Open[2]) und Kerze bei Index 1 (Close[1] > Open[1]). Der Körper jeder Kerze muss größer als die ATR sein (z.B. Close[3] - Open[3] > ATR), kleine obere Dochte haben (z.B. High[3] - Close[3] < 0,3 * ATR) und jede Kerze muss innerhalb des Körpers der vorherigen Kerze öffnen (z.B. Open[2] > Open[3] && Open[2] < Close[3])


    // Check for Three White Soldiers pattern
    // Candle 3 is bullish with large body and small upper wick
    if( Close[3] > Open[3] && (Close[3] - Open[3]) > ATR[1] && (High[3] - Close[3]) < 0.3 * ATR[1] &&  
     // Candle 2 is bullish with large body and small upper wick  
        Close[2] > Open[2] && (Close[2] - Open[2]) > ATR[1] && (High[2] - Close[2]) < 0.3 * ATR[1] &&    
     // Candle 1 is bullish with large body and small upper wick
        Close[1] > Open[1] && (Close[1] - Open[1]) > ATR[1] && (High[1] - Close[1]) < 0.3 * ATR[1] && 
    // Candle 2 opens within candle 3's body and closes higher   
        Open[2] > Open[3] && Open[2] < Close[3] && Close[2] > Close[3] &&  
    // Candle 1 opens within candle 2's body and closes higher   
        Open[1] > Open[2] && Open[1] < Close[2] && Close[1] > Close[2] )     
    {
        Print("Three White Soldiers pattern detected");
    }

    Three Black CrowsDas Muster der „Three Black Crows“ wird erkannt, wenn drei aufeinanderfolgende Abwärtskerzen auftreten: Kerze bei Index 3 (Close[3] < Open[3]), Kerze bei Index 2 (Close[2] < Open[2]) und Kerze bei Index 1 (Close[1] < Open[1]). Der Körper jeder Kerze muss größer als die ATR sein (z.B. Open[3] - Close[3] > ATR), kleine untere Dochte haben (z.B. Open[3] - Low[3] < 0,3 * ATR) und jede Kerze muss innerhalb des Körpers der vorherigen Kerze öffnen (z.B. Open[2] < Open[3] && Open[2] > Close[3])


    // Check for Three Black Crows pattern
     // Candle 3 is bearish with large body and small lower wick
    if( Close[3] < Open[3] && (Open[3] - Close[3]) > ATR[1] && (Open[3] - Low[3]) < 0.3 * ATR[1] &&   
     // Candle 2 is bearish with large body and small lower wick
        Close[2] < Open[2] && (Open[2] - Close[2]) > ATR[1] && (Open[2] - Low[2]) < 0.3 * ATR[1] &&  
       // Candle 1 is bearish with large body and small lower wick
        Close[1] < Open[1] && (Open[1] - Close[1]) > ATR[1] && (Open[1] - Low[1]) < 0.3 * ATR[1] && 
    // Candle 2 opens within candle 3's body and closes lower  
        Open[2] < Open[3] && Open[2] > Close[3] && Close[2] < Close[3] && 
    // Candle 1 opens within candle 2's body and closes lower    
        Open[1] < Open[2] && Open[1] > Close[2] && Close[1] < Close[2] )     
    {
        Print("Three Black Crows pattern detected");
    }

    Bullish HaramiDas Muster „Bullish Harami“ wird identifiziert, wenn die Kerze bei Index 2 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h. Close[2] < Open[2]) mit einem Körper, der größer ist als die ATR (Open[2] - Close[2] > ATR), und die Kerze bei Index 1 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h., Close[1] > Open[1]) und ihr Körper liegt vollständig innerhalb des Körpers von Kerze 2 (Open[1] > Close[2] && Close[1] < Open[2])


    // Check for Bullish Harami pattern
    // Candle 2 is bearish with large body
    if( Close[2] < Open[2] && (Open[2] - Close[2]) > ATR[1] && 
    // Candle 1 is bullish and within candle 2's body    
        Close[1] > Open[1] && Open[1] > Close[2] && Close[1] < Open[2] )     
    {
        Print("Bullish Harami pattern detected");
    }

    Bearish HaramiDas Muster „Bearish Harami“ wird identifiziert, wenn die Kerze bei Index 2 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h. Close[2] > Open[2]) mit einem Körper, der größer ist als die ATR (Close[2] - Open[2] > ATR), und die Kerze bei Index 1 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h., Close[1] < Open[1]) und ihr Körper liegt vollständig innerhalb des Körpers von Kerze 2 (Open[1] < Close[2] && Close[1] > Open[2])


    // Check for Bearish Harami pattern
    // Candle 2 is bullish with large body
    if( Close[2] > Open[2] && (Close[2] - Open[2]) > ATR[1] &&  
    // Candle 1 is bearish and within candle 2's body   
        Close[1] < Open[1] && Open[1] < Close[2] && Close[1] > Open[2] )     
    {
        Print("Bearish Harami pattern detected");
    }

    Bullish EngulfingDas Muster des „Bullish Engulfing“ liegt vor, wenn die Kerze bei Index 2 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h. Close[2] < Open[2]) und die Kerze bei Index 1 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h. Close[1] > Open[1]). Außerdem muss die Kerze bei Index 1 den Körper der Kerze bei Index 2 verschlingen, indem sie unter ihrem Schlusskurs öffnet (Open[1] < Close[2]) und über ihrem Open schließt (Close[1] > Open[2])


    // Check for Bullish Engulfing pattern
    if( Close[2] < Open[2] &&     // Candle at index 2 is bearish
        Close[1] > Open[1] &&     // Candle at index 1 is bullish
        Open[1] < Close[2] &&     // Candle at index 1 opens below candle at index 2's close
        Close[1] > Open[2] )     // Candle at index 1 closes above candle at index 2's open
    {
        Print("Bullish Engulfing pattern detected");
    }

    Bearish EngulfingDas Muster „Bearish Engulfing“ wird identifiziert, wenn die Kerze bei Index 2 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h. Close[2] > Open[2]) und die Kerze bei Index 1 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h. Close[1] < Open[1]). Darüber hinaus muss die Kerze bei Index 1 den Körper der Kerze bei Index 2 vollständig verschlingen, indem sie über ihrem Schlusskurs öffnet (Open[1] > Close[2]) und unter ihrem Open schließt (Close[1] < Open[2])


    // Check for Bearish Engulfing pattern
    if( Close[2] > Open[2] && // Candle at index 2 is bullish
        Close[1] < Open[1] &&   // Candle at index 1 is bearish
        Open[1] > Close[2] &&  // Candle at index 1 opens above candle at index 2's close
        Close[1] < Open[2] )   // Candle at index 1 closes below candle at index 2's open
    {
        Print("Bearish Engulfing pattern detected");
    }

    Three Inside UpDas Muster „Three Inside Up“ wird erkannt, wenn die Kerze bei Index 3 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h., Close[3] < Open[3]) mit einem großen Körper (Open[3] - Close[3] > ATR), die Kerze bei Index 2 ist bullisch (Close[2] > Open[2]) und in Kerze 3 enthalten (Open[2] > Close[3] && Close[2] < Open[3]), und Kerze 1 ist bullisch (Close[1] > Open[1]) und schließt über dem Hoch von Kerze 2 (Close[1] > High[2])


    // Check for Three Inside Up pattern
     // Candle 3 is bearish with large body
    if( Close[3] < Open[3] && (Open[3] - Close[3]) > ATR[1] && 
     // Candle 2 is bullish and within candle 3's body   
        Close[2] > Open[2] && Open[2] > Close[3] && Close[2] < Open[3] &&
    // Candle 1 is bullish and closes above candle 2's high    
        Close[1] > Open[1] && Close[1] > High[2] )     
    {
        Print("Three Inside Up pattern detected");
    }

    Three Inside DownDas Muster „Three Inside Down“ wird identifiziert, wenn die Kerze bei Index 3 eine Aufwärtskerze ist (ihr Close ist höher als ihr Open, d.h., Close[3] > Open[3]) mit einem großen Körper (Close[3] - Open[3] > ATR), die Kerze bei Index 2 eine Abwärtskerze ist (Close[2] < Open[2]) und in Kerze 3 enthalten ist (Open[2] < Close[3] && Close[2] > Open[3]), und Kerze 1 eine Abwärtskerze ist (Close[1] < Open[1]) und unter dem Tief von Kerze 2 schließt (Close[1] < Low[2])


    // Check for Three Inside Down pattern
    // Candle 3 is bullish with large body
    if( Close[3] > Open[3] && (Close[3] - Open[3]) > ATR[1] && 
    // Candle 2 is bearish and within candle 3's body    
        Close[2] < Open[2] && Open[2] < Close[3] && Close[2] > Open[3] &&
    // Candle 1 is bearish and closes below candle 2's low    
        Close[1] < Open[1] && Close[1] < Low[2] ) 
    {     
        Print("Three Inside Down pattern detected");
    }

    Tweezer BottomDas Muster „Tweezer Bottom“ wird erkannt, wenn die Kerze bei Index 2 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h. Close[2] < Open[2]), die Kerze bei Index 1 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h., Close[1] > Open[1]), und die Tiefststände beider Kerzen sind nahezu gleich (die absolute Differenz zwischen Low[2] und Low[1] ist kleiner als das 0,1-fache der ATR, d.h. MathAbs(Low[2] - Low[1]) < 0,1 * ATR)


    // Check for Tweezer Bottom pattern
    if( Close[2] < Open[2] &&     // Candle at index 2 is bearish
        Close[1] > Open[1] &&     // Candle at index 1 is bullish
    // Lows of both candles are nearly equal
        MathAbs(Low[2] - Low[1]) < 0.1 * ATR[1] )
    {
        Print("Tweezer Bottom pattern detected");
    }


    Tweezer TopDas Muster „Tweezer Top“ wird identifiziert, wenn die Kerze bei Index 2 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungskurs, d.h. Close[2] > Open[2]), die Kerze bei Index 1 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungskurs, d.h., Close[1] < Open[1]), und die Höchststände der beiden Kerzen sind nahezu gleich (die absolute Differenz zwischen High[2] und High[1] ist kleiner als das 0,1-fache der ATR, d.h. MathAbs(High[2] - High[1]) < 0,1 * ATR)


    // Check for Tweezer Top pattern
    if( Close[2] > Open[2] &&     // Candle at index 2 is bullish
        Close[1] < Open[1] &&     // Candle at index 1 is bearish
    // Highs of both candles are nearly equal
        MathAbs(High[2] - High[1]) < 0.1 * ATR[1] )
    {
        Print("Tweezer Top pattern detected");
    }

    Bullish KickerDas Muster „Bullish Kicker“ wird erkannt, wenn die Kerze bei Index 2 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungswert, d.h. Close[2] < Open[2]) und die Kerze bei Index 1 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungswert, d.h. Close[1] > Open[1]), wobei ihr Eröffnungswert über dem Eröffnungswert von Kerze 2 liegt (Open[1] > Open[2]).


    // Check for Bullish Kicker pattern
    if( Close[2] < Open[2] && // Candle at index 2 is bearish
    // Candle at index 1 is bullish
        Close[1] > Open[1] && 
    // Candle at index 1 opens above candle at index 2's open
        Open[1] > Open[2] ) 
    {
        Print("Bullish Kicker pattern detected");
    }

    Bearish KickerDas Muster „Bearish Kicker“ wird erkannt, wenn die Kerze bei Index 2 eine Aufwärtskerze ist (ihr Schlusskurs ist höher als ihr Eröffnungswert, d.h. Close[2] > Open[2]) und die Kerze bei Index 1 eine Abwärtskerze ist (ihr Schlusskurs ist niedriger als ihr Eröffnungswert, d.h. Close[1] < Open[1]) und ihr Eröffnungswert unter dem Eröffnungswert von Kerze 2 liegt (Open[1] < Open[2]).


    // Check for Bearish Kicker pattern
    // Candle at index 2 is bullish
    if( Close[2] > Open[2] &&  
    // Candle at index 1 is bearish
        Close[1] < Open[1] &&  
    // Candle at index 1 opens below candle at index 2's open
        Open[1] < Open[2]  
    {
        Print("Bearish Kicker pattern detected");
    }

    Diese Tabelle ließe sich endlos fortsetzen, denn es gibt noch viele weitere Muster, die ich nicht aufgeführt habe. Um die Diskussion kurz zu halten, werde ich nun den Schwerpunkt auf die Umsetzung dieser Strategien in einem einzigen, sinnvollen Programm legen. Das ultimative Ziel ist es, eine umfassende Bibliothek von Kerzenmustern aufzubauen.

    Ich habe Nachforschungen angestellt und bemerkenswerte Arbeit in der MQL5 Codebase gefunden, die von einigen der Pioniere des algorithmischen Handels vor mehr als einem Jahrzehnt entwickelt wurde. Für einen detaillierteren Ansatz können Sie deren Arbeit erkunden. Unser Ziel in dieser Diskussion ist es hingegen, die Dinge für Anfänger so einfach wie möglich zu halten. In diesem Sinne werden wir nun mit der Entwicklung unserer eigenen Kerzenmuster-Bibliothek fortfahren.

    Erstellung einer wiederverwendbaren Kerzenmuster-Header-Datei

    An dieser Stelle zeige ich Ihnen, wie Sie eine Funktionsbibliothek erstellen, die eine Sammlung von Kerzenmustern enthält. Wir bezeichnen sie als Bibliothek, weil sie mehrere wiederverwendbare Funktionen zur Mustererkennung zusammenfasst. Einmal entwickelt, können diese Muster leicht in andere Projekte integriert werden, indem die Bibliothek eingebunden und die Funktionen nach Bedarf aufgerufen werden.

    Der korrekte Begriff für diese Art von Datei ist eine Header-Datei, und ich freue mich, sie infinity_candlestick_pattern.mqh zu nennen, was ihre Erweiterbarkeit widerspiegelt, da mit der Zeit weitere Muster hinzugefügt werden können. Ich habe sie als Vorlage strukturiert, die ich später in einem Indikator demonstrieren werde, um ihre praktische Anwendung zu zeigen.

    In den Anhängen werde ich eine umfassendere Version der Header-Datei zur Verfügung stellen, die Funktionen für die Muster enthält, die wir zuvor in der Referenztabelle aufgeführt haben. Sie können diese Bibliothek weiter ausbauen, indem Sie die kommentierten Richtlinien in den Codefragmenten folgen.

    Die Datei enthält zwei primäre Funktionen, IsHammer und IsShootingStar, die Arrays von Preisdaten zusammen mit einer begleitenden Average True Range (ATR) analysieren, um festzustellen, ob eine bestimmte Kerze die Bedingungen für diese Muster erfüllt. Jede Funktion prüft, ob der angegebene Index gültig ist, berechnet die Körpergröße der Kerze und wertet dann die Länge der Dochte im Verhältnis zur Körpergröße und zu den ATR-Werten aus. Dieser sorgfältige Ansatz quantifiziert visuelle Handelsmuster anhand präziser mathematischer Kriterien und ermöglicht eine robuste Mustererkennung, die sich der Marktvolatilität anpasst. Darüber hinaus hilft die Verwendung des PatternATR-Parameters (der als Referenz übergeben wird), potenzielle Konflikte und Warnungen zu vermeiden, wenn der ATR-Wert später im Beispielindikator verwendet wird, und gewährleistet die Konsistenz des übergebenen Wertes.

    Um diese Funktionen in andere Projekte zu integrieren, können Sie diese Header-Datei einfach mit #include in Ihren Quellcode einbinden. Sobald sie enthalten sind, können sie die Funktion IsHammer oder IsShootingStar aufrufen, indem sie die entsprechenden Arrays und den gewünschten Index übergeben. 

    //+------------------------------------------------------------------+
    //|                     infinity_candlestick_pattern.mqh (Template)  |
    //|                                   Copyright 2025, Metaquotes Ltd |
    //|                                            https://www.mql5.com/ |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2025, Metaquotes Ltd"
    #property link      "https://www.mql5.com/"
    #ifndef INFINITY_CANDLESTICK_PATTERNS_MQH
    #define INFINITY_CANDLESTICK_PATTERNS_MQH
    
    //+------------------------------------------------------------------+
    //| Single-Candlestick Pattern Functions                             |
    //+------------------------------------------------------------------+
    
    // Hammer Pattern
    bool IsHammer(double &open[], double &high[], double &low[], double &close[], double &patternATR[], int index)
    {
       if (index < 0) return false; // Ensure the index is valid
       
       // Calculate the body size (absolute difference between close and open)
       double body = MathAbs(close[index] - open[index]);
       
       // Check if the body is small relative to ATR (less than 30% of ATR)
       if (body >= 0.3 * patternATR[index]) return false;
       
       // Calculate wick lengths
       double upperWick = high[index] - MathMax(open[index], close[index]);
       double lowerWick = MathMin(open[index], close[index]) - low[index];
       
       // Hammer conditions: long lower wick (2x body), small upper wick (≤0.5x body)
       if (lowerWick >= 2 * body && upperWick <= 0.5 * body)
          return true;
       
       return false;
    }
    
    // Shooting Star Pattern
    bool IsShootingStar(double &open[], double &high[], double &low[], double &close[], double &patternATR[], int index)
    {
       if (index < 0) return false; // Ensure the index is valid
       
       // Calculate the body size (absolute difference between close and open)
       double body = MathAbs(close[index] - open[index]);
       
       // Check if the body is small relative to ATR (less than 30% of ATR)
       if (body >= 0.3 * patternATR[index]) return false;
       
       // Calculate wick lengths
       double upperWick = high[index] - MathMax(open[index], close[index]);
       double lowerWick = MathMin(open[index], close[index]) - low[index];
       
       // Shooting Star conditions: long upper wick (2x body), small lower wick (≤0.5x body)
       if (upperWick >= 2 * body && lowerWick <= 0.5 * body)
          return true;
       
       return false;
    }
    
    //+------------------------------------------------------------------+
    //| How to Expand the Library                                        |
    //+------------------------------------------------------------------+
    // To add more patterns:
    // 1. Create a new function, e.g., IsDoji, IsEngulfing, etc.
    // 2. Use the same inputs: open[], high[], low[], close[], patternATR[], index
    // 3. Define the pattern’s conditions (e.g., for Doji, check if open ≈ close)
    // 4. Return true if the pattern matches, false otherwise
    // 5. For multi-candle patterns, adjust the index check (e.g., index < 1 for 2 candles)
    // 6. Use patternATR to adapt to volatility (optional)
    // 7. Add comments to explain your logic
    
    #endif
    //+------------------------------------------------------------------+

    Lassen Sie uns nun einen Indikator entwickeln, der die Anwendung der soeben erstellten Header-Datei demonstriert. Ich habe beschlossen, den Indikator Hammer&ShootingStar zu nennen, da er unsere Bibliothek nutzen wird, um diese beiden Kerzenmuster zu erkennen und auf dem Chart zu visualisieren. Dies wird ein praktisches Beispiel dafür sein, wie unsere wiederverwendbaren Funktionen in realen Handelsszenarien implementiert werden können. Indem wir die Bibliothek am Anfang des Indikators einbinden, erhalten wir unmittelbaren Zugriff auf die Funktionen zur Erkennung von Kerzenmustern, in diesem Zusammenhang also IsHammer und IsShootingStar. Dieser modulare Aufbau ermöglicht es dem Indikator, sich auf die Erfassung und Verarbeitung von Marktdaten zu konzentrieren und die Logik der Musterauswertung an die Bibliothek zu delegieren, wodurch Konsistenz gewährleistet und die Wartung vereinfacht wird.

    In der Initialisierungsphase (OnInit) richtet der Indikator seine Puffer und Charteigenschaften ein, einschließlich der Definition von zwei Pfeilzeichen, die die erkannten Muster visuell darstellen. Außerdem wird ein ATR-Handle erstellt, das zum Abrufen von Marktvolatilitätsdaten verwendet wird, die die Bibliotheksfunktionen benötigen. Während der Berechnungsphase (OnCalculate) ruft der Indikator Kursdaten und ATR-Werte ab und iteriert dann durch die Kursreihen. Bei jeder Iteration ruft es die Bibliotheksfunktionen auf, um zu prüfen, ob eine bestimmte Kerze die Kriterien für einen Hammer (Kaufsignal) oder einen Shooting Star (Verkaufssignal) erfüllt. Je nach Ergebnis wird der entsprechende Puffer entweder mit dem Preisniveau gefüllt, auf dem ein Pfeil gezeichnet werden soll.

    Außerdem ist der Indikator so konzipiert, dass er in Zukunft erweitert werden kann. Sie können problemlos weitere Puffer hinzufügen, wenn zusätzliche Mustererkennungsfunktionen in die Bibliothek aufgenommen werden. Dieser flexible Ansatz fördert die Erweiterung der Musterbibliothek, wobei eine saubere Trennung zwischen der Kernlogik des Indikators und den Algorithmen zur Mustererkennung beibehalten wird. Wenn Sie mehr Programmiererfahrung sammeln möchten, können Sie mit den Funktionen in der beigefügten Bibliothek weitere Puffer erstellen.

    //+------------------------------------------------------------------+
    //|                                          Hammer&ShootingStar.mq5 |
    //|                                   Copyright 2025, Metaquotes Ltd |
    //|                                            https://www.mql5.com/ |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2025, Metaquotes Ltd"
    #property link      "https://www.mql5.com/"
    #property version   "1.00"
    #property indicator_chart_window
    
    //--- Include the library
    #include <infinity_candlestick pattern.mqh>
    
    //--- Indicator settings
    #property indicator_chart_window
    #property indicator_buffers 2
    #property indicator_plots 2
    
    #property indicator_type1 DRAW_ARROW
    #property indicator_color1 0x0000FF
    #property indicator_label1 "Sell "
    
    #property indicator_type2 DRAW_ARROW
    #property indicator_color2 0xFF0000
    #property indicator_label2 "Buy "
    
    //--- Indicator buffers and variables
    double Buffer1[];
    double Buffer2[];
    double Open[];
    double High[];
    double Low[];
    double Close[];
    double atr[];
    int atrHandle;
    
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    int OnInit()
    {
       SetIndexBuffer(0, Buffer1);
       PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(0, PLOT_ARROW, 242);
       SetIndexBuffer(1, Buffer2);
       PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
       PlotIndexSetInteger(1, PLOT_ARROW, 241);
    
       // Create ATR handle
       atrHandle = iATR(_Symbol, _Period, 14);
       if (atrHandle == INVALID_HANDLE)
       {
          Print("Failed to create ATR handle");
          return(INIT_FAILED);
       }
       return(INIT_SUCCEEDED);
    }
    
    //+------------------------------------------------------------------+
    //| Custom indicator iteration function                              |
    //+------------------------------------------------------------------+
    int OnCalculate(const int rates_total,
                    const int 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 int& spread[])
    {
       // Copy price data and ATR
       if (CopyOpen(Symbol(), PERIOD_CURRENT, 0, rates_total, Open) <= 0) return(rates_total);
       ArraySetAsSeries(Open, true);
       if (CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
       ArraySetAsSeries(High, true);
       if (CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
       ArraySetAsSeries(Low, true);
       if (CopyClose(Symbol(), PERIOD_CURRENT, 0, rates_total, Close) <= 0) return(rates_total);
       ArraySetAsSeries(Close, true);
       if (CopyBuffer(atrHandle, 0, 0, rates_total, atr) <= 0) return(rates_total);
       ArraySetAsSeries(atr, true);
    
       ArraySetAsSeries(Buffer1, true);
       ArraySetAsSeries(Buffer2, true);
    
       // Main loop
       for (int i = rates_total-2; i >= 0; i--)
       {
          // Sell Supply (Shooting Star)
          if (IsShootingStar(Open, High, Low, Close, atr, i))
             Buffer1[i] = High[i]; // Arrow at high
          else
             Buffer1[i] = EMPTY_VALUE;
    
          // Buy Supply (Hammer)
          if (IsHammer(Open, High, Low, Close, atr, i))
             Buffer2[i] = Low[i]; // Arrow at low
          else
             Buffer2[i] = EMPTY_VALUE;
       }
       return(rates_total);
    }



    Tests

    Nachdem ich alles erfolgreich integriert hatte, konnte ich den Indikator Hammer&ShootingStar auf dem Chart des MetaTrader 5 ausführen und hervorragende Ergebnisse beobachten. Der Indikator hat die Kerzenmuster effektiv identifiziert und hervorgehoben und damit die Genauigkeit und Praktikabilität unserer Bibliothek unter realen Marktbedingungen bewiesen.

     Volatility 75 (1s) Index.0,5: Test des Hammer&ShootingStar testing.

     Volatilität 75 (1s) Index.0,5: Test des Hammer&ShootingStar



    Schlussfolgerung

    Diese Diskussion war sehr umfangreich, aber sie wird als eines der wertvollsten und am häufigsten wieder aufgegriffenen Themen zum Nachschlagen und Lernen dienen. Mit dem nun vorhandenen Algorithmus haben wir das Problem der manuellen Suche nach Mustern gelöst. Der Prozess kann nun vollständig automatisiert werden, und ohne visuelle Indikatoren auf dem Chart war die Verwaltung Ihrer Strategien noch nie so einfach. Der Algorithmus stellt die Genauigkeit sicher, indem er alle Berechnungen, einschließlich der ATR-Werte, durchführt, was den Prozess sowohl effizient als auch präzise macht.

    Wir haben eine breite Palette von Konzepten und Techniken behandelt, die für die Programmierung von Kerzenmustern und die Erstellung von Indikatoren mit mehreren Puffern nützlich sind. Während sich diese Diskussion in erster Linie auf Kerzenmuster konzentrierte, haben wir einen algorithmischen Ansatz zur Analyse und Nutzung dieser Muster vorgestellt, der besonders für Anfänger nützlich ist, die ihre Handelsstrategien automatisieren möchten. Denken Sie daran, dass die von Kerzenmustern generierten Signale möglicherweise zusätzliche Filter benötigen, um zuverlässige Handelssignale zu werden. Die Codebase-Dokumentation ist eine hervorragende Ressource, wenn Sie die von Kerzenmustern generierten Signale verbessern oder erweiterte Funktionen hinzufügen möchten.

    Ich würde mich freuen, wenn Sie Ihre Ergebnisse mit dem beigefügten Code im Kommentarbereich mitteilen würden. Wenn es die Zeit erlaubt, werde ich dieses Thema erneut aufgreifen, um auf dem bisher Erreichten aufzubauen und weitere Fortschritte zu erkunden.
    DateinameBeschreibung
    infinity_candlestick_pattern.mqhEine Header-Datei mit einer Sammlung von booleschen Funktionen für die gängigsten Kerzenmuster, die in anderen Projekten aufgerufen werden können.
    Hammer&ShootingStar.mq5,  Ein Beispielindikator, der die Bibliothek infinity_Kerzen_pattern.mqh integriert.

    Zurück zur Einleitung

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

    Letzte Kommentare | Zur Diskussion im Händlerforum (1)
    Huynh Cong Chinh
    Huynh Cong Chinh | 27 Apr. 2025 in 02:30
    Cảm ơn bạn đã giải thích chi tiết này! Tôi rất muốn tìm hiểu cách lập trình các mẫu nến thành một chỉ báo tùy chỉnh trong MQL5. Tôi đồng ý rằng việc tự động phát hiện mẫu có thể tiết kiệm rất nhiều thời gian và cải thiện độ chính xác. Tôi tò mò - khi tạo thư viện mẫu nến có thể tái sử dụng, bạn sẽ đề xuất tập trung vào khái niệm hoặc kỹ thuật toán học nào trước?
    Automatisieren von Handelsstrategien in MQL5 (Teil 15): Price Action Harmonic Cypher Pattern mit Visualisierung Automatisieren von Handelsstrategien in MQL5 (Teil 15): Price Action Harmonic Cypher Pattern mit Visualisierung
    In diesem Artikel befassen wir uns mit der Automatisierung des harmonischen Cypher-Musters in MQL5 und erläutern seine Erkennung und Visualisierung auf MetaTrader 5-Charts. Wir implementieren einen Expert Advisor, der Umkehrpunkte identifiziert, Fibonacci-basierte Muster validiert und Handelsgeschäfte mit klaren grafischen Kommentaren ausführt. Der Artikel schließt mit einer Anleitung zu den Backtests und zur Optimierung des Programms für einen effektiven Handel.
    Formulierung eines dynamischen Multi-Pair EA (Teil 2): Portfolio-Diversifizierung und -Optimierung Formulierung eines dynamischen Multi-Pair EA (Teil 2): Portfolio-Diversifizierung und -Optimierung
    Portfolio-Diversifizierung und -Optimierung sorgt für eine strategische Streuung der Anlagen auf mehrere Vermögenswerte, um das Risiko zu minimieren und gleichzeitig die ideale Mischung von Vermögenswerten auszuwählen, um die Renditen auf der Grundlage risikobereinigter Performance-Kennzahlen zu maximieren.
    Integration des AI-Modells in eine bereits bestehende MQL5-Handelsstrategie Integration des AI-Modells in eine bereits bestehende MQL5-Handelsstrategie
    Dieses Thema konzentriert sich auf die Einbindung eines trainierten KI-Modells (z. B. eines Verstärkungslernmodells wie LSTM oder eines auf maschinellem Lernen basierenden Prognosemodells) in eine bestehende MQL5-Handelsstrategie.
    Entwicklung des Price Action Analysis Toolkit (Teil 21): Das Tool Market Structure Flip Detector Entwicklung des Price Action Analysis Toolkit (Teil 21): Das Tool Market Structure Flip Detector
    Der Market Structure Flip Detector Expert Advisor (EA) agiert als Ihr aufmerksamer Partner, der ständig die Veränderungen der Marktstimmung beobachtet. Durch die Verwendung von Average True Range (ATR)-basierten Schwellenwerten erkennt es effektiv Strukturumkehrungen und kennzeichnet jedes höhere Tief und niedrigere Hoch mit klaren Indikatoren. Dank der schnellen Ausführung und der flexiblen API von MQL5 bietet dieses Tool eine Echtzeitanalyse, die die Anzeige für eine optimale Lesbarkeit anpasst und ein Live-Dashboard zur Überwachung der Anzahl und des Timings von Flips bereitstellt. Darüber hinaus sorgen anpassbare Ton- und Push-Benachrichtigungen dafür, dass Sie über kritische Signale informiert bleiben, sodass Sie sehen können, wie einfache Eingaben und Hilfsroutinen Kursbewegungen in umsetzbare Strategien verwandeln können.