English
preview
Automatisieren von Handelsstrategien in MQL5 (Teil 46): Liquidity Sweep on Break of Structure (BoS)

Automatisieren von Handelsstrategien in MQL5 (Teil 46): Liquidity Sweep on Break of Structure (BoS)

MetaTrader 5Handel |
25 5
Allan Munene Mutiiria
Allan Munene Mutiiria

Einführung

In unserem vorangegangenen Artikel (Teil 45) haben wir das System von Inverse Fair Value Gap (IFVG) in MetaQuotes Language 5 (MQL5) entwickelt, das Kurslücken mit einer Mindestgrößenfilterung erkennt, Zustände als normal/gemildert/invertiert verfolgt, Überschneidungen ignoriert, Inversionen mit festen Stop-Levels, Handelsmodi und Trailing-Stops handelt und Rechtecke mit Kennzeichnungen/Symbolen visualisiert. In Teil 46 entwickeln wir das System der Liquiditätsbereinigung (Liquidity-Sweeps) bei einem Strukturbruch (BoS).

Dieses System erkennt Schwankungen über eine definierte Zeitspanne, kennzeichnet sie als Schwankungen, um BoS, den Strukturbruch, zu identifizieren (HH in Aufwärtstrends, LL in Abwärtstrends), erkennt Bereinigungen, wenn der Kurs über die Umkehrpunkte hinausschießt, aber bei innerhalb der dem Trend entsprechenden Kerzen schließt, kauft bei der Bereinigung einer Sell-Side-Liquidität (SSL) in einem Aufwärts-BoS oder verkauft bei Buy Side-Liquidität (BSL) in Abwärtstrends mit dynamischen Stop-Levels, maximalen Handelsvolumina, schließt Gegenpositionen und visualisiert mit Symbolen/Kennzeichnungen, Rechtecken, gestrichelten Linien und Pfeilen sowie dynamischen Schriftarten. Wir werden die folgenden Themen behandeln: Wir werden die folgenden Themen behandeln:

  1. Verständnis der Strategie der Liquiditätsbereinigung bei einem Strukturbruch (BoS)
  2. Implementation in MQL5
  3. Backtests
  4. Schlussfolgerung

Am Ende verfügen Sie über eine funktionsfähige MQL5-Strategie für den Handel mit BoS-Liquiditäts-Sweeps, komplett mit visuellen Darstellungen und Risikokontrollen – fangen wir an!


Verständnis der Strategie der Liquiditätsbereinigung bei einem Strukturbruch (BoS)

Die Liquiditätsbereinigung bei einem Strukturbruch (BoS) ist eine Preisaktionsstrategie, die Trendidentifikation durch Umkehrpunkte mit der Erkennung von manipulativen Bereinigungen über diese Punkte hinaus kombiniert, um Liquidität vor einer Umkehr abzufangen. Wir scannen die umliegenden Balken, um hohe Umkehrpunkte (höher als die linken/rechten Nachbarn) und tiefe (niedriger) zu finden, und kennzeichnen sie relativ zu den Prioritäten: HH (höheres Hoch) oder LH (niedrigeres Hoch) für Höchstwerte, HL (höheres Tief) oder LL (niedrigeres Tief) für Tiefstwerte. BoS tritt bei HH in Aufwärtstrends (Aufwärts-Fortsetzung) oder LL in Abwärtstrends (fallend) auf und signalisiert einen Strukturbruch; eine Bereinigung tritt auf, wenn der Preis über den Umkehrpunkt hinausgeht (SSL unter dem Tiefpunkt in einem Aufwärtstrend, BSL über dem Hochpunkt in einem Abwärtstrend), aber innerhalb einer Richtungskerze schließt, was auf ein Einfangen der Stops vor der eigentlichen Bewegung hinweist.

Unser Plan ist es, Schwankungen über die Eingabelänge zu erkennen, HH/HL/LH/LL zu markieren, um den BoS-Trend festzulegen, Bereinigungen auf dem BoS mit Docht außerhalb des Umkehrpunkte zu erkennen und innerhalb der Trend-Kerze zu schließen, Käufe bei einem SSL und einem Aufwärts-BoS oder Verkäufe bei einem BSL und einem Abwärts-BoS mit dynamischen Handelsniveaus, maximalen Handelslimits, entgegengesetzten Schließungen zu handeln und mit Icons/Labels auf Umkehrpunkte, Rechtecken der Bereinigungen, gestrichelten Linien auf BoS-Ausbrüchen, Pfeilen auf Eingängen sowie dynamischen Schriftarten auf Skalenänderungen zu visualisieren. Liquidity-Sweep kann für jede Konstellation verwendet werden; wir haben uns für die Strategie des Strukturbruchs entschieden, weil sie einfach ist, aber sie kann auch für jede andere Konstellation verwendet werden, wie z.B. für Ungleichgewichte. Kurz gesagt, hier ist eine visuelle Darstellung unserer Ziele.

SYSTEM DER LIQUIDITÄTSBEREINIGUNG MIT BoS


Implementation in MQL5

Um das Programm in MQL5 zu erstellen, öffnen wir den MetaEditor, gehen zum Navigator, suchen den Ordner „Experts“, klicken auf die Registerkarte „Neu“ und folgen den Anweisungen, um die Datei zu erstellen. Sobald sie erstellt ist, müssen wir in der Programmierumgebung einige Eingabeparameter und globale Variablen deklarieren, die wir im gesamten Programm verwenden werden.

//+------------------------------------------------------------------+
//|                                       BOS Liquidity Sweep EA.mq5 |
//|                           Copyright 2025, Allan Munene Mutiiria. |
//|                                   https://t.me/Forex_Algo_Trader |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Allan Munene Mutiiria."
#property link      "https://t.me/Forex_Algo_Trader"
#property version   "1.00"

#include <Trade/Trade.mqh>

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
CTrade obj_Trade;                                                 //--- Trade object

//+------------------------------------------------------------------+
//| Input Parameters                                                 |
//+------------------------------------------------------------------+
input group "EA GENERAL SETTINGS"
input int    SwingLength       = 5;                               // Swing Length in Bars (left/right check)
input double LotSize           = 0.01;                            // Fixed lot size
input double SL_Buffer_Pips    = 10.0;                            // SL buffer in pips below/above sweep
input double RiskRewardRatio   = 2.0;                             // Take profit multiplier (e.g., 2:1 RR)
input int    MaxTrades         = 1;                               // Max open trades
input long   MagicNumber       = 12345;                           // Unique magic number
input group "VISUALIZATION SETTINGS"
input color  clr_Bullish       = clrBlue;                         // Bullish Color (HH/HL)
input color  clr_Bearish       = clrRed;                          // Bearish Color (LL/LH)
input color  clr_SSL_Rect      = clrLightBlue;                    // SSL Sweep Rectangle Color
input color  clr_BSL_Rect      = clrLightCoral;                   // BSL Sweep Rectangle Color
input color  clr_SSL_Line      = clrBlue;                         // SSL Sweep Line Color
input color  clr_BSL_Line      = clrRed;                          // BSL Sweep Line Color
input color  clr_BullBOS       = clrGreen;                        // Bullish BOS Line Color
input color  clr_BearBOS       = clrMaroon;                       // Bearish BOS Line Color
input int    LineWidth         = 2;                               // Line Width
input bool   PrintLogs         = true;                            // Print Statements

