Automatisierte Optimierung eines Handelsroboters in Realem Handel

Igor Malcev | 1 Februar, 2016

Einführung

Es wird angenommen, dass ein Expert Advisor mit an der Historie ausgerichteten Eingaben, in der ersten (ziemlich kurzen) Zeit, profitabel handeln wird. Indirekte Bestätigungen dieser Empfehlung kamen auf, nachdem ich die Automatisiertes Trading Meisterschaft 2006 angesehen habe. Als die Meisterschaft startete, gab es viel mehr profitable Expert Advisors als später, als einige von ihnen nicht mehr wettbewerbsfähig waren. Deshalb nehme ich an, dass die meisten dieser Expert Advisor, die das Ziel nicht erreichten, nach der Historie ausgerichtet waren.

Die Idee, diese Annahme in der Praxis zu überprüfen, wurde in dem russischen Forum auf dieser Webseite geboren, in dem Bereich Ideal Automatisiertes Handelssystem. Die Grundidee ist es, die Optimierung eines EA automatisch einmal am Tag zu starten, und dann die erhaltenen Optimierungsergebnisse zu analysieren und sie in den Variablen des EA zu notieren.

Um diese Idee umzusetzen, beschlossen wir den fertigen Expert Advisor MACD Sample, aus dem MetaTrader 4 Terminal, zu nehmen, und unsere eigene Funktion der automatisierten Optimierung in ihn einzufügen. Ein wenig später war der Code dieses automatisierten Optimierers fertig, und in dem selben Forum in dem Bereich Automatisierte Optimierer hochgeladen. Nach etwas mehr Zeit, erschienen die ersten Bestätigungen der Idee, in dem Bereich Automatisierte Optimierer. Später wurde der Optimierer in eine mqh-Bibliothek umgewandelt, für eine bessere Bedienbarkeit.


Installation des Automatisierten Optimierer

Unten sehen Sie was Sie tun müssen, um diese Aufgabe auszuführen:

Für eine bessere Benutzerfreundlichkeit, werden wir im Folgenden das ursprüngliche Terminal in "Terminal" umbenennen, während die Kopie "Terminal-Tester" genannt wird. Wir werden einen überprüfenden Test auf EURUSD auf dem Zeitrahmen H1 ausführen, unter Verwendung des anfänglich durch das Terminal bereitgestellten Expert Advisor, aber mit leichten Veränderungen - MACD_Sample_1.mp4.


Terminal-Tester Einrichtung

Bitte vergessen Sie nicht MACD_Sample_1.mp4 im Terminal-Tester zu kompilieren. Wir starten zuerst das Client Terminal, dann den Strategie-Tester, und richten ihn ein, so wie in dem Screenshot unten gezeigt.

Die Optimierung wird für drei Tage durchgeführt. Dies ist ausreichend, um den automatisierten Optimierer zu überprüfen. Wir werden das Optimierungsdatum "Von" wählen, entsprechend der folgenden Formel - das aktuelle Datum minus drei Tage. Während der Optimierung muss die benötigte Historie des gewählten Symbols (in unserem Fall ist es EURUSD) heruntergeladen werden.

Diejenigen, die Optimierung zum ersten Mal ausführen, finden die Beschreibung erforderlicher Verfahren im Hilfe-Menü des MetaTrader 4 Client Terminals: <Help - Help Hilfe F1 - Auto Trading - Expert Optimization - Setup>. Oder Sie lesen den Artikel mit dem Namen Testen von Expert Advisors in dem MetaTrader 4 Client Terminal: Ein Blick nach Außen.

Dann lassen Sie uns die Variablen prüfen, die wie unten im Screenshot gezeigt optimiert werden.

Automatisierte Optimierung ist auf vier Variablen beschränkt, aber es wird ausreichen nur drei für unsere Zwecke zu haben, und um Zeit zu sparen. Nachdem die Variablen ausgewählt wurden, speichern wir die Optimierungs-Einstellungen die die set-Datei, mit dem Namen MACD Sample_1.set. Diese Datei muss in dem 'Tester' Ordner des Terminal-Tester gespeichert werden. Dann starten Sie die Vor-Optimierung und merken sich die Startzeit. Dies ist notwendig um die benötigte Zeitperiode für automatisierte Optimierung mit voreingestellten Parametern zu berechnen. Nachdem die Optimierung abgeschlossen ist, werden wir die notwendige Wartezeit berechnen. Dann müssen wir das Terminal schließen, weil wir sonst nich in der Lages sind, es programmgesteuert zu starten.


Einrichtung des im Terminal platzierten Expert Advisor

Hierzu öffnen wir den Test Expert Advisor MACD_Sample_1.mq4 im MetaEditor und führen das folgende durch:

- Einstellen der Startzeit für Auto Optimierung, z.B. 00:01 täglich:

datetime SetHour    = 0;  // Optimization starting hour; 
        datetime SetMinute  = 1;  // Optimization starting minute.

- Einstellen der Menge an Tagen für die Optimierung (es muss die gleiche sein wie bei der Vor-Optimierung):

int TestDay = 3;

- Einstellen der Optimierung Abschluss-Wartezeit, in Minuten, die wir vorher berechnet haben, zum Beispiel 4 Minuten:

int TimeOut = 4;

- Eingeben des Expert Advisor Namen:

string NameMTS = "MACD Sample_1";  // EA's name

- Eingeben des Namen der set-Datei mit den Eistellungen:

// Set-file name with the settings
        string NameFileSet = "MACD Sample_1.set";

- Eingeben des Pfads zu dem Ordner mit dem installierten Terminal-Tester, zum Beispiel:

// Path to the tester        
        string PuthTester = "D:\Program Files\Forex Best Trade Station";

- Einstellen der Priorität beim Filtern:

// Sorting by Maximal profit
        int Gross_Profit = 1;                      
        // Sorting by Maximal profit factor        
        int Profit_Factor = 2;     
        // Sorting by Maximal expected payoff
        int Expected_Payoff = 3;

- Schreiben der Namen der Variablen für Optimierung:

string Per1 = "FastEMA";
        string Per2 = "SlowEMA";
        string Per3 = "SignalSMA";
        string Per4 = "";

- kopieren Sie die angehängte Datei auto_optimization.mqh in den 'Include' Ordner,

- fügen Sie die Bibliothek in den Expert Advisor ein:

//--- Including the auto optimizer's library
#include <auto_optimization.mqh>

- es bleibt nur noch den Code unten an den Anfang der start() Funktion Ihres Expert Advisor zu kopieren. MACD_Sample_1.mq4 enthält ihn bereits.

// Not to be launched at testing and optimizing   
  if(!IsTesting() && !IsOptimization())
    {                
      // Compare the current hour with that preset for launching
      if(TimeHour(TimeLocal()) == SetHour)
        {
          // Protection against restarting
          if(!StartTest)
            {
              // Compare the minute range to the minute
              // preset for launching
              if(TimeMinute(TimeLocal()) > SetMinute - 1)
                {     
                  // the range is necessary, in case that for some reasons 
                  // no new tick is available for a long time
                  if(TimeMinute(TimeLocal()) < SetMinute + 1)
                    {  
                      // Flag of tester launching
                      StartTest    = true;
                      TimeStart    = TimeLocal();
                      Tester(TestDay, NameMTS, NameFileSet, PuthTester, 
                             TimeOut, Gross_Profit, Profit_Factor, 
                             Expected_Payoff, Per1, Per2, Per3, Per4);
                    
                    }
                }
            }
        }
    }
    
                        
   FastEMA      = GlobalVariableGet(Per1);
   SlowEMA      = GlobalVariableGet(Per2);
   SignalSMA    = GlobalVariableGet(Per3);
   TrailingStop = GlobalVariableGet(Per4);  
// If the tester launching is flagged  
  if(StartTest)
    {                                        
      // If more time has elapsed the launching than it was set 
      // to be the test waiting time
      if(TimeLocal() - TimeStart > TimeOut*60)
        {            
          // Zeroize the flag
          StartTest = false;                              
        }
    }

Das ist alles. Nachdem der automatisierte Optimierer neu kompiliert wurde, can er gestartet werden, aber er kann nur für das gleiche Symbol und den gleichen Zeitrahmen verwendet werden, für die die Vor-Optimierung ausgeführt wurde. In unserem Fall ist dies EURUSD auf H1. Um den automatisierten Optimierer zu prüfen, können Sie den unten angegebenen Code eingeben, in die int init () Funktion, dann wird der automatisierte Optimierer beim Start des Expert Advisor starten.

Tester(TestDay,NameMTS,NameFileSet,PuthTester,TimeOut, Gross_Profit,Profit_Factor, 
       Expected_Payoff, Per1,Per2,Per3,Per4);


Wie Automatisierte Optimierer Funktionieren

Der automatisierte Optimierer arbeitet auf Grundlage der Verwendung von Terminal-Tester, um Parameter des an das Chart im Terminal angehangenen Expert Advisor zu optimieren. Dazu sendet das Programm eine Datei mit Optimierungsparamatern (optimize.ini) und startet den Terminal-Tester im Optimierungsmodus. Dann kopiert er die erhaltenen Ergebnisse von "FileReport........htm" zurück zum Terminal und foltert die besten Werte der erhaltenen Ergebnisse.


Weitere Details darüber, Wie Automatisierte Optimierer Funktionieren

Zu der vorgegebenen Zeit, zum Beispiel 00:01, soll der automatisierte Optimierer starten. Variablen sollten mit Werten ausgefüllt sein

// Path to the terminal 
string PuthTerminal = TerminalPath() + "\experts\files";
// Name of the ini file for the tester
string FileOptim    = "optimise.ini";
string FileOptim1   = "\optimise.ini";                                  
// Calculation of the starting date
datetime DayStart   = TimeLocal()-86400*TestDay;
// Optimization starting date
string DateStart    = TimeToStr(DayStart,TIME_DATE);
// Optimization ending date
string DateStop     = TimeToStr(TimeLocal(),TIME_DATE);
// Tester report file name
string FileReport   = "FileReport_" + Symbol() + "_" + DateStop + ".htm";
string FileReport1  = "\FileReport_" + Symbol() + "_" + DateStop + ".htm";
// Limitation for the minimum amount of trades per day
double MinTr        = TestDay - 2;
// Limitation for maximal amount of trades per day
double MaxTr        = (60 / Period()*TestDay) + 2;
// The amount of attempts to copy the report file
int    KvoPptk      = 10;
// The amount of lines for sorting
int    StepRes      = 12;

Dann werden die Parameter der ini Datei in das String Array geschrieben:

// Prepare the ini file for optimization
ArrayOpttim[0] = ";optimise strategy tester";             
// Enable/Disable Expert Advisors
ArrayOpttim[1] = "ExpertsEnable = false";
// Name of the EA file
ArrayOpttim[2] = "TestExpert=" + NameMTS;
// Name of the file containing parameters
ArrayOpttim[3] = "TestExpertParameters=" + NameFileSet;
// Symbol
ArrayOpttim[4] = "TestSymbol=" + Symbol();
// Timeframe
ArrayOpttim[5] = "TestPeriod=" + Period();
// Modeling mode
ArrayOpttim[6] = "TestModel=" + 0;
// Recalculate
ArrayOpttim[7] = "TestRecalculate=false";
// Optimization
ArrayOpttim[8] = "TestOptimization=true";
// Use date
ArrayOpttim[9] = "TestDateEnable=true";
// From
ArrayOpttim[10] = "TestFromDate=" + DateStart;
// To
ArrayOpttim[11] = "TestToDate=" + DateStop;
// Report file name
ArrayOpttim[12] = "TestReport=" + FileReport;
// Rewrite the report file
ArrayOpttim[13] = "TestReplaceReport=true";
// Shut down the terminal upon completion
ArrayOpttim[14] = "TestShutdownTerminal=true";

Die Optimierungsparameter werden in der ini Datei des Array aufgezeichnet. Sie können darüber, wie man eine ini-Datei erstell, auch in der MetaTrader 4 Terminal Hilfe lesen, unter <Hilfe - Hilfe F1 - Tools - Configuration at Startup>.

// Write data into the ini file                
// Find out about the array size
OptimArraySize = ArraySize(ArrayOpttim);
// Open a file to write
opttim = FileOpen(FileOptim, FILE_CSV|FILE_WRITE, 0x7F);
if(opttim > 0)
  {
    for(int i = 0; i < OptimArraySize; i++)
      {
        // from the array into the variable
        ini = ArrayOpttim[i];                                     
        // from the variable into the file
        FileWrite(opttim, ini);
      } 
    // close the file
    FileClose(opttim);
  }
else
  {
    Print("Failed writing data into the ini file. Error No ", 
          GetLastError());
    return(0);
  }

Nachdem die Parameter in der ini-Datei aufgezeichnet wurden, wird die in Standard-Windows enthaltene shell32.dll kontaktiert und die Funktion ShellExecuteA startet.

#import  "shell32.dll"               //Connect a dll (provided with Windows)       
  int ShellExecuteA(int hwnd,string Operation,string 
                    File,string Parameters,string Directory,int ShowCmd); 
#import

Datei, welche die Parameter beinhaltet, wird an den Terminal-Tester Ordner gesendet.

// copy the ini file into the tester folder 
copyini = ShellExecuteA(0,"Open","xcopy", "\"" + PuthTerminal + 
                        FileOptim1 + "\" \"" + PuthTester + "\" /y", 
                        "", 3);
// wait until the file is copied
Sleep(1200);                                                    
if(copyini < 0)
  {
    Print("Failed copying ini file");
    return(0);
  }

Dann ist der Tester gestartet und beginnt festgelegte Variablen zu optimieren. Der Expert Advisor befindet sich während der Optimierung im angehaltenen Status

// Start Tester 
start = ShellExecuteA(0, "Open", "terminal.exe", FileOptim,
                      PuthTester, 3);
if(start < 0)
  {
    Print("Failed starting Tester");
    return(0);
  }
Comment("Wait until optimization is complete");
// wait until optimization is complete
Sleep(60000*TimeOut);

Nachdem die Optimierung abgeschlossen ist, wird der Tester die Ergebnisse automatisch in der Report-Datei aufzeichnen. Diese Datei wird in den Ordner kopiert, der das Terminal enthält.

for(Pptk = 0; Pptk < KvoPptk; Pptk++)
  {                    
    //Start a cycle attempting to compy the resport file
    Comment("Attempt # " + Pptk + " to copy the report file");
    ShellExecuteA(0, "Open", "xcopy", "\"" + PuthTester + FileReport1 + 
                  "\" \"" + PuthTerminal + "\" /y", "", 3);
    // wait until the file is copied
    Sleep(1200);
    // Try to open the report file
    file = FileOpen(FileReport, FILE_READ, 0x7F);
    if(file < 0)
      {
        // if it fails to open, wait some more and try again
        Sleep(60000);
      }                    
    else 
        break;             
  }
if(file < 0)
  {
    Print("Failed copying the report file");
    return(0);
  }

Danach werden die Daten der Report-Datei zur weiteren Verarbeitung in das String Array platziert.

// Read from file into the array
// Cycle, until the file ends
while(FileIsEnding(file) == false)
  {                 
    // Read a string from the report file
    FileLine = FileReadString(file);
    // Find the necessary string and set the reference point there
    index = StringFind(FileLine, "title", 20);
    if(index > 0)
      {
        // Increase the array in size
        ArrayResize(ArrayStrg, NumStr + 1);
        // Record the strings from the file in the array
        ArrayStrg[NumStr] = FileLine;
        NumStr++;
      }
  }
// Close the file
FileClose(file);
// Delete the file in order not to produce too many copies
FileDelete(FileReport);
// Set the array size by the amount of data read from the file
ArrayResize(ArrayData, NumStr);    

Dann werden die notwendigen Werte in dem Array ausgewählt:

for(text = 0; text < NumStr; text++)
     {
      select = ArrayStrg[text]; 
    //-------------------------------------------------------------------------
    //   Reporting text processing (These are apples and oranges)              | 
    //-------------------------------------------------------------------------
    // Position Pass 
    ClStep=StringFind(select, "; \">",20)+4;
    // Find the end of position
    ClStepRazm = StringFind(select, "td>", ClStep);
    // Read the value
    CycleStep = StringSubstr(select, ClStep, ClStepRazm - ClStep);
    // Position Profit 
    // Find the beginning of the position
    GrProf = StringFind(select, "", ClStepRazm);
    // Find the end of position
    GrProfRazm = StringFind(select, "td>", GrProf);
    // Read value
    GrossProfit = StringSubstr(select, GrProf+4, GrProfRazm - (GrProf + 4));
    // Position Total Trades
    // Find the beginning of position
    TotTrad = StringFind(select, "", GrProfRazm);
    // Find the end of position
    TotTradRazm = StringFind(select, "td>", TotTrad);
    // Read the value
    TotalTrades = StringSubstr(select, TotTrad+4, TotTradRazm - 
                               (TotTrad + 4));
    // Position Profitability
    // Find the beginning of position
    ProfFact = StringFind(select, "", TotTradRazm);
    // Find the end of position
    ProfFactRazm = StringFind(select, "td>", ProfFact);
    // Read the value
    ProfitFactor = StringSubstr(select, ProfFact + 4, ProfFactRazm - 
                                (ProfFact + 4));
    // Position Expected Payoff 
    // Find the beginning of position
    ExpPay = StringFind(select, "", ProfFactRazm);
    // Find the dn of position
    ExpPayRazm=StringFind(select, "td>", ExpPay);
    // Read the value
    ExpectedPayoff = StringSubstr(select, ExpPay+4, ExpPayRazm - 
                                  (ExpPay + 4));
    // Variables' positions starting with the second one
    // Find the beginning of position
    P1 = StringFind(select, Per1, 20);
    // Find the end of position
    P1k = StringFind(select, ";", P1);
    // Read the Variable
    Perem1 = StringSubstr(select, P1 + StringLen(Per1) + 1, P1k - 
                          (P1 + 1 + StringLen(Per1)));
    // Find the beginning of position
    P2 = StringFind(select, Per2, 20);
    // Find the end of position
    P2k = StringFind(select, ";", P2); 
    // Read the Variable
    Perem2 = StringSubstr(select, P2 + StringLen(Per2) + 1, P2k - 
                          (P2 + 1 + StringLen(Per2)));
    // Find the beginning of position
    P3 = StringFind(select, Per3, 20);
    // Find the end of position
    P3k = StringFind(select, ";", P3);
    // Read the Variable
    Perem3 = StringSubstr(select, P3 + StringLen(Per3) + 1, P3k - 
                          (P3 + 1 + StringLen(Per3)));
    // Find the beginning of position
    P4 = StringFind(select, Per4, 20);
    // Find the end of position
    P4k = StringFind(select, ";", P4);
    // Read the Variable 
    Perem4 = StringSubstr(select, P4 + StringLen(Per4) + 1, P4k - 
                          (P4 + 1 + StringLen(Per4)));
    Comment("The obtained results are being analyzed");

Danach werden die erhaltenen Ergebnisse, bevor sie in das Zahlenformat umgewandelt werden, gefiltert nach der minimalen und der maximalen Menge an Trades. Null in dem Wert von Profit_Factor wird ersetzt durch 1000, für die korrekte Sortierung und anschließende Überprüfung.

// Transform into number format
TotalTradesTransit = StrToDouble(TotalTrades);
GrossProfitTransit = StrToDouble(GrossProfit);
ExpectedPayoffTran = StrToDouble(ExpectedPayoff);
nodubl = true;
if(MinTr < TotalTradesTransit && MaxTr > TotalTradesTransit)
  {                    
    // Filter by the amount of trades
    PrFactDouble = StrToDouble(ProfitFactor);
    // Replace 0 in the Profit_Factor for proper analysis
    if(PrFactDouble == 0)
      {
        PrFactDouble = 1000;
      }

Dann werden die Werte auf Duplikate geprüft und ausgefiltert.

// Filter data having identical values
for(Dubl = 0; Dubl <= ResizeArayNew; Dubl++)
  {                    
    // Start the loop searching for identical values
    if(GrossProfitTransit == ArrayData[Dubl][1])
      {          
        // check whether the results for maximal profit coincide
        if(TotalTradesTransit == ArrayData[Dubl][2])
          {       
            // check whether the results for the amount of trades coincide
            if(PrFactDouble == ArrayData[Dubl][3])
              {          
                // check whether the results for Profit Factor coincide
                if(ExpectedPayoffTran == ArrayData[Dubl][4])
                  { 
                    // check whether the results for expected payoff coincide
                    nodubl=false;                              
                    // If everything coincides, flag it as coincided
                  }
              }
          }
      }
  }

Anschließend werden die Werte für die im Array geschriebene Sortierung vorbereitet.

// Write the filtered data in the array
if(nodubl)
  {
    ArrayData[text][1] = GrossProfitTransit;                                
    ArrayData[text][2] = TotalTradesTransit;
    ArrayData[text][3] = PrFactDouble;
    ArrayData[text][4] = ExpectedPayoffTran;
    ArrayData[text][5] = StrToDouble(Perem1);
    ArrayData[text][6] = StrToDouble(Perem2);
    ArrayData[text][7] = StrToDouble(Perem3);
    ArrayData[text][8] = StrToDouble(Perem4);
    ResizeArayNew++; 
  }

Dann wird begonnen die Daten in der vorgegebenen Prioritätsfolge zu analysieren. Die Analyse wird wie folgt durchgeführt:

// Analyzer
// Analyzing principle is the sequential checking of maximal 
// values according to the predefined filtering priority   
ArrayResize(ArrayTrans, ResizeArayNew - 1);
for(int PrioStep = 1; PrioStep < 4; PrioStep++)
  {
    for(PrCycle = 0; PrCycle < ResizeArayNew; PrCycle++)
      {
        Sort     = ArrayData[PrCycle][0];
        Prior1   = ArrayData[PrCycle][1];             
        transit  = ArrayData[PrCycle][2];
        Prior2   = ArrayData[PrCycle][3];             
        Prior3   = ArrayData[PrCycle][4];             
        transit1 = ArrayData[PrCycle][5];
        transit2 = ArrayData[PrCycle][6];
        transit3 = ArrayData[PrCycle][7];
        transit4 = ArrayData[PrCycle][8]; 
           
        if(PrioStep == 1)
          {
            //Prepare for the 1st sorting
            if(Gross_Profit ==1)
              {
                SortTrans = Prior1;
              }
            if(Profit_Factor == 1)
              {
                SortTrans = Prior2;
              }
            if(Expected_Payoff == 1)
              {
                SortTrans = Prior3;
              }
          }
        if(PrioStep == 2)
          {
            // Restore
            if(Gross_Profit ==1)
              {
                Prior1 = Sort;
              }
            if(Profit_Factor == 1)
              {
                Prior2 = Sort;
              }
            if(Expected_Payoff == 1)
              {
                Prior3 = Sort;
              } 
            //Prepare for the 2nd sorting
            if(Gross_Profit == 2)
              {
                SortTrans = Prior1;
              }
            if(Profit_Factor == 2)
              {
                SortTrans = Prior2;
              }
            if(Expected_Payoff == 2)
              {
                SortTrans = Prior3;
              }
          }
        if(PrioStep == 3)
          {
            // Restore
            if(Gross_Profit == 2)
              {
                Prior1 = Sort;
              }
            if(Profit_Factor == 2)
              {
                Prior2 = Sort;
              }
            if(Expected_Payoff == 2)
              {
                Prior3 = Sort;
              } 
            //Prepare for the 3rd sorting
            if(Gross_Profit ==3)
              {
                SortTrans = Prior1;
              }
            if(Profit_Factor == 3)
              {
                SortTrans = Prior2;
              }
            if(Expected_Payoff == 3)
              {
                SortTrans = Prior3;
              }
          }          
        ArrayTrans[PrCycle][0] = SortTrans;
        ArrayTrans[PrCycle][1] = Prior1;
        ArrayTrans[PrCycle][2] = transit;
        ArrayTrans[PrCycle][3] = Prior2;
        ArrayTrans[PrCycle][4] = Prior3;
        ArrayTrans[PrCycle][5] = transit1;
        ArrayTrans[PrCycle][6] = transit2;
        ArrayTrans[PrCycle][7] = transit3;
        ArrayTrans[PrCycle][8] = transit4;
      }
    ArraySort(ArrayTrans,StepRes, 0, MODE_DESCEND); // Sort the array
    ArrayResize(ArrayTrans, StepRes);               // Cut off the unnecessary things
    for(int CopyAr = 0; CopyAr < StepRes; CopyAr++)
      {
        ArrayData[CopyAr][0] = ArrayTrans[CopyAr][0];
        ArrayData[CopyAr][1] = ArrayTrans[CopyAr][1];
        ArrayData[CopyAr][2] = ArrayTrans[CopyAr][2];
        ArrayData[CopyAr][3] = ArrayTrans[CopyAr][3];
        ArrayData[CopyAr][4] = ArrayTrans[CopyAr][4];             
        // Per1    Variable 1
        ArrayData[CopyAr][5] = ArrayTrans[CopyAr][5];              
        // Per2    Variable 2
        ArrayData[CopyAr][6] = ArrayTrans[CopyAr][6];
        // Per3    Variable 3
        ArrayData[CopyAr][7] = ArrayTrans[CopyAr][7];
        // Per4    Variable 4
        ArrayData[CopyAr][8] = ArrayTrans[CopyAr][8];
      }
   StepRes = StepRes / 2;
  }

Die auf diese Weise gefilterten Werte, werden in globale Variablen geschrieben. Die Werte von globalen Variablen werden im EA ersetzt.

// Write the obtained results in variables
   double Peremen1 = ArrayTrans[0][5];                         
   double Peremen2 = ArrayTrans[0][6];
   double Peremen3 = ArrayTrans[0][7];
   double Peremen4 = ArrayTrans[0][8];
   // If the variable name is specified, write the result in 
   // global variables
   if(Per1 != "")
     {
       GlobalVariableSet(Per1, Peremen1);
     }             
   if(Per2 != "")
     {
       GlobalVariableSet(Per2,Peremen2);
     }
   if(Per3 != "")
     {
       GlobalVariableSet(Per3,Peremen3);
     }
   if(Per4 != "")
     {
       GlobalVariableSet(Per4,Peremen4);
     }
   Comment(Per1, " ", Peremen1, "  | ", Per2, " ", Peremen2, "  | ", Per3, 
           " ", Peremen3, "  | ", Per4, " ", Peremen4);
   Print(Per1, " ", Peremen1, "  | ", Per2, " ", Peremen2, "  | ", Per3, 
         " ", Peremen3,"  | ",Per4," ",Peremen4);
  }  // Function ends. That's all, automated optimization is complete.


Auto Optimierer Betriebsergebnisse

Die Betriebsergebnisse des automatisierten Optimierers können über die Verwendung von Nachrichten beobachtet werden, die in der linken oberen Ecke erscheinen, so wie in dem Screenshot unten gezeigt:

Vollständige Optimierung Referenzzeit.

Analyse der nach der Optimierung Erhaltenen Werte.

Resultierende Werte der Variablen.

Wenn die Optimierungsergebnisse in der Nachricht erscheinen, bedeutet das, dass die Optimierung abgeschlossen ist und die Daten empfangen wurden.

Um den automatisierten Optimierer unabhängig einzuschätzen, kann man durch alle Dateien schauen, die Zwischenergebnisse enthalten und während des Arbeitsvorgangs gespeichert wurden. Der Tester speichert Daten in der Datei mit dem Namen "FileReport_EURUSD_2007.03. 12. htm", wobei das Symbol und das Datum im Dateinamen ersetzt werden, entsprechend dem gewählten Symbol und dem aktuellen Datum der Optimierung. Diese Datei befindet sich im Terminal-Tester Ordner. Diese Dateien mit Berichten werden nicht automatisch gelöscht, wodurch man sie verwenden kann, um die Änderungen der Parameter zu überprüfen.

Die nächste Datei, FileTest1.csv, wird gespeichert, nachdem die Werte nach der Menge der Trades gefiltert und die Kopien gelöscht wurden. Die Datei wird gespeichert unter: D:\Program Files\Terminal_Ordner_Name\Experten/Dateien

Dann werden die nach jeder Untersuchung erhaltenen Werte in in FilerTaes2.csv gespeichert. Die Datei wird auch in dem Ordner D:\Program Files\Terminal_Ordner_Name\Experten/Dateien gespeichert.

Die Tabellen oben zeigen, wie die erhaltenen Werte gefiltert werden. Die Filterreihenfolge wurde so als Standard eingestellt: 1- Gross_Profit, 2- Profit_Factor, 3- Expected_Payoff.

Der Code des Automatisierten Optimierers enthält detaillierte Kommentare und Sie können die am besten geeigneten Parameter anpassen, wenn notwendig. Zum Beispiel, Sie wollen Ihren EA für einen anderen Zeitraum als die letzten Tage optimieren, oder Sie planen die Anzahl der Trades innerhalb der Optimierungsperiode zu erhöhen/verringern. Hierzu müssen Sie nur die entsprechenden Variablen direkt in auto_optimization.mqh ändern.

// Limitation of minimal amount of trades per day
double MinTr   = TestDay - 2; 
// Limitation on maximal amount of trades per day
double MaxTr   = (60 / Period()*TestDay) + 2;
// The amount of attempts to copy the report file
int    KvoPptk = 10;
// The amount of strings to be sorted
int    StepRes = 12;


Fazit

Dieser Artikel ist nicht darauf Ausgerichtet Neulingen die Elemente der Optimierung zu lehren, so dass es sehr zu empfehlen ist, normale Optimierung zu lernen,. bevor Sie automatisierte Optimierung für Ihren Expert Advisor einrichten. Es ist besser den automatisierten Optimierer zu verwenden, nachdem Sie die grundlegenden Variablen ausgewählt haben, die Ihren Expert Advisor zu verschiedenen Zeiten beeinflussen. Das heißt, es ist besser den automatisierten Optimierer zu verwenden, um die Parameter der Variablen anzupassen, die den EA-Betrieb mehr als andere beeinflussen, in Abhängigkeit von der Marktvolatilität.

Außerdem ist es besser, keine sehr lange Optimierungsperiode einzustellen. Angenommen, der Expert Advisor wurde jeden Tag für 6 - 12 Stunden optimiert. Dann taucht die Frage auf: Wann wird er traden? Mit anderen Worten, Optimierung ist kein Selbstzweck. Es wird empfohlen die Optimierungshäufigkeit (die Häufigkeit der Starts des Optimierers ist gemeint) in Anbetracht des Zeitrahmens festzulegen, in dem der EA traden soll. Das bedeutet, dass es nötig ist zu berücksichtigen, dass die historischen Daten gezogen werden, wenn das Tester-Terminal gestartet ist, und es möglich ist, dass der Broker die erforderlichen Daten für den festgelegten Zeitrahmen nicht besitzt. Um die Hypothese zu Beginn dieses Artikels zu verifizieren, benötigen Sie 24 Stunden und eine stabile Internetverbindung.

Die entwickelten Automatisierte Optimierungs Progammer befinden sich in den angehangenen Dateien:: auto_optimization.mqh - die Bibliothek selbst, MACD Sample_1.mq4 - leicht veränderter Expert Advisor, der in der MetaTrader 4 Client Terminal Standardausführung enthalten ist.