English 日本語
preview
Entwicklung des Price Action Analysis Toolkit (Teil 31): Python-Engine für Kerzenmuster (I) - Manuelles Erkennen

Entwicklung des Price Action Analysis Toolkit (Teil 31): Python-Engine für Kerzenmuster (I) - Manuelles Erkennen

MetaTrader 5Integration |
155 0
Christian Benjamin
Christian Benjamin

Inhalt



Einführung

Kerzen-Charts sind ein grundlegendes Instrument, das von Finanzanalysten und Händlern zur Visualisierung und Interpretation von Kursbewegungen im Zeitverlauf verwendet wird. Diese Charts, die vor Jahrhunderten von japanischen Reishändlern entwickelt wurden, haben sich zu einem wichtigen Bestandteil der technischen Analyse auf verschiedenen Finanzmärkten, einschließlich Aktien, Devisen und Futures, entwickelt. 

Muster

Eine Kerze liefert wichtige Informationen über die Marktstimmung, indem er wichtige Datenpunkte wie Eröffnungs-, Schluss-, Höchst- und Tiefstkurse innerhalb eines bestimmten Zeitrahmens anzeigt. Die einzigartige Struktur jeder Kerze gibt Aufschluss über die Marktpsychologie und kann als potenzielles Handelssignal dienen. 

In diesem Artikel untersuchen wir die Entwicklung eines umfassenden Kerzen-Erkennungssystems, das die Möglichkeiten von MQL5 und Python nutzt. Wir beginnen mit der Implementierung manueller Erkennungsmethoden, indem wir ein Skript erstellen, das Metriken aus MQL5 extrahiert und Musternamen anhand vordefinierter Kriterien zuweist. Obwohl diese Erkennung vollständig innerhalb von MQL5 erreicht werden kann, haben wir uns für eine Rollenteilung zwischen MQL5 und Python entschieden, um die jeweiligen Stärken zu nutzen und eine größere Flexibilität und Robustheit zu gewährleisten. 

In einem späteren Artikel werden wir dieses System durch die Integration von Python-Bibliotheken erweitern, die erweiterte Funktionen für die Erkennung von Kerzenmustern bieten und so die Genauigkeit und Vielfalt der Mustererkennung verbessern. Begleiten Sie uns, wenn wir uns mit den Feinheiten der Kerzenmusteridentifikation beschäftigen und untersuchen, wie dieser integrierte Ansatz die Handelsanalyse verbessert. Nachstehend finden Sie eine Übersicht über die Schritte, die wir unternehmen werden:

  • Analyse von jedem Muster: Wir werden jedes Kerzenmuster einzeln untersuchen und erkunden, wie seine Erkennung in Python implementiert ist.
  • Erforschen der Interaktion zwischen MQL5 und Python: Wir werden uns ansehen, wie der MQL5 Expert Advisor mit dem Python-Server interagiert, einschließlich des Datenaustauschprozesses und des Kommunikationsflusses.
  • Auswertung der Ergebnisse und ziehen der Schlussfolgerungen: Abschließend werden wir die Ergebnisse des Systems bewerten, seine Wirksamkeit erörtern und Schlussfolgerungen zu seiner Leistung und möglichen Verbesserungen ziehen.


Analyse von Kerzenmustern

Der breite Abschnitt einer Kerze wird als echter Körper bezeichnet, der die Differenz zwischen dem Eröffnungs- und dem Schlusskurs innerhalb eines bestimmten Zeitraums darstellt. Ein gefüllter oder farbiger Körper zeigt in der Regel an, dass der Schlusskurs niedriger war als der Eröffnungskurs, was auf eine Abwärtsbewegung hindeutet. Umgekehrt deutet ein nicht ausgefüllter oder anders gefärbter Körper darauf hin, dass der Schlusskurs höher war als der Eröffnungskurs, was auf einen Aufwärtstrend hindeutet.

Die Schatten oder Dochte erstrecken sich vom eigentlichen Körper aus und veranschaulichen die höchsten und niedrigsten Kurse, die während der Handelssitzung erreicht wurden. Die Länge und Position dieser Schatten geben Aufschluss über die Marktvolatilität und die Stimmung der Anleger, da sie zeigen, wie die Kurse im Verhältnis zu den Eröffnungs- und Schlusskursen geschwankt haben.

Kerzenmuster verkörpern die kollektive Psychologie der Marktteilnehmer und spiegeln ihre emotionalen Reaktionen und Erwartungen wider. Technische Analysten nutzen diese visuellen Anhaltspunkte, um potenzielle Einstiegs- und Ausstiegspunkte zu identifizieren. Der Ursprung der Kerzen-Charts geht auf das Japan des 18. Jahrhunderts zurück, wo Reishändler diese Technik zur Überwachung der Reispreise verwendeten. Auch heute noch ist es ein vielseitiges Instrument zur Analyse von liquiden Vermögenswerten wie Aktien, Devisenpaaren und Futures.

Auf- und Abwärtskerzen

  • Aufwärtskerzen:

Eine Kerze gilt als aufwärts, wenn der Schlusskurs über den Eröffnungskurs liegt. Dies wird oft als weiße oder grüne Kerze dargestellt und signalisiert eine Aufwärtsdynamik. Solche Kerzen deuten darauf hin, dass die Käufer in dieser Zeit die Kontrolle haben. Die Bedeutung langer Aufwärtskerzen nimmt zu, wenn sie in der Nähe wichtiger Unterstützungsniveaus auftreten, was auf ein starkes Kaufinteresse hindeutet.

  • Abwärtskerzen:

Umgekehrt tritt eine Abwärtskerze auf, wenn der Schlusskurs unter den Eröffnungskurs fällt. Diese werden in der Regel als schwarze oder rote Kerzen angezeigt und weisen auf Verkaufsdruck und eine Abwärtsbewegung des Preises hin. Lange Abwärtskerzen signalisieren oft starke Verkaufsaktivitäten und eine mögliche Fortsetzung des Abwärtstrends.

  • Farbkonventionen

Während viele Handelsplattformen traditionell Aufwärtskerzen in Weiß oder Grün und Abwärtskerzen in Schwarz oder Rot darstellen, ist die Wahl der Farbe flexibel. Entscheidend ist, die Beziehung zwischen Eröffnungs- und Schlusskursen zu verstehen und sich nicht strikt an Farbschemata zu halten. Das Hauptaugenmerk sollte immer auf dem Positionsverhältnis von Eröffnungs- und Schlusskurs liegen, um die Marktstimmung richtig zu interpretieren.

Angesichts der großen Vielfalt an Kerzenmustern konzentriert sich unser System auf eine ausgewählte Gruppe von Schlüsselformationen. Im Folgenden werden wir das visuelle Erscheinungsbild der einzelnen Muster untersuchen und erörtern, wie man sie mit Python identifizieren kann:

Hammer

Die Kerze Hammer bildet sich, wenn der Eröffnungs-, der Höchst- und der Schlusskurs nahe beieinander liegen, was zu einem kleinen echten Körper führt. Sein charakteristisches Merkmal ist ein ausgeprägter langer unterer Schatten, der signalisiert, dass die Käufer versucht haben, den Preis nach unten zu drücken, aber letztlich abgewiesen wurden. Dies deutet auf eine mögliche Verschiebung des Momentums nach oben hin und spiegelt die zugrunde liegende Aufwärtsstimmung wider. Nachfolgend ein Codefragment zur Erkennung des Hammer-Musters im Python-Skript

# inside detect_patterns(df: pd.DataFrame)
for i, _ in enumerate(df.index):
    o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
    body = abs(c - o)
    lower = min(o,c) - l
    upper = h - max(o,c)
    
    if lower >= 2*body and upper <= body:
        pats[i] = "hammer"
        continue

  • Körper ist der tatsächliche Körper der Kerze (abs(close - open)).
  • Der untere Docht muss mindestens 2× die Körpergröße haben.
  • Der obere Docht sollte klein sein (nicht größer als die Größe des Körpers).
  • Wenn diese Bedingung erfüllt ist, wird sie im Array pats[] mit „Hammer“ gekennzeichnet.

Shooting Star

Das Muster des Shooting-Stars tritt auf, wenn der Eröffnungs-, der Tiefst- und der Schlusskurs alle in der Nähe desselben Niveaus liegen. Dies führt zu einer Kerze mit einem sehr kleinen echten Körper und einem ausgeprägten oberen Schatten. Der Shooting Star wird oft als das fallende Gegenstück zum Hammer betrachtet und signalisiert eine mögliche Umkehr oder ein Zögern des Aufwärtsmomentums. Experten für technische Analyse empfehlen in der Regel, dass der obere Schatten mindestens doppelt so lang wie der Körper sein sollte, um die Bedeutung des Musters zu bestätigen.

# inside detect_patterns(df: pd.DataFrame)
for i, _ in enumerate(df.index):
    o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
    body = abs(c - o)
    lower = min(o,c) - l
    upper = h - max(o,c)
    
    if upper >= 2*body and lower <= body:
        pats[i] = "shootingstar"
        continue

  • Der Körper ist der Unterschied zwischen offen und geschlossen.
  • Der obere Docht muss mindestens 2× so groß sein wie der Körper, der untere Docht muss klein sein (kleiner oder gleich groß wie der Körper).
  • Wenn diese Bedingungen erfüllt sind, wird das Muster als „shootingstar“ markiert.

Engulfing (Auf- & Abwärts)

 Ein Aufwärts-Engulfing-Muster entsteht, wenn auf eine kleine rote (Abwärts-) Kerze eine größere grüne (Aufwärts-) Kerze folgt, die den Körper der vorherigen Kerze vollständig „verschlingt“. Dieses Muster deutet auf eine mögliche Umkehr von einem Abwärtstrend zu einem Aufwärtstrend hin, da der Kaufdruck den Verkaufsdruck überwunden hat. 

# Bullish Engulfing: small red followed by large green that engulfs it
if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c
    if (prev_c < prev_o and curr_c > curr_o and  # red candle then green
        curr_o < prev_c and curr_c > prev_o):    # body engulfs previous
        pats[i] = "bullishengulfing"
        continue

Ein Abwärts-Engulfing-Muster ist das Gegenteil davon. Er tritt auf, wenn auf eine kleine grüne (Aufwärts-) Kerze eine größere rote (Abwärts-) Kerze folgt, die den Körper der vorherigen Kerze vollständig verschlingt. Dieses Muster deutet auf eine potenzielle Umkehr von einem Aufwärtstrend zu einem Abwärtstrend hin und spiegelt einen erhöhten Verkaufsdruck wider.

# Bearish Engulfing: small green followed by large red that engulfs it
if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c
    if (prev_c > prev_o and curr_c < curr_o and  # green candle then red
        curr_o > prev_c and curr_c < prev_o):    # body engulfs previous
        pats[i] = "bearishengulfing"
        continue

Doji

Ein Doji ist eine Kerze, die sich bildet, wenn der Eröffnungs- und der Schlusskurs praktisch identisch sind, was zu einem sehr kleinen oder gar nicht vorhandenen realen Körper führt. Dieses Muster deutet auf Unentschlossenheit auf dem Markt hin, da weder Käufer noch Verkäufer während der Handelssitzung die Kontrolle übernommen haben.

# Doji: very small or no real body
if abs(c - o) <= (h - l) * 0.1:
    pats[i] = "doji"
    continue

  • abs(c - o): tatsächliche Körpergröße (Differenz zwischen Schluss- und Eröffnungskurs).
  • (h - l): Gesamter Kerzenbereich (Hoch minus Tief). Wenn der Körper weniger als oder gleich 10 % des Kerzenbereichs beträgt, wird er als Doji betrachtet.

Harami (Auf- & Abwärts)

Das Harami-Muster, abgeleitet von dem japanischen Wort für „schwanger“, ist eine bekannte Formation in der technischen Analyse, die potenzielle Trendumkehr oder -fortsetzung signalisiert. Sie besteht aus zwei Kerzen: Die erste, größere Kerze wird oft als „Mutterkerze“ bezeichnet, gefolgt von einer kleineren „Babykerze“, die sich innerhalb des Bereichs der ersten Kerze befindet. Damit das Muster als gültig angesehen werden kann, sollte die zweite Kerze innerhalb des Körpers der vorherigen Kerze schließen, was auf eine mögliche Pause oder Umkehr der Marktdynamik hinweist.

Das Harami-Muster kann eine Abwärts-Trendwende signalisieren, wenn es nach einem Aufwärtstrend auftritt und darauf hindeutet, dass der Kaufdruck nachlässt und ein Abschwung folgen könnte. Umgekehrt kann er, wenn er nach einem Abwärtstrend auftritt, als Aufwärtsindikator fungieren und auf eine mögliche Aufwärtskorrektur oder Trendumkehr hindeuten.

if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c

    # Previous candle: large body (engulfing candle)
    prev_body = abs(prev_c - prev_o)
    curr_body = abs(curr_c - curr_o)

    if prev_body > 0 and curr_body > 0:
        # Bullish Harami
        if prev_o > prev_c and curr_o < curr_c:  # bearish → bullish
            if curr_o > prev_c and curr_c < prev_o:
                pats[i] = "bullishharami"
                continue

        # Bearish Harami
        if prev_o < prev_c and curr_o > curr_c:  # bullish → bearish
            if curr_o < prev_c and curr_c > prev_o:
                pats[i] = "bearishharami"
                continue

Morning Star

Der Morgenstern (Morning Star) ist ein auffälliges Aufwärts-Umkehrmuster, das in der Regel nach einem Abwärtstrend auftritt und einen potenziellen Wechsel der Marktstimmung von abwärts zu aufwärts signalisiert. Es besteht aus drei Kerzen: Die erste ist eine große Abwärtskerze, die auf starken Verkaufsdruck hinweist; die zweite ist eine kleine Kerze - entweder auf- oder abwärts - die sich von der ersten Kerze entfernt, was eine Unentschlossenheit oder eine Pause in der Dynamik anzeigt; und die dritte ist eine große Aufwärtskerze, die weit in den Körper der ersten Kerze hinein schließt, was eine Verschiebung hin zu einer Aufwärtsdynamik bestätigt.

Dieses Muster deutet darauf hin, dass die Verkäufer die Kontrolle verlieren und die Käufer an Stärke gewinnen, was häufig zu einer anhaltenden Aufwärtsbewegung führt, sobald diese bestätigt wird. Der Morning Star wird von Händlern häufig verwendet, um potenzielle Einstiegspunkte für Kaufpositionen zu identifizieren, insbesondere wenn er nach einem längeren Rückgang erscheint.

if i >= 2:
    o1, c1 = df.iloc[i-2][["OPEN", "CLOSE"]]  # First candle
    o2, c2 = df.iloc[i-1][["OPEN", "CLOSE"]]  # Second (small) candle
    o3, c3 = df.iloc[i][["OPEN", "CLOSE"]]    # Third candle

    # Candle directions
    is_bearish1 = c1 < o1
    is_small2 = abs(c2 - o2) < abs(c1 - o1) * 0.5
    is_bullish3 = c3 > o3

    # Morning Star Logic
    if is_bearish1 and is_small2 and c3 > ((o1 + c1) / 2) and c3 > o3:
        if min(o2, c2) < c1 and max(o2, c2) > c1:  # small gap
            pats[i] = "morningstar"
            continue

  • Kerze 1: Eine lange Abwärtskerze (abwärts gerichteter Körper).
  • Kerze 2: Eine Kerze mit kleinem Körper (kann auf- oder abwärts sein).
  • Kerze 3: Eine stark Aufwärtskerze, die oberhalb des Mittelpunkts von Kerze 1 schließt.

Dies ist ein Drei-Kerzen-Umkehrmuster, das in der Regel das Ende eines Abwärtstrends signalisiert.

Evening Star

Der Evening Star ist ein bemerkenswertes Abwärts-Umkehrmuster, das im Allgemeinen nach einem Aufwärtstrend auftritt und einen potenziellen Wechsel von einer Aufwärts- zu einer Abwärts-Stimmung anzeigt. Es besteht aus drei Kerzen: Die erste ist eine große Aufwärtskerze, die einen starken Kaufdruck widerspiegelt; die zweite ist eine kleine Kerze - entweder auf- oder abwärts - die sich von der ersten Kerze entfernt, was auf eine Unentschlossenheit oder ein Zögern des Marktes hindeutet; und die dritte ist eine große Abwärtskerze, die weit in den Körper der ersten Kerze hinein schließt und die Umkehrung bestätigt.

Dieses Muster signalisiert, dass die Käufer an Dynamik verlieren und die Verkäufer die Kontrolle übernehmen, was häufig zu einem Abwärtstrend oder einer Korrektur führt. Händler nutzen den Evening Star häufig als Signal, um Verkaufspositionen in Erwägung zu ziehen oder Kaufpositionen aufzugeben, insbesondere wenn er nach einer längeren Rallye erscheint.

if i >= 2:
    o1, c1 = df.iloc[i-2][["OPEN", "CLOSE"]]  # First candle
    o2, c2 = df.iloc[i-1][["OPEN", "CLOSE"]]  # Second (small) candle
    o3, c3 = df.iloc[i][["OPEN", "CLOSE"]]    # Third candle

    is_bullish1 = c1 > o1
    is_small2 = abs(c2 - o2) < abs(c1 - o1) * 0.5
    is_bearish3 = c3 < o3

    if is_bullish1 and is_small2 and c3 < ((o1 + c1) / 2) and c3 < o3:
        if max(o2, c2) > c1 and min(o2, c2) < c1:  # small gap possible
            pats[i] = "eveningstar"
            continue

  • Kerze 1: Langer Aufwärtskörper.
  • Kerze 2: Kleiner echter Körper (Unentschlossenheit).
  • Kerze 3: Starke Abwärtskerze, die deutlich unter dem Mittelpunkt von Kerze 1 schließt.

Dieses Drei-Kerzen-Muster signalisiert eine mögliche Trendwende von aufwärts zu abwärts.


MQL5 Python Interaktion

In unserem Setup wird die schwere Arbeit der Logik der Kerzenmuster von einem Python-Microservice übernommen, während sich der MQL5-EA auf die Datenerfassung, die Chart-Beschriftung und die Warnungen konzentriert. Jedes Mal, wenn ein neuer Balken schließt, greift der EA auf die letzten 31 Balken der OHLC-Daten zu, übergibt sie als JSON an einen lokalen Flask-Server und zeichnet dann alle Muster, die der Server meldet - und das nahezu in Echtzeit. So funktioniert es Schritt für Schritt:
  • MQL5 EA: Datenerfassung in MQL5
Bei jedem neuen Balken (OnTick) zieht der EA Zeitstempel sowie Eröffnungs-, Höchst-, Tiefst- und Schlusskurse für die letzten 31 Balken in Arrays.
void OnTick()
{
   static datetime lastBar = 0;
   datetime bar = iTime(_Symbol, InpTF, 0);
   if(bar == lastBar) return;
   lastBar = bar;

   double o[ BARS ], h[ BARS ], l[ BARS ], c[ BARS ];
   long   t[ BARS ];
   for(int i=0; i<BARS; i++)
   {
      o[i] = iOpen(_Symbol, InpTF, i+1);
      h[i] = iHigh(_Symbol, InpTF, i+1);
      l[i] = iLow (_Symbol, InpTF, i+1);
      c[i] = iClose(_Symbol, InpTF, i+1);
      t[i] = (long)iTime(_Symbol, InpTF, i+1);
   }
   // …then build JSON…
}
  • MQL5 EA: Aufbau der JSON-Nutzlast
Mit StringFormat kombiniert der EA Symbol, Zeitrahmen, Zeitstempel und OHLC-Arrays zu einem einzeiligen JSON-String, der für die Übertragung bereit ist.
string json = StringFormat(
  "{\"symbol\":\"%s\",\"timeframe\":%d,"
  "\"time\":[%s],\"open\":[%s],\"high\":[%s],"
  "\"low\":[%s],\"close\":[%s]}",
  _Symbol, InpTF,
  CSVInt(t), CSV(o), CSV(h), CSV(l), CSV(c)
);
  • MQL5 EA: Versenden über HTTP POST
Der EA feuert eine WebRequest(“POST“, ...) an http://127.0.0.1:5000/patterns ab. Wenn die Anfrage fehlschlägt, wird der Fehler protokolliert, andernfalls wird die JSON-Antwort des Python-Servers erfasst.
char body[];    StringToCharArray(json, body);
char reply[];   string hdr="Content-Type: application/json\r\n", respHdr;
int code = WebRequest("POST", InpURL, hdr, InpTimeout, body, reply, respHdr);
if(code == -1)
  Print("[CSLAB] WebRequest failed: ", GetLastError());
else
  string resp = CharArrayToString(reply, 0, -1, CP_UTF8);
  • Python: Flask Server Verarbeitung
Der Python-Dienst entfernt jeglichen Müll am Ende, dekodiert das saubere JSON in ein Dict und erstellt einen Pandas DataFrame mit den angegebenen Zeitstempeln.
@app.route("/patterns", methods=["POST"])
def patterns():
    raw = request.get_data(as_text=True)
    idx = raw.rfind("}")
    clean = raw[:idx+1] if idx != -1 else raw
    payload = json.loads(clean)   # may raise JSONDecodeError
    # …build DataFrame…

  • Python: DataFrame erstellen

Die Funktion build_dataframe verwandelt die rohen JSON-Arrays von Zeitstempeln, Eröffnungen, Höchst-, Tiefst- und Schlussständen in einen zeitindizierten DataFrame, mit dem unser Musterdetektor problemlos arbeiten kann:

def build_dataframe(payload):
    times = [ datetime.fromtimestamp(int(t), timezone.utc)
              for t in payload["time"] ]
    df = pd.DataFrame({
      "OPEN":  payload["open"],
      "HIGH":  payload["high"],
      "LOW":   payload["low"],
      "CLOSE": payload["close"]
    }, index=times)
    df.index.name = "datetime"
    return df

  • Python: Manuelles Erkennen von Mustern

Unsere nutzerdefinierte Routine detect_patterns(df) durchsucht jede Zeile nach den Signalen von Doji, Hammer, Shooting Star, Engulfing, Harami, Morning Star und Evening Star, ohne dass externe TA-Bibliotheken erforderlich sind.
def detect_patterns(df):
    pats = ["None"]*len(df)
    for i in range(len(df)):
        o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
        body = abs(c-o); rng = max(h-l,1e-6)
        lower = min(o,c)-l; upper = h-max(o,c)
        # doji
        if body/rng <= 0.1:
            pats[i] = "doji"; continue
        # hammer
        if lower>=2*body and upper<=body:
            pats[i] = "hammer"; continue
        # shooting star
        if upper>=2*body and lower<=body:
            pats[i] = "shootingstar"; continue
        # bullish engulfing
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc<po and c>o and o<=pc and c>=po:
                pats[i] = "bullishengulfing"; continue
        # bearish engulfing
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc>po and c<o and o>=pc and c<=po:
                pats[i] = "bearishengulfing"; continue
        # harami
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc<po and o<c and o>pc and c<po:
                pats[i] = "bullishharami"; continue
            if pc>po and o>c and o<pc and c>po:
                pats[i] = "bearishharami"; continue
        # morning star
        if i>1:
            o1,c1 = df.iloc[i-2][["OPEN","CLOSE"]]
            o2,c2 = df.iloc[i-1][["OPEN","CLOSE"]]
            if c1<o1 and abs(c2-o2)<(df.iloc[i-1]["HIGH"]-df.iloc[i-1]["LOW"])*0.3 \
               and c>o2 and c>(o1+c1)/2:
                pats[i] = "morningstar"; continue
        # evening star
        if i>1:
            o1,c1 = df.iloc[i-2][["OPEN","CLOSE"]]
            o2,c2 = df.iloc[i-1][["OPEN","CLOSE"]]
            if c1>o1 and abs(c2-o2)<(df.iloc[i-1]["HIGH"]-df.iloc[i-1]["LOW"])*0.3 \
               and c<o2 and c<(o1+c1)/2:
                pats[i] = "eveningstar"; continue
    return pats
  • Python: Ausarbeitung der Antwort

Der Server sammelt alle Muster, die nicht „None“ sind, und gibt eine übersichtliche JSON-Struktur zurück:

pats = detect_patterns(df)
counts = Counter(pats)
log_lines = [f"{k}={v}" for k,v in counts.items() if k!="None"]
resp = {"patterns": pats, "log": log_lines, "ms": round((datetime.now(timezone.utc)-start).total_seconds()*1000,2)}
return make_response(json.dumps(resp), 200, {"Content-Type":"application/json"})
  • MQL5 EA: EA Parses & Acts
Zurück in MQL5 extrahieren wir das Array „patterns“, stellen sicher, dass es mit 31 Einträgen übereinstimmt, und protokollieren alle „log“-Meldungen. Dann wird für jedes echte Muster eine Textbeschriftung über dem entsprechenden Balken gezeichnet und ein Alert() ausgelöst.
// extract patterns array
string patTxt; ExtractArray(resp, "patterns", patTxt);
string patt[]; ParseArray(patTxt, patt);
// draw+alert
for(int i=0;i<BARS;i++)
   if(patt[i]!="None")
   {
      datetime tm=iTime(_Symbol,InpTF,i+1);
      ObjectCreate(0,"CS_"+i,OBJ_TEXT,0,tm,iHigh(_Symbol,InpTF,i+1));
      ObjectSetString(0,"CS_"+i,OBJPROP_TEXT,patt[i]);
      Alert(_Symbol, " ", patt[i], " at ", TimeToString(tm,TIME_DATE|TIME_MINUTES));
   }


Tests und Ergebnisse

In diesem Abschnitt werden wir uns auf das Testen des Systems und die Analyse der Ergebnisse konzentrieren. Bevor wir fortfahren, sollten wir uns zunächst ansehen, wie man Python installiert und den Server so einrichtet, dass er reibungslos läuft.

Herunterladen

Der erste Schritt besteht darin, Python von der offiziellen Website. herunterzuladen und zu installieren. Klicken Sie auf die große gelbe Schaltfläche mit der Aufschrift „Python 3.x.x herunterladen“.

Starten des Installationsprogramms

Doppelklicken Sie auf die heruntergeladene Datei. Bevor Sie auf „Install Now“ klicken, aktivieren Sie das Kästchen „Add Python to PATH“. Dies macht es mühelos möglich, Python von überall in der Eingabeaufforderung auszuführen. Klicken Sie auf Install Now und dann auf Close, wenn der Vorgang abgeschlossen ist.

Überprüfung

Drücken Sie Win + R, geben Sie cmd ein und drücken Sie die Eingabetaste. Geben Sie in das schwarze Fenster, das sich öffnet, ein:

python --version

Sie sollten etwas wie Python 3.10.4 sehen. Wenn Sie dies tun, ist Python erfolgreich installiert.

Nachdem wir Python erfolgreich installiert haben, erstellen wir im nächsten Schritt unser Python-Skript.

Notepad++ öffnen

Starten Sie Notepad++ (oder einen anderen Texteditor Ihrer Wahl).

Eine neue Datei erstellen

Wählen Sie Datei => Neu und dann Sprache => P => Python für eine schöne Farbgebung (optional).

Einfügen des Server-Codes

Kopieren Sie den gesamten Inhalt von pattern_server.py (die Flask-App mit detect_patterns(df) und allem) und fügen Sie ihn in dieses neue Fenster ein.

Speichern Sie die Datei

  • Gehen Sie auf Datei => Speichern unter...
  • Navigieren Sie zu einem Ordner, den Sie sich merken können, z. B. C:\PatternServer\.
  • Geben Sie unter „Dateiname“ pattern_server.py ein (die Erweiterung .py ist entscheidend).
  • Klicken Sie auf Speichern.

Erforderliche Bibliotheken installieren

Öffnen der Eingabeaufforderung

Drücken Sie zunächst gleichzeitig die Windows-Taste + R, um das Dialogfeld Ausführen zu öffnen. Geben Sie cmd in das Eingabefeld ein und drücken Sie die Eingabetaste oder klicken Sie auf „OK“, um das Fenster der Eingabeaufforderung zu öffnen. Hier führen Sie Befehle aus, um in Ihrem System zu navigieren und Skripte auszuführen.

Verzeichnis ändern

Als Nächstes müssen Sie Windows zu dem Ordner leiten, der Ihr Python-Skript enthält. Verwenden Sie in der Eingabeaufforderung den Befehl cd (Verzeichnis wechseln), gefolgt von dem Pfad zu Ihrem Skriptordner. Zum Beispiel:

cd path\to\your\script\folder
Ersetzen Sie path\to\your\script\ordner durch den tatsächlichen Pfad auf Ihrem System. Dieser Schritt stellt sicher, dass Ihre Terminalsitzung auf den korrekten Speicherort Ihres Skripts verweist, sodass Sie es nahtlos ausführen können.

Flask und Pandas installieren

pip install flask pandas

Dadurch werden Flask (unser kleiner Webserver) und Pandas (für die Datenverarbeitung) heruntergeladen. Sie sehen dann etwas wie:

* Serving Flask app "pattern_server"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Das bedeutet, dass Ihr Microservice aktiv ist und auf Anfragen wartet. Als Nächstes kompilieren Sie Ihren MQL5 Expert Advisor (EA) und ziehen ihn auf den Chart. Diese Aktion stellt eine Verbindung zwischen dem EA und dem laufenden Python-Server her. Nachfolgend finden Sie die Ergebnisse und Beobachtungen, die wir nach der Ausführung des Systems erhalten haben. 

Test auf EURUSD

MetaTrader 5 Registerkarte Experten (Logs)

2025.07.09 22:25:42.248 Candlestick Label (EURUSD,M15)  [CSLAB] EA started – allow http://127.0.0.1:5000/patterns in Tools→Options→Expert Advisors→WebRequest
2025.07.09 22:25:42.790 Candlestick Label (EURUSD,M15)  [CSLAB] JSON-OUT: {"symbol":"EURUSD",
"timeframe":0,"time":[1752064200,1752065100,1752066000,1752066900,1752067800,1752068700,1752069600,
1752070500,1752071400,1752072300,1752073200,1752074100,1752075000,1752075900,1752076800,1752077700,
1752078600,1752079500,1752080400,1752081300,1752082200,1752083100,1752084000,1752084900,1752085800,
1752086700,1752087600,1752088500,1752089400,1752090300,1752091200],"open":[1.17051,1.17045,1.17153,
1.17167,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17148,1.17095,1.1706

2025.07.09 22:25:42.790 Candlestick Label (EURUSD,M15)  [CSLAB] POST http://127.0.0.1:5000/patterns
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] HTTP 200 RESP: {"patterns": ["doji",
 "bullishengulfing", "None", "None", "eveningstar", "None", "bullishengulfing", "None", "doji", 
"bearishengulfing", "None", "None", "None", "None", "None", "bearishengulfing", "None", "None", 
"bullishengulfing", "doji", "bearishengulfing", "None", "None", "None", "None", "None", "None",
 "None", "hammer", "eveningstar", "None"], "log": ["doji=3", "bullishengulfing=3", "eveningstar=2",
 "bearishengulfing=3", "hammer=1", "total patterns=12"], "ms": 128.25}
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: doji=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: bullishengulfing=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: eveningstar=2
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: bearishengulfing=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: hammer=1
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: total patterns=12

CMD Python-Logs

2025-07-09 22:25:42,806 [INFO] RAW BODY: {"symbol":"EURUSD","timeframe":0,"time":[1752064200,1752065100,1752066000,1752066900,1752067800,
1752068700,1752069600,1752070500,1752071400,1752072300,1752073200,1752074100,1752075000,1752075900,1752076800,1752077700,1752078600,
1752079500,1752080400,1752081300,1752082200,1752083100,1752084000,1752084900,1752085800,1752086700,1752087600,1752088500,1752089400,
1752090300,1752091200],"open":[1.17051,1.17045,1.17153,1.17167,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17148,1.17095,1.17066,
1.17085,1.17060,1.17072,1.17015,1.17066,1.17050,1.17087,1.17088,1.17059,1.17086,1.17174,1.17160,1.17105,1.17134,1.17166,1.17216,1.17226,
1.17189],"high":[1.17091,1.17170,1.17206,1.17225,1.17186,1.17098,1.17160,1.17246,1.17223,1.17194,1.17163,1.17112,1.17098,1.17103,1.17091,
1.17088,1.17071,1.17073,1.17109,1.17104,1.17092,1.17102,1.17179,1.17176,1.17164,1.17147,1.17170,1.17222,1.17232,1.17232,1.17199],
"low":[1.17008,1.17036,1.17120,1.17109,1.17088,1.17005,1.17028,1.17152,1.17152,1.17131,1.17095,1.17050,1.17055,1.17050,1.17059,1.17009,1.17013,
1.17039,1.17039,1.17077,1.17043,1.17056,1.17051,1.17141,1.17091,1.17101,1.17130,1.17163,1.17188,1.17180,1.17163],"close":[1.17045,
1.17153,1.17170,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17149,1.17096,1.17066,1.17086,1.17061,1.17072,1.17015,1.17067,
1.17050,1.17087,1.17088,1.17058,1.17087,1.17175,1.17160,1.17104,1.17133,1.17165,1.17216,1.17227,1.17189,1.17177]}
2025-07-09 22:25:42,934 [INFO] SEND: {'patterns': ['doji', 'bullishengulfing', 'None', 'None', 'eveningstar', 'None', 'bullishengulfing',
 'None', 'doji', 'bearishengulfing','None', 'None', 'None', 'None', 'None', 'bearishengulfing', 'None', 'None', 'bullishengulfing', 'doji',
 'bearishengulfing', 'None', 'None', 'None', 'None', 'None', 'None', 'None','hammer', 'eveningstar', 'None'], 'log': ['doji=3', 
'bullishengulfing=3', 'eveningstar=2', 'bearishengulfing=3', 'hammer=1', 'total patterns=12'], 'ms': 128.25}
2025-07-09 22:25:42,936 [INFO] 127.0.0.1 - - [09/Jul/2025 22:25:42] "POST /patterns HTTP/1.1" 200 -

Test auf Crash 1000


Schlussfolgerung

Zusammenfassend lässt sich sagen, dass diese zweiteilige Architektur - der MQL5 EA auf der einen Seite und der Python-Muster-Server auf der anderen - sich als robust und reaktionsschnell erweist. Der EA verpackt die OHLC-Daten jedes neuen Balkens sauber, sendet sie ab und rendert dann die zurückgegebenen Musteretiketten originalgetreu auf Ihrem Chart. In der Zwischenzeit nimmt der Python-Dienst diese JSON-Daten auf, durchläuft unsere handgefertigte Erkennungslogik und protokolliert jede Anfrage und jedes Ergebnis, um vollständige Transparenz zu gewährleisten. Zusammen bilden sie eine nahtlose Pipeline mit geringer Latenzzeit: Neue Balken treffen ein, Muster werden erkannt und Charts fast sofort aktualisiert. Die übersichtliche, strukturierte Protokollierung auf beiden Seiten stellt sicher, dass Sie immer genau wissen, was passiert, und macht die Fehlersuche einfach.

Insgesamt ist die Integration solide, die Leistung ist zuverlässig, und das System liefert genaue Kerzen-Einsichten in Echtzeit, genau wie geplant. Sie können je nach Bedarf weitere Kerzenmuster einbauen. Wie bereits erwähnt, werden wir uns in den kommenden Artikeln eingehender mit der Verwendung von Python-Bibliotheken für die Kerzen-Erkennung befassen und fortgeschrittenere Techniken und Tools vorstellen.





   
Chart Projector
Analytical Comment
Analytics Master
Analytics Forecaster 
Volatility Navigator
Der Mean Reversion Signal Reaper
Signal Pulse 
Metrics Board 
External Flow
VWAP
Heikin Ashi   FibVWAP  
RSI DIVERGENCE
Parabolic Stop and Reverse (PSAR) 
Quarters Drawer Script
Intrusion Detector
TrendLoom Tool  Quarters Board 
ZigZag Analyzer  Correlation Pathfinder  Market Structure Flip Detector Tool
Correlation Dashboard   Währungsstärkemesser 
PAQ-Analyse-Tool 
Dual EMA Fractal Breaker
Pin-Bar, Engulfing und RSI-Divergenz
Liquidity Sweep Werkzeug zum Ausbrechen aus dem Eröffnungsbereich Ausleger und Crash Interceptor CCI Zero-Line EA
Erkennen von Kerzenmuster          

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

Beigefügte Dateien |
patterns.py (5.24 KB)
Formulierung eines dynamischen Multi-Pair EA (Teil 3): Mean-Reversion- und Momentum-Strategien Formulierung eines dynamischen Multi-Pair EA (Teil 3): Mean-Reversion- und Momentum-Strategien
In diesem Artikel werden wir den dritten Teil unserer Reise zur Formulierung eines dynamischen Multi-Pair Expert Advisors (EA) erkunden und uns dabei speziell auf die Integration von Mean Reversion- und Momentum-Handelsstrategien konzentrieren. Wir werden aufschlüsseln, wie man Kursabweichungen vom Mittelwert (Z-Score) erkennt und darauf reagiert, und wie man das Momentum bei mehreren Devisenpaaren misst, um die Handelsrichtung zu bestimmen.
Automatisieren von Handelsstrategien in MQL5 (Teil 21): Verbesserung des Handels mit neuronalen Netzen durch adaptive Lernraten Automatisieren von Handelsstrategien in MQL5 (Teil 21): Verbesserung des Handels mit neuronalen Netzen durch adaptive Lernraten
In diesem Artikel verbessern wir eine Handelsstrategie mit neuronalen Netzen in MQL5 mit einer adaptiven Lernrate, um die Genauigkeit zu erhöhen. Wir entwerfen und implementieren diesen Mechanismus und testen anschließend seine Leistungsfähigkeit. Der Artikel schließt mit Optimierungserkenntnissen für den algorithmischen Handel.
MQL5-Assistenz-Techniken, die Sie kennen sollten (Teil 75): Verwendung des Awesome Oszillators und des Envelopes MQL5-Assistenz-Techniken, die Sie kennen sollten (Teil 75): Verwendung des Awesome Oszillators und des Envelopes
Der Awesome Oscillator von Bill Williams und der Envelopes-Kanal sind ein Paar, das komplementär in einem MQL5 Expert Advisor verwendet werden kann. Wir verwenden den Awesome Oscillator wegen seiner Fähigkeit, Trends zu erkennen, während der Envelope-Kanal zur Definition unserer Unterstützungs-/Widerstandsniveaus herangezogen wird. Bei der Erkundung dieser Indikatorpaarung verwenden wir den MQL5-Assistenten, um das Potenzial dieser beiden Indikatoren zu ermitteln und zu testen.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 72): Verwendung der Muster von MACD und OBV mit überwachtem Lernen MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 72): Verwendung der Muster von MACD und OBV mit überwachtem Lernen
Wir knüpfen an unseren letzten Artikel an, in dem wir das Indikatorpaar MACD und OBV vorgestellt haben, und untersuchen, wie dieses Paar durch maschinelles Lernen verbessert werden kann. MACD und OBV ergänzen sich in Bezug auf Trend und Volumen. Unser Ansatz des maschinellen Lernens verwendet ein neuronales Faltungsnetzwerk, das bei der Feinabstimmung der Prognosen dieses Indikatorpaares den Exponential-Kernel bei der Dimensionierung seiner Kerne und Kanäle einsetzt. Wie immer wird dies in einer nutzerdefinierten Signalklassendatei durchgeführt, die mit dem MQL5-Assistenten arbeitet, um einen Expert Advisor zusammenzustellen.