//+------------------------------------------------------------------+
//| Global Variables Continued                                       |
//+------------------------------------------------------------------+
static double   current_swing_high = -1.0, current_swing_low = -1.0; //--- Current swing high and low
static datetime swing_high_time = 0, swing_low_time = 0;          //--- Swing high and low times
int    MarketTrend = 0;                                           //--- Market trend (1: Bullish BOS, -1: Bearish BOS, 0: Neutral)
int    OpenTrades = 0;                                            //--- Open trades count
int    current_font_size = 10;                                    //--- Current font size
int    object_code = 174;                                         //--- Wingdings arrow code for swings
int    buy_arrow_code = 233;                                      //--- Wingdings up arrow for buy
int    sell_arrow_code = 234;                                     //--- Wingdings down arrow for sell
string ObjPrefix = "BOSLiqSweep_";                                //--- Object prefix

Wir beginnen die Implementierung, indem wir die Handelsbibliothek mit „#include <Trade/Trade.mqh>“ einbinden, die die Klasse CTrade für die Auftrags- und Positionsverwaltung bereitstellt. Wir deklarieren „obj_Trade“ als eine globale Instanz von „CTrade“, um Handelsoperationen abzuwickeln. Wir gruppieren die Eingabeparameter unter „EA GENERAL SETTINGS“ für den Eigenschaftsdialog: „SwingLength“, um die Anzahl der Balken für Links-/Rechts-Prüfungen der Umkehrpunkte festzulegen, „LotSize“ für feste Lots, „SL_Buffer_Pips“ als Puffer unterhalb/oberhalb der Bereinigung für Stop-Loss, „RiskRewardRatio“ für Take-Profit-Multiples, „MaxTrades“, um offene Positionen zu begrenzen, und „MagicNumber“ für die Handelsidentifikation. Unter „VISUALISIERUNGSEINSTELLUNGEN“ haben wir Farben wie „clr_Bullish“ für HH/HL (blau), „clr_Bearish“ für LL/LH (rot), „clr_SSL_Rect“ für SSL-Rechtecke (hellblau), „clr_BSL_Rect“ für BSL (hellkoralle), „clr_SSL_Line“ für SSL-Linien (blau), „clr_BSL_Line“ für BSL (rot), „clr_BullBoS“ für Aufwärts-BoS (grün), „clr_BearBoS“ für Abwärts-BoS (kastanienbraun), „LineWidth“ für die Linienstärke und „PrintLogs“ zum Umschalten der Protokollierung.

EINGANGSPARAMETER

Dann kommen wir zu den weiteren globalen Variablen: statische „current_swing_high“ und „current_swing_low“, initialisiert auf -1.0 für die Verfolgung der letzten Schwankungen, statische „swing_high_time“ und „swing_low_time“ für ihre Zeitstempel, „MarketTrend“ als 1 für Aufwärts-BoS, -1 für Abwärts-BoS, 0 für neutral, „OpenTrades“ zum Zählen der aktuellen Positionen, „current_font_size“ mit 10 für dynamischen Text, „object_code“ mit 174 für das Symbol aus Wingdings, „buy_arrow_code“ mit 233 für Kaufpfeile, „sell_arrow_code“ mit 234 für Verkaufspfeile und „ObjPrefix“ mit „BoSLiqSweep_“ für die Benennung der Objekte. Nun können wir die Programmlogik initialisieren. Wir wollen die Objekte, die wir bei der Initialisierung erstellen, löschen, um das bestehende Durcheinander zu beseitigen. Wir werden zunächst einige Hilfsfunktionen definieren.

//+------------------------------------------------------------------+
//| Update font sizes                                                |
//+------------------------------------------------------------------+
void UpdateFontSizes() {
   long scale = 0;                                                //--- Init scale
   if (ChartGetInteger(0, CHART_SCALE, 0, scale)) {               //--- Get scale
      current_font_size = (int)(7 + scale * 0.7);                 //--- Calculate font size
      if (current_font_size < 6) current_font_size = 6;           //--- Set minimum font size
      if (current_font_size > 15) current_font_size = 15;         //--- Set maximum font size
      for (int i = ObjectsTotal(0, -1, -1) - 1; i >= 0; i--) {    //--- Iterate objects reverse
         string name = ObjectName(0, i, -1, -1);                  //--- Get object name
         long type = ObjectGetInteger(0, name, OBJPROP_TYPE);     //--- Get object type
         if (type == OBJ_TEXT) {                                  //--- Check text type
            ObjectSetInteger(0, name, OBJPROP_FONTSIZE, current_font_size); //--- Set font size
         }
      }
      ChartRedraw(0);                                             //--- Redraw chart
   }
}

//+------------------------------------------------------------------+
//| Delete objects by prefix                                         |
//+------------------------------------------------------------------+
void DeleteObjectsByPrefix(string prefix) {
   int total = ObjectsTotal(0, 0, -1);                            //--- Get total objects
   for (int i = total - 1; i >= 0; i--) {                         //--- Iterate reverse
      string name = ObjectName(0, i, 0, -1);                      //--- Get name
      if (StringFind(name, prefix) == 0) {                        //--- Check prefix
         ObjectDelete(0, name);                                   //--- Delete object
      }
   }
}

//+------------------------------------------------------------------+
//| Count open trades                                                |
//+------------------------------------------------------------------+
int CountOpenTrades() {
   int count = 0;                                                 //--- Init count
   for (int i = PositionsTotal() - 1; i >= 0; i--) {              //--- Iterate reverse
      ulong ticket = PositionGetTicket(i);                        //--- Get ticket
      if (PositionSelectByTicket(ticket)) {                       //--- Select position
         if (PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) { //--- Check symbol and magic
            count++;                                              //--- Increment count
         }
      }
   }
   return count;                                                  //--- Return count
}

Hier implementieren wir die Funktion „UpdateFontSizes“, um die Größe der Textobjekte im Chart dynamisch an die aktuelle Zoomstufe anzupassen und so die Lesbarkeit zu gewährleisten. Wir initialisieren „scale“ auf 0 und rufen den Skalenwert des Charts mit ChartGetInteger unter Verwendung von CHART_SCALE ab. Bei Erfolg wird „current_font_size“ als 7 plus 70 % der Skala berechnet, sodass der Wert zwischen 6 und 15 liegt. Anschließend werden alle Objekte im Chart in einer Schleife rückwärts durchlaufen, wobei ObjectsTotal -1 für alle Fenster und Typen angibt und jeder Name über ObjectName und jeder Typ mit ObjectGetInteger und OBJPROP_TYPE abgerufen wird. Bei OBJ_TEXT-Objekten wird die Schriftgröße mit ObjectSetInteger und OBJPROP_FONTSIZE aktualisiert und das Chart dann neu gezeichnet.

Wir definieren die Funktion „DeleteObjectsByPrefix“, um alle Chartobjekte zu entfernen, die mit einem bestimmten Präfix übereinstimmen, der zum Aufräumen verwendet wird. Wir ermitteln die Gesamtzahl der Objekte im Hauptdiagramm und alle Typen und führen dann eine Rückwärtsschleife durch: für jedes Objekt holen wir den Namen, prüfen, ob es mit dem Präfix beginnt, indem wir StringFind verwenden, das 0 zurückgibt, und löschen es über ObjectDelete, wenn es übereinstimmt. Wir erstellen die Funktion „CountOpenTrades“, um die aktuellen offenen Positionen zu zählen, die zu diesem Programm gehören. Wir initialisieren „count“ auf 0, durchlaufen eine Schleife rückwärts durch PositionsTotal, rufen jedes Ticket mit PositionGetTicket ab und wählen die Position mit der Funktion PositionSelectByTicket aus. Wenn das Symbol mit „PositionGetString“ und „POSITION_SYMBOL“ und die magische Zahl mit „PositionGetInteger“ und „POSITION_MAGIC“ übereinstimmen erhöhen wir „count“, bevor wir es zurückgeben. Wir werden einige weitere Hilfsfunktionen für die Visualisierung definieren.

//+------------------------------------------------------------------+
//| Draw swing point with label                                      |
//+------------------------------------------------------------------+
void DrawSwingPoint(string objName, datetime time, double price, int arrCode, color clr, int direction, string label) {
   UpdateFontSizes();                                             //--- Update font sizes
   objName = ObjPrefix + label + TimeToString(time);              //--- Set obj name
   if (ObjectFind(0, objName) < 0) {                              //--- Check no object
      string iconName = objName + "_icon";                        //--- Icon name
      ObjectCreate(0, iconName, OBJ_TEXT, 0, time, price);        //--- Create icon
      ObjectSetString(0, iconName, OBJPROP_FONT, "Wingdings");    //--- Set font
      ObjectSetInteger(0, iconName, OBJPROP_FONTSIZE, current_font_size); //--- Set font size
      ObjectSetString(0, iconName, OBJPROP_TEXT, CharToString((uchar)arrCode)); //--- Set text
      ObjectSetInteger(0, iconName, OBJPROP_COLOR, clr);          //--- Set color
      ObjectSetInteger(0, iconName, OBJPROP_ANCHOR, ANCHOR_RIGHT); //--- Set anchor
      string txtName = objName + "_txt";                          //--- Text name
      ObjectCreate(0, txtName, OBJ_TEXT, 0, time, price);         //--- Create text
      ObjectSetString(0, txtName, OBJPROP_FONT, "Arial");         //--- Set font
      ObjectSetInteger(0, txtName, OBJPROP_COLOR, clr);           //--- Set color
      ObjectSetInteger(0, txtName, OBJPROP_FONTSIZE, current_font_size); //--- Set font size
      ObjectSetInteger(0, txtName, OBJPROP_ANCHOR, ANCHOR_LEFT);  //--- Set anchor
      ObjectSetString(0, txtName, OBJPROP_TEXT, label);           //--- Set text
   }
   ChartRedraw(0);                                                //--- Redraw chart
}

//+------------------------------------------------------------------+
//| Draw sweep rectangle (no text)                                   |
//+------------------------------------------------------------------+
void DrawSweepRectangle(string objName, datetime time, double level, double extremum, color clr, bool is_ssl) {
   UpdateFontSizes();                                             //--- Update font sizes
   objName = ObjPrefix + objName + TimeToString(time, TIME_SECONDS); //--- Set obj name
   if (ObjectFind(0, objName) < 0) {                              //--- Check no object
      double top = MathMax(level, extremum);                      //--- Calc top
      double bottom = MathMin(level, extremum);                   //--- Calc bottom
      datetime end_time = time + PeriodSeconds(_Period);          //--- Calc end time
      ObjectCreate(0, objName, OBJ_RECTANGLE, 0, time, top, end_time, bottom); //--- Create rectangle
      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);           //--- Set color
      ObjectSetInteger(0, objName, OBJPROP_BACK, true);           //--- Set back
      ObjectSetInteger(0, objName, OBJPROP_FILL, true);           //--- Set fill
      ObjectSetInteger(0, objName, OBJPROP_STYLE, STYLE_SOLID);   //--- Set style
      // No text inside rectangle to reduce clutter
   }
   ChartRedraw(0);                                                //--- Redraw chart
}

//+------------------------------------------------------------------+
//| Draw horizontal dashed break level                               |
//+------------------------------------------------------------------+
void DrawBreakLevel(string objName, datetime time1, double price, datetime time2, double price2, color clr, int direction, string label) {
   UpdateFontSizes();                                             //--- Update font sizes
   objName = ObjPrefix + objName + label + TimeToString(time2, TIME_SECONDS); //--- Set obj name
   if (ObjectFind(0, objName) < 0) {                              //--- Check no object
      ObjectCreate(0, objName, OBJ_TREND, 0, time1, price, time2, price); //--- Create trend line
      ObjectSetInteger(0, objName, OBJPROP_COLOR, clr);           //--- Set color
      ObjectSetInteger(0, objName, OBJPROP_WIDTH, LineWidth);     //--- Set width
      ObjectSetInteger(0, objName, OBJPROP_STYLE, STYLE_DASH);    //--- Set style
      ObjectSetInteger(0, objName, OBJPROP_RAY_RIGHT, false);     //--- Set no ray right
      string txt = label + " Sweep";                              //--- Set text
      string txtName = objName + "_txt";                          //--- Text name
      ObjectCreate(0, txtName, OBJ_TEXT, 0, time2, price);        //--- Create text
      ObjectSetInteger(0, txtName, OBJPROP_COLOR, clr);           //--- Set color
      ObjectSetInteger(0, txtName, OBJPROP_FONTSIZE, current_font_size); //--- Set font size
      if (direction > 0) {                                        //--- Check positive
         ObjectSetInteger(0, txtName, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER); //--- Set anchor
         ObjectSetString(0, txtName, OBJPROP_TEXT, " " + txt);    //--- Set text
      } else {                                                    //--- Negative
         ObjectSetInteger(0, txtName, OBJPROP_ANCHOR, ANCHOR_RIGHT_LOWER); //--- Set anchor
         ObjectSetString(0, txtName, OBJPROP_TEXT, " " + txt);    //--- Set text
      }
   }
   ChartRedraw(0);                                                //--- Redraw chart
}

//+------------------------------------------------------------------+
//| Draw entry arrow with Wingdings                                  |
//+------------------------------------------------------------------+
void DrawEntryArrow(datetime time, double price, bool is_buy) {
   UpdateFontSizes();                                             //--- Update font sizes
   string objName = ObjPrefix + "Entry_" + TimeToString(time, TIME_SECONDS); //--- Set obj name
   if (ObjectFind(0, objName) < 0) {                              //--- Check no object
      int arrCode = is_buy ? buy_arrow_code : sell_arrow_code;    //--- Set arrow code
      color arrow_color = is_buy ? clrBlue : clrRed;              //--- Set color
      ObjectCreate(0, objName, OBJ_TEXT, 0, time, price);         //--- Create text
      ObjectSetString(0, objName, OBJPROP_FONT, "Wingdings");     //--- Set font
      ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, current_font_size); //--- Set font size
      ObjectSetString(0, objName, OBJPROP_TEXT, CharToString((uchar)arrCode)); //--- Set text
      ObjectSetInteger(0, objName, OBJPROP_COLOR, arrow_color);   //--- Set color
      ObjectSetInteger(0, objName, OBJPROP_ANCHOR, is_buy ? ANCHOR_UPPER : ANCHOR_LOWER); //--- Set anchor
   }
   ChartRedraw(0);                                                //--- Redraw chart
}

Zunächst definieren wir die Funktion „DrawSwingPoint“, um erkannte Umkehrpunkte im Chart mit einem Symbol und einer Kennzeichnung zu visualisieren. Wir rufen „UpdateFontSizes“ auf, um die aktuelle Schriftgröße zu gewährleisten, und bilden einen eindeutigen Objektnamen, indem wir „ObjPrefix“, die Bezeichnung und die Zeitangabe kombinieren. Wenn kein Objekt per ObjectFind existiert, erstellen wir ein Wingdings-Icon als OBJ_TEXT mit dem Suffix „_icon“ bei Zeit und Preis, setzen die Schriftart auf Wingdings, die Größe auf „current_font_size“, den Text auf das Zeichen aus „arrCode“ via CharToString, die Farbe auf „clr“ und den Anker rechts. Dann erstellen wir die Textbeschriftung mit dem Suffix „_txt“ als ein weiteres „OBJ_TEXT“, verwenden die Schriftart Arial, dieselbe Farbe und Größe, setzen den Anker links und den Text auf „label“. Wir zeichnen das Chart mit der Funktion ChartRedraw neu.

Dann implementieren wir die Funktion „DrawSweepRectangle“, um ein gefülltes Rechteck zu zeichnen, das den Sweep-Bereich ohne internen Text hervorhebt, um Unordnung zu vermeiden. Wir rufen „UpdateFontSizes“ auf, bilden den Namen mit „ObjPrefix“ und die Zeit mit Sekunden als Zeichenkette. Wenn kein Objekt vorhanden ist, berechnen wir oben als Maximum von Level und Extremum, unten als Minimum, die Endzeit als Zeit plus eine Balkenperiode, erstellen OBJ_RECTANGLE, das die Zeit oben bis zum Ende unten überspannt, setzen die Farbe auf „clr“, back true, fill true, solid style, und zeichnen das Chart neu. Wir erstellen die Funktion „DrawBreakLevel“, um BoS-Unterbrechungen mit einer horizontalen gestrichelten Linie und Text zu markieren. Wir rufen „UpdateFontSizes“, Formularname mit „ObjPrefix“, Label und Zeit 2 Sekunden String. Wenn kein Objekt vorhanden ist, erstellen wir OBJ_TREND vom Zeitpunkt 1 zum Preis zum Zeitpunkt 2 zum Preis (horizontal), setzen die Farbe auf „clr“, die Breite auf „LineWidth“, den Stil auf Strichform, nicht als Strahl nach rechts. Wir fügen den Text als „OBJ_TEXT“ zum Zeitpunkt 2 und den Preis mit dem Suffix „_txt“ hinzu, die Farbe setzen wir auf „clr“, die Größe auf „current_font_size“, den Anker nach rechts-oben, wenn die Richtung positiv ist, oder rechts-unten, wenn negativ.

Schließlich definieren wir die Funktion „DrawEntryArrow“, um einen Wingdings-Pfeil zu platzieren, der Handelseinträge anzeigt. Wir rufen „UpdateFontSizes“ auf, formen den Namen mit „ObjPrefix + "Entry_" + Zeitstring mit Sekunden“. Wenn kein Objekt vorhanden ist, wählen wir „arrCode“ als „buy_arrow_code“ für Käufe oder „sell_arrow_code“ für Verkäufe, Farbe als blau für Käufe oder rot für Verkäufe, erstellen „OBJ_TEXT“ zu Zeit und Preis, setzen die Schriftart auf „Wingdings“, die Größe auf „current_font_size“, den Text auf das Zeichen aus „arrCode“, die Farbe und den Anker oben für „buys“ oder unten für „sells“, und zeichnen das Chart neu. Wir können nun mit der Initialisierung fortfahren, um die Eingabevariablen zu bereinigen und zu überprüfen.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   obj_Trade.SetExpertMagicNumber(MagicNumber);                   //--- Set magic number for trade object
   if (SwingLength < 1 || LotSize <= 0 || SL_Buffer_Pips < 0 || RiskRewardRatio < 1.0 || MaxTrades < 1) { //--- Check invalid inputs
      Print("Invalid input parameters.");                         //--- Log invalid parameters
      return(INIT_PARAMETERS_INCORRECT);                          //--- Return incorrect parameters
   }
   DeleteObjectsByPrefix(ObjPrefix);                              //--- Delete objects by prefix
   UpdateFontSizes();                                             //--- Update font sizes
   Print("EA Initialized Successfully.");                         //--- Log initialization success
   return(INIT_SUCCEEDED);                                        //--- Return success
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   DeleteObjectsByPrefix(ObjPrefix);                              //--- Delete objects by prefix
   Print("EA Deinitialized.");                                    //--- Log deinitialization
}

In der Ereignisbehandlung von OnInit, die ausgeführt wird, wenn das Programm an einen Chart angehängt oder geladen wird, setzen wir die Eingabe „MagicNumber“ auf „obj_Trade“ mit „SetExpertMagicNumber“, um unsere Trades zu identifizieren. Anschließend werden die wichtigsten Eingaben überprüft: Wenn „SwingLength“ kleiner als 1 ist, „LotSize“ nicht positiv ist, „SL_Buffer_Pips“ negativ ist, „RiskRewardRatio“ unter 1,0 liegt oder „MaxTrades“ kleiner als 1 ist, wird „Invalid input parameters“ mit Print protokolliert und INIT_PARAMETERS_INCORRECT zurückgegeben. Andernfalls rufen wir „DeleteObjectsByPrefix“ auf, um das vorhandene Bildmaterial zu löschen, „UpdateFontSizes“, um die anfängliche Textgröße festzulegen, protokollieren „EA Initialized Successfully“ und geben INIT_SUCCEEDED zurück. In der Ereignisbehandlung von OnDeinit, der aufgerufen wird, wenn das Programm beendet oder das Terminal geschlossen wird, rufen wir „DeleteObjectsByPrefix“ auf, um alle Chartobjekte, die unserem Präfix entsprechen, zu entfernen und so ein sauberes Ende ohne visuelle Überreste zu gewährleisten. Wir können nun mit der nächsten Logik in der Ereignisbehandlung von OnTick fortfahren, um die ganze schwere Arbeit zu erledigen. Wir werden mit der Erkennung von Schwankungen und Brüchen beginnen.

//+------------------------------------------------------------------+
//| Detect swings and BOS                                            |
//+------------------------------------------------------------------+
void DetectSwingsAndBOS() {
   int curr_bar = SwingLength;                                    //--- Set current bar
   bool isSwingHigh = true, isSwingLow = true;                    //--- Init swing flags
   for (int j = 1; j <= SwingLength; j++) {                       //--- Iterate length
      int right_index = curr_bar - j;                             //--- Calc right index (newer)
      int left_index = curr_bar + j;                              //--- Calc left index (older)
      if (iHigh(_Symbol, _Period, curr_bar) <= iHigh(_Symbol, _Period, right_index) || iHigh(_Symbol, _Period, curr_bar) < iHigh(_Symbol, _Period, left_index)) { //--- Check not high
         isSwingHigh = false;                                     //--- Set not high
      }
      if (iLow(_Symbol, _Period, curr_bar) >= iLow(_Symbol, _Period, right_index) || iLow(_Symbol, _Period, curr_bar) > iLow(_Symbol, _Period, left_index)) { //--- Check not low
         isSwingLow = false;                                      //--- Set not low
      }
   }
   if (isSwingHigh) {                                             //--- Check swing high
      double new_high = iHigh(_Symbol, _Period, curr_bar);        //--- Get new high
      string label = "H";                                         //--- Init label
      color clr = clr_Bullish;                                    //--- Set color
      if (current_swing_high > 0) {                               //--- Check existing high
         if (new_high > current_swing_high) {                     //--- Check higher
            label = "HH";                                         //--- Set HH
            MarketTrend = 1;                                      //--- Set bullish trend
            if (PrintLogs) Print("Bullish BOS Detected");         //--- Log bullish BOS
            datetime break_time = FindBreakTime(swing_high_time, current_swing_high, true); //--- Find break time
            if (break_time > 0) DrawBreakLevel("Bull_BOS_", swing_high_time, current_swing_high, break_time, current_swing_high, clr_BullBOS, -1, "Bullish BOS"); //--- Draw BOS
         } else {                                                 //--- Lower
            label = "LH";                                         //--- Set LH
            clr = clr_Bearish;                                    //--- Set bearish color
         }
      }
      if (PrintLogs) Print("SWING HIGH @ BAR INDEX ", curr_bar, " of High: ", new_high, " Label: ", label); //--- Log high
      DrawSwingPoint(TimeToString(iTime(_Symbol, _Period, curr_bar)), iTime(_Symbol, _Period, curr_bar), new_high, object_code, clr, -1, label); //--- Draw high point
      current_swing_high = new_high;                              //--- Update high
      swing_high_time = iTime(_Symbol, _Period, curr_bar);        //--- Update high time
   }
   if (isSwingLow) {                                              //--- Check swing low
      double new_low = iLow(_Symbol, _Period, curr_bar);          //--- Get new low
      string label = "L";                                         //--- Init label
      color clr = clr_Bearish;                                    //--- Set color
      if (current_swing_low > 0) {                                //--- Check existing low
         if (new_low < current_swing_low) {                       //--- Check lower
            label = "LL";                                         //--- Set LL
            MarketTrend = -1;                                     //--- Set bearish trend
            if (PrintLogs) Print("Bearish BOS Detected");         //--- Log bearish BOS
            datetime break_time = FindBreakTime(swing_low_time, current_swing_low, false); //--- Find break time
            if (break_time > 0) DrawBreakLevel("Bear_BOS_", swing_low_time, current_swing_low, break_time, current_swing_low, clr_BearBOS, 1, "Bearish BOS"); //--- Draw BOS
         } else {                                                 //--- Higher
            label = "HL";                                         //--- Set HL
            clr = clr_Bullish;                                    //--- Set bullish color
         }
      }
      if (PrintLogs) Print("SWING LOW @ BAR INDEX ", curr_bar, " of Low: ", new_low, " Label: ", label); //--- Log low
      DrawSwingPoint(TimeToString(iTime(_Symbol, _Period, curr_bar)), iTime(_Symbol, _Period, curr_bar), new_low, object_code, clr, 1, label); //--- Draw low point
      current_swing_low = new_low;                                //--- Update low
      swing_low_time = iTime(_Symbol, _Period, curr_bar);         //--- Update low time
   }
}

//+------------------------------------------------------------------+
//| Find break candle time (based on close)                          |
//+------------------------------------------------------------------+
datetime FindBreakTime(datetime prev_time, double prev_level, bool is_high_break) {
   int prev_shift = iBarShift(_Symbol, _Period, prev_time);       //--- Get prev shift
   if (prev_shift < 0) return 0;                                  //--- Return invalid
   for (int i = prev_shift - 1; i >= 0; i--) {                    //--- Iterate reverse
      if (is_high_break) {                                        //--- Check high break
         if (iClose(_Symbol, _Period, i) > prev_level) return iTime(_Symbol, _Period, i); //--- Return time if break
      } else {                                                    //--- Low break
         if (iClose(_Symbol, _Period, i) < prev_level) return iTime(_Symbol, _Period, i); //--- Return time if break
      }
   }
   return 0;                                                      //--- Return no break
}

Um die Erkennungslogik unterzubringen, definieren wir die Funktion „DetectSwingsAndBoS“, um Umkehrpunkte zu identifizieren und Strukturbrüche bei jedem neuen Balken zu erkennen, wobei die Trendrichtung und das Bildmaterial entsprechend aktualisiert werden. Wir setzen „curr_bar“ auf „SwingLength“ als Zielbalken zum Scannen, initialisieren „isSwingHigh“ und „isSwingLow“ auf true. Dann wird eine Schleife von 1 bis „SwingLength“ durchlaufen: Für jedes j wird „right_index“ als „curr_bar - j“ (jüngere Balken) und „left_index“ als „curr_bar + j“ (ältere Balken) berechnet, wobei überprüft wird, ob das Hoch des aktuellen Balkens nicht streng über dem rechten und linken Hoch liegt.Wenn diese Bedingung nicht erfüllt ist, wird „isSwingHigh“ auf „false“ gesetzt. Ähnlich verhält es sich mit den Tiefs, wobei „isSwingLow“ auf „false“ gesetzt wird, wenn sie nicht streng genommen niedriger sind.

Wenn „isSwingHigh“ wahr bleibt, erfassen wir das Hoch in „new_high“, initialisieren das Label als „H“ und die Farbe als „clr_Bullish“. Wenn ein vorheriger Wert von „current_swing_high“ vorhanden ist, vergleichen wir ihn: Ist er höher, kennzeichnen wir ihn mit „HH“, setzen „MarketTrend“ auf 1 (aufwärts) und protokollieren „Bullish BoS Detected“, sofern „PrintLogs“ auf „true“ gesetzt ist; ermitteln wir die Durchbruchzeit mit „FindBreakTime“ unter Verwendung von „swing_high_time“, „current_swing_high“ und „true“ für einen Durchbruch nach oben, und falls gültig, rufen wir „DrawBreakLevel“ mit dem Präfix „Bull_BoS_“, Zeiten, Level, „clr_BullBoS“, Richtung -1 und dem Text „Bullish BoS“ auf.

Ist er niedriger, kennzeichnen wir ihn mit „LH“ und der Farbe „clr_Bearish“. Wir protokollieren den Umkehrpunkt mit „PrintLogs“, rufen „DrawSwingPoint“ mit time string, time, price, „object_code“, color, direction -1, label auf, aktualisieren „current_swing_high“ und „swing_high_time“. Wir spiegeln für den tiefen Umkehrpunkt. Wir implementieren die Funktion „FindBreakTime“, um den ersten Balken-Schlusskurs über ein vorheriges Niveau des Umkehrpunkts hinaus zu finden, ermitteln die Verschiebung von „prev_time“ mit „iBarShift“ und geben 0 zurück, wenn sie ungültig ist, und führen eine Rückwärtsschleife von prev_shift -1 bis 0 durch: für den Ausbruch nach oben, wenn der Schlusskurs über „prev_level“ liegt, geben wir die Zeit dieses Balkens mit iTime zurück; für den Ausbruch nach unten, wenn der Schlusskurs darunter liegt. Es wird 0 zurückgegeben, wenn kein Ausbruch gefunden wird. Wir verwenden diese Funktion nun, um die Erkennung pro Balken durchzuführen, indem wir sie wie folgt aufrufen.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   static bool isNewBar = false;                                  //--- New bar flag
   int currBars = iBars(_Symbol, _Period);                        //--- Get current bars
   static int prevBars = currBars;                                //--- Previous bars
   if (prevBars == currBars) {                                    //--- Check same bars
      isNewBar = false;                                           //--- Set not new bar
   } else if (prevBars != currBars) {                             //--- Check new bars
      isNewBar = true;                                            //--- Set new bar
      prevBars = currBars;                                        //--- Update previous bars
   }
   if (!isNewBar) return;                                         //--- Return if not new bar
   OpenTrades = CountOpenTrades();                                //--- Count open trades
   if (OpenTrades >= MaxTrades) return;                           //--- Return if max trades reached
   DetectSwingsAndBOS();                                          //--- Detect swings and BOS
}

Hier verwenden wir in OnTick, das bei jedem Preis-Tick ausgeführt wird, um die Kernlogik zu verwalten, ein statisches „isNewBar“-Flag und „prevBars“, um Balkenänderungen zu erkennen: Wir holen alle Balken mit iBars in „currBars“, vergleichen ihn mit „prevBars“ – ist er unverändert, weisen wir „isNewBar“ false zu, ist er erhöht true und aktualisieren „prevBars“. Wenn es sich nicht um einen neuen Balken handelt, kehren wir früher zurück. Andernfalls aktualisieren wir „OpenTrades“ durch den Aufruf von „CountOpenTrades“ und kehren bei Erreichen oder Überschreiten von „MaxTrades“ zurück, um neue Einträge zu verhindern. Dann rufen wir „DetectSwingsAndBoS“ auf, um nach Schwankungen und Strukturbrüchen zu suchen. Nach dem Kompilieren erhalten wir folgendes Ergebnis:

Konstellation der Abwärtsbereinigung (Bearish Sweep Setup):

KONSTELLATION DER ABWÄRTSBEREINIGUNG

Konstellation der Aufwärtsbereinigung (Bullish Sweep Setup):

KONSTELLATION DER AUFWÄRTSBEREINIGUNG:

Nachdem die Erkennung abgeschlossen ist, müssen wir nun mit den Liquidity-Sweeps handeln. Aus Gründen der Modularität werden wir die Logik in einer Funktion unterbringen.

//+------------------------------------------------------------------+
//| Detect and trade sweep on BOS                                    |
//+------------------------------------------------------------------+
void DetectAndTradeSweepOnBOS() {
   if (MarketTrend == 0) return;                                  //--- Return if neutral
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);            //--- Get bid
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);            //--- Get ask
   // Bullish BOS + SSL Sweep for Buy
   if (MarketTrend == 1 && current_swing_low > 0.0 && iLow(_Symbol, _Period, 1) < current_swing_low && iClose(_Symbol, _Period, 1) > current_swing_low && iClose(_Symbol, _Period, 1) > iOpen(_Symbol, _Period, 1)) { //--- Check bullish sweep
      if (PrintLogs) Print("Bullish BOS + SSL Sweep Detected");   //--- Log sweep
      double sweep_low = iLow(_Symbol, _Period, 1);               //--- Get sweep low
      datetime sweep_time = iTime(_Symbol, _Period, 1);           //--- Get sweep time
      DrawSweepRectangle("SSL_Rect_", sweep_time, current_swing_low, sweep_low, clr_SSL_Rect, true); //--- Draw SSL rect
      DrawBreakLevel("SSL_Line_", swing_low_time, current_swing_low, sweep_time, current_swing_low, clr_SSL_Line, 1, "SSL"); //--- Draw SSL line
      CloseOpposite(true);                                        //--- Close opposite
      double sl = NormalizeDouble(sweep_low - SL_Buffer_Pips * _Point, _Digits); //--- Calc SL
      double entry = ask;                                         //--- Set entry
      double risk = entry - sl;                                   //--- Calc risk
      double tp = NormalizeDouble(entry + risk * RiskRewardRatio, _Digits); //--- Calc TP
      obj_Trade.Buy(LotSize, _Symbol, entry, sl, tp, "BOS SSL Buy"); //--- Open buy
      if (obj_Trade.ResultRetcode() == TRADE_RETCODE_DONE) {      //--- Check success
         DrawEntryArrow(sweep_time, iLow(_Symbol,_Period, 1), true);                 //--- Draw buy arrow
         MarketTrend = 0;                                         //--- Reset trend
      } else Print("Buy order failed: ", obj_Trade.ResultRetcodeDescription()); //--- Log failure
   }
   // Bearish BOS + BSL Sweep for Sell
   if (MarketTrend == -1 && current_swing_high > 0.0 && iHigh(_Symbol, _Period, 1) > current_swing_high && iClose(_Symbol, _Period, 1) < current_swing_high && iClose(_Symbol, _Period, 1) < iOpen(_Symbol, _Period, 1)) { //--- Check bearish sweep
      if (PrintLogs) Print("Bearish BOS + BSL Sweep Detected");   //--- Log sweep
      double sweep_high = iHigh(_Symbol, _Period, 1);             //--- Get sweep high
      datetime sweep_time = iTime(_Symbol, _Period, 1);           //--- Get sweep time
      DrawSweepRectangle("BSL_Rect_", sweep_time, current_swing_high, sweep_high, clr_BSL_Rect, false); //--- Draw BSL rect
      DrawBreakLevel("BSL_Line_", swing_high_time, current_swing_high, sweep_time, current_swing_high, clr_BSL_Line, -1, "BSL"); //--- Draw BSL line
      CloseOpposite(false);                                       //--- Close opposite
      double sl = NormalizeDouble(sweep_high + SL_Buffer_Pips * _Point, _Digits); //--- Calc SL
      double entry = bid;                                         //--- Set entry
      double risk = sl - entry;                                   //--- Calc risk
      double tp = NormalizeDouble(entry - risk * RiskRewardRatio, _Digits); //--- Calc TP
      obj_Trade.Sell(LotSize, _Symbol, entry, sl, tp, "BOS BSL Sell"); //--- Open sell
      if (obj_Trade.ResultRetcode() == TRADE_RETCODE_DONE) {      //--- Check success
         DrawEntryArrow(sweep_time, iHigh(_Symbol,_Period,1), false);                //--- Draw sell arrow
         MarketTrend = 0;                                         //--- Reset trend
      } else Print("Sell order failed: ", obj_Trade.ResultRetcodeDescription()); //--- Log failure
   }
}

Hier definieren wir die Funktion „DetectAndTradeSweepOnBoS“, um Liquidity-Sweeps nach einem Strukturbruch zu erkennen und dementsprechend Handelsgeschäfte auszuführen, während die Darstellung aktualisiert und bestehende Positionen verwaltet werden. Wir kehren zunächst vorzeitig zurück, wenn „MarketTrend“ 0 ist, was auf neutrale Bedingungen ohne aktive BoS hinweist. Die aktuellen Geld- und Briefkurse werden über SymbolInfoDouble mit SYMBOL_BID und SYMBOL_ASK abgefragt. Bei einem Aufwärts-BoS („MarketTrend == 1“) mit einem gültigen „current_swing_low“ über 0.0, prüfen wir, ob es sich um einen SSL-Sweep handelt: Wenn das Tief des vorherigen Balkens („iLow“ bei Shift 1) unter das „current_swing_low“ fiel, sein Schlusskurs („iClose“ bei 1) jedoch darüber und über dem Eröffnungskurs (iOpen bei 1) endete, bestätigt dies eine Aufwärtskerze, die Verkäufe beendet. Wenn erkannt, wird, wenn „PrintLogs“ true ist, „Bullish BoS + SSL Sweep Detected“ protokolliert, es werden der Bereinigungstiefpunkt und die Zeit mit iLow und „iTime“ bei Index 1 erfasst und es wird „DrawSweepRectangle“ aufgerufen mit Präfix „SSL_Rect_“, Zeit, „current_swing_low“, Sweep low, „clr_SSL_Rect“ und true für SSL.

Wir spiegeln die Logik für Abwärts-BoS („MarketTrend == -1“) mit einem gültigen „current_swing_high“ wider: Wir prüfen, ob das vorherige Hoch über dem „current_swing_high“ lag, aber unter der Eröffnung schloss, was eine Abwärtskerze bestätigt. Wenn ja, protokollieren wir „Bearish BoS + BSL Sweep Detected“, erfassen das Bereinigungshoch und die Zeit, zeichnen ein Rechteck mit „BSL_Rect_“, „clr_BSL_Rect“, false für BSL, und dem Ausbruchsniveau mit „BSL_Line_“, „clr_BSL_Line“, Richtung -1, Bezeichnung „BSL“. Wir rufen „CloseOpposite“ mit „false“ auf, um Kaufpositionen zu schließen; setzen den Stop-Loss über das Sweep-Hoch plus Puffer; der Eröffnungspreis ist der Geldkurs; das Risiko entspricht dem Stop-Loss minus Eröffnungspreis; der Take-Profit entspricht dem Eröffnungspreis minus Risiko mal Ratio; wir verkaufen mit „obj_Trade.Sell“ und fügen den Kommentar „BOS BSL Sell“ hinzu. Bei Erfolg wird ein Pfeil mit false für Verkauf gezeichnet und der Trend zurückgesetzt; andernfalls wird ein Fehler protokolliert. Danach rufen wir die Funktion einfach über die Tick-Funktion auf und erhalten folgendes Ergebnis.

GIF DES TESTS DES LIQUIDITY SWEEP AUF BoS

Anhand der Visualisierung können wir sehen, dass wir die Konstellationen der Lquidity-Sweeps erkennen, handeln und verwalten und somit unsere Ziele erreichen. Bleibt nur noch der Backtest des Programms, und das wird im nächsten Abschnitt behandelt.


Backtests

Nach einem gründlichen Backtest erhalten wir folgende Ergebnisse.

Backtest-Grafik:

GRAPH

Bericht des Backtests:

BERICHT


Schlussfolgerung

Abschließend haben wir ein System mit dem Liquidity Sweep on Break of Structure (BoS) in MQL5 entwickelt. Es erkennt Schwankungen über die Eingabelänge und markiert die Umkehrpunkte, um den Trend festzulegen. Es zeigt Bereinigungen an, wenn es einen Docht jenseits eines Umkehrpunkts und einen Schlusskurs innerhalb der Richtungskerze gibt. Das System kauft bei einem Sell-Side-Liquidity (SSL) und einem Aufwärts-BoS, oder verkauft bei einem Buy-Side-Liquidity (BSL) und einem Abwärts-BoS. Es verwendet dynamische Handelsstufen, ein maximales Handelslimit und schließt entgegengesetzte Positionen. Die Visualisierung umfasst Symbole für Umkehrpunkte, gestrichelte Linien für Unterbrechungen, gefüllte Rechtecke für Umkehrpunkte, Pfeile für Eingaben und adaptive Schriftgrößen zum Skalieren.

Haftungsausschluss: Dieser Artikel ist nur für Bildungszwecke gedacht. Der Handel ist mit erheblichen finanziellen Risiken verbunden, und die Volatilität der Märkte kann zu Verlusten führen. Gründliche Backtests und sorgfältiges Risikomanagement sind entscheidend, bevor Sie dieses Programm auf den Live-Märkten einsetzen.

Mit dieser Strategie der Liquiditätsbereinigung, des Liquidity-Sweeps, und dem Strukturbruch können Sie manipulative Dochte eines BoS erkennen. Sie sind für den Handel mit Umkehr-Konstellationen gerüstet und bereit für weitere Optimierungen auf Ihrer Handelsreise. Viel Spaß beim Handeln!

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

Beigefügte Dateien |
Liquidity_Sweep.mq5 (55.03 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (5)
jumah55
jumah55 | 14 Dez. 2025 in 15:01
Die angehängte Datei funktioniert nicht auf mt5
Allan Munene Mutiiria
Allan Munene Mutiiria | 15 Dez. 2025 in 19:41
jumah55 #:
Die angehängte Datei funktioniert nicht auf mt5
Irgendwelche Fehler oder Warnungen oder funktioniert nicht wie?
ersan yurdakul
ersan yurdakul | 20 Dez. 2025 in 20:56
Dieser Code macht repaint?
Emile Munro
Emile Munro | 2 Jan. 2026 in 10:14

Hallo Allan, herzlichen Glückwunsch zum neuen Jahr. Vielen Dank für den Artikel, es hilft mir auf meinem Weg, um herauszufinden, wie man meine Multi Timeframe BOS EA Code, indem Sie Ihre Schritte und die Eingabe von alles, wie ich gehe entlang statt nur kopieren einfügen. Ich habe jetzt jedoch in einen Fehler bei der "Detect Swings und BOS" Abschnitt des Codes laufen, beim Kompilieren erhalte ich eine "undeclared Bezeichner" Fehler für die "FindBreakTime" Zeile des Codes. Wie haben Sie es geschafft, dass es mit "FindBreakTime" funktioniert, da es so aussieht, als ob ich lieber etwas wie "SymbolInfoSessionsTrade" verwenden sollte?

Ich danke Ihnen.

Emile Munro
Emile Munro | 2 Jan. 2026 in 13:13
Emile Munro #:

Hallo Allan, herzlichen Glückwunsch zum neuen Jahr. Vielen Dank für den Artikel, es hilft mir auf meinem Weg, um herauszufinden, wie man meine Multi Timeframe BOS EA Code, indem Sie Ihre Schritte und die Eingabe von alles, wie ich gehe entlang statt nur kopieren einfügen. Ich habe jetzt jedoch in einen Fehler bei der "Detect Swings und BOS" Abschnitt des Codes laufen, beim Kompilieren erhalte ich eine "undeclared Bezeichner" Fehler für die "FindBreakTime" Zeile des Codes. Wie haben Sie es mit "FindBreakTime" zum Funktionieren gebracht, da es so aussieht, als ob ich lieber etwas wie "SymbolInfoSessionsTrade" verwenden sollte?

Ich danke Ihnen.

Ok, vergiss es, ich habe es hinbekommen, danke.
Adaptive Smart Money Architektur (ASMA): Verschmelzung von SMC-Logik und Marktstimmung für dynamische Strategie-Wechsel Adaptive Smart Money Architektur (ASMA): Verschmelzung von SMC-Logik und Marktstimmung für dynamische Strategie-Wechsel
Dieses Thema befasst sich mit dem Aufbau einer Adaptive Smart Money Architecture (ASMA) – einem intelligenten Expert Advisor, der Smart-Money-Konzepte (Orderblöcke, Strukturbrüche, Fair-Value-Gaps) mit der Marktstimmung in Echtzeit kombiniert, um automatisch die beste Handelsstrategie in Abhängigkeit von den aktuellen Marktbedingungen auszuwählen.
Reine Implementierung der RSA-Verschlüsselung in MQL5 Reine Implementierung der RSA-Verschlüsselung in MQL5
MQL5 verfügt über keine eingebaute asymmetrische Kryptografie, was den sicheren Datenaustausch über unsichere Kanäle wie HTTP erschwert. Dieser Artikel stellt eine reine MQL5-Implementierung von RSA mit PKCS#1 v1.5 Padding vor, die eine sichere Übertragung von AES-Sitzungsschlüsseln und kleinen Datenblöcken ohne externe Bibliotheken ermöglicht. Dieser Ansatz bietet eine HTTPS-ähnliche Sicherheit über Standard-HTTP und füllt darüber hinaus eine wichtige Lücke in der sicheren Kommunikation für MQL5-Anwendungen.
ARIMA-Prognose-Indikator in MQL5 ARIMA-Prognose-Indikator in MQL5
In diesem Artikel implementieren wir den ARIMA-Prognose-Indikator in MQL5. Es wird untersucht, wie das ARIMA-Modell Prognosen erstellt und wie es sich auf den Devisenmarkt und den Aktienmarkt im Allgemeinen anwenden lässt. Außerdem wird erklärt, was AR-Autoregression ist, wie autoregressive Modelle für Prognosen verwendet werden und wie der Autoregressionsmechanismus funktioniert.
Die Grenzen des maschinellen Lernens überwinden (Teil 9): Korrelationsbasierte Lernen von Merkmalen im selbstüberwachten Finanzwesen Die Grenzen des maschinellen Lernens überwinden (Teil 9): Korrelationsbasierte Lernen von Merkmalen im selbstüberwachten Finanzwesen
Selbstüberwachtes Lernen ist ein leistungsstarkes Paradigma des statistischen Lernens, das nach Überwachungssignalen sucht, die aus den Beobachtungen selbst generiert werden. Mit diesem Ansatz werden schwierige Probleme des unüberwachten Lernens in vertrautere überwachte Probleme umgewandelt. Diese Technologie hat Anwendungen für unser Ziel als Gemeinschaft von algorithmischen Händlern übersehen. Unsere Diskussion zielt daher darauf ab, dem Leser eine leicht verständliche Brücke in das offene Forschungsgebiet des selbstüberwachten Lernens zu schlagen und bietet praktische Anwendungen, die robuste und zuverlässige statistische Modelle der Finanzmärkte ohne Überanpassung an kleine Datensätze liefern.