English Русский 中文 Español 日本語 Português
preview
Aufbau eines Modells aus Kerzen, Trend und Nebenbedingungen (Teil 3): Erkennung von Trendänderungen bei der Verwendung dieses Systems

Aufbau eines Modells aus Kerzen, Trend und Nebenbedingungen (Teil 3): Erkennung von Trendänderungen bei der Verwendung dieses Systems

MetaTrader 5Handel |
251 0
Clemence Benjamin
Clemence Benjamin

Inhalt


Einführung

Im Allgemeinen sind die Märkte nicht statisch. Unabhängig davon, ob der Markt nach oben oder nach unten tendiert, kann es zu unerwarteten Bewegungen kommen, wenn der Markt seinen Kurs ändert. Es ist von entscheidender Bedeutung, dass ein System diese Veränderungen erkennt und sich ihnen anpasst. Selbst eine lang anhaltende rückläufige D1-Kerze kann eine Veränderung der Dynamik signalisieren, wenn eine Umkehr auf einem niedrigeren Zeitrahmen erfolgt. Dieser Artikel befasst sich mit verschiedenen Methoden zur Erkennung von Veränderungen in Preistrends. Wenn Händler durch die Komplexität der Finanzmärkte navigieren, ist die Fähigkeit, sich schnell an sich verändernde Bedingungen anzupassen, von größter Bedeutung. Das Erkennen der Nuancen von Preisbewegungen, das Verstehen der Bedeutung von Schlüsselindikatoren und die Interpretation der Marktstimmung sind alles entscheidende Komponenten, um der Zeit voraus zu sein. Indem sie die Fähigkeit verbessern, Trendveränderungen zu erkennen, können sich Händler strategisch positionieren, um Chancen zu nutzen, die sich in der sich ständig verändernden Landschaft der Finanzwelt ergeben.

Verschiedene Faktoren beeinflussen die Markttrends oder treiben sie voran. Hier sind einige Beispiele:

  • das Anlegerverhalten, d. h. Kauf und Verkauf
  • Wirtschaftsnachrichten wie BIP und Non-Farm Payroll
  • Währungspolitik
  • globale Ereignisse wie Naturkatastrophen
  • politische Ereignisse wie Krieg usw.

Durch verschiedene Lernressourcen haben wir umfangreiches Wissen über die manuelle Erkennung von Trendänderungen erworben. Dazu gehört auch das Konzept der Trendlinienanalyse, bei der auf einem Kurs-Chart Linien gezeichnet werden, die die Höchst- oder Tiefststände der Kursbewegung eines Vermögenswerts miteinander verbinden, sodass Händler Einblicke in potenzielle Trendänderungen gewinnen können, wenn der Kurs diese Linien über- oder unterschreitet. Im weiteren Verlauf dieses Artikels werden wir eine Methode zur Erkennung von Markttrendänderungen auswählen und sie in unseren Trend Constraint-Indikator mit MQL5 integrieren. Zunächst werden wir verschiedene technische Analyseinstrumente wie gleitende Durchschnitte, Kerzen-Muster, den Relative-Stärke-Index (siehe Teil 2) und Trendlinien (siehe Abb. 1) untersuchen, um mögliche Trendumkehrungen zu erkennen. Wir werden unseren Trend-Constraint-Indikator in MQL5 ändern, um diese neue Funktionalität zu integrieren. 

Haftungsausschluss: Die in diesem Artikel vorgestellten Strategien und Techniken sind nur für Bildungszwecke gedacht. Ihre Geschäfte sind das Ergebnis Ihres eigenen Handelns. Ich übernehme keine Haftung für Verluste, die sich aus der Nutzung der hier bereitgestellten Informationen oder Tools ergeben
Wir haben einen sehr einfachen Datensatz gewählt,

Trendillustration

ABB. 1: Veranschaulichung von Trends

Anmerkung: Das obige Bild wurde zu Lernzwecken von Hand gezeichnet; es wird kein echter Vermögenswert dargestellt.

Die obige Abbildung zeigt einen typischen Aufwärtstrend, wobei die Tiefststände A und B durch eine blaue Trendlinie verbunden sind, die einen Aufwärtstrend anzeigt. In den folgenden Beispielen werden wir reale Chart-Beispiele untersuchen, um Trends besser zu verstehen. Unser primäres Ziel ist es, Markttrendänderungen zu erkennen und mit Hilfe von MQL5-Code eine geeignete Methode in unser System einzubauen. 


Möglichkeiten zur Erkennung von Veränderungen der Markttrends.

Lassen Sie uns zunächst die Markttrends definieren:

Der Markttrend gibt die allgemeine Richtung an, in die sich ein Markt im Laufe der Zeit bewegt und spiegelt das Verhalten von Käufern und Verkäufern wider. Trends können aufwärts (Hausse), abwärts (Baisse) oder seitwärts (Konsolidierung) verlaufen, siehe (Abb. 1) in der Einleitung.

Definieren wir nun eine Trendumkehr als:

Eine Trendumkehr tritt ein, wenn die Kursbewegung von einem Aufwärtstrend zu einem Abwärtstrend wechselt oder umgekehrt. Diese Veränderung lässt sich durch die Analyse wichtiger technischer Indikatoren wie gleitende Durchschnitte, Trendlinien, Kerzenmuster und Unterstützungs-/Widerstandsniveaus erkennen. Händler und Investoren beobachten diese Veränderungen der Markttrends genau, um fundierte Entscheidungen zu treffen und ihre Strategien entsprechend anzupassen.


Gleitende Durchschnitte zur Erkennung einer Trendumkehr verwenden

In Teil 1 dieser Serie haben wir einen Indikator für die Überkreuzung des gleitenden Durchschnitts entwickelt, der bei einer Überkreuzung Signale zur Trendfortsetzung liefert. Gleitende Durchschnitte mit längerer Periode können jedoch auf eine signifikante Trendänderung während eines Kreuzens hinweisen. In diesem Artikel werden wir untersuchen, wie gleitende Durchschnitte reagieren, wenn der Markt seine Richtung ändert. Nachfolgend ein Bild:

USDJPYmicroM5 zeigt, wie gleitende Durchschnitte eine Umkehr signalisieren können

Abb. 2: Das Kreuzen der gleitende Durchschnitte als Signal für eine Trendumkehr.

Mit Kerzen-Formen Trendwenden erkennen

Kerzen-Muster können effektiv genutzt werden, um mögliche Umkehrungen zu erkennen. Sie wurden im Laufe der Geschichte immer wieder daraufhin untersucht, ob sie die Marktstimmung erheblich verändern können. Visionäre wie Homma Munehisa, der Schöpfer der Bibel der Kerzenanalyse, haben unser Verständnis der Kerzen bereichert. Hier sind einige der gängigsten Kerzen-Muster für Marktumkehrungen:

Name des Kerzen-Musters Beschreibung
Hammer 
kleiner Körper und ein langer unterer Schatten
umgekehrter Hammer
kleiner Körper und ein langer oberer Schatten
Aufwärts-Engulfing-Muster
eine Aufwärtskerze umhüllt die vorherige Abwärtskerze vollständig
Abwärts-Engulfing-Muster
eine Abwärtskerze umhüllt die vorherige Aufwärtskerze vollständig
Doji ein kleiner Körper und lange obere und untere Schatten
Sternschnuppe (shooting star) einen kleinen Körper und einen langen oberen Schatten
Henker (hanging man) ein kleiner Körper und ein langer unterer Schatten
Morgenstern (morning star) eine lange rückläufige Kerze, gefolgt von einer schmalen Kerze mit einem tieferen Tief und einem höheren Hoch
Abendstern (evening star) eine lange bullische Kerze, gefolgt von einer schmalen Kerze mit einem höheren Hoch und einem niedrigeren Tief
Alle diese Kerzen-Charakteristika sind mit MQL5 programmierbar, da sie alle Preisniveaus (Open Close High und Low) enthalten, die für die Programmierung entscheidend sind.


Trendlinien zur Erkennung einer Trendumkehr verwenden

Im Chart der Mt5.Platform können wir das Trendlinien-Objekt-Tool verwenden, um Trends darzustellen, indem wir aufeinanderfolgende Tiefpunkte in einer Preisreihe eines digitalen Assets verbinden. Eine durchbrochene Trendlinie weist auf einen Trendwechsel hin. Um eine Trendlinie zu zeichnen, klicken Sie einfach auf das Trendlinienwerkzeug in der Symbolleiste, klicken Sie dann auf den ersten Tiefpunkt und ziehen Sie die Linie zum nächsten Tiefpunkt. Die Trendlinie läuft automatisch weiter nach rechts auf dem Chart.

Bruch der Trendlinie des B300-Index

Abb. 3: Trendlinie als Instrument zur Erkennung einer Trendumkehr

Verwendung von Unterstützungs-/Widerstandsniveaus zur Erkennung einer Trendumkehr

Eine horizontale Linie im MT5-Chart kann verwendet werden, um Unterstützungs- und Widerstandsniveaus in Trends darzustellen, indem man sie auf Kursspitzen platziert. Die Beobachtung des Kurses, wenn er diese Niveaus durchbricht, könnte auf eine Trendwende hinweisen. Sehen Sie sich das Erklärvideo unten an.

Probleme mit unserem derzeitigen System.

Wir haben unser System erfolgreich so konfiguriert, dass es sein Signal an der D1-Trendform ausrichtet und Indikatoren wie den SMA 400 in Teil 2 einbezieht. Bei den historischen Daten lassen sich jedoch erhebliche Probleme feststellen. Wir müssen die Fluktuationen in den unteren Zeitrahmen berücksichtigen, die die anfängliche Stimmung zu Beginn des Tages umkehren können. So kann ein Tag beispielsweise mit einem Abwärtstendenz beginnen, aber mit einer „Pin-Bar“ oder einer Aufwärtsstimmung enden. Umkehrsignale treten häufig in niedrigeren Zeitrahmen auf, was uns dazu veranlasst, den Signalisierungsmechanismus des Systems anzupassen, um Trendänderungen zu berücksichtigen, selbst wenn sie ursprünglich auf die tägliche Marktstimmung beschränkt waren.


Einbindung der Funktion zur Erkennung von Trendänderungen mit MQL5

Ich habe mich dafür entschieden, den SMA 200 als langsamen gleitenden Durchschnitt und den EMA 100 als schnellen gleitenden Durchschnitt zu verwenden. In der Regel liegen diese gleitenden Durchschnitte bei starken Trends weiter auseinander, während sie bei einer schwachen Marktdynamik oder einer Seitwärtsbewegung des Kurses enger beieinander liegen. Wenn sich die beiden Durchschnittswerte kreuzen, signalisiert dies häufig einen Richtungswechsel. Es wäre sehr nützlich, wenn unser System dies erkennen und uns warnen würde. Unser Ziel ist es, dass das System uns nur das Signal liefert, sodass unsere Zwangssignale entsprechend angepasst werden können. Mit diesem Ansatz versuchen wir, potenzielle Trendumkehrungen zu erfassen und profitable Handelsmöglichkeiten zu nutzen. Ich werde einige Schlüsselfunktionen erklären und dann den Hauptcode einfügen

Unser MA-Handler wird wie folgt deklariert.

MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE); // For EMA 100

MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE); // For SMA 200

Der folgende Code zeigt die Kreuzungsbedingungen in MQL5 unter der Iterationsfunktion.

//Indicator Buffer 3
      if(MA3[i] > MA4[i]
      && MA3[i+1] < MA4[i+1] //Moving Average crosses above Moving Average
      )
        {
         Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer3[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 4
      if(MA3[i] < MA4[i]
      && MA3[i+1] > MA4[i+1] //Moving Average crosses below Moving Average
      )
        {
         Buffer4[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer4[i] = EMPTY_VALUE;
        }

Der Indikator Trend-Constraint aus dem vorherigen Artikel enthielt 2 Puffer, einen für Kaufsignale und einen für Verkaufssignale zur Trendfortsetzung. Um unser Ziel zu erreichen, wollen wir zwei weitere Puffer hinzufügen, einen für den Verkauf und einen für den Kauf, die alle Umkehrsignale darstellen, wenn ein Crossover stattfindet. Im Programm werden sie nacheinander als Puffer3 und Puffer4 bezeichnet. Wir haben einen neuen Anzeigestil für die Funktion optimiert. Die Darstellung des Indikators kann durch Auswahl des mql5-Objekts Wingdings angepasst werden. Hier habe ich die Objektnummer 236 für mein Kaufumkehrsignal und die Objektnummer 238 für das Verkaufsumkehrsignal verwendet.

// under OnInit() function. The wingding objects can be customized by altering those highlighted values choosing from wingding listing.
  SetIndexBuffer(2, Buffer3);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(2, PLOT_ARROW, 236);
   SetIndexBuffer(3, Buffer4);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(3, PLOT_ARROW, 238);

Der andere Aspekt ist der Farbcode mit MQL5. Diese Farben können über die Eingabeeinstellungen im Metatrader 5 optimiert werden. Jede Farbe wird durch einen eindeutigen Code innerhalb eines Programms dargestellt, z. B. C'0,0,0' steht für Schwarz, siehe Codeausschnitt unten:

#property indicator_type3 DRAW_ARROW
#property indicator_width3 1  // with can be adjusted up to 5 times.
#property indicator_color3 0x04CC04 //color for buy reversal
#property indicator_label3 "buy reversal"

#property indicator_type4 DRAW_ARROW
#property indicator_width4 1              //with can be adjusted up to 5 times.
#property indicator_color4 0xE81AC6  // Color code for sell reversal
#property indicator_label4 "sell reversal"

Weitere Details und Kommentare im Hauptcode unten, nachdem ich alle Teile und Ideen zusammengefügt habe.

///Indicator Name: Trend Constraint
#property copyright "Clemence Benjamin"
#property link      "https://mql5.com"
#property version   "1.03"
#property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"

//+------------------------------------------------------------------------------------------------------------------------------+
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4

#property indicator_type1 DRAW_ARROW
#property indicator_width1 5
#property indicator_color1 0xFF3C00
#property indicator_label1 "Buy"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 5
#property indicator_color2 0x0000FF
#property indicator_label2 "Sell"

#property indicator_type3 DRAW_ARROW
#property indicator_width3 1
#property indicator_color3 0x04CC04
#property indicator_label3 "Buy Reversal"

#property indicator_type4 DRAW_ARROW
#property indicator_width4 1
#property indicator_color4 0xE81AC6
#property indicator_label4 "Sell Reversal"

#define PLOT_MAXIMUM_BARS_BACK 5000
#define OMIT_OLDEST_BARS 50

//--- indicator buffers
double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];

input double Oversold = 30;
input double Overbought = 70;
datetime time_alert; //used when sending alert
input bool Audible_Alerts = true;
input bool Push_Notifications = true;
double myPoint; //initialized in OnInit
int RSI_handle;
double RSI[];
double Open[];
double Close[];
int MA_handle;
double MA[];
int MA_handle2;
double MA2[];
int MA_handle3;
double MA3[];
int MA_handle4;
double MA4[];
double Low[];
double High[];

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
   else if(type == "indicator")
     {
      if(Audible_Alerts) Alert(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {   
   SetIndexBuffer(0, Buffer1);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(0, PLOT_ARROW, 241);
   SetIndexBuffer(1, Buffer2);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(1, PLOT_ARROW, 242);
   SetIndexBuffer(2, Buffer3);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(2, PLOT_ARROW, 236);
   SetIndexBuffer(3, Buffer4);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(3, PLOT_ARROW, 238);
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 3)
     {
      myPoint *= 10;
     }
   RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE);
   if(RSI_handle < 0)
     {
      Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE);
   if(MA_handle < 0)
     {
      Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle2 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle2 < 0)
     {
      Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
   if(MA_handle3 < 0)
     {
      Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle4 < 0)
     {
      Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
   int limit = rates_total - prev_calculated;
   //--- counting from 0 to rates_total
   ArraySetAsSeries(Buffer1, true);
   ArraySetAsSeries(Buffer2, true);
   ArraySetAsSeries(Buffer3, true);
   ArraySetAsSeries(Buffer4, true);
   //--- initial zero
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
      ArrayInitialize(Buffer3, EMPTY_VALUE);
      ArrayInitialize(Buffer4, EMPTY_VALUE);
     }
   else
      limit++;
   datetime Time[];
   
   datetime TimeShift[];
   if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total);
   ArraySetAsSeries(TimeShift, true);
   int barshift_M1[];
   ArrayResize(barshift_M1, rates_total);
   int barshift_D1[];
   ArrayResize(barshift_D1, rates_total);
   for(int i = 0; i < rates_total; i++)
     {
      barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]);
      barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]);
   }
   if(BarsCalculated(RSI_handle) <= 0) 
      return(0);
   if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total);
   ArraySetAsSeries(RSI, true);
   if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total);
   ArraySetAsSeries(Open, true);
   if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total);
   ArraySetAsSeries(Close, true);
   if(BarsCalculated(MA_handle) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
   ArraySetAsSeries(MA, true);
   if(BarsCalculated(MA_handle2) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
   ArraySetAsSeries(MA2, true);
   if(BarsCalculated(MA_handle3) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total);
   ArraySetAsSeries(MA3, true);
   if(BarsCalculated(MA_handle4) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total);
   ArraySetAsSeries(MA4, true);
   if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
   ArraySetAsSeries(Low, true);
   if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
   ArraySetAsSeries(High, true);
   if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
   ArraySetAsSeries(Time, true);
   //--- main loop
   for(int i = limit-1; i >= 0; i--)
     {
      if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
      
      if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue;
      if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue;
      
      //Indicator Buffer 1
      if(RSI[i] < Oversold
      && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value
      && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close
      && MA[i] > MA2[i] //Moving Average > Moving Average
      && MA3[i] > MA4[i] //Moving Average > Moving Average
      )
        {
         Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer1[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 2
      if(RSI[i] > Overbought
      && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value
      && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close
      && MA[i] < MA2[i] //Moving Average < Moving Average
      && MA3[i] < MA4[i] //Moving Average < Moving Average
      )
        {
         Buffer2[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer2[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 3
      if(MA3[i] > MA4[i]
      && MA3[i+1] < MA4[i+1] //Moving Average crosses above Moving Average
      )
        {
         Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer3[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 4
      if(MA3[i] < MA4[i]
      && MA3[i+1] > MA4[i+1] //Moving Average crosses below Moving Average
      )
        {
         Buffer4[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer4[i] = EMPTY_VALUE;
        }
     }
   return(rates_total);
  }
//Thank you for getting this far, you are amazing.
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+


Erkundung der Ergebnisse des endgültigen Systems

Die Ergebnisse des Systems sind beeindruckend. Wir können nun unser Signalsystem auf das D1-Marktsentiment beschränken und auch Signale erhalten, wenn ein Umkehrimpuls über das Kreuzen von EMA(100) und SMA(200) erfolgt. Die folgenden Bilder zeigen die Ausgabe des Indikators im aktuellen Chart-Historie. Das System scheint bei der Erfassung von Stimmungsumschwüngen am Markt und der Identifizierung potenzieller Umkehrpunkte außerordentlich gut zu funktionieren. Indem wir uns auf die D1-Marktstimmung konzentrieren und die EMA(100) und SMA(200) Crossover-Signale nutzen, können wir unsere Handelsstrategien verbessern und fundiertere Entscheidungen treffen. Die Indikatorausgabe auf den historischen Chartdaten zeigt deutlich die Wirksamkeit dieser Signale bei der Vorhersage von Marktbewegungen.

USDJPYM1 mit Trend Constraint v1.03

Abb. 4 : Ergebnisse von Trend Constraint V1.03 auf USDJPYmicroM1

Anmerkung: Wenn Sie Probleme mit fehlenden Signalpfeilen auf Ihrem Chart haben, nachdem Sie den Indikator hinzugefügt haben, versuchen Sie zu aktualisieren, indem Sie mit der rechten Maustaste (RMB) auf den MT5-Chart klicken und „Refresh“ aus dem angezeigten Menü auswählen.

Die aus unseren Entwicklungen gewonnenen Daten können später in Systeme des maschinellen Lernens und der künstlichen Intelligenz zur weiteren Verfeinerung einfließen. Diese Systeme können so geschult werden, dass sie fortgeschrittene Analysen durchführen können, was bei der Überwindung der Probleme, die wir mit dem derzeitigen Modell haben, von Vorteil wäre. Die Signale im obigen Ergebnisbild stimmen mit dieser Idee überein, aber es gab auch einige irreführende Signale. Dies ist typisch für jedes System und dient als Motivation, weitere Methoden zur Verbesserung unseres derzeitigen Systems zu erforschen. Die Synthetik kann bei der Verwendung dieses Systems, wie es von Deriv Limited angeboten wird, verschiedene Ergebnisse liefern.


Erklärvideo zum Ergebnis

Sehen Sie sich das Video unten an, um die Leistungsfähigkeit unserer neuen Version zu erkunden.




Schlussfolgerung

Die Einbeziehung von Funktionen zur Erkennung von Trendänderungen in unser System hat es erheblich verbessert. Während wir unsere Signale auf den aktuellen Markttrend beschränken, haben wir erfolgreich potenzielle Verluste gemildert, die aus Signalen entstehen könnten, die einen ungültigen Trend unterstützen, obwohl die D1-Stimmung diesen unterstützt. Wir sind auf Probleme mit den Umkehrsignalen gestoßen, die von diesem System während eines anhaltenden Trends geliefert werden. Deshalb habe ich beschlossen, den Zeitraum der verwendeten gleitenden Durchschnitte zu verlängern. In den nächsten Artikeln werde ich auf dieses Thema zurückkommen und näher darauf eingehen, wie sich diese Anpassung entwickelt hat. Ich hoffe, Sie konnten diesen Ideen etwas abgewinnen und freue mich über Ihre Meinung in den unten stehenden Kommentaren. Unsere zukünftigen Artikel werden fortgeschrittene Visualisierungen unseres Indikatorsystems unter Verwendung der vielseitigen Sprache MQL5 enthalten.




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

Klassische Strategien neu interpretieren: Rohöl Klassische Strategien neu interpretieren: Rohöl
In diesem Artikel greifen wir eine klassische Rohölhandelsstrategie wieder auf, um sie durch den Einsatz von Algorithmen des überwachten maschinellen Lernens zu verbessern. Wir werden ein Modell der kleinsten Quadrate konstruieren, um zukünftige Brent-Rohölpreise auf der Grundlage der Differenz zwischen Brent- und WTI-Rohölpreisen vorherzusagen. Unser Ziel ist es, einen Frühindikator für künftige Veränderungen der Brent-Preise zu ermitteln.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 18): Neuronale Architektursuche mit Eigenvektoren MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 18): Neuronale Architektursuche mit Eigenvektoren
Die Suche nach neuronaler Architektur, ein automatischer Ansatz zur Bestimmung der idealen Einstellungen für neuronale Netze, kann bei vielen Optionen und großen Testdatensätzen von Vorteil sein. Wir untersuchen, wie dieser Prozess bei gepaarten Eigenvektoren noch effizienter gestaltet werden kann.
Ein Algorithmus zur Auswahl von Merkmalen, der energiebasiertes Lernen in reinem MQL5 verwendet Ein Algorithmus zur Auswahl von Merkmalen, der energiebasiertes Lernen in reinem MQL5 verwendet
In diesem Artikel stellen wir die Implementierung eines Algorithmus zur Auswahl von Merkmalen vor, der in einer wissenschaftlichen Arbeit mit dem Titel „FREL: A stable feature selection algorithm“ vorgestellt wurde und auch als Merkmalsgewichtung als reguliertes energiebasiertes Lernen bezeichnet werden kann.
Modifizierter Grid-Hedge EA in MQL5 (Teil IV): Optimierung der einfachen Grid-Strategie (I) Modifizierter Grid-Hedge EA in MQL5 (Teil IV): Optimierung der einfachen Grid-Strategie (I)
In diesem vierten Teil greifen wir die zuvor entwickelten Simple Hedge und Simple Grid Expert Advisors (EAs) wieder auf. Wir konzentrieren uns darauf, den Simple Grid EA durch mathematische Analysen und einen Brute-Force-Ansatz zu verfeinern, mit dem Ziel, eine optimale Strategie anzuwenden. Dieser Artikel befasst sich eingehend mit der mathematischen Optimierung der Strategie und legt den Grundstein für die künftige Erforschung der kodierungsbasierten Optimierung in späteren Ausgaben.