English Русский 日本語
preview
Einführung in MQL5 (Teil 23): Automatisieren der Opening Range Breakout Strategie

Einführung in MQL5 (Teil 23): Automatisieren der Opening Range Breakout Strategie

MetaTrader 5Handel |
35 3
Israel Pelumi Abioye
Israel Pelumi Abioye

Einführung

Willkommen zurück zu Teil 23 der Serie Einführung in MQL5! In diesem Artikel führe ich Sie durch die Automatisierung des Opening Range Breakout (ORB, Eröffnungsbereichs-Ausbruch) Ansatzes mit MQL5. Ziel ist es, Ihnen MQL5 in einer projektbasierten, einsteigerfreundlichen Art und Weise beizubringen, und nicht, Ihnen Gewinne zu versprechen oder eine Handelsstrategie zu empfehlen. Die Arbeit an konkreten Beispielen wie diesen wird Ihnen helfen, Ihre MQL5-Kenntnisse auf nützliche Weise weiterzuentwickeln, während Sie gleichzeitig praktische Erfahrungen mit Ideen wie der Erkennung von Ausbruchsbereichen, der Ausführung automatisierter Aufträge und der programmatischen Verwaltung von Handelsgeschäften sammeln.

Dieser Artikel erklärt die Strategie des Opening Range Breakout (ORB, Eröffnungsbereichs-Ausbruch) und zeigt Ihnen, wie Sie MQL5 verwenden können, um sie zu automatisieren. Sie lernen, wie Sie Handelsbedingungen festlegen, die Eröffnungsspanne aufzeichnen und Ihren Expert Advisor so konfigurieren, dass er bei Ausbrüchen automatisch handelt. Um sicherzustellen, dass Eingaben nur während des festgelegten Marktfensters erfolgen, werden wir uns auch ansehen, wie man eine zeitbasierte Logik einsetzt, um zu regeln, wann Geschäfte ausgeführt werden dürfen. Am Ende werden Sie genau wissen, wie Sie MetaTrader 5 nutzen können, um diese klassische Handelsstrategie in ein vollautomatisches Handelssystem zu verwandeln.


Opening Range Breakout (ORB)

Die Strategie des Eröffnungsbereichs-Ausbruchs verfolgt die Höchst- und Tiefststände in einem kleinen Zeitfenster unmittelbar nach der Markteröffnung. Der Eröffnungsbereich besteht aus diesem Hoch und Tief. Danach können Sie darauf achten, dass der Kurs entweder unter oder über dem Tiefpunkt der Spanne ausbricht. Ein mögliches Aufwärts-Momentum wird durch einen Ausbruch über das Hoch angezeigt, während ein mögliches Abwärts-Momentum durch einen Ausbruch unter das Tief angezeigt wird. Der Gedanke dahinter ist, dass die Tendenz für den Rest des Tages häufig durch die Volatilität der frühen Sitzung bestimmt wird.

Die ersten fünf, fünfzehn, dreißig oder sechzig Minuten der Sitzung sind typische Eröffnungsbereiche. Kürzere Bandbreiten liefern mehr Signale, aber auch mehr Rauschen, das die extrem frühe Volatilität erfasst. Obwohl sie weniger Signale erzeugen und glatter sind, sind größere Reichweiten häufig von besserer Qualität. Wählen Sie einen Bereich, der der Anlage und dem Handelszeitraum entspricht.  Sie können die ersten 15 oder 30 Minuten für Intraday-Aktienstrategien nutzen.

Eine einfache Ausbruchsregel ist der Kurs, der über dem Hoch der Anfangsspanne für einen Kauf oder unter dem Tief der Anfangsspanne für einen Verkauf schließt. Einige Händler benötigen mehr Bestätigung, wie z. B. den Schlusskurs einer Kerze plus einen kleinen Pip-Puffer, um falsche Ausbrüche durch Rauschen zu verhindern. Andere warten auf einen erneuten Test, bei dem der Kurs ausbricht, sich zurück an die Grenze der Handelsspanne bewegt und sich dann wieder in Richtung des Ausbruchs bewegt. Wählen Sie die Bestätigungsregel aus, die Ihrer Risikotoleranz am besten entspricht, und führen Sie einen Backtest durch. Ausbrüche können umgesetzt werden, indem man Stop-Orders an der Grenze der Handelsspanne platziert und dem Markt erlaubt, sie zu aktivieren, oder indem man sofort beim ersten bestätigten Ausbruch in den Markt einsteigt.

Analogie

Stellen Sie sich ein Szenario vor, in dem der Markt genau um 9:30 Uhr eröffnet wird. Die M15-Kerze, die sich zu diesem Zeitpunkt zu bilden beginnt, ist dann Ihr Hauptaugenmerk. Sie notieren sich die Höchst- und Tiefstkurse der Kerze nach deren Schließung, und dies wird Ihr Eröffnungsbereich.

Danach warten Sie geduldig und wechseln zu einem kleineren Zeitrahmen, z. B. dem 5-Minuten-Chart. Ein potenzieller Aufwärts-Ausbruch (steigende Kurse) wird angezeigt, wenn der Kurs anschließend das Hoch dieser 15-Minuten-Kerze überschreitet. Ein potenzieller Durchbruch nach unten wird angezeigt, wenn der Kurs unter den Tiefststand fällt.

Einfach ausgedrückt, legen Sie in den ersten fünfzehn Minuten nach Markteröffnung Grenzen fest und halten dann Ausschau nach Ihrem Opening Range Breakout (ORB), der eintritt, wenn der Kurs diese Parameter durchbricht.

Abbildung 1. ORB


Wie der EA funktioniert

Bevor Sie mit der programmatischen Implementierung beginnen, müssen Sie zunächst die Funktionsweise des Expert Advisors (EA) verstehen, indem Sie seine detaillierte Vorgehensweise verfolgen. Der erste Schritt ist die Feststellung, dass der Markt um 9:30 Uhr (Serverzeit) öffnet. Die erste 15-Minuten-Kerze, die sich um genau 9:30 Uhr bildet, wird dann vom EA sorgfältig abgewartet. Der EA identifiziert die Eröffnungsspanne, indem er Linien auf den Höchst- und Tiefstkursen der Kerze markiert und zeichnet, sobald diese geschlossen wird.

Der EA kopiert dann die relevanten Kursdaten und beginnt mit der Suche nach Ausbruchsindikationen. Um ein Kaufgeschäft zu starten, wird auf eine Aufwärtskerze gewartet, die über dem Hoch der ursprünglichen Spanne schließt. Der SL wird auf den niedrigsten Preis der Spanne gesetzt, und der Take Profit wird durch das vom Nutzer festgelegte Risiko-Ertrags-Verhältnis (RRR) bestimmt.

Abbildung 2. Kauflogik

Das Programm sucht dann nach einer Abwärtskerze, die unter dem Tiefpunkt derselben 15-Minuten-Kerze schließt, um eine Verkaufstransaktion einzuleiten. Der TP hält sich erneut an die nutzerdefinierte RRR, während der SL am höchsten ist. Die Anzahl der Orte, die der EA gleichzeitig öffnen soll, ist eine weitere Option, die dem Nutzer zur Verfügung steht. Der EA sollte den Handel nach dem Durchbruch der Handelsspanne, dem ersten Ausbruchsignal des Tages, beenden. 

Abbildung 3. Verkaufslogik


Ermittlung der Marktstartzeit

Der nächste Schritt besteht darin, den Zeitpunkt der Markteröffnung zu bestimmen, sobald wir die Funktionsweise des EA genau verstanden haben. Zur Veranschaulichung: Angenommen, der Markt öffnet um 9:30 Uhr Serverzeit. Wir verlangen, dass der EA diese bestimmte Zeit immer automatisch erkennt. Wenn Ihr EA auf einem VPS läuft und Sie das Datum nicht jeden Tag manuell aktualisieren möchten, benötigen Sie eine Möglichkeit, nur den Zeitanteil zu isolieren, da die Zeitwerte in MQL5 sehr genau sind, da sie Jahr, Monat, Tag, Stunde, Minute und Sekunde enthalten. Auf diese Weise kann das Programm automatisch den Tag, den Monat und das Jahr jeder neuen Handelssitzung ermitteln.

Die Schwierigkeit ergibt sich aus der Tatsache, dass zwar das zugrunde liegende Datum variiert, aber die gleiche Stunde und Minute täglich wiederkehrt. Ein vollständiger Datumswert wird nur einmal übereinstimmen, bevor er an aufeinanderfolgenden Tagen fehlschlägt, wenn Sie ihn lediglich mit einer bestimmten Zahl vergleichen. Der EA muss zwischen der Zeit- und der Datumskomponente unterscheiden, um dies zu bewältigen. So kann es feststellen, ob der aktuelle Balken oder Tick, unabhängig von Tag, Monat oder Jahr, mit der Startzeit des Marktes übereinstimmt.

Beispiel:

string open_time_string = "9:30";
datetime open_time;

ulong chart_id = ChartID();
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

   ObjectsDeleteAll(chart_id);

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

   open_time = StringToTime(open_time_string);

   Comment("OPEN TIME: ",open_time);

   ObjectCreate(chart_id,"OPEN TIME",OBJ_VLINE,0,open_time,0);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_COLOR,clrBlue);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_STYLE,STYLE_DASH);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_WIDTH,2);

  }

Ausgabe:

Abbildung 4. Eröffnungszeit

Erläuterung:

Die Marktstartzeit wird zunächst als einfache Zeichenkette in der Zeile string open_time_string = "9:30"; gespeichert, zum Beispiel. Dies ist lediglich eine für Menschen lesbare Darstellung der Öffnungszeit, die der EA erkennen soll. Diese Zeit wird anschließend in einem Format gespeichert, das MQL5 für Berechnungen und Charts in der Variablen datetime open_time; verwenden kann.

Das Programm wandelt die Zeichenfolge in einen gültigen Datumswert um. Obwohl datetime in MQL5 das vollständige Datum und die Uhrzeit enthält, wird die Uhrzeit bei Verwendung einer Zeichenkette wie dieser automatisch auf 9:30 Uhr des aktuellen Tages gesetzt. Dadurch wird sichergestellt, dass der EA die Öffnungszeit jeden Tag berechnen kann, ohne das Datum explizit zu aktualisieren.

Anschließend wird genau zum Zeitpunkt der Markteröffnung eine vertikale Linie auf dem Chart gezeichnet. Diese vertikale Linie dient als visuelle Markierung für den Beginn des Öffnungsbereichs.


Identifizierung des Hochs und Tiefs der ersten 15-Minuten-Kerze

Der nächste Schritt ist das Kopieren der Kerzendaten für die erste 15-Minuten-Kerze, die sich um genau 9:30 Uhr Serverzeit bildet. Diese beiden Preise sind von großer Bedeutung, da sie den Eröffnungsbereich des Tages festlegen. Das Tief dieser Kerze zeigt das Niveau für einen Ausbruch nach unten an, und das Hoch zeigt das Niveau an, bei dem ein Ausbruch nach oben bestätigt werden würde. Wir legen den Referenzbereich fest, den der EA nutzen wird, um über den Einstieg in den Handel während der AM-Sitzung zu entscheiden, indem wir diese beiden entscheidenden Punkte bestimmen.

Da sie die Grenze für mögliche Kursschwankungen festlegt, ist die Erfassung der Eröffnungsspanne von wesentlicher Bedeutung. Nach der anfänglichen Konsolidierungsphase können Sie anhand dieser Niveaus feststellen, ob der Markt aufwärts oder abwärts tendiert. Diese Werte dienen als Benchmark im EA; ein Kaufsignal kann erzeugt werden, wenn der Preis über den Höchststand steigt, und ein Verkaufssignal kann ausgelöst werden, wenn er unter den Tiefststand fällt. So wird sichergestellt, dass nur dann gehandelt wird, wenn der Markt einen deutlichen Ausbruch aus der Eröffnungsspanne zeigt.

Beispiel:
string open_time_string = "9:30";
datetime open_time;

string open_time_bar_close_string = "9:45";
datetime open_time_bar_close;

ulong chart_id = ChartID();

double m15_high[];
double m15_low[];
double m15_close[];
double m15_open[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

   ObjectsDeleteAll(chart_id);

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

   open_time = StringToTime(open_time_string);

   Comment("OPEN TIME: ",open_time);

   ObjectCreate(chart_id,"OPEN TIME",OBJ_VLINE,0,open_time,0);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_COLOR,clrBlue);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_STYLE,STYLE_DASH);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_WIDTH,2);

   open_time_bar_close = StringToTime(open_time_bar_close_string);

   if(TimeCurrent() >= open_time_bar_close)
     {

      CopyHigh(_Symbol,PERIOD_M15,open_time,1,m15_high);
      CopyLow(_Symbol,PERIOD_M15,open_time,1,m15_low);
      CopyClose(_Symbol,PERIOD_M15,open_time,1,m15_close);
      CopyOpen(_Symbol,PERIOD_M15,open_time,1,m15_open);

      ObjectCreate(chart_id,"High",OBJ_TREND,0,open_time,m15_high[0],TimeCurrent(),m15_high[0]);
      ObjectSetInteger(chart_id,"High",OBJPROP_COLOR,clrBlue);
      ObjectSetInteger(chart_id,"High",OBJPROP_WIDTH,2);

      ObjectCreate(chart_id,"Low",OBJ_TREND,0,open_time,m15_low[0],TimeCurrent(),m15_low[0]);
      ObjectSetInteger(chart_id,"Low",OBJPROP_COLOR,clrBlue);
      ObjectSetInteger(chart_id,"Low",OBJPROP_WIDTH,2);

     }

  }

Ausgabe:

Abbildung 5. Bereich hoch und niedrig

Erläuterung:

Dieser Teil ermittelt die gesamte Entstehungszeit der ersten 15-Minuten-Kerze, extrahiert ihre wichtigen Preisinformationen und wandelt ihre Schlusszeit in eine Zeichenkette um, sodass sie in Berechnungen verwendet werden kann. Das Programm wartet dann, um die Beendigung der Kerze zu überprüfen, und extrahiert sicher ihre Hoch-, Tief-, Öffnungs- und Schlusskurse, wenn die Serverzeit diese Schlusszeit erreicht oder überschreitet.

Der Ansatz des Opening Range Breakout hängt von diesen ermittelten Werten ab. Das Programm verwendet die Höchst- und Tiefstkurse, die den Eröffnungsbereich abgrenzen, um auf kürzeren Zeitrahmen nach Ausbruchsmöglichkeiten Ausschau zu halten. Zur besseren Veranschaulichung werden auf dem Chart auch Linien an diesen Höchst- und Tiefstständen eingezeichnet. Auf diese Weise können Sie vor dem Abschluss von Handelsgeschäften sicherstellen, dass der EA die richtigen Niveaus verfolgt, und Sie können den Eröffnungsbereich klar erkennen.

Das Programm zeigt eine vertikale Linie an, um die genaue Öffnungszeit des Marktes jeden Tag zu markieren, da die Öffnungszeit eine einzige Variable ist. Es wartet dann, bis die M15-Kerze vollständig geschlossen ist, bevor es seine Höchst- und Tiefstwerte verwendet, um korrekte Daten zu garantieren und Probleme mit „Array out of range“ zu vermeiden.


Verwendung von 5-Minuten-Charts zur Erkennung von Ausbrüchen aus dem Eröffnungsbereich

Nachdem der anfängliche Höchst- und Tiefststand ermittelt wurde, prüft das Programm als Nächstes den M5-Zeitrahmen auf Ausbrüche über oder unter der Spanne. Ein über dem M15-Hoch gestiegener Schlusskurs deutet auf einen möglichen Kauf hin, während ein unter dem Tiefpunkt gefallener Schlusskurs auf einen möglichen Verkauf hindeutet. Diese Analyse mit verkürztem Zeitraum ermöglicht einen rechtzeitigen und präzisen Einstieg in den Handel.

Beispiel:
double m5_high[];
double m5_low[];
double m5_close[];
double m5_open[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   ArraySetAsSeries(m5_high,true);
   ArraySetAsSeries(m5_low,true);
   ArraySetAsSeries(m5_close,true);
   ArraySetAsSeries(m5_open,true);

//---
   return(INIT_SUCCEEDED);
  }
if(TimeCurrent() >= open_time_bar_close)
  {

   CopyHigh(_Symbol,PERIOD_M15,open_time,1,m15_high);
   CopyLow(_Symbol,PERIOD_M15,open_time,1,m15_low);
   CopyClose(_Symbol,PERIOD_M15,open_time,1,m15_close);
   CopyOpen(_Symbol,PERIOD_M15,open_time,1,m15_open);

   ObjectCreate(chart_id,"High",OBJ_TREND,0,open_time,m15_high[0],TimeCurrent(),m15_high[0]);
   ObjectSetInteger(chart_id,"High",OBJPROP_COLOR,clrBlue);
   ObjectSetInteger(chart_id,"High",OBJPROP_WIDTH,2);

   ObjectCreate(chart_id,"Low",OBJ_TREND,0,open_time,m15_low[0],TimeCurrent(),m15_low[0]);
   ObjectSetInteger(chart_id,"Low",OBJPROP_COLOR,clrBlue);
   ObjectSetInteger(chart_id,"Low",OBJPROP_WIDTH,2);

  }

CopyHigh(_Symbol,PERIOD_M5,1,5,m5_high);
CopyLow(_Symbol,PERIOD_M5,1,5,m5_low);
CopyClose(_Symbol,PERIOD_M5,1,5,m5_close);
CopyOpen(_Symbol,PERIOD_M5,1,5,m5_open);

if(TimeCurrent() >= open_time_bar_close && m5_close[0] > m15_high[0] && m5_close[1] < m15_high[0])
  {

//BUY

  }

if(TimeCurrent() >= open_time_bar_close && m5_close[0] < m15_low[0] && m5_close[1] > m15_low[0])
  {

//SELL

  }

Erläuterung:

In diesem Abschnitt des Programms werden vier Arrays deklariert. Die Höchst-, Tiefst-, Schluss- und Eröffnungskurse der Kerzen auf dem M5-Zeitrahmen werden in diesen Arrays gespeichert. Die jüngste Kerze wird durch den Index 0 dargestellt, frühere Kerzen werden durch höhere Indizes dargestellt. Jedes Array enthält eine Folge von Preisdaten, die über einen Index abgerufen werden können.

Alle diese Arrays werden mit der Funktion ArraySetAsSeries() innerhalb des Initialisierungscodes als Zeitreihen festgelegt. Auf diese Weise wird gewährleistet, dass die aktuellsten Daten bei Index 0 erscheinen, während ältere Daten in aufsteigender Reihenfolge folgen. Da dies mit der Art und Weise übereinstimmt, wie MetaTrader 5 die Chartdaten anordnet, bei der der jüngste Balken am Anfang der Serie steht, ist es wichtig, die Arrays auf diese Weise zu setzen.

Diese Programme extrahieren den Höchst-, Tiefst-, Eröffnungs- und Schlusskurs sowie die letzten 5-Minuten-Kerzendaten aus dem Chart. Gemäß den Kriterien sollte der EA, beginnend mit der Kerze, die sich vor der aktuellen Kerze bildet, Daten für die letzten fünf abgeschlossenen 5-Minuten-Kerzen sammeln. Der EA kann dann die Kursbewegung verfolgen und feststellen, ob ein Ausbruch über oder unter dem Bereich der ersten 15-Minuten-Kerze stattfindet, indem er diese Daten für eine spätere Analyse in Arrays speichert.

Nach dem Schließen der ersten Fünfzehn-Minuten-Kerze sucht diese Logik nach Durchbruchsbedingungen. Wenn die letzte Kerze des unteren Zeitrahmens über dem Hoch der fünfzehnminütigen Eröffnungsspanne geschlossen hat und die vorherige fünfminütige Kerze noch unter diesem Hoch lag, deutet das erste Kriterium auf einen Aufwärtsausbruch hin. Dies ist ein Beleg für den Ausbruch des Kurses nach oben. Wenn die jüngste Fünf-Minuten-Kerze unter das Tief der 15-Minuten-Spanne fällt, nachdem die vorherige Kerze darüber lag, ist das zweite Kriterium ein Ausbruch nach unten. Dies deutet auf eine mögliche Verkaufsgelegenheit hin und bestätigt einen Durchbruch nach unten.

Durch die Prüfung der Ausrichtung der Kerze bietet die Argumentation ein zusätzliches Maß an Sicherheit. Um ein Kaufsignal zu generieren, stellt das Programm sicher, dass die letzte ein Aufwärtskerze ist, d.h. höher endet als sie eröffnet wurde, und über dem Hoch der Handelsspanne bricht und schließt. Auf diese Weise lassen sich falsche Ausbrüche, die durch vorübergehende Kurssteigerungen verursacht werden, vermeiden. Wenn ein Verkaufssignal generiert wird, prüft das Programm, ob es eine Abwärtskerze ist, d. h., ob sie tiefer geschlossen hat als sie eröffnet wurde und ob sie unter dem Tiefpunkt der Handelsspanne geschlossen hat. Dadurch wird sichergestellt, dass der Ausbruch eine echte Dynamik aufweist, bevor ein Handel eingeleitet wird.

Sie werden feststellen, dass sich die Argumentation von der bekannteren, auf der Eröffnung basierenden Methode insofern unterscheidet, als sie sich auf den Schluss der vorherigen Kerze und nicht auf die Eröffnung der aktuellen Kerze bezieht. Diese Prüfung auf Basis des Schlusskurses hat den Vorteil, dass überprüft werden kann, ob der Kurs tatsächlich den Eröffnungsbereich zwischen zwei abgeschlossenen Kerzen überschritten hat. Ein echter Ausbruch zeigt sich darin, dass die letzte Kerze oberhalb der Spanne schloss, während die vorherige Kerze unterhalb der Spanne lag.

Andererseits kann es bei Kurslücken oder abrupten Kursanstiegen irreführend sein, sich nur auf die Eröffnung der Kerze zu verlassen. Die Bedingung kann fehlschlagen, obwohl sich der Kurs tatsächlich über die Spanne hinaus bewegt hat, wenn die Kerze aufgrund eines plötzlichen Ausschlags oberhalb der Spanne eröffnet, oder sie kann ein irreführendes Signal erzeugen, wenn die Eröffnung durch einen ungewöhnlichen Tick ausgelöst wurde. Diese Probleme werden durch die Verwendung des vorangegangenen Schlusskurses vermieden, der auch eine genauere Möglichkeit bietet, echte Ausbrüche zu erkennen, insbesondere in volatilen Märkten.

Abbildung 6. Lücke


Ausführung des Handels

Der nächste Schritt besteht darin, das Programm dazu zu bringen, auf der Grundlage der von uns erstellten Ausbruchslogik Handelsgeschäfte auszuführen. Sobald der EA einen gültigen Ausbruch über oder unter die 15-Minuten-Spanne feststellt, sollte er automatisch eine Kauf- bzw. Verkaufsposition eröffnen.

Beispiel:
#include <Trade/Trade.mqh>
CTrade trade;
int MagicNumber = 533930;  // Unique Number
input double RRR= 2; // RRR
input double lot_size = 0.2;
double ask_price;
double take_profit;
datetime lastTradeBarTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   ArraySetAsSeries(m5_high,true);
   ArraySetAsSeries(m5_low,true);
   ArraySetAsSeries(m5_close,true);
   ArraySetAsSeries(m5_open,true);

   trade.SetExpertMagicNumber(MagicNumber);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

   ObjectsDeleteAll(chart_id);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   open_time = StringToTime(open_time_string);

   Comment("OPEN TIME: ",open_time);

   ObjectCreate(chart_id,"OPEN TIME",OBJ_VLINE,0,open_time,0);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_COLOR,clrBlue);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_STYLE,STYLE_DASH);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_WIDTH,2);

   open_time_bar_close = StringToTime(open_time_bar_close_string);

   if(TimeCurrent() >= open_time_bar_close)
     {

      CopyHigh(_Symbol,PERIOD_M15,open_time,1,m15_high);
      CopyLow(_Symbol,PERIOD_M15,open_time,1,m15_low);
      CopyClose(_Symbol,PERIOD_M15,open_time,1,m15_close);
      CopyOpen(_Symbol,PERIOD_M15,open_time,1,m15_open);

      ObjectCreate(chart_id,"High",OBJ_TREND,0,open_time,m15_high[0],TimeCurrent(),m15_high[0]);
      ObjectSetInteger(chart_id,"High",OBJPROP_COLOR,clrBlue);
      ObjectSetInteger(chart_id,"High",OBJPROP_WIDTH,2);

      ObjectCreate(chart_id,"Low",OBJ_TREND,0,open_time,m15_low[0],TimeCurrent(),m15_low[0]);
      ObjectSetInteger(chart_id,"Low",OBJPROP_COLOR,clrBlue);
      ObjectSetInteger(chart_id,"Low",OBJPROP_WIDTH,2);
     }

   CopyHigh(_Symbol,PERIOD_M5,1,5,m5_high);
   CopyLow(_Symbol,PERIOD_M5,1,5,m5_low);
   CopyClose(_Symbol,PERIOD_M5,1,5,m5_close);
   CopyOpen(_Symbol,PERIOD_M5,1,5,m5_open);

   datetime currentBarTime = iTime(_Symbol, PERIOD_M5, 0);
   ask_price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);

   if(TimeCurrent() >= open_time_bar_close && m5_close[0] > m15_high[0] && m5_close[1] < m15_high[0] && m5_close[0] > m5_open[0] && currentBarTime != lastTradeBarTime)
     {

      //BUY
      take_profit = MathAbs(ask_price + ((ask_price - m15_low[0]) * RRR));
      trade.Buy(lot_size,_Symbol,ask_price,m15_low[0],take_profit);
      lastTradeBarTime = currentBarTime;

     }

   if(TimeCurrent() >= open_time_bar_close && m5_close[0] < m15_low[0] && m5_close[1] > m15_low[0] && m5_close[0] < m5_open[0] && currentBarTime != lastTradeBarTime)
     {

      //SELL
      take_profit = MathAbs(ask_price - ((m15_high[0] - ask_price) * RRR));
      trade.Sell(lot_size,_Symbol,ask_price,m15_high[0],take_profit);
      lastTradeBarTime = currentBarTime;
     }
  }

Abbildung 7. Mehrere Ausbrüche

Erläuterung:

Die Software kann die eingebauten Handelsroutinen zum Eröffnen, Ändern und Schließen von Aufträgen nutzen, indem sie die Handelsbibliothek einbindet. Alle mit dem Handel zusammenhängenden Aktionen werden dann von einem Handelsobjekt abgewickelt. Eine MagicNumber ist eine spezielle Identifikationsnummer, die jeder Expert Advisor verwendet, um seine eigenen Handelsgeschäfte zu identifizieren und zu kontrollieren, selbst wenn mehrere automatisierte Systeme auf demselben Konto operieren.

Nutzerdefinierte Parameter sind Losgröße und RRR (Risk-Reward Ratio). Lot_size regelt das Transaktionsvolumen, und RRR legt fest, um wieviel größer der Abstand des Take-Profit gegenüber dem vom Stop-Loss sein soll. Die Variablen ask_price, take_profit und lastTradeBarTime helfen bei der Verwaltung der Handelsausführung, indem sie den aktuellen Briefkurs, den berechneten Take-Profit und den Zeitpunkt der letzten Transaktion aufzeichnen, um mehrere Eingaben auf derselben Kerze zu vermeiden.

Um zu gewährleisten, dass die eindeutige Identifikationsnummer des EA in jedem von ihm eröffneten Handelsgeschäft enthalten ist, wird ein Befehl verwendet. Während eine Variable den letzten Briefkurs aufzeichnet, erfasst eine andere die Öffnungszeit der aktuellen Kerze. Problematisch wird es jedoch, wenn der EA mehrere Ausbruchsgeschäfte in einer einzigen Sitzung tätigt, was in einem volatilen Markt riskant sein kann. Das Risiko wird durch mehrere Ausbruchsgeschäfte erhöht, da der Stop-Loss normalerweise weit vom Einstiegspunkt entfernt ist. Der EA sollte idealerweise so eingestellt werden, dass er nur den ersten legitimen Ausbruchshandel des Tages ausführt, um das Risiko zu verringern und Übertreibungen zu vermeiden.

Um dies zu erreichen, müssen wir das Programm so ändern, dass es nach dem ersten Ausbruch sucht und dann nach Abschluss dieses Handels für den Rest der Sitzung keine weiteren Geschäfte mehr annimmt. Auf diese Weise ist gewährleistet, dass der EA diszipliniert bleibt und sich ausschließlich auf die erste Ausbruchsmöglichkeit konzentriert, anstatt auf jede potenzielle Fehlbewegung zu reagieren, die sich später am Tag ergeben könnte.

Beispiel:
int open_to_current;
bool isBreakout = false;
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

   open_time = StringToTime(open_time_string);

   ObjectCreate(chart_id,"OPEN TIME",OBJ_VLINE,0,open_time,0);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_COLOR,clrBlue);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_STYLE,STYLE_DASH);
   ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_WIDTH,2);

   open_time_bar_close = StringToTime(open_time_bar_close_string);

   if(TimeCurrent() >= open_time_bar_close)
     {

      CopyHigh(_Symbol,PERIOD_M15,open_time,1,m15_high);
      CopyLow(_Symbol,PERIOD_M15,open_time,1,m15_low);
      CopyClose(_Symbol,PERIOD_M15,open_time,1,m15_close);
      CopyOpen(_Symbol,PERIOD_M15,open_time,1,m15_open);

      ObjectCreate(chart_id,"High",OBJ_TREND,0,open_time,m15_high[0],TimeCurrent(),m15_high[0]);
      ObjectSetInteger(chart_id,"High",OBJPROP_COLOR,clrBlue);
      ObjectSetInteger(chart_id,"High",OBJPROP_WIDTH,2);

      ObjectCreate(chart_id,"Low",OBJ_TREND,0,open_time,m15_low[0],TimeCurrent(),m15_low[0]);
      ObjectSetInteger(chart_id,"Low",OBJPROP_COLOR,clrBlue);
      ObjectSetInteger(chart_id,"Low",OBJPROP_WIDTH,2);

      open_to_current = Bars(_Symbol,PERIOD_M5,open_time_bar_close,TimeCurrent());

      CopyHigh(_Symbol,PERIOD_M5,1,open_to_current,m5_high);
      CopyLow(_Symbol,PERIOD_M5,1,open_to_current,m5_low);
      CopyClose(_Symbol,PERIOD_M5,1,open_to_current,m5_close);
      CopyOpen(_Symbol,PERIOD_M5,1,open_to_current,m5_open);

     }

   datetime currentBarTime = iTime(_Symbol, PERIOD_M5, 0);
   ask_price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);

   if(TimeCurrent() >= open_time_bar_close && m5_close[0] > m15_high[0] && m5_close[1] < m15_high[0] && m5_close[0] > m5_open[0] && currentBarTime != lastTradeBarTime && isBreakout == false)
     {

      //BUY
      take_profit = MathAbs(ask_price + ((ask_price - m15_low[0]) * RRR));
      trade.Buy(lot_size,_Symbol,ask_price,m15_low[0],take_profit);
      lastTradeBarTime = currentBarTime;

     }

   if(TimeCurrent() >= open_time_bar_close && m5_close[0] < m15_low[0] && m5_close[1] > m15_low[0] && m5_close[0] < m5_open[0] && currentBarTime != lastTradeBarTime && isBreakout == false)
     {

      //SELL
      take_profit = MathAbs(ask_price - ((m15_high[0] - ask_price) * RRR));
      trade.Sell(lot_size,_Symbol,ask_price,m15_high[0],take_profit);
      lastTradeBarTime = currentBarTime;

     }

   if(TimeCurrent() >= open_time_bar_close)
     {
      for(int i = 0; i < open_to_current; i++)
        {
         if(i + 1  < open_to_current)
           {
            if((m5_close[i] > m15_high[0] && m5_close[i + 1] < m15_high[0]) || (m5_close[i] < m15_low[0] && m5_close[i + 1] > m15_low[0]))
              {
               isBreakout = true;
               break;
              }
           }
        }
     }

   if(TimeCurrent() < open_time)
     {
      isBreakout = false;
     }

   Comment(isBreakout);

  }

Ausgabe:

Abbildung 8. Einzelne Unterbrechung

Erläuterung:

Zwei neue Variablen wurden hinzugefügt, eine zur Bestimmung der Anzahl der Kerzen, die sich seit dem Ende des Fünfzehn-Minuten-Balkens gebildet haben, und eine weitere zur Überwachung des Auftretens eines Ausbruchs. Das Programm prüft kontinuierlich die Kerzendaten bis zum aktuellen Zeitpunkt anhand einer dynamischen Variable, um Ausbrüche zu erkennen.

Damit der EA nur ein Handelsgeschäft pro Sitzung tätigen kann, dient die Variable isBreakout als Flagge. Wenn er zum ersten Mal auf „false“ gesetzt wird, steht es dem System frei, einen Breakout-Handel auszuführen. Wenn ein legitimer Ausbruch identifiziert wird, entweder nach oben oder nach unten, setzt der Code innerhalb der Schleife isBreakout auf true, was weitere Handelsgeschäfte verhindert. Dies hilft bei der Einhaltung der Vorgabe, dass der EA nur einen Ausbruch pro Tag durchführen sollte.

Alle verfügbaren Kerzendaten vom Ende des Eröffnungsbereichs bis zur Gegenwart werden nun vom Programm über eine dynamische Variable erfasst. Diese Verbesserung erhöht die Genauigkeit und Effizienz der Ausbruchserkennung, indem sie es ermöglicht, neue Kerzen kontinuierlich zu überwachen, sobald sie entstehen.

Schließlich setzt der Abschnitt if(TimeCurrent() < open_time) isBreakout auf false zurück, bevor der neue Handelstag beginnt, damit der EA bereit ist, den Ausbruch des nächsten Tages zu erkennen und zu handeln.

Sie können der Software erlauben, während eines einzigen Ausbruchs mehrere Positionen zu eröffnen, da sie nur einen Ausbruch pro Tag ausführen soll. Mehrfache Einträge ist ein gängiger Begriff, um diese Idee zu beschreiben. Bei einem Ausbruch kann der EA eine vom Nutzer festgelegte Anzahl von Geschäften auf einmal eröffnen, anstatt nur eines. 

Beispiel:

#include <Trade/Trade.mqh>
CTrade trade;
int MagicNumber = 533930;  // Unique Number
input double RRR= 2; // RRR
input double lot_size = 0.2;
input int pos_num = 2; // Number of Positions to Open 
if(TimeCurrent() >= open_time_bar_close && TimeCurrent() <= close_time && m5_close[0] > m15_high[0] && m5_close[1] < m15_high[0] && m5_close[0] > m5_open[0] && currentBarTime != lastTradeBarTime && isBreakout == false)
  {

//BUY
   take_profit = MathAbs(ask_price + ((ask_price - m15_low[0]) * RRR));

   for(int i = 0; i < pos_num; i++)  // open 3 trades
     {
      trade.Buy(lot_size,_Symbol,ask_price,m15_low[0],take_profit);
     }
   lastTradeBarTime = currentBarTime;
  }

if(TimeCurrent() >= open_time_bar_close && m5_close[0] < m15_low[0] && m5_close[1] > m15_low[0] && m5_close[0] < m5_open[0] && currentBarTime != lastTradeBarTime && isBreakout == false)
  {

//SELL
   take_profit = MathAbs(ask_price - ((m15_high[0] - ask_price) * RRR));

   for(int i = 0; i < pos_num; i++)  // open 3 trades
     {
      trade.Sell(lot_size,_Symbol,ask_price,m15_high[0],take_profit);
     }

   lastTradeBarTime = currentBarTime;
  }

if(TimeCurrent() >= open_time_bar_close)
  {
   for(int i = 0; i < open_to_current; i++)
     {
      if(i + 1  < open_to_current)
        {
         if((m5_close[i] > m15_high[0] && m5_close[i + 1] < m15_high[0]) || (m5_close[i] < m15_low[0] && m5_close[i + 1] > m15_low[0]))
           {
            isBreakout = true;
            break;
           }
        }
     }
  }

Erläuterung:

Um Händlern die Möglichkeit zu geben, auszuwählen, wie viele Positionen das Programm bei einem gültigen Ausbruch öffnen soll, wurde eine nutzerdefinierte Eingabe hinzugefügt. Bevor der EA gestartet wird, kann dieser Wert in den Eingabeeinstellungen geändert werden. Wenn zum Beispiel eine Ausbruchsbedingung erkannt wird, eröffnet der EA automatisch zwei verschiedene Positionen, wenn die Anzahl auf 2 eingestellt ist.

Das Programm verwendet eine Schleife, um mehrere Handelsgeschäfte entsprechend der vom Nutzer eingegebenen Anzahl zu eröffnen. Je nach Eingabewert wiederholt sich die Schleife und eröffnet jedes Mal einen neuen Handel mit den gleichen Einstiegskriterien, Stop-Loss- und Take-Profit-Parametern. Wenn beispielsweise ein legitimer Ausbruch bestätigt wird, führt die Software zwei Handelsgeschäfte hintereinander aus, wenn die Zahl auf 2 gesetzt wird.

Außerdem möchten wir bestätigen, dass der EA nur vor 15:00 Uhr Serverzeit Handelsgeschäfte durchführen kann. Auf diese Weise bleibt die Handelsdisziplin gewahrt, und das System wird davon abgehalten, in Zeiten geringerer Aktivität, in denen die Volatilität und Liquidität möglicherweise abgenommen haben, Transaktionen durchzuführen. Nach fünfzehn Uhr soll der EA keine weiteren Handelsgeschäfte mehr machen. Außerdem sollte der EA alle offenen Transaktionen, die zu diesem Zeitpunkt noch aktiv sind, sofort schließen. Auf diese Weise bleibt der Ansatz konsistent und verringert unnötige Risiken, da gewährleistet ist, dass jede Handelsaktivität innerhalb der aktiven Sitzung abgeschlossen wird.

 Beispiel:

open_time = StringToTime(open_time_string);
close_time = StringToTime(close_time_string);
ObjectCreate(chart_id,"OPEN TIME",OBJ_VLINE,0,open_time,0);
ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_COLOR,clrBlue);
ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_STYLE,STYLE_DASH);
ObjectSetInteger(chart_id,"OPEN TIME",OBJPROP_WIDTH,2);

ObjectCreate(chart_id,"CLOSE TIME",OBJ_VLINE,0,close_time,0);
ObjectSetInteger(chart_id,"CLOSE TIME",OBJPROP_COLOR,clrRed);
ObjectSetInteger(chart_id,"CLOSE TIME",OBJPROP_STYLE,STYLE_DASH);
ObjectSetInteger(chart_id,"CLOSE TIME",OBJPROP_WIDTH,2);
if(TimeCurrent() >= open_time_bar_close && TimeCurrent() <= close_time && m5_close[0] > m15_high[0] && m5_close[1] < m15_high[0] && m5_close[0] > m5_open[0] && currentBarTime != lastTradeBarTime && isBreakout == false)
  {

//BUY
   take_profit = MathAbs(ask_price + ((ask_price - m15_low[0]) * RRR));

   for(int i = 0; i < pos_num; i++)  // open 3 trades
     {
      trade.Buy(lot_size,_Symbol,ask_price,m15_low[0],take_profit);
     }
   lastTradeBarTime = currentBarTime;
  }

if(TimeCurrent() >= open_time_bar_close && TimeCurrent() <= close_time && m5_close[0] < m15_low[0] && m5_close[1] > m15_low[0] && m5_close[0] < m5_open[0] && currentBarTime != lastTradeBarTime && isBreakout == false)
  {

//SELL
   take_profit = MathAbs(ask_price - ((m15_high[0] - ask_price) * RRR));

   for(int i = 0; i < pos_num; i++)  // open 3 trades
     {
      trade.Sell(lot_size,_Symbol,ask_price,m15_high[0],take_profit);
     }

   lastTradeBarTime = currentBarTime;
  }

if(TimeCurrent() >= open_time_bar_close)
  {
   for(int i = 0; i < open_to_current; i++)
     {
      if(i + 1  < open_to_current)
        {
         if((m5_close[i] > m15_high[0] && m5_close[i + 1] < m15_high[0]) || (m5_close[i] < m15_low[0] && m5_close[i + 1] > m15_low[0]))
           {
            isBreakout = true;
            break;
           }
        }
     }
  }

if(TimeCurrent() < open_time)
  {
   isBreakout = false;
  }

// Comment(isBreakout);

for(int i = 0; i < PositionsTotal(); i++)
  {
   ulong ticket = PositionGetTicket(i);

   if(PositionGetInteger(POSITION_MAGIC) == MagicNumber  && PositionGetString(POSITION_SYMBOL) == ChartSymbol(chart_id))
     {

      if(TimeCurrent() >= close_time)
        {
         // Close the position
         trade.PositionClose(ticket);
        }
     }
  }

Ausgabe:

Abbildung 9. Öffnungs- und Schließzeit

Erläuterung:

Die gewünschte Handelsschlusszeit, die angibt, wann der EA keine neuen Handelsgeschäfte mehr annehmen soll, wird zunächst vom Programm als Textwert definiert. Danach wird eine Variable generiert, die diese Zeit in geeigneter Weise festhält, sodass das System sie verstehen und für ausführungsbasierte Zeitvergleiche nutzen kann. Die Anwendung wandelt dann den angegebenen Text der Schlusszeit in einen Echtzeitwert um, den sie identifizieren und mit der Marktzeit zu diesem Zeitpunkt vergleichen kann. Zusätzlich wird eine vertikale, rot gestrichelte Linie eingeblendet, um den genauen Zeitpunkt, an dem der Handel eingestellt werden sollte, visuell darzustellen. Dies macht es für Händler einfach, den Grenzwert für die Handelsausführung auf dem Chart zu sehen.

Diese Anforderung stellt sicher, dass der EA nur vor der festgelegten Endzeitpunkt neue Handelsgeschäfte tätigen kann. Das Programm stoppt automatisch die Eröffnung neuer Positionen, wenn die aktuelle Zeit den festgelegten Grenzwert überschreitet, und verhindert so, dass ein Handel außerhalb der zulässigen Handelsperiode stattfindet. Schließlich werden alle aktiven Handelsgeschäfte von dem Teil, der nach offenen Positionen sucht, gescannt. Durch den Vergleich der eindeutigen Identifikationsnummer und des Symbols wird bestätigt, dass jede Position diesem EA gehört. Der EA schließt automatisch alle aktiven Handelsgeschäfte, wenn die aktuelle Zeit den festgelegten Grenzwert erreicht oder überschreitet.

Anmerkung:

Die Strategie dieses Artikels ist vollständig projektbasiert und soll den Lesern MQL5 durch reale, praktische Anwendung vermitteln. Es handelt sich nicht um eine garantierte Methode, um im Live-Handel Gewinne zu erzielen.

 

Schlussfolgerung

In diesem Artikel haben wir uns die Automatisierung der Methode des Opening Range Breakout (ORB) mit MQL5 angesehen. Wir haben einen EA entwickelt, der Ausbrüche zwischen verschiedenen Zeitrahmen erkennt und automatisch Handelsgeschäfte gemäß den vorgegebenen Richtlinien durchführt. Darüber hinaus haben wir ein spezielles Handelsfenster eingerichtet, um Handelsgeschäfte nach 15:00 Uhr Serverzeit zu stoppen, und Handelsbeschränkungen eingeführt, um die Anzahl der Einträge pro Ausbruch zu begrenzen. Um eine disziplinierte Ausführung und ein effizientes Risikomanagement zu gewährleisten, beendet der EA auch alle offenen Positionen nach der Handelsperiode. Dieser methodische Ansatz ermöglicht den Aufbau anspruchsvoller und zuverlässiger automatisierter Handelssysteme.

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

Beigefügte Dateien |
Letzte Kommentare | Zur Diskussion im Händlerforum (3)
Mustafa Nail Sertoglu
Mustafa Nail Sertoglu | 15 Okt. 2025 in 14:07
Vielen Dank für das Teilen Ihrer ORB-Handelsideen, aber bitte überprüfen Sie Ihre SELL / BUY-Bedingung scheint, dass sie REVERSE oder im Gegensatz zu Ihren Definitionen sind (ich werde es auch wieder überprüfen) Kommentar sagt SELL aber über ORB ?
Mustafa Nail Sertoglu
Mustafa Nail Sertoglu | 15 Okt. 2025 in 14:16
Mustafa Nail Sertoglu #:
Vielen Dank für die gemeinsame Nutzung Ihrer ORB Trading-Ideen, aber bitte überprüfen Sie Ihre SELL / BUY Bedingung scheint, dass sie REVERSE oder im Gegensatz zu Ihren Definitionen (ich werde es auch wieder überprüfen)
vielleicht BUY Signal "NOT completed ALL CONDITIONS" sogar ask/bid Preis xauusd- BUY über ORB über der ORB-Oberlinie?
Israel Pelumi Abioye
Israel Pelumi Abioye | 15 Okt. 2025 in 14:31
Mustafa Nail Sertoglu #:
Vielen Dank für das Teilen Ihrer ORB-Handelsideen, aber bitte überprüfen Sie Ihre SELL / BUY-Bedingung scheint, dass sie REVERSE oder im Gegensatz zu Ihren Definitionen sind (ich werde es auch wieder überprüfen)
Hallo, vielen Dank für Ihre freundlichen Worte. Die Bedingungen sind perfekt genau wie in dem Artikel erklärt, keine Fehler.
Die Grenzen des maschinellen Lernens überwinden (Teil 6): Effektive Speichervalidierung Die Grenzen des maschinellen Lernens überwinden (Teil 6): Effektive Speichervalidierung
In dieser Diskussion stellen wir den klassischen Ansatz der Zeitreihen-Kreuzvalidierung modernen Alternativen gegenüber, die seine Grundannahmen in Frage stellen. Wir zeigen die wichtigsten blinden Flecken der traditionellen Methode auf – insbesondere ihr Versagen, die sich verändernden Marktbedingungen zu berücksichtigen. Um diese Lücken zu schließen, führen wir die Effective Memory Cross-Validation (EMCV) ein, einen domänenspezifischen Ansatz, der die lange gehegte Annahme in Frage stellt, dass mehr historische Daten immer die Leistung verbessern.
Vom Neuling zum Experten: Synchronisieren der Zeitrahmen des Marktes Vom Neuling zum Experten: Synchronisieren der Zeitrahmen des Marktes
In dieser Diskussion stellen wir ein Synchronisierungsinstrument der Zeitrahmen von länger zu kürzer vor, das das Problem der Analyse von Marktmustern lösen soll, die sich über höhere Zeitrahmen bilden. Die eingebauten Periodenmarker in MetaTrader 5 sind oft begrenzt, starr und lassen sich nicht ohne weiteres an nicht standardisierte Zeitrahmen anpassen. Unsere Lösung nutzt die MQL5-Sprache, um einen Indikator zu entwickeln, der eine dynamische und visuelle Möglichkeit bietet, Strukturen mit höherem Zeitrahmen in Charts mit niedrigerem Zeitrahmen auszurichten. Dieses Instrument kann für eine detaillierte Marktanalyse sehr wertvoll sein. Um mehr über die Funktionen und die Umsetzung zu erfahren, lade ich Sie ein, sich an der Diskussion zu beteiligen.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Statistische Arbitrage durch kointegrierte Aktien (Teil 6): Bewertungssystem Statistische Arbitrage durch kointegrierte Aktien (Teil 6): Bewertungssystem
In diesem Artikel schlagen wir ein Bewertungssystem für die Strategien der Rückkehr zum Mittelwert vor, das auf der statistischen Arbitrage von kointegrierten Aktien basiert. In dem Artikel werden Kriterien vorgeschlagen, die von der Liquidität und den Transaktionskosten bis zur Anzahl der Kointegrationsränge und der Zeit bis zur Umkehrung des Mittelwerts reichen, wobei die strategischen Kriterien der Datenhäufigkeit (Zeitrahmen) und des Rückblickzeitraums für die Kointegrationstests berücksichtigt werden, die vor der Bewertung der Rangfolge richtig bewertet werden. Die für die Reproduktion des Backtests erforderlichen Dateien werden zur Verfügung gestellt, und ihre Ergebnisse werden ebenfalls kommentiert.