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

Nikolay Kositsin | 29 März, 2016

Einführung

In meinen vorherigen Artikeln Nr.2 und 3 habe ich die Grundlagen von Backtests beschrieben. Meiner Meinung nach, besteht der Hauptzweck des Backtests in der qualitativen Analyse eines EA-Verhaltens innerhalb eines bestimmten Zeitraums, vorausgesetzt, dass die EA-Parameter von Zeit zu Zeit geändert werden. Die Strategie der Verwendung von Optimierungsergebnissen in diesem Vorgang wird eine strikte Regel der Auswahl der Parameter aller Varianten sein, erhalten als Ergebnis jeder Optimierung. Zum Beispiel, eine Variante mit maximaler Rentabilität und minimalem Drawdown.

Eine solche Variante wird unter allen Varianten einer gesonderten Optimierung ausgewählt, unabhängig davon, was wir in vorherigen Optimierungen hatten. Wenn Sie erkennen, dass eine solche Strategie in einigen Zeiträumen rentabel ist und in einigen Zeiträumen nah am ausgeglichenen Niveau, können Sie daraus schließen, dass Ihr Handelssystem mit einer solchen Strategie der Verwendung optimierter Parameter in Zukunft in einem bestimmten Zeitraum rentabel sein wird.

Dies ist der perfekte Fall. Aber was müssen wir tun, wenn ein EA mit einer scheinbar sehr rationalen Betriebslogik in der Hälfte aller Backtest-Fälle als hoffnungslos verlustbringend erscheint? In der Tat, Strategien, die auf der EA-Parameter Auswahl bei jeder einzelnen Optimierung basieren sind nicht die einzige mögliche Methode. Es ist interessanter statistische Analysen durchzuführen und EA-Parameter aus verschiedenen Optimierungen zu vergleichen.

Darüber hinaus nehmen Optimierungen in Backtests viel Zeit in Anspruch, und es ist nicht sinnvoll diese Optimierungen nur für die Backtests selbst durchzuführen. Zum Beispiel, zusammen mit Optimierungen können wir die Ergebnisse aller rentablen Optimierung-Durchläufe in einer Datei speichern, in Form einer Tabelle, die einfach mit Mitteln statistischer Analyse von Tabellen verarbeitet werden, wie sie in Programmen wie Microsoft Excel verfügbar sind. Das MetaTrader 4 Terminal bietet die Möglichkeit Optimierungsergebnisse in Form einer HTML Tabelle zu speichern:

diese kann einfach in Microsoft Excel geladen werden. Aber für die Verarbeitung werden nur abschließende Berichte jeder Optimierung in Form einer Tabelle dargestellt. Externe Parameter eines Expert Advisor sind in der Tabelle nicht enthalten:

Außerdem ist es das Ergebnis von nur einer Optimierung. Und für die Analyse müssen wir die Ergebnisse aller Optimierungen in einer Datei erfassen. Tatsächlich kann dies alles mit MQL4 Mitteln umgesetzt werden, so dass ich in diesem Artikel meine eigene Variante der Lösung anbieten möchte.



Erfassen der EA-Optimierungsergebnisse in Form einer HTML Tabelle in einer Datei

Zur Umsetzung einer solchen Erfassung in einer Datei, habe ich die folgende Funktion geschrieben:

void Write_Param_htm
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsNemes_Up, string ExtrVarblsVelues_Up, 
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsNemes_Dn, string ExtrVarblsVelues_Dn
)

Diese Funktion ermöglicht es die Ergebnisse aller Optimierungen zu erfassen, die für ein Paar, in einem Zeitrahmen und in einer Handelsrichtung durchgeführt wurden, zu erfassen. Dieser Funktionsaufruf ist im EA De-Initialisierung-Block (innerhalb der deinit() Funktion) platziert:

int deinit()
{
//----+
//---- Recording EA parameters into a text file
if (IsOptimization())
{ 
//---- +------------------------------------------+
//Here is the code of external variables initialization of the Write_Param_htm() function
//---- +------------------------------------------+
//---- RECORDING STRINGS INTO A HTML FILE
Write_Param_htm(Test_Up, Timeframe_Up, ExtVarNemes_Up, ExtVarVelues_Up, Test_Dn, Timeframe_Dn, 
ExtVarNemes_Dn, ExtVarVelues_Dn);
//----+ +-------------------------------------------------------+
}
//---- End of the EA deinitialzation
return(0);
//----+ 
}

Diese Funktion schreibt drei Dateien in C:\Verzeichnis: zwei Dateien mit Optimierungsergebnissen (Long-und Short-Positionen entsprechend) und eine Protokolldatei (MetaTraderTester.log), in die Pfade und Namen dieser zwei Dateien geschrieben werden. Die Namen der Dateien sehen aus wie dies (OptReport_Exp_5_2_GBPUSD_240_Long.htm):

Die Write_Param_htm() ist in der Datei durch das Verzeichnis enthalten:

#include <TestReport.mqh>

die besser vor der Deklaration externer EA Variablen getan werden sollte. Neben dieser Funktion, enthält die TestReport.mqh Datei weitere Funktionen, die im Code mit verwendet werden mit der Funktion Write_Param_htm(), ich werde ihre Bedeutung später erklären. Diese Datei enthält außerdem die bereits bekannte Funktion IsBackTestingTime() mit externen Variablen für Backtests (die Funktion wurde im vorherigen Artikel beschrieben). Der Funktionsaufruf sollte im Block der start() Funktion gemacht werden:

//----+ Execution of backtesting conditions
if (!IsBackTestingTime())
return(0);

Somit ist die einfachste Verwendung der TestReport.mqh Datei absolut analog zur Verwendung von IsBackTestingTime.mqh aus dem vorherigen Artikel, aber in diesem Fall werden während der EA-Kompilierung alle anderen Funktionen nicht verwendet. Als externe Parameter werden in den Write_Param_htm() Funktionen acht Variablen verwendet. Diese Variablen können in zwei Gruppen unterteilt werden: zum Erfassen von Optimierungsergebnissen in einer Datei mit Long-Positionen auf _Up endend und zum Erfassen von Short-Positionen auf _Dn endend.

Analysieren wir eine Gruppe, die zweite ist analog. Der ToResolveWrite_Up Parameter übergibt an die Funktion die Erlaubnis oder das Verbot zum Erfassen in einer Datei. Der Timeframe_Up Parameter übergibt den Zeitrahmen, auf dem der EA Long-Algorithmus arbeitet. Der ExtrVarblsNemes_Up Parameter übergibt einen String, bestehend aus Namen der externen EA-Parameter, an die Funktion. Auf die gleiche Weise wird der Parameter ExtrVarblsVelues_Up verwendet, bestehend aus Werten externer EA-Parameter für Long-Positionen.

Besprechen wir nun die Initialisierung der beiden letzteren zwei Variablen. Nehmen wir an, wir haben die folgenden externen Variablen für Long-Positionen:

n_ExternParam_1, n_ExternParam_2, d_ExternParam_3, n_ExternParam_4, b_ExternParam_5, d_ExternParam_6, 
d_ExternParam_7, n_ExternParam_8

Der Präfix "n_" bezeichnet, dass der Parameter vom Integer-Typ ist, "d_" bedeutet, dass ein Parameter vom double-Typ ist, "b_" - vom bool Typ. Vor der Initialisierung von ExtrVarblsNemes_Up und ExtrVarblsVelues_Up, sollte ein Paar zusätzlicher String Variablen due HTML-Codeteile deklariert und initialisiert werden:

string n_Width = "</td><td><center>";
string d_Width = "</td><td class=mspt><center>";

Danach können wir notwendige Strings zusammensetzen. Für die externe Variable ExtrVarblsNemes_Up wird dieser Code folgendermaßen aussehen:

ExtVarNemes_Up =
StringConcatenate
(
n_Width, "n_ExternParam_1", 
n_Width, "n_ExternParam_2", 
n_Width, "d_ExternParam_3", 
n_Width, "n_ExternParam_4", 
n_Width, "b_ExternParam_5", 
n_Width, "d_ExternParam_6", 
n_Width, "d_ExternParam_7", 
n_Width, "n_ExternParam_8"
);

Die Initialisierung der externen Variable ExtVarVelues_Up ist ein wenig schwieriger:

ExtVarVelues_Up = 
StringConcatenate
(
n_Width, n_ExternParam_1, 
n_Width, n_ExternParam_2, 
d_Width, d_ExternParam_3, 
n_Width, n_ExternParam_4, 
n_Width, b_ExternParam_5, 
d_Width, d_ExternParam_6, 
d_Width, d_ExternParam_7, 
n_Width, n_ExternParam_8
);

In diesem Code vor externen Parametern, wird immer die d_Width Variable platziert, bevor alle anderen n_Width Parameter geschrieben werden. In einer solchen Anordnung des letzten Strings, werden alle Parameter des double Typs mit vier Zeichen hinter dem Komma an die Write_Param_htm() Funktion übergeben. Wenn eine andere Anzahl an Zeichen benötigt wird, verwenden Sie die folgende Funktion:

DoubleToStr( double value, int digits)

Bitte beachten Sie, dass diese Strings nicht mehr als 255 Zeichen enthalten dürfen. Wenn die Länge größer ist, werden überzählige Zeichen verborgen und der Compiler zeigt die entsprechende Benachrichtigung. In solchen Situationen gibt es nur einen Ausweg: in den ExtVarNemes_Up Namen externer Variablen smuss gekürzt werden, in ExtVarVelues_Up muss die Anzahl an Variablen zur Zusammensetzung von Strings beschnitten werden. Allerdings sind 255 Zeichen für die meisten Aufgaben mehr als ausreichend>

Hier ist die Variante zur Umsetzung der Erfassung in einer HTML Datei am Beispiel von Exp_5_2.mq4:

//+==================================================================+
//| expert deinitialization function |
//+==================================================================+ 
int deinit()
{
//----+
//---- Recording EA parameters into a text file
if (IsOptimization())
{
string ExtVarNemes_Up, ExtVarVelues_Up;
string ExtVarNemes_Dn, ExtVarVelues_Dn, n_Width, d_Width;

//---- INITIALIZATION OF STRINGS FOR THE Write_Param_htm FUNCTION
//----+ +-------------------------------------------------------+ 
n_Width = "</td><td><center>";
d_Width = "</td><td class=mspt><center>";
//---- 
ExtVarNemes_Up =
StringConcatenate( 
n_Width, "IndLevel_Up",
n_Width, "FastEMA_Up",
n_Width, "SlowEMA_Up",
n_Width, "SignalSMA_Up",
n_Width, "STOPLOSS_Up",
n_Width, "TAKEPROFIT_Up",
n_Width, "TRAILINGSTOP_Up",
n_Width, "PriceLevel_Up",
n_Width, "ClosePos_Up");

ExtVarVelues_Up = 
StringConcatenate(
d_Width, DoubleToStr(IndLevel_Up, Digits), // 9
n_Width, FastEMA_Up, // 10
n_Width, SlowEMA_Up, // 11
n_Width, SignalSMA_Up, // 12
n_Width, STOPLOSS_Up, // 13
n_Width, TAKEPROFIT_Up, // 14
n_Width, TRAILINGSTOP_Up, // 15
n_Width, PriceLevel_Up, // 16
n_Width, ClosePos_Up); // 17 
//----+ +-------------------------------------------------------+
ExtVarNemes_Dn =
StringConcatenate( 
n_Width, "IndLevel_Dn",
n_Width, "FastEMA_Dn",
n_Width, "SlowEMA_Dn",
n_Width, "SignalSMA_Dn",
n_Width, "STOPLOSS_Dn",
n_Width, "TAKEPROFIT_Dn",
n_Width, "TRAILINGSTOP_Dn",
n_Width, "PriceLevel_Dn",
n_Width, "ClosePos_Dn"); 

ExtVarVelues_Dn = 
StringConcatenate(
d_Width, DoubleToStr(IndLevel_Dn, Digits), // 9
n_Width, FastEMA_Dn, // 10
n_Width, SlowEMA_Dn, // 11
n_Width, SignalSMA_Dn, // 12
n_Width, STOPLOSS_Dn, // 13
n_Width, TAKEPROFIT_Dn, // 14
n_Width, TRAILINGSTOP_Dn, // 15
n_Width, PriceLevel_Dn, // 16
n_Width, ClosePos_Dn); // 17 

//---- RECORDING STRINGS INTO HTML FILE
Write_Param_htm
(Test_Up, Timeframe_Up, ExtVarNemes_Up, ExtVarVelues_Up, 
Test_Dn, Timeframe_Dn, ExtVarNemes_Dn, ExtVarVelues_Dn);
//----+ +-------------------------------------------------------+
}
//---- End of the EA deinitialization
return(0);
//----+ 
}

Hier ist die resultierende HTML Tabelle von Parametern für diesen EA, geöffnet in Microsoft Excel:


Die Tabelle enthält die Ergebnisse aller durchgeführten Optimierungen. Die Tabelle selbst hat die folgende Form (die ersten acht Spalten enthalten die EA Handelsergebnisse:

Beachten Sie, die Parameter Drawdown $ und Drawdown % werden nur für geschlossene Trades berechnet, weshalb sie von den im Strategietester verfügbaren abweichen. Berücksichtigen sie außerdem, dass der 'Profit factor' Parameter nur Sin ergibt, wenn es mindestens einen Verlust-Trade gegeben hat, ohne Verlust-Trade ist er sinnlos. Anfangs enthält die Tabelle keine verlustbringenden Trades, weshalb ich für Situationen ganz ohne Verluste diesen Parameter gleich Null gesetzt habe.

Rechts von den EA-Handelsergebnissen befinden sich die optimierten EA-Parameter:

Somit haben wir in Form einer Tabelle alle notwendige Werte von jedem Optimierungsdurchlauf gelichzeitig. Dies ermöglicht uns den Tester und ein Terminal für einige Zeit zu verlassen um statistische Analysen durchzuführen, auf Grundlage der in einer HTML Datei erhaltenen Informationen, mit in aktuellen Programm-Analysatoren verfügbaren sehr effizienten Mitteln zur Analyse von Tabelleninhalten.

Eine weitere Sache. Die beschriebene HTML Datei, die dies erfasst hat, wird einen unvollständigen HTML Code haben, wegen dem fortlaufenden Hinzufügen von Daten in die Datei. Wenn Sie später keine weiteren Daten in die Datei hinzufügen wollen, müssen die folgenden Zeilen am Ende des HTML Codes geschrieben werden (öffnen Sie sie in einem Text-Editor):

</table>
</body></html>


Einige Erklärungen über TestReport.mqh Inhalte

Diese Datei, die ich verwendet habe um den MQL4 Code für den Export von Daten in eine HTML Datei zu schreiben, enthält viele benutzerdefinierte Funktionen. Diese Funktionen in einer fertigen Form können für jeden EA-Autor nützlich sein, so dass ich diese Funktionen in Einzelheiten betrachten möchte:

Die Datei beginnt mit der Deklaration externer Variablen für Backtests und IsBackTestingTime(), beschrieben in dem vorherigen Artikel. Danach kommt die Deklaration der spezialisierten CountTime() Funktion, aber sie wird kaum von Lesern genutzt werden.

Die Anweisung

#include <Read_Write_File.mqh>

umfasst in der TestReport.mqh Datei die Inhalte der Read_Write_File.mqh Datei: Import von Funktionen zum Erfassen und Lesen von Dateien in jedem Verzeichnis von Modulen des arbeitenden Windows Systems.:

#include <WinUser32.mqh>
#import "kernel32.dll"
int _lopen (string path, int of);
int _lcreat (string path, int attrib);
int _llseek (int handle, int offset, int origin);
int _lread (int handle, int& buffer[], int bytes);
int _lwrite (int handle, string buffer, int bytes);
int _lclose (int handle);
#import

Die Bedeutung der Verwendung dieser Funktion kann aus dem Code von vier benutzerdefinierten, in dieser Datei enthaltenen Funktionen verstanden werden:

int _FileSize
(
string path
)

bool WriteFile 
(
string path, string buffer
) 

bool ReadFile
(
string path, string&amp;amp; StrBuffer[]
)

SpellFile
(
string path, string&amp; SpellBuffer[]
)

Die Funktionen enthalten die Variable path, die einen String mit einem Pfad zu einer Textdatei und ihrem Namen einfügt.

Die _FileSize() Funktion gibt die Dateigröße in Bytes zurück.

Die WriteFile() Funktion erfasst am Dateiende den Inhalt des 'buffer' Strings. Wenn sie jeden String in eine neue Zeile schreiben müssen, fügen sie am Ende jeder Zeile "\n" hinzu:

buffer = buffer + "\n";

Die ReadFile() Funktion ändert die Größe des String Puffer StrBuffer[] und lädt die Dateiinhalte nach Strings, bestehend aus vier Buchstaben in einer Pufferzelle.

Die SpellFile() Funktion ändert die Größe des String Puffer und lädt den Dateiinhalt Buchstabe für Buchstabe.

Nachdem die #include <Read_Write_File.mqh> Anweisung in der TestReport.mqh Datei ist dort eine Gruppe von benutzerdefinierten Funktionen zur Berechnung der sogenannten Optimierungsparameter,

CountProfit(int cmd) 
CountMaxDrawdownPrs(int cmd) 
CountMaxDrawdown(int cmd) 
CountAbsDrawdown(int cmd) 
CountProfitFactor(int cmd) 
CountProfitTrades(int cmd) 
CountTotalTrades(int cmd) 
CountExpectedPayoff(int cmd)

die analog zu denen sind, die in der Registerkarte "Ergebnisse der Optimierung" im Strategietester erscheinen. Diese Funktionen führen Berechnungen nur auf Grundlager der Daten von geschlossenen Trades durch, weshalb die Funktionen CountMaxDrawdownPrs(), CountMaxDrawdown(), CountAbsDrawdown() ihre Werte unterschiedlich zu den im Strategietester erhaltenen zurückgeben. Wenn die 'cmd' Variable den Wert OP_BUY akzeptiert, werden Berechnungen in allen Funktionen nur für Long-Positionen durchgeführt, wen OP_SELL - für geschlossene Short-Positionen. Alle anderen Werte dieser Variable stellen Berechnungen für alle geschlossenen Positionen bereit.

Nach diesen Funktionen werden vier weitere Funktionen in der Datei deklariert - zum Erfassen von Optimierungsergebnissen und und optimierter Parameter in Dateien:

void Write_Param_htm
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsNemes_Up, string ExtrVarblsVelues_Up, 
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsNemes_Dn, string ExtrVarblsVelues_Dn
)

void Write_Param_1htm
(
int Timeframe, string ExtrVarblsNemes, string ExtrVarblsVelues
)

void Write_Param_txt
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsVelues_Up,
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsVelues_Dn
)

void Write_Param_1txt
(
int Timeframe, string ExtrVarblsVelues
)

Wie für Write_Param_htm(), ist oben beschrieben.

Die Write_Param_1htm() Funktion ist vollständig analog zu der vorherigen Funktion, aber sie wurde für Expert Advisors erstellt, in denen externe Parameter nicht in solche für Long- und Short-Positionen unterteilt werden. Die ToResolveWrite Funktion wird hier nicht benötigt und wurde deshalb gelöscht.

Die Write_Param_txt() Funktion ist analog zu Write_Param_htm(), sie zeichnet die gleichen Daten auf, aber ohne HTML Angabe. Die zusätzliche Variable zum Zusammensetzen eines Strings, bestehend aus Optimierungsergebnissen und optimierten Parametern, wird auf die folgende Weise initialisiert:

Width = " ";

Jeder neue String wird in einer Datei in einer neuen Zeile erfasst, am Ende von jedem String in der Textdatei wird ";" geschrieben. Zwischen den Werten externer Variablen eines Strings werden Leerzeichen in der Textdatei geschriebnen.

Die Write_Param_1txt() Funktion ist vollständig analog mit der Write_Param_txt() Funktion, ist aber für Expert Advisors erstellt, in denen externe Parameter nicht in solche für Long- und Short-Positionen unterteilt werden.

Und die letzten zwei Funktonen

void Write_Param_htm_B
(
bool ToResolveWrite_Up, int Timeframe_Up, string ExtrVarblsNemes_Up, string ExtrVarblsVelues_Up, 
bool ToResolveWrite_Dn, int Timeframe_Dn, string ExtrVarblsNemes_Dn, string ExtrVarblsVelues_Dn
)

void Write_Param_1htm_B
(
int Timeframe, string ExtrVarblsNemes, string ExtrVarblsVelues
)

sind vollständig analog zu Write_Param_htm() und Write_Param_1htm(), aber mit ihrer Hilfe erhaltene HTML Dateien kehren die Farben um. Hier ist ein Beispiel:

Wahrscheinlich gibt es Menschen, die es bevorzugen mit solchen Dateien zu arbeiten. Ich persönlich mag diese Art der Informationsdarstellung.

Parabolic Handelssystem


Der arbeitende Indikator dieses Handelssystems ist in allen beliebten Handelsplattformen eingeschlossen, für die Arbeit in Forex- und Aktienmärkten.

Ich werde hier ein System einbringen mit Pending Ordern des BuyLimit und SellLimit Typs.

Hier ist die Variante der Algorithmus-Umsetzung für BuyLimit:


Die Algorithmus-Variante für SellLimit ist analog:

Hier ist die Umsetzung des Programm-Codes für einen Expert Advisor:

//+==================================================================+
//|                                                        Exp_8.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 int    Timeframe_Up = 240;
extern double Money_Management_Up = 0.1;
extern double Step_Up = 0.02; 
extern double Maximum_Up = 0.2;
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
                          // pending order triggering price
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 int    Timeframe_Dn = 240;
extern double Money_Management_Dn = 0.1;
extern double Step_Dn = 0.02; 
extern double Maximum_Dn = 0.2;
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 
                          // pending order triggering price
extern bool   ClosePos_Dn = true; // forced position closing
                                              //is allowed
//----+ +------------------------------------------------------------+
//---- Integer variables for the minimum of calculation bars
int MinBar_Up, 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("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 Timeframe_Dn variable value 
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);  
//---- Initialization of variables             
   MinBar_Up  = 5;
   MinBar_Dn  = 5;                               
//---- 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 SAR1, SAR2, CLOSE1, CLOSE2;
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static datetime StopTime_Up, StopTime_Dn; 
   static int LastBars_Up, LastBars_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS 1
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      
      if (IBARS_Up >= MinBar_Up)
       {
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           BUY_Stop = false;
           LastBars_Up = IBARS_Up;
           StopTime_Up = iTime(NULL, Timeframe_Up, 0)
                                           + 60 * Timeframe_Up;
           
           //----+ CALCULATING INDICATOR VALUES AND UPLOADING THEM TO BUFFERS                                        
           SAR1 = iSAR(NULL, Timeframe_Up, Step_Up, Maximum_Up, 1);         
           SAR2 = iSAR(NULL, Timeframe_Up, Step_Up, Maximum_Up, 2);
           //---
           CLOSE1 = iClose(NULL, Timeframe_Up, 1);
           CLOSE2 = iClose(NULL, Timeframe_Up, 2);
           
           //----+ DEFINING SIGNALS FOR TRADES                                           
           if (SAR2 > CLOSE2)
             if (SAR1 < CLOSE1)
                          BUY_Sign = true;
                          
           if (SAR1 > CLOSE1)
                          BUY_Stop = true;                                           
          }
          //----+ EXECUTION OF TRADES
          if (PriceLevel_Up == 0)
           {           
            if (!OpenBuyOrder1(BUY_Sign, 1, 
                Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up))
                                                                return(-1);
           }
          else
           {           
            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 1
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      
      if (IBARS_Dn >= MinBar_Dn)
       {
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
           SELL_Stop = false;
           LastBars_Dn = IBARS_Dn;
           StopTime_Dn = iTime(NULL, Timeframe_Dn, 0)
                                           + 60 * Timeframe_Dn;
           
           //----+ CALCULATING INDICATOR VALUES AND UPLOADING THEM TO BUFFERS                                        
           SAR1 = iSAR(NULL, Timeframe_Dn, Step_Dn, Maximum_Dn, 1);         
           SAR2 = iSAR(NULL, Timeframe_Dn, Step_Dn, Maximum_Dn, 2);
           //---
           CLOSE1 = iClose(NULL, Timeframe_Dn, 1);
           CLOSE2 = iClose(NULL, Timeframe_Dn, 2);
           
           //----+ DEFINING SIGNALS FOR TRADES                                           
           if (SAR2 < CLOSE2)
             if (SAR1 > CLOSE1)
                          SELL_Sign = true;
                          
           if (SAR1 < CLOSE1)
                          SELL_Stop = true;                                           
          }
          //----+ EXECUTION OF TRADES
          if (PriceLevel_Dn == 0)
           {           
            if (!OpenSellOrder1(SELL_Sign, 2, 
                Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn))
                                                                return(-1);
           }
          else
           {           
            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);
  }
//+------------------------------------------------------------------+

Der Block der Handelsausführung ist komplizierter in diesem EA. Hier werden die Funktionen für den Einstieg in den Markt OpenBuyOrder1() und OpenSellOrder1() und die Funktionen zum Platzieren von Pending Ordern OpenBuyLimitOrder1() und OpenSellLimitOrder1() zusammen verwendet. Dies wird für den Fall gemacht, wenn die externen Variablen PriceLevel_Up und PriceLevel_Dn gleich Null sind. In einer solchen Situation öffnet der EA Trades am Markt, während ein EA nur mit Pending Ordern, diese Ordern in einem minimalen Abstand vom Markt platzieren wird.



Breakout Handelssystem

Für auf Breakout-Ebenen basierte Handelssysteme gilt, es gibt sehr viele von ihnen, und Sie können noch immer ein neues Breakout-System erfinden. In diesem Artikel werde ich ein System beschreiben, in dem Breakout-Ebenen durch die Seiten eines auf der Grundlage von Bewegung gebildeten Kanals bestimmt werden:

Der Breakout wird durch geschlossene Balken bestimmt. Außerdem werde ich ein Breakout-Handelssystem mit einer gewissen Erholung nach einem Breakout verwenden. Hier ist die Variante des Handelssystems mit BuyLimit Ordern:

Das gleiche für SellLimit:

Der EA-Code hat keine Besonderheiten in der Konstruktion, weshalb ich ihn nicht in den Artikel einfüge. Sie finden den Code an den EA angehangen (Exp_9.mq4). Es gibt kein erzwungenes Schließen von Positionen in dem EA. Neue Variablen werden in dem EA Initialisierungsblock initialisiert.

dMovLevel_Up = MovLevel_Up * Point;
dMovLevel_Dn = MovLevel_Dn * Point;

diese Variablen werden verwendet zur Berechnung der Werte von UpMovLeve1 und DownMovLevel1 Ebenen.



Trading auf Pressemeldungen

Sehr häufig geschieht eine Situation am Markt, wenn starke Bewegungen stets zur gleichen Zeit auftreten. Man kann vorher kaum mit Sicherheit sagen, in welche Richtung die Bewegung auftreten wird. Aber man kann vorher feststellen, dass es eine solche Bewegung geben wird. Zum Beispiel können solche starken Bewegungen aus Arbeitsmarktdaten resultieren. Viele Trader möchten solche starken Bewegungen einfangen. Es wäre interessant zu prüfen, ob ein solches Handelssystem sinnvoll ist. Der Grundgedanke des Systems besteht aus der Platzierung von zwei Pending Ordern des BuyStop und des SellStop Typs, und wartet bis eine starke Bewegung eine von ihnen einen Trade öffnet und wird mit Take Profit geschlossen:

Dies ist eine weitere Variante eines Breakout-Systems. Die Umsetzung eines solchen Systems in einem Programm-Code ist nicht sehr schwierig:

//+==================================================================+
//|                                                       Exp_10.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 PLACING PENDING ORDERS
extern int    NewsWeekDay = 5;  // Weekday for news release
// if parameter is less than 1 or more than 5 any working day is used
extern int    NewsHour = 15;  // hour of news release
extern int    NewsMinute = 0;  // minute of news release
extern int    OrderLife = 30;  // Number of minutes of pending order validity
//----+ +------------------------------------------------------------+
//---- ea INPUT PARAMETERS FOR CLOSING POSITIONS
extern int    PosLife = 120;  // Number of minutes of an opened position validity
                                              //from news release time
//----+ +------------------------------------------------------------+
//---- 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    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 pending order triggering
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    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 pending order triggering
extern bool   ClosePos_Dn = true; // forced position closing
                                              //is allowed
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- 
    if (NewsHour > 23) 
             NewsHour = 23;
    if (NewsMinute > 59)
           NewsMinute = 59;                               
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static datetime StopTime, PosStopTime; 
   static bool BUY_Sign, SELL_Sign, BUY_Stop, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   
   //----+ DEFINING SIGNALS FOR TRADES 
   if (DayOfWeek() == NewsWeekDay || NewsWeekDay < 1 || NewsWeekDay > 5)
     if (Hour() == NewsHour)
        if (Minute() == NewsMinute)
    {
     StopTime = TimeCurrent() + OrderLife * 60;
     PosStopTime = TimeCurrent() + PosLife * 60;
     BUY_Sign = true;
     SELL_Sign = true;
    }
    
    
    
   //----+ +---------------------------------------------------------------+ 
   //----++ CODE FOR LONG POSITIONS 1
   if (Test_Up) 
    {
      //----+ EXECUTION OF TRADES          
      if (!OpenBuyStopOrder1(BUY_Sign, 1, 
                Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up,
                                            PriceLevel_Up, StopTime))
                                                                return(-1);
      if (TimeCurrent() >= PosStopTime)                                                                    
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                           return(-1);
                                        
      if (!Make_TreilingStop(1, TRAILINGSTOP_Up))
                                           return(-1);
     }
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS 1
   if (Test_Dn) 
     {
      //----+ EXECUTION OF TRADES
      if (!OpenSellStopOrder1(SELL_Sign, 2, 
                Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn,
                                            PriceLevel_Dn, StopTime))
                                                                return(-1);
      if (TimeCurrent() >= PosStopTime)            
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                           return(-1);
                                        
      if (!Make_TreilingStop(2, TRAILINGSTOP_Dn))
                                           return(-1);
     }
   //----+ +---------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+


Fazit

In diesem Artikel habe ich einen universellen Ansatz zum Exportieren verschiedener Informationen über Optimierungsergebnisse in ein Tabellenformat angeboten, der breite Möglichkeiten für eine tiefe Analyse dieser Informationen öffnet und ernsthafte Verbesserungen von Handelsergebnissen bei der Verwendung von Expert Advisors im automatisierten Handel. Ich hoffe mein Ansatz ist für jeden EA Autor hilfreich.