Separates Optimieren von Trend- und Seitwärtsstrategie

12 Februar 2019, 10:30
Alexander Fedosov
0
451

Inhalt


Einführung

Bei der Entwicklung von Handelsstrategien besteht die erste Aufgabe darin, die Markteintrittsbedingungen, die Positionsverfolgungsmethode und den Ausstiegspunkt festzulegen. Dazu werden verschiedene mathematische, statistische und andere analytische Methoden eingesetzt. Sie werden oft durch vorgefertigte autonome Systeme ergänzt, mit denen Marktmerkmale in Form von Indikatoren bewertet werden. Eines der Hauptprobleme bei der Entwicklung einer Handelsstrategie ist die mangelnde Vielseitigkeit. Ein Handelssystem ist nicht in der Lage, unter allen möglichen Marktbedingungen mit gleicher Effizienz zu arbeiten. Daher wählen Händler in der Regel Bedingungen für die Erkennung bestimmter (potenziell profitabler) Marktbedingungen bei der Entwicklung von Expert Advisors. 

Außerdem hat jedes Handelssystem seine Nachteile. Trendfolgende Strategien scheitern in längeren Seitwärtsbewegungen, während Seitwärtsstrategien bei starken Richtungsbewegungen zu Verlustpositionen führen. Um die Wirkung von Fehlsignalen zu reduzieren und die Rentabilität zu verbessern, werden die Systeme flexibel gestaltet, d.h. sie verfügen über einen bestimmten Satz von Einstellungen oder Eingangsdaten, was gerechtfertigt ist, da sich das Marktverhalten ständig ändert.

Mit der Zeit wird jedes Handelssystem weniger effizient, und deshalb ist es notwendig, seine Parameter an die neuen Bedingungen anzupassen. Der Integrierte Strategy Tester des MetaTrader 5 soll dieses Problem lösen. Dieses Tool hilft bei der Analyse der Performance eines jeden Handels-EAs auf der Historie und definiert optimale Einstellungen für seine weitere Verwendung als Grundlage für den realen Handel.


Konzept des separaten Optimierens

In diesem Artikel werden wir die Anwendung des Strategietesters in einem weiteren Sinne in Betracht ziehen. Offensichtlich handelt die Mehrheit der Handelssysteme in zwei Richtungen (Kauf und Verkauf unter bestimmten Bedingungen). Die Abb. 1 zeigt ein einfaches Beispiel für eine Handelsstrategie in Aktion. Die Idee ist einfach — kaufen Sie zu einem niedrigen Preis und verkaufen Sie zu einem hohen Preis.


Abb. 1. Eine Trendfolgestrategie in Aktion

In der Regel wird ein Satz von Einstellungen verwendet, um den Auf- und Abwärtstrend in einem solchen System zu bestimmen, und die Eingangsbedingungen werden gespiegelt. Aber der Punkt ist, dass die Besonderheiten des Marktwachstums und -rückgangs in vielen Merkmalen, wie Geschwindigkeit und Dauer, sehr unterschiedlich sein können. In diesem Zusammenhang schlage ich vor, ein System in Betracht zu ziehen, das die Markteintritte getrennt nach Aufwärtstrend und Abwärtstrend bestimmt.

Um dies zu erreichen, benötigen wir zwei Parametersätze, die die Markteintritts- und Ausstiegsbedingungen definieren. An dieser Stelle kommen wir zum Konzept des "separaten Optimierens".

Separates Optimieren bedeutet, die optimalen Parameter des Handelssystems mit dem Strategietester für einen Aufwärtstrend und einen Abwärtstrend getrennt zu definieren.

Um die separate Optimierung zu testen, entschied ich mich für zwei Handelssysteme: einen für den Trend und für die Seitwärtsbewegung. In der Trendfolge-Strategie werden wir Auf- und Abwärtstrend separat optimieren, während wir bei der Seitwärtsstrategie eine separate Optimierung des Handels in einem Kanal prüfen werden. 


Auswahl einer trendorientierten Handelsstrategie

Ich werde J. F. Ehlers' Center of Gravity Indikator verwenden, der durch ein farbiges OSMA-Histogramm (CenterOfGravityOSMA) dargestellt wird, um eine separate Optimierung zu testen. Sein Signal wird durch den Indikator bestätigt, der die Durchschnittsgeschwindigkeit des Preises berechnet.

Parameter Beschreibung
Verwendeter Indikator CenterOfGravityOSMA
Verwendeter Indikator Average Speed
Zeitrahmen H1
Kaufbedingungen Das Histogramm des Center of Gravity zeigt Wachstum (der Indikatorwert ist kleiner als Null) und der Wert des Average Speed liegt über dem Schwellenwert (voreingestellt in den Parametern).
Verkaufsbedingungen Das Histogramm des Center of Gravity fällt (der Indikatorwert ist größer als Null) und der Wert des Average Speed liegt über dem Schwellenwert (voreingestellt in den Parametern).
Ausstiegsbedingungen Take-Profit/Stop-Loss

Die Strategie ist in Abb. 2 visuell dargestellt. Wie aus der obigen Tabelle ersichtlich ist, hat die Handelsstrategie klar definierte Bedingungen für den Markteintritt beim Kauf und Verkauf. Da es sich um eine trendorientierte Strategie handelt, entsprechen die Kaufbedingungen einem Aufwärtstrend, während die Verkaufsbedingungen einem Abwärtstrend entsprechen. 

Abb. 2. Eröffnungsbedingung für die Trendfolgestrategie

Bei der Umsetzung der Strategie in MetaEditor sollten wir die EA-Arbeitsbedingungen so einstellen, dass sie nur bei einem Aufwärtstrend, nur bei einem Abwärtstrend oder in beiden Fällen verwendet werden können. 

Wir sollten auch die folgenden Punkte berücksichtigen:

  • Fähigkeit, die Testmodi für Aufwärts- und Abwärtstrends sowie für beide Fälle zu regeln.
  • Für eine separate Optimierung ist es notwendig, das EA getrennt für einen Aufwärtstrend, einen Abwärtstrend und einen gemeinsamen Betrieb zu verwenden;
  • Aufwärtstrend und Abwärtstrend sollten über eigene, unabhängige Parameter verfügen. Dies ist notwendig, um sie im gemeinsamen Handel zu nutzen;

Um diese EA-Entwicklungsbedingungen zu erfüllen, verwenden wir folgenden Code:

//+------------------------------------------------------------------+
//| Enumeration der Operationsmodi                                   |
//+------------------------------------------------------------------+
enum Trend_type
  {
   UPTREND = 1,            //Aufwärtstrend       
   DOWNTREND,              //Abwärtstrend
   BOTH                    //Beide Trends
  };

Die Eingabeparameter schauen wie folgt aus:

//+------------------------------------------------------------------+
//| EA Eingabeparameter                                              |
//+------------------------------------------------------------------+
input string               Inp_EaComment="Trend Strategy";              //EA Kommentar
input double               Inp_Lot=0.01;                                //Lot
input MarginMode           Inp_MMode=LOT;                               //MM

input Trend_type           Inp_Trend_type=3;                            //Trend Typ
//--- Aufwärtstrend Parameter
input string               Inp_Str_label1="===Uptrend parameters===";   //Bezeichnung
input int                  Inp_MagicNum1=1111;                          //Magicnummer
input int                  Inp_StopLoss1=40;                            //Stop-Loss(points)
input int                  Inp_TakeProfit1=60;                          //Take-Profit(points)

//--- CenterOfGravityOSMA Indikatorparameter
input uint                 Period_1=9;                                  //Glättungslänge
input uint                 SmoothPeriod1_1=3;                           //Glättungslänge 1
input ENUM_MA_METHOD       MA_Method_1_1=MODE_SMA;                      //Glättungsverfahren 1
input uint                 SmoothPeriod2_1=3;                           //Glättungslänge 2
input ENUM_MA_METHOD       MA_Method_2_1=MODE_SMA;                      //Glättungsverfahren 2
input Applied_price_       AppliedPrice1=PRICE_OPEN_;                   //Berechnungspreis

//--- Average Speed Indikatorparameter
input int                  Inp_Bars1=1;                                 //Tage
input ENUM_APPLIED_PRICE   Price1=PRICE_CLOSE;                          //Berechnungspreis
input double               Trend_lev1=2;                                //Trend Level

//--- Abwärtstrend Parameter
input string               Inp_Str_label2="===Downtrend parameters==="; //Bezeichnung
input int                  Inp_MagicNum2=2222;                          //Magicnummer
input int                  Inp_StopLoss2=40;                            //Stop-Loss(points)
input int                  Inp_TakeProfit2=60;                          //Take-Profit(points)

//--- CenterOfGravityOSMA Indikatorparameter
input uint                 Period_2=9;                                  //Glättungslänge
input uint                 SmoothPeriod1_2=3;                           //Glättungslänge 1
input ENUM_MA_METHOD       MA_Method_1_2=MODE_SMA;                      //Glättungsverfahren 1
input uint                 SmoothPeriod2_2=3;                           //Glättungslänge 2
input ENUM_MA_METHOD       MA_Method_2_2=MODE_SMA;                      //Glättungsverfahren 2
input Applied_price_       AppliedPrice2=PRICE_OPEN_;                   //Berechnungspreis

//--- Average Speed Indikatorparameter
input int                  Inp_Bars2=1;                                 //Tage
input ENUM_APPLIED_PRICE   Price2=PRICE_CLOSE;                          //Berechnungspreis
input double               Trend_lev2=2;                                //Trend Level

Wie wir im Code sehen können, ist die Variable Inp_Trend_type für die Auswahl der EA-Betriebsart verantwortlich, während die Eingaben für die Modi Uptrend und Downtrend entsprechend in 'Uptrend parameters' und 'Downtrend parameters' getrennt sind. Bei der Auswahl des Modus Both werden die Eingänge beider Abschnitte verwendet, während der Implementierungscode der Hauptlogik in der folgenden Auflistung angegeben ist:

//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Datenabfrage für die Berechnung

   if(!GetIndValue())
      return;

   if(Inp_Trend_type==1 && !Trade.IsOpenedByMagic(Inp_MagicNum1))
     {
      //--- Eröffnungsauftrag im Falle eines Kaufsignals
      if(BuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
     }
   else if(Inp_Trend_type==2 && !Trade.IsOpenedByMagic(Inp_MagicNum2))
     {
      //--- Eröffnen einer Position wegen eines Verkaufssignals
      if(SellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
   else if(Inp_Trend_type==3)
     {
      //--- Eröffnungsauftrag im Falle eines Kaufsignals
      if(BuySignal() && !Trade.IsOpenedByMagic(Inp_MagicNum1))
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
      //--- Eröffnen einer Position wegen eines Verkaufssignals
      if(SellSignal() && !Trade.IsOpenedByMagic(Inp_MagicNum2))
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
  }
//+------------------------------------------------------------------+
//| Bedingungen für Kaufen                                           |
//+------------------------------------------------------------------+
bool BuySignal()
  {
   return(avr_speed1[0]>Trend_lev1 && cog1[1]<cog1[0] &&(cog1[1]<0 && cog1[0]<0))?true:false;
  }
//+------------------------------------------------------------------+
//| Bedingungen für Verkaufen                                        |
//+------------------------------------------------------------------+
bool SellSignal()
  {
   return(avr_speed2[0]>Trend_lev2 && cog2[1]>cog2[0] &&(cog2[1]>0 && cog2[0]>0))?true:false;
  }
//+------------------------------------------------------------------+
//| Abrufen des aktuellen Indikatorwertes                            |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle1,0,0,2,cog1)<=0 ||
          CopyBuffer(InpInd_Handle2,0,0,2,cog2)<=0 ||
          CopyBuffer(InpInd_Handle3,0,0,2,avr_speed1)<=0 ||
          CopyBuffer(InpInd_Handle4,0,0,2,avr_speed2)<=0
          )?false:true;
  }
//+------------------------------------------------------------------+

Die Handelsregeln sind für die Modi Uptrend und Downtrend einfach: Kaufen während eines Aufwärtstrends und Verkaufen während eines Abwärtstrends, d.h. dem Trend folgen. Im Modus Both arbeiten diese Systeme zusammen und unabhängig voneinander mit ihren jeweiligen Eingabeparametern — Uptrend+Downtrend.


Testen der Handelsstrategie

Für das Testen und separate Optimieren einer ausgewählten Strategie wäre es sinnvoll, glasklare Aufwärtsphasen für den Aufwärtsmodus und Abwärtsphasen für den Abwärtstrend auszuwählen. Deshalb habe ich mich entschieden, die folgenden in Abb. 3 dargestellten Zeiträume zu wählen.

Abb. 3. Zeiträume, die für einen Test ausgewählt wurden

Fassen wir also die Testeinstellungen zusammen.

  • Intervall: Für den Aufwärtstrend-Modus: 10.04.2017 - 01.02.2018. Für Abwärtstrend-Modus: 08.05.2014 - 13.03.2015.
  • Symbol: EURUSD.
  • Handelsmodus: Keine Verzögerung. Dies sind keine hochfrequenten Handelsstrategien, so dass der Effekt von Verzögerungen sehr gering wäre.
  • Test: М1 OHLC. Vor-Tests mit realen Ticks zeigen fast die gleichen Ergebnisse. 
  • Erste Einzahlung: 1000 USD.
  • Test: М1 OHLC. Vor-Tests mit realen Ticks zeigt fast die gleichen Ergebnisse.
  • Server: MetaQuotes-Demo.
  • Kurse: 5 Dezimalstellen.

Die Ziele der Tests und der Optimierung sind die Parameter der Indikatoren, die in der Strategie verwendet werden, sowie die Werte für Take-Profit und Stop-Loss.

Die Optimierungsergebnisse für einen Aufwärtstrend stellen sich wie folgt dar:


Abb. 4. Ergebnisse der Tests und der Optimierung im Aufwärtstrend

Die Optimierungsergebnisse des Abwärtstrends sind wie folgt:


Abb. 5. Test- und Optimierungsergebnisse zum Abwärtstrend

Nachdem die besten Parameter durch Optimierung auf die für die ausgewählten Modi günstigen Zeitintervalle definiert wurden, ist es an der Zeit, diese Parameter in einem gemischten Intervall mit Aufwärts- und Abwärtstrend auszuprobieren. Dies wird es uns ermöglichen, die Vielseitigkeit der Handelsstrategie zu testen. 

Ich habe mich entschieden, das folgende Zeitintervall zu wählen, das für die oben genannten Anforderungen sehr geeignet ist.

Abb. 6. Ausgewählter Zeitraum für gemischte Tests

Wie wir in Abb. 6 sehen können, zeigt dieses Zeitintervall sowohl Aufwärts- als auch Abwärtstrends mit Korrekturen und Seitwärtsbewegungen. Lassen Sie uns nun sehen, wie sich der EA in einer unbekannten Zeit der Geschichte verhalten wird.


Abb. 7. Testergebnisse der optimierten Trendfolgestrategie im ungünstigen Intervall


Unter Berücksichtigung der Testergebnisse dieser trendorientierten Strategien können wir die folgenden Beobachtungen machen:

  • Die Strategie hat ein positives Ergebnis in einem ungünstigen Intervall gezeigt.
  • Der Prozentsatz der erfolgreichen Kaufpositionen hat sich als höherwertig erwiesen als der Prozentsatz der Verkaufspositionen.
  • Auch Parameter wie Rentabilität und erwartetes Ergebnis haben gezeigt, dass die Strategie in der Regel eine positive Dynamik in diesem Testintervall aufweist. 

Auswahl einer Seitwärtsstrategie

Um eine separate Optimierung auf einem flachen Markt durchzuführen, habe ich Williams's Percent Range gewählt, der den überkauften/überverkauften Zustand bestimmt. Dieses Tool ist als Hauptindikator für die Suche nach Positionseröffnungen zu verwenden. Der ADX-Trendfolgeindikator wird verwendet, das Fehlen eines Trends zu bestätigen.

Parameter Beschreibung
Verwendeter Indikator Williams Percent Range
Verwendeter Indikator ADX
Zeitrahmen H1
Kaufbedingungen Der Indikator WPR liegt im überverkauften Bereich (unter -80) und der ADX unter dem Schwellenwert.
Verkaufsbedingungen Der Indikator WPR liegt im überkauften Bereich (über -20) und der ADX unter dem Schwellenwert.
Ausstiegsbedingungen   Take-Profit/Stop-Loss

Abb. 8 zeigt beispielsweise das Eröffnen gemäß der Marktbedingungen und der Strategie.

Abb. 8. Eröffnungsbedingungen nach der Seitwärtsstrategie

Basierend auf der gewählten Strategie wird eine separate Optimierung nach Art der Transaktion durchgeführt: Kauf- und Verkaufsmodi.

//+------------------------------------------------------------------+
//| Enumeration der Operationsmodi                                   |
//+------------------------------------------------------------------+
enum Trend_type
  {
   UPTREND = 1,            //Kaufen    
   DOWNTREND,              //Verkaufen
   BOTH                    //Beides 
  };

Auf diese Weise ist es möglich, das Verhalten der gewählten Strategie in einer Seitwärtsbewegung zu bestimmen. Der EA-Code ist unten aufgeführt:

//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Datenabfrage für die Berechnung

   if(!GetIndValue())
      return;

   if(Inp_Trend_type==1 && !Trade.IsOpenedByMagic(Inp_MagicNum1))
     {
      //--- Eröffnungsauftrag im Falle eines Kaufsignals
      if(BuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
     }
   else if(Inp_Trend_type==2 && !Trade.IsOpenedByMagic(Inp_MagicNum2))
     {
      //--- Eröffnen einer Position wegen eines Verkaufssignals
      if(SellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
   else if(Inp_Trend_type==3)
     {
      //--- Eröffnungsauftrag im Falle eines Kaufsignals
      if(BuySignal() && !Trade.IsOpenedByMagic(Inp_MagicNum1))
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
      //--- Eröffnen einer Position wegen eines Verkaufssignals
      if(SellSignal() && !Trade.IsOpenedByMagic(Inp_MagicNum2))
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);
     }
  }
//+------------------------------------------------------------------+
//| Bedingungen für Kaufen                                           |
//+------------------------------------------------------------------+
bool BuySignal()
  {
   return(wpr1[0]<-80 && adx1[0]<Inp_FlatLevel1)?true:false;
  }
//+------------------------------------------------------------------+
//| Bedingungen für Verkaufen                                        |
//+------------------------------------------------------------------+
bool SellSignal()
  {
   return(wpr2[0]>=-20 && adx2[0]<Inp_FlatLevel2)?true:false;
  }
//+------------------------------------------------------------------+
//| Abrufen des aktuellen Indikatorwertes                            |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle1,0,0,2,wpr1)<=0  ||
          CopyBuffer(InpInd_Handle2,0,0,2,wpr2)<=0 || 
          CopyBuffer(InpInd_Handle3,0,0,2,adx1)<=0  ||
          CopyBuffer(InpInd_Handle4,0,0,2,adx2)<=0
          )?false:true;
  }
//+------------------------------------------------------------------+


Testen der Seitwärtsstrategie

Ähnlich wie beim Testen der Trendfolgestrategie sollten wir zunächst einen Teil der Historie für das Training und die Optimierung der gewählten Seitwärtsstrategie auswählen. Die folgende Abbildung zeigt das Testintervall:

Abb. 9. Ausgewähltes Testintervall für die Seitwärtsstrategie

Die allgemeinen Testbedingungen sehen wie folgt aus:

  • Intervall: 13.03.2015 — 01.01.2017.
  • Symbol: EURUSD.
  • Handelsmodus: Keine Verzögerung. Dies sind keine hochfrequenten Handelsstrategien, so dass der Effekt von Verzögerungen sehr gering wäre.
  • Test: М1 OHLC. Vor-Tests mit realen Ticks zeigen fast die gleichen Ergebnisse. 
  • Erste Einzahlung: 1000 USD.
  • Test: М1 OHLC. Vor-Tests mit realen Ticks zeigt fast die gleichen Ergebnisse.
  • Server: MetaQuotes-Demo.
  • Kurse: 5 Dezimalstellen.

Take-Profit und Stop-Loss werden für Tests und Optimierungen verwendet. Separate Optimierungsergebnisse im Kaufmodus werden in der folgenden Tabelle angezeigt.


Abb. 10. Optimierungsergebnisse der Seitwärtsstrategie im Kaufmodus

Separate Optimierungsergebnisse im Verkaufsmodus sind wie folgt:


Abb. 11. Die Ergebnisse der Seitwärtsstrategie im Verkaufsmodus

Nachdem die besten Parameter für beide Modi durch separate Optimierung definiert wurden, ist es an der Zeit, die Strategie in einem ungünstigen Intervall zu überprüfen und herauszufinden, wie sie sich unter neuen Bedingungen verhält. Als Experiment wählen wir ein Zeitintervall nicht in einer Seitwärtsbewegung, das bereits gewählt wurde, um die Trendfolge-Strategie (die in Abb. 6 dargestellte) zu testen. Wir haben es für einen gemischten Test der Trendfolgestrategie im Modus Both (Auf- und Abwärtstrend) verwendet.

Das Ergebnis sieht wie folgt aus:


Abb. 12. Die Testergebnisse der optimierten Seitwärtsstrategie auf dem ungünstigen Intervall

Die Seitwärtsstrategie in einem Testzeitraum mit einem Trend erzielte gute Ergebnisse und zeigt Gewinne. 


Kombinieren beider Strategien

Wir haben die Trendfolge- und Seitwärtsstrategien als Beispiel für eine separate Optimierung besprochen. Beide Strategien wurden in zwei Komponenten aufgeteilt und in günstigen Märkten optimiert. Darüber hinaus wurde ihre Lebensfähigkeit im unbekannten Marktintervall getestet mit vielversprechenden Ergebnissen. Schauen wir uns nun die Strategie an, die die beiden oben beschriebenen Strategien in einem größeren Zeitintervall kombiniert. Aber zuerst sollten wir beide Strategien zu einer einzigen kombinieren. 

Unmittelbar nach der Implementierung der Strategie im Code des EAs wurden die optimierten Parameter der beiden Modi der Trendfolge und der beiden Modi der Seitwärtsstrategie festgelegt:

//+------------------------------------------------------------------+
//| EA Eingabeparameter                                              |
//+------------------------------------------------------------------+
input string               Inp_EaComment="Universe Strategy";           //EA Kommentar
input double               Inp_Lot=0.01;                                //Lot
input MarginMode           Inp_MMode=LOT;                               //MM

//--- Aufwärtstrend Parameter
input string               Inp_Str_label1="===Uptrend parameters===";   //Bezeichnung
input int                  Inp_MagicNum1=1111;                          //Magicnummer
input int                  Inp_StopLoss1=50;                            //Stop-Loss(points)
input int                  Inp_TakeProfit1=55;                          //Take-Profit(points)

//--- CenterOfGravityOSMA Indikatorparameter
input uint                 Period_1=9;                                  //Glättungslänge
input uint                 SmoothPeriod1_1=3;                           //Glättungslänge 1
input ENUM_MA_METHOD       MA_Method_1_1=MODE_SMA;                      //Glättungsverfahren 1
input uint                 SmoothPeriod2_1=3;                           //Glättungslänge 2
input ENUM_MA_METHOD       MA_Method_2_1=MODE_SMA;                      //Glättungsverfahren 2
input Applied_price_       AppliedPrice1=PRICE_TRENDFOLLOW1_;           //Berechnungspreis

//--- Average Speed Indikatorparameter
input int                  Inp_Bars1=1;                                 //Tage
input ENUM_APPLIED_PRICE   Price1=PRICE_LOW;                            //Berechnungspreis
input double               Trend_lev1=1.6;                              //Trend Level

//--- Abwärtstrend Parameter
input string               Inp_Str_label2="===Downtrend parameters==="; //Bezeichnung
input int                  Inp_MagicNum2=2222;                          //Magicnummer
input int                  Inp_StopLoss2=40;                            //Stop-Loss(points)
input int                  Inp_TakeProfit2=70;                          //Take-Profit(points)

//--- CenterOfGravityOSMA Indikatorparameter
input uint                 Period_2=15;                                 //Glättungslänge
input uint                 SmoothPeriod1_2=3;                           //Glättungslänge 1
input ENUM_MA_METHOD       MA_Method_1_2=MODE_SMA;                      //Glättungsverfahren 1
input uint                 SmoothPeriod2_2=3;                           //Glättungslänge 2
input ENUM_MA_METHOD       MA_Method_2_2=MODE_SMA;                      //Glättungsverfahren 2
input Applied_price_       AppliedPrice2=PRICE_HIGH_;                   //Berechnungspreis

//--- Average Speed Indikatorparameter
input int                  Inp_Bars2=1;                                 //Tage
input ENUM_APPLIED_PRICE   Price2=PRICE_WEIGHTED;                       //Berechnungspreis
input double               Trend_lev2=1.0;                              //Trend Level


//--- Kauf-Parameter
input string               Inp_Str_label3="===Buy parameters===";       //Bezeichnung
input int                  Inp_MagicNum3=3333;                          //Magicnummer
input int                  Inp_StopLoss3=40;                            //Stop-Loss(points)
input int                  Inp_TakeProfit3=60;                          //Take-Profit(points)

//--- Indikatorparameter vom WPR
input int                  Inp_WPRPeriod1=11;                           //Periodenlänge WPR
//--- ADX Indikatorparameter
input int                  Inp_ADXPeriod1=13;                           //Periodenlänge ADX
input int                  Inp_FlatLevel1=25;                           //Seitwärts-Level ADX

//--- Verkaufsparameter
input string               Inp_Str_label4="===Sell parameters===";      //Bezeichnung
input int                  Inp_MagicNum4=4444;                          //Magicnummer
input int                  Inp_StopLoss4=30;                            //Stop-Loss(points)
input int                  Inp_TakeProfit4=30;                          //Take-Profit(points)

//--- Indikatorparameter vom WPR
input int                  Inp_WPRPeriod2=7;                            //Periodenlänge WPR
//--- ADX Indikatorparameter
input int                  Inp_ADXPeriod2=15;                           //Periodenlänge ADX
input int                  Inp_FlatLevel2=40;                           //Seitwärts-Level ADX

Auch die Möglichkeit, die Modi einzustellen, wurde entfernt, da der kombinierte EA nicht trainiert oder optimiert wird. Die Strategie selbst wird wie folgt umgesetzt:

//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Datenabfrage für die Berechnung

   if(!GetIndValue())
      return;

//--- Eröffnungsauftrag im Falle eines Kaufsignals (Trendfolgestrategie)
   if(BuySignal_1() && !Trade.IsOpenedByMagic(Inp_MagicNum1))
      Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss1,Inp_TakeProfit1,Inp_MagicNum1,Inp_EaComment);
//--- Eröffnungsauftrag im Falle eines Verkaufssignals (Trendfolgestrategie)
   if(SellSignal_1() && !Trade.IsOpenedByMagic(Inp_MagicNum2))
      Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss2,Inp_TakeProfit2,Inp_MagicNum2,Inp_EaComment);

//--- Eröffnungsauftrag im Falle eines Kaufsignals (Seitwärtsstrategie)
   if(BuySignal_2() && !Trade.IsOpenedByMagic(Inp_MagicNum3))
      Trade.BuyPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss3,Inp_TakeProfit3,Inp_MagicNum3,Inp_EaComment);
//--- Eröffnungsauftrag im Falle eines Verkaufssignals (Seitwärtsstrategie)
   if(SellSignal_2() && !Trade.IsOpenedByMagic(Inp_MagicNum4))
      Trade.SellPositionOpen(Symbol(),Inp_Lot,Inp_StopLoss4,Inp_TakeProfit4,Inp_MagicNum4,Inp_EaComment);
  }
//+------------------------------------------------------------------+
//| Kaufbedingungen (Trendfolgestrategie)                            |
//+------------------------------------------------------------------+
bool BuySignal_1()
  {
   return(avr_speed1[0]>Trend_lev1 && cog1[1]<cog1[0] &&(cog1[1]<0 && cog1[0]<0))?true:false;
  }
//+------------------------------------------------------------------+
//| Verkaufsbedingungen (Trendfolgestrategie)                        |
//+------------------------------------------------------------------+
bool SellSignal_1()
  {
   return(avr_speed2[0]>Trend_lev2 && cog2[1]>cog2[0] &&(cog2[1]>0 && cog2[0]>0))?true:false;
  }
//+------------------------------------------------------------------+
//| Kaufbedingungen (Seitwärtsstrategie)                             |
//+------------------------------------------------------------------+
bool BuySignal_2()
  {
   return(wpr1[0]<-80 && adx1[0]<Inp_FlatLevel1)?true:false;
  }
//+------------------------------------------------------------------+
//| Verkaufsbedingungen (Seitwärtsstrategie)                         |
//+------------------------------------------------------------------+
bool SellSignal_2()
  {
   return(wpr2[0]>=-20 && adx2[0]<Inp_FlatLevel2)?true:false;
  }
//+------------------------------------------------------------------+
//| Abrufen des aktuellen Indikatorwertes                            |
//+------------------------------------------------------------------+
bool GetIndValue()
  {
   return(CopyBuffer(InpInd_Handle1,0,0,2,cog1)<=0       ||
          CopyBuffer(InpInd_Handle2,0,0,2,cog2)<=0       ||
          CopyBuffer(InpInd_Handle3,0,0,2,avr_speed1)<=0 ||
          CopyBuffer(InpInd_Handle4,0,0,2,avr_speed2)<=0 ||
          CopyBuffer(InpInd_Handle5,0,0,2,wpr1)<=0       ||
          CopyBuffer(InpInd_Handle6,0,0,2,wpr2)<=0       ||
          CopyBuffer(InpInd_Handle7,0,0,2,adx1)<=0       ||
          CopyBuffer(InpInd_Handle8,0,0,2,adx2)<=0
          )?false:true;
  }
//+------------------------------------------------------------------+

Alle vier Modi der beiden Strategien arbeiten unabhängig voneinander, haben nach dem Training einen eigenen Parametersatz festgelegt und beeinflussen sich in keiner Weise. Für einen Test habe ich mich entschieden, einen größeren Zeitraum zu verwenden - die letzten drei Jahre. Die vollständige Liste der Testbedingungen ist wie folgt:

  • Intervall: 01.01.2015 — 30.11.2018.
  • Symbol: EURUSD.
  • Handelsmodus: Keine Verzögerung. Dies sind keine hochfrequenten Handelsstrategien, so dass der Effekt von Verzögerungen sehr gering wäre.
  • Test: М1 OHLC. Vor-Tests mit realen Ticks zeigen fast die gleichen Ergebnisse. 
  • Erste Einzahlung: 1000 USD.
  • Test: М1 OHLC. Vor-Tests mit realen Ticks zeigt fast die gleichen Ergebnisse.
  • Server: MetaQuotes-Demo.
  • Kurse: 5 Dezimalstellen.

Und das sind die Testergebnisse:


Abb. 13. Testergebnisse der kombinierten Strategie

Es wurde keine erneute Optimierung der Parameter durchgeführt. Die Parameter wurden "wie besehen" aus den bei der separaten Optimierung definierten optimalen Werten in den günstigen Intervallen übernommen. Wenn man bedenkt, dass die vier unabhängigen Strategien unter gemeinsamen ungünstigen Bedingungen arbeiteten, ist das Ergebnis positiv.


Zusammenfassung

Nach dem Vergleich der Testergebnisse der beiden Strategien unter Auf-, Abwärts- und ohne Trend können wir die folgenden Schlussfolgerungen ziehen:

  • Für die getesteten Strategien zeigt die separate Optimierungsmethode eine positive Dynamik.
  • Nach den gewonnenen Ergebnissen erwies sich die Methode der separaten Optimierung (bzw. des separaten Trainings) in den günstigen Marktintervallen als recht effizient.
  • Selbst das Testen in strategieungünstigen Zeitintervallen (Testen der trainierten Seitwärtsstrategie in trendigen Intervalle) zeigt eine positive Dynamik.
  • Der Test der kombinierten Strategie, bestehend aus den beiden trainierten Strategien, dient als doppelte Überprüfung der Lebensfähigkeit beider Systeme. Beide Strategien arbeiteten über ein großes Zeitintervall ohne Korrekturen, ohne Optimierungen und ohne Anpassung. Außerdem wurden sie nicht von Anfang an als Module eines einzigen Handelssystems ausgewählt.

In Anbetracht der Tatsache, dass ich zufällige Handelssysteme für die Prüfung und Verbesserung durch separate Optimierung ausgewählt habe und die Endkontrolle auf den ungünstigsten Zeitraum in der Historie durchgeführt wurde, ist das Ergebnis dieser Studie positiv. Die Ergebnisse zeigen, dass die Methode der separaten Optimierung sehr effizient ist und es verdient, bei der Entwicklung und Konfiguration von Handelssystemen eingesetzt zu werden.


Schlussfolgerung

Das angehängte Archiv enthält alle besprochenen Dateien, die sich in den entsprechenden Ordnern befinden. Für einen korrekten Betrieb sollten Sie den Ordner MQL5 im Stammverzeichnis des Terminals speichern.

Die Programme dieses Artikels:

#
 Name
Typ
Beschreibung
1
TrendStrategy.mq5 EA
 EA auf Basis der Trendfolgestrategie.
2
FlatStrategy.mq5 EA  EA auf Basis der Seitwärtsstrategie.
3 UniverseStrategy.mql5  EA   EA auf Basis der Kombination beider Strategien.
4 Trade.mqh Bibliothek  Klasse der Handelsfunktionen.
5
average_speed.mq5 Indikator  Der Indikator Average price speed wird von der Trendfolgestrategie verwendet.
6 centerofgravityosma.mq5 Indikator  Ehlers Indikator Center of Gravity wird von der Trendfolgestrategie verwendet.



Übersetzt aus dem Russischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/ru/articles/5427

Beigefügte Dateien |
Hilfen zur Auswahl und Navigation in MQL5 und MQL4: Tabs für "Hausaufgaben" und das Sichern grafischer Objekte Hilfen zur Auswahl und Navigation in MQL5 und MQL4: Tabs für "Hausaufgaben" und das Sichern grafischer Objekte

In diesem Artikel werden wir die Fähigkeiten des zuvor erstellten Hilfsprogramms erweitern, indem wir Tabs (Registerkarten) zur Auswahl der benötigten Symbole hinzufügen. Wir werden auch lernen, wie man grafische Objekte, die wir erstellt haben, auf dem spezifischen Symboldiagramm speichert, damit wir sie nicht ständig neu erstellen müssen. Außerdem erfahren wir, wie man nur mit Symbolen arbeitet, die zuvor über eine bestimmte Website ausgewählt wurden.

Wie man nutzerdefinierte MOEX-Symbole in MetaTrader 5 erstellt und testet Wie man nutzerdefinierte MOEX-Symbole in MetaTrader 5 erstellt und testet

Der Artikel beschreibt die Erstellung eines nutzerdefinierten Symbols einer Börse mit der Sprache MQL5. Insbesondere wird die Verwendung von Börsenkursen von der beliebten Finam-Website in Betracht gezogen. Eine weitere in diesem Artikel betrachtete Option ist die Möglichkeit, mit einem beliebigen Format von Textdateien zu arbeiten, die bei der Erstellung des nutzerdefinierten Symbols verwendet werden. Dies ermöglicht die Arbeit mit beliebigen Finanzsymbolen und Datenquellen. Nachdem wir ein benutzerdefiniertes Symbol erstellt haben, können wir alle Funktionen des Strategy Tester des MetaTrader 5 nutzen, um Handelsalgorithmen für Börseninstrumente zu testen.

Die praktische Verwendung eines neuronalen Kohonen-Netzes im algorithmischen Handel. Teil I: Werkzeug Die praktische Verwendung eines neuronalen Kohonen-Netzes im algorithmischen Handel. Teil I: Werkzeug

Der vorliegende Artikel entwickelt die Idee, die Kohonen-Netzen in MetaTrader 5 zu Verwenden, was aber auch in einigen früheren Publikationen behandelt wurde. Die verbesserten und erweiterten Klassen bieten Werkzeuge zur Lösung von Anwendungsaufgaben.

Die Analyse der Handelsergebnisse mit den HTML-Berichten Die Analyse der Handelsergebnisse mit den HTML-Berichten

Die MetaTrader 5 Plattform bietet Funktionen zum Speichern von Handelsberichten sowie die Test- und Optimierungsberichte des Expert Advisors. Handels- und Testberichte können in zwei Formaten gespeichert werden: XLSX und HTML, während der Optimierungsbericht in XML gespeichert werden kann. In diesem Artikel beschäftigen wir uns mit dem HTML-Testbericht, dem XML-Optimierungsbericht und dem HTML-Bericht über die Handelshistorie.