Expert Advisors Basierend auf Beliebten Handelssystemen und Alchemie der Handelsroboter Optimierung (Teil V)

Nikolay Kositsin | 29 März, 2016


Einführung

In meinen vorherigen Artikeln aus diesem Zyklus (1, 2, 3, 4), habe ich einfachste Handelssysteme beschrieben, deren markantestes nur auf einen Rahmen arbeitete. Als Ergebnis zeigt ein solches Handelssystem überhaupt keine Reaktion auf die Änderung von Markttrends in einer globaleren Zeitskala. Dies kann bei veränderten Marktbedingungen zu Verlusten führen, weil solche Änderungen von einem System dieser Art nicht erkannt werden. Eigentlich können Im Live-Trading Handelssysteme auf Grundlage von Daten eines Charts von nur einem Zeitrahmen kaum verwendet werden. In der Regel werden mindestens zwei Zeitrahmen für einen normalen Betrieb verwendet. Ein aktueller Trend wird in der Regel auf einem Chart mit einem größeren Zeitrahmen identifiziert, während der Punkt zum Markteintritt in die Richtung dieses Trends auf einem Chart mit kleinerem Zeitrahmen berechnet wird. Meiner Meinung nach, sind die Beispiele einfachster Handelssysteme in den vorherigen Artikeln für einen Leser ausreichend, um das Entwerfen solcher Systeme zu lernen. Besprechen wir also Methoden zum Verbessern solcher Handelssysteme auf Basis der oben beschriebenen Argumentation.



Handelssystem mit Verwendung von zwei Zeitrahmen

Aus der Sicht er Logik, gibt es keinen Unterschied, auf Basis welches Handelsystems aus vorherigen Artikeln wir ein komplizierteres System aufbauen. Wie in ihrem ursprünglichen Wesen, kann jedes möglichst einfache Handelssystem in der folgenden Form dargestellt werden:

Für Long-Positionen:



Für Short-Positionen:


In unserem Handelssystem mit zwei Zeitrahmen, werden diese Bedingungen für den Markteintritt bestimmt auf der Grundlage von Indikatoren auf einem kleineren Zeitrahmen berechnet. Die Richtung des Trends wird auf einem höheren Zeitrahmen bestimmt. Also wir der Algorithmus, der diese Bedingungen beinhaltet, wie folgt aussehen:

Für Long-Positionen:


Für Short-Positionen:


In diesem Fall bestimmt sie Trend-Variable nur die Richtung eines aktuellen Trends auf einem höheren Zeitrahmen und die zusätzliche Bedingung für den Markteinstieg begrenzt Handelsaktionen eines Expert Advisor nur auf die Richtung dieses globalen Trends. Aus der Sicht des Programm-Codes mit welchem Algorithmus der Trend auf einem höheren Zeitrahmen erkannt wird. Also liegt es an einem EA-Autor zu entscheiden, welchen Algorithmus er für beides, die Berechnung des Markt-Einstiegspunkts auf einem kleineren Zeitrahmen und die Erkennung des aktuellen Trends auf einem höheren Zeitrahmen, verwendet. Untersuchen wir den früher beschriebenen Algorithmus mit dem OSMA Indikator, dargestellt durch den EA Exp_5.mq4, zur Bestimmung des aktuellen Trends verwenden wir den gleitenden J2JMA.mq4. In einem solchen Fall ist die Bestimmung der Handelsbedingung sehr einfach:

Also, jetzt fügen dem bestehenden Exp_5.mq4 etwas Code hinzu, der die oben beschriebene Logik enthält. Der fertige Code wird wie folgt aussehen:

//For the EA operation Metatrader\EXPERTS\indicators folder must
//contain indicators 5c_OsMA.mq4 and J2JMA.mq4
//+==================================================================+
//|                                                       Exp_11.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +--------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
//---- input parameters of the custom indicator J2JMA.mq4
extern int    TimeframeX_Up = 240;
extern int    Length1X_Up = 4;  // depth of the first smoothing
extern int    Phase1X_Up = 100; // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Up = 4;  // depth of the second smoothing
extern int    Phase2X_Up = 100; // parameter of the second smoothing, 
       //changing in the range -100 ... +100, influences the quality
       //of the transient process of averaging;  
extern int    IPCX_Up = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- input parameters of the custom indicator 5c_OsMA.mq4
extern int    Timeframe_Up = 60;
extern double IndLevel_Up = 0; // breakout level of the indicator
extern int    FastEMA_Up = 12;  // quick EMA period
extern int    SlowEMA_Up = 26;  // slow EMA period
extern int    SignalSMA_Up = 9;  // signal SMA period
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern int    TRAILINGSTOP_Up = 0; // trailing stop
extern int    PriceLevel_Up =40; // difference between the current price and
                                         // the price of a pending order triggering
extern bool   ClosePos_Up = true; // forced position closing allowed
//----+ +--------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
//---- input parameters of the custom indicator J2JMA.mq4
extern int    TimeframeX_Dn = 240;
extern int    Length1X_Dn = 4;  // smoothing depth 
extern int    Phase1X_Dn = 100;  // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality
       //of the transient process of averaging;  
extern int    Length2X_Dn = 4;  // smoothing depth
extern int    Phase2X_Dn = 100; // parameter of the second smoothing 
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    IPCX_Dn = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- input parameters of the custom indicator 5c_OsMA.mq4
extern int    Timeframe_Dn = 60;
extern double IndLevel_Dn = 0; // breakout level of the indicator
extern int    FastEMA_Dn = 12;  // quick EMA period
extern int    SlowEMA_Dn = 26;  // slow EMA period
extern int    SignalSMA_Dn = 9;  // signal SMA period
extern int    STOPLOSS_Dn = 50;  // stop loss
extern int    TAKEPROFIT_Dn = 100; // take profit
extern int    TRAILINGSTOP_Dn = 0; // trailing stop
extern int    PriceLevel_Dn = 40; // difference between the current price and
                                         // the price of a pending order triggering
extern bool   ClosePos_Dn = true; // forced position closing allowed
//----+ +--------------------------------------------------------------------------+
//---- Integer variables for the minimum of calculation bars
int MinBarX_Up, MinBar_Up, MinBarX_Dn, MinBar_Dn;
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("TimeframeCheck: Parameter ",Name,
                     " cannot ", "be equal to", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up); 
   //---- Checking the correctness of TimeframeX_Up variable value
   TimeframeCheck("TimeframeX_Up", TimeframeX_Up);                                                                        
//---- Checking the correctness of Timeframe_Dn variable value
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);
   //---- Checking the correctness of Timeframe_Dn variable value
   TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn);    
//---- Initialization of variables
   MinBar_Up  = 3 + MathMax(FastEMA_Up, SlowEMA_Up) + SignalSMA_Up;
   MinBarX_Up  = 3 + 30 + 30;
   MinBar_Dn  = 3 + MathMax(FastEMA_Dn, SlowEMA_Dn) + SignalSMA_Dn;
   MinBarX_Dn  = 3 + 30 + 30;                              
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaring local variables
   double J2JMA1, J2JMA2, Osc1, Osc2;
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static double TrendX_Up, TrendX_Dn;
   static datetime StopTime_Up, StopTime_Dn; 
   static int LastBars_Up, LastBarsX_Up, LastBarsX_Dn, LastBars_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS                                        |
   //----+ +---------------------------------------------------------------+
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Length2X_Up,
                                             Phase1X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Length2X_Up,
                                             Phase1X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 2);
           
           //----+ defining trend
           TrendX_Up = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (TrendX_Up < 0)
                      BUY_Stop = true;                                      
          }
          
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           LastBars_Up = IBARS_Up;
           StopTime_Up = iTime(NULL, Timeframe_Up, 0)
                                          + 60 * Timeframe_Up;
           //----+ calculating indicator values
           Osc1 = iCustom(NULL, Timeframe_Up, 
                         "5c_OsMA", FastEMA_Up, SlowEMA_Up,
                                               SignalSMA_Up, 5, 1);
           //---                   
           Osc2 = iCustom(NULL, Timeframe_Up, 
                         "5c_OsMA", FastEMA_Up, SlowEMA_Up,
                                               SignalSMA_Up, 5, 2);
           
           //----+ defining signals for trades
           if (TrendX_Up > 0)                                           
            if (Osc2 < IndLevel_Up)
             if (Osc1 > IndLevel_Up)
                        BUY_Sign = true;                               
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
         if (!OpenBuyLimitOrder1(BUY_Sign, 1, 
              Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up,
                                            PriceLevel_Up, StopTime_Up))
                                                                 return(-1);
         if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
                                        
         if (!Make_TreilingStop(1, TRAILINGSTOP_Up))
                                              return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS                                       |
   //----+ +---------------------------------------------------------------+
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      int IBARSX_Dn = iBars(NULL, TimeframeX_Dn);
      
      if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Dn != IBARSX_Dn)
          {
           //--- Initialization of variables 
           LastBarsX_Dn = IBARSX_Dn;
           SELL_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Dn, 
                                "J2JMA", Length1X_Dn, Length2X_Dn,
                                             Phase1X_Dn, Phase2X_Dn,  
                                                     0, IPCX_Dn, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Dn, 
                                "J2JMA", Length1X_Dn, Length2X_Dn,
                                             Phase1X_Dn, Phase2X_Dn,  
                                                     0, IPCX_Dn, 0, 2);
           
           //----+ defining trend                                 
           TrendX_Dn = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (TrendX_Dn > 0)
                      SELL_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
           LastBars_Dn = IBARS_Dn;
           StopTime_Dn = iTime(NULL, Timeframe_Dn, 0)
                                          + 60 * Timeframe_Dn;
           //----+ calculating indicator values    
           Osc1 = iCustom(NULL, Timeframe_Dn, 
                         "5c_OsMA", FastEMA_Dn, SlowEMA_Dn,
                                               SignalSMA_Dn, 5, 1);
           //---                   
           Osc2 = iCustom(NULL, Timeframe_Dn, 
                         "5c_OsMA", FastEMA_Dn, SlowEMA_Dn,
                                               SignalSMA_Dn, 5, 2);
           
           //----+ defining signals for trades
           if (TrendX_Dn < 0)                                           
            if (Osc2 > IndLevel_Dn)
             if (Osc1 < IndLevel_Dn)
                        SELL_Sign = true;                               
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenSellLimitOrder1(SELL_Sign, 2, 
              Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn,
                                            PriceLevel_Dn, StopTime_Dn))
                                                                 return(-1);
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
                                        
          if (!Make_TreilingStop(2, TRAILINGSTOP_Dn))
                                                  return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

Optisch ist der Code zweimal größer als der ursprüngliche Exp_5mq4 Code, obwohl der Grundgedanke scheinbar nicht so umfassend war! Besprechen wir nun die Ergebnisse. Ich werde wieder nur den EA-Teil für Long-Positionen analysieren, der für Short-Positionen ist analog. Der zusätzliche Quellcode zum Erhalt notwendiger Werte des J2JMA Indikators sieht folgendermaßen aus:

//----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, "J2JMA", Length1X_Up, Phase1X_Up, Length2X_Up, Phase2X_Up, 0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, "J2JMA", Length1X_Up, Phase1X_Up, Length2X_Up, Phase2X_Up, 0, IPCX_Up, 0, 2);
//----+ defining trend
           Trend_Up = J2JMA1 - J2JMA2;

Aus diesem Grund erhält der EA-Header Teil nun die Deklaration von sechs neuen externen Variablen, entsprechend dem J2JMA Indikator-Aufruf:


extern int    TimeframeX_Up = 240;
extern int    Length1X_Up = 4;  // depth of the first smoothing
extern int    Phase1X_Up = 100; // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Up = 4;  // depth of the second smoothing
extern int    Phase2X_Up = 100; // parameter of the second smoothing, 
       //changing in the range -100 ... +100, influences the quality
       //of the transient process of averaging;  
extern int    IPCX_Up = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */

Eine neue analoge Variable MinBarX_Up wird in die Zeile der globalen Variablen für das Minimum der Berechnung von Balken hinzugefügt, die den externen EA Variablen folgt:

//---- Integer variables for the minimum of calculation bars
int MinBarX_Up, MinBar_Up, MinBarX_Dn, MinBar_Dn;

Im EA Initialisierungsblock wird eine zusätzliche Prüfung der Richtigkeit der neuen externen Variable TimeframeХ_Up gemacht:

//---- Checking the correctness of TimeframeX_Up variable value
   TimeframeCheck("TimeframeХ_Up", TimeframeX_Up);

Führen Sie im selben Block die Initialisierung einer Variable MinBarX_Up aus:

MinBarX_Up  = 3 + 30 + 30;

Weitere Modifizierungen des Codes werden in dem Block der start() Funktion des EA durchgeführt. Zwei neue Variablen werden der Zeile zur Deklaration lokaler Variablen hinzugefügt: J2JMA1 and J2JMA2:

//----+ Declaring local variables
   double J2JMA1, J2JMA2, Osc1, Osc2;

Die Trend_Up Variable wird als statische Variable deklariert, weil sie nur einmal bei einem Balkenwechsel initialisiert wird, ihr Wert wird im weiteren Tick der start() Funktion genutzt:

static double TrendX_Up, TrendX_Dn;

Analog wird die Variable LastBarsX_Up als statisch deklariert:

static int LastBars_Up, LastBarsX_Up, LastBarsX_Dn, LastBars_Dn;

Un dem Code für Long-Positionen wird die Überprüfung der ausreichenden Menge für Berechnungen komplizierter:

if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {
         // CODE FOR LONG POSITIONS
       }
     }

und ein neuer Block wir hinzugefügt:

         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Phase1X_Up,
                                            Length2X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Phase1X_Up,
                                            Length2X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 2);
           
           //----+ defining trend                                 
           TrendX_Up = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (Trend_Up < 0)
                      BUY_Stop = true;                                      
          }

In diesem Block wird die notwendige Variable Trend_Up initialisiert, außerdem werden Signale für das erzwungene Schließen von Positionen hier bestimmt (Initialisierung der BUY_Stop Variable). Generell wird wurde im ursprünglichen Exp_5.mq4 die letzte Variable in dem Block "DEFINING SIGNALS FOR MARKET ENTERING" initialisiert, aber es ist logischer diese Initialisierung in dem neuen EA in dem Block "DEFINING TREND" zu platzieren und den Algorithmus dieser Initialisierung zu ändern.

Und das Wichtigste ist, eine kleine Änderung des Signal-definierenden Algorithmus in dem Block "DEFINING SIGNALS FOR MARKET ENTERING":

           //----+ defining signals for trades
           if (TrendX_Up > 0)                                           
            if (Osc2 < IndLevel_Up)
             if (Osc1 > IndLevel_Up)
                        BUY_Sign = true;

Nach allen Änderungen berücksichtigt dieser Algorithmus die Richtung des aktuellen Trends mit Hilfe der Variable Trend_Up.

Jetzt zu einigen Details der EA-Optimierung. Natürlich sollte der EA einzeln, entweder nur für Long- oder Short-Positionen optimiert werden, und auch in diesem Fall gibt es zu viele externe Variablen zur Optimierung. Es ist wahrscheinlich nicht sinnvoll, alle diese Variablen gleichzeitig zu optimieren. Umso mehr, weil - der generische Algorithmus der Optimierung wird nicht mehr als acht Variablen optimieren! Die geeignetste Lösung in diesem Fall ist die Festsetzung einiger Variablen und nur die verbleibenden, nicht festgesetzten, zu optimieren - die wichtigsten Variablen. Und nach der Optimierung wählen Sie die geeignetste Variante und versuchen die verbleibenden Parameter zu optimieren.

Für Long-Positionen kann es, zum Beispiel, wie das folgende aussehen:


Eine Datei mit diesen Einstellungen für den Tester Exp_11.ini befindet sich in dem TESTER.zip Archiv. Hier müssen wir Money_Management_Up nicht optimieren, sowie TimeframeX_Up. Für die TimeframeX_Up Variable muss beachtet werden, dass ihr ursprünglicher Wert größer sein muss als der Wert der Variable Timeframe_Up. Die Werte von Length1X_Up können in einem ziemlich großen Bereich von -100 bis 100 geändert werden. Die Parameter Length2X_Up, Phase2X_Up und IPCX_Up sollten bei der ersten Optimierung besser festgesetzt werden, das gleiche gilt für den in meinem vorherigen Artikel, der den Exp_5.mq4 erklärt, beschriebenen Parameter IndLevel_Up. Für FastEMA_Up und SlowEMA_Up Parametersollten geänderte Werte nicht zu klein sein. Natürlich, sie könnten erstaunliche Ergebnisse zeigen, aber machen diese Ergebnisse irgendeinen Sinn? Die Zuverlässigkeit der Verwendung des Trailing Stop nach der Optimierung ebenfalls überprüft werden. Das erzwungene Schließen von Positionen durch die logische Variable ClosePos_Up sollte immer nach einem Trendwechsel angewandt werden. Ihr Wert sollte besser auf 'true' festgesetzt werden.

Während der Optimierung sollte die Chart-Periode gleich zu dem Wert der Variable Timeframe_Up oder Timeframe_Dn sein(abhängig von der Handelsrichtung während der Optimierung) und in dem abschließenden Test oder dem Betrieb auf einem Konto, sollte die Chart-Periode gleich zu dem kleinsten dieser Werte eingestellt sein. Es gibt ein weiteres wichtiges Detail. Dieser Expert Advisor verwendet mindestens zwei Zeitrahmen, also achten Sie darauf, wenn Sie die Daten der Historie für Optimierungen, Tests und den Betrieb auf einem Konto herunterladen, insbesondere, wenn Sie mehrere bei verschiedenen Brokern geöffnete Konten verwenden.

In dem vierten Artikel beschrieb ich das Exportieren von Optimierungsergebnissen für weitere statistische Analysen in Microsoft Excel. Meiner Meinung nach, ist der in diesem Artikel angebotene EA für ein solches Verfahren am besten geeignet. Falls dies jemand ausprobieren möchte, habe ich den EA-Code unter Berücksichtigung der Empfehlungen dieses Artikels geändert (Exp_11_2.mq4). Der Code ist an den Artikel angehangen.



Ein weiteres Beispiel der Verwendung eine EA zur Berechnung von Daten von Zwei Charts aus Verschiedenen Zeitrahmen

Ich nehme an, ein Beispiel eines EAs zu dieser Idee ist nicht ausreichend für diesen Artikel, also werde ich einen weiteren Expert Advisor einfügen, der nach diesem Prinzip konstruiert ist. Als Grundlage verwende ich meinen ersten EA EA Exp_1.mq4 aus meinem ersten Artikel. Der verantwortliche Teil des Codes zur Bestimmung von Bedingungen für den Markteintritt und das Verwalten von Positionen ist fertig. Jetzt müssen wir den aktiven Markttrend für einen größeren Zeitrahmen bestimmen. In diesem Expert Advisor verwende ich den Indikator MAMA_NK.mq4:

Die Bedingung zur Bestimmung einer Trendrichtung ist in diesem Fall die Differenz zwischen den Werten von zwei Bewegungen auf dem ersten Balken:


Schreiben wir einen durchaus ähnlichen Code, zu dem Exp_11.mq4 als Vorlage verwendet wird:

//+==================================================================+
//|                                                       Exp_12.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +---------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
//----
extern int    TimeframeX_Up = 240;
extern double FastLimitX_Up = 0.5;
extern double SlowLimitX_Up = 0.05;
extern int    IPCX_Up = 9;/* Selecting prices, upon which the indicator will be calculated
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close, 15-Heiken Ashi Open0.) */
//---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
extern int    Timeframe_Up = 60;
extern int    Length_Up = 4;  // smoothing depth
extern int    Phase_Up = 100; // parameter changing in the range
          //-100 ... +100, influences the quality of a transient process;
extern int    IPC_Up = 0;/* Selecting prices, upon which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern bool   ClosePos_Up = true; // forced position closing is allowed
//----+ +---------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES 
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
//----
extern int    TimeframeX_Dn = 60;
extern double FastLimitX_Dn = 0.5;
extern double SlowLimitX_Dn = 0.05;
extern int    IPCX_Dn = 9;/* Selecting prices, upon which the indicator will be calculated 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close, 15-Heiken Ashi Open0.) */
//---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
extern int    Timeframe_Dn = 60;
extern int    Length_Dn = 4;  // smoothing depth
extern int    Phase_Dn = 100; // parameter changing in the range
         // -100 ... +100, influences the quality of a transient process; 
extern int    IPC_Dn = 0;/* Selecting prices, upon which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int   STOPLOSS_Dn = 50;  // stop loss
extern int   TAKEPROFIT_Dn = 100; // take profit
extern bool   ClosePos_Dn = true; // forced position closing is allowed
//----+ +---------------------------------------------------------------------------+
//---- Integer variables for the minimum of counted bars
int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn;
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("Parameter ",Name,
                     " cannot ", "be equal to ", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("TimeframeX_Up", TimeframeX_Up);
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up);
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn);
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);
//---- Initialization of variables
   MinBarX_Up = 1 + 7;
   MinBar_Up = 4 + 39 + 30;
   MinBarX_Dn = 1 + 7;
   MinBar_Dn = 4 + 39 + 30;                                       
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaration of local variables
   int    bar;
   double Mov[3], dMov12, dMov23, Mama1, Fama1;
   //----+ declaration of static variables
   static double TrendX_Up, TrendX_Dn;
   static int LastBars_Up, LastBars_Dn, LastBarsX_Up, LastBarsX_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS                                        |
   //----+ +---------------------------------------------------------------+
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {       
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values
           Fama1 = iCustom(NULL, TimeframeX_Up, 
                    "MAMA_NK", FastLimitX_Up, SlowLimitX_Up, IPCX_Up, 0, 1);
           //---         
           Mama1 = iCustom(NULL, TimeframeX_Up, 
                    "MAMA_NK", FastLimitX_Up, SlowLimitX_Up, IPCX_Up, 1, 1);
           //----+ defining trend
           TrendX_Up = Mama1 - Fama1;
           //----+ defining signals for trade closing
           if (TrendX_Up < 0)
                      BUY_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           LastBars_Up = IBARS_Up; 
           
           //----+ calculating indicator values and uploading them into buffer      
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up, 
                                "JFatl", Length_Up, Phase_Up, 
                                                   0, IPC_Up, 0, bar);
           
           //----+ defining signals for trades
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
            
           if (TrendX_Up > 0)                     
              if (dMov23 < 0)
                if (dMov12 > 0)
                        BUY_Sign = true;                                    
          }
         
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, 
                                          STOPLOSS_Up, TAKEPROFIT_Up))
                                                                 return(-1);
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
        }
     }
     
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS                                       |
   //----+ +---------------------------------------------------------------+
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      int IBARSX_Dn = iBars(NULL, TimeframeX_Dn);
      
      if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Dn != IBARSX_Dn)
          {
           //----+ Initialization of variables
           LastBarsX_Dn = IBARSX_Dn;
           SELL_Stop = false;
           
           //----+ calculating indicator values
           Fama1 = iCustom(NULL, TimeframeX_Dn, 
                    "MAMA_NK", FastLimitX_Dn, SlowLimitX_Dn, IPCX_Dn, 0, 1);
           //---         
           Mama1 = iCustom(NULL, TimeframeX_Dn, 
                    "MAMA_NK", FastLimitX_Dn, SlowLimitX_Dn, IPCX_Dn, 1, 1);
           //----+ defining trend
           TrendX_Dn = Mama1 - Fama1;
           //----+ defining signals for trade closing
           if (TrendX_Dn > 0)
                      SELL_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
                      LastBars_Dn = IBARS_Dn; 
           
           //----+ calculating indicator values and uploading them into buffer     
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn, 
                                "JFatl", Length_Dn, Phase_Dn, 
                                                   0, IPC_Dn, 0, bar);
           
           //----+ defining signals for trades   
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
            
           if (TrendX_Dn < 0)                                 
              if (dMov23 > 0)
                if (dMov12 < 0)
                       SELL_Sign = true;                                         
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenSellOrder1(SELL_Sign, 2, Money_Management_Dn, 
                                            STOPLOSS_Dn, TAKEPROFIT_Dn))
                                                                   return(-1);
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
        }
     }
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

Obwohl der grundlegende Algorithmus dieses EA sich von dem zugrunde liegenden des vorherigen EA unterscheidet, scheint die Idee der Verwendung von zwei Diagrammen in diesem Fall durchaus auch betrieben zu werden.



Fazit

Ich denke, der in diesem Artikel beschriebene Ansatz zur Konstruktion automatischer Handelssysteme den Lesern, die bereits über etwas Erfahrung im Schreiben von EAs verfügen, helfen wird einen analogen Expert Advisor mit minimalem Aufwand zu konstruieren. Es sollte hier auch angefügt werden, dass der praktische Nutzen eines solchen Expert Advisors stark von dessen richtiger Optimierung abhängt.