English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
preview
Die Grundlagen für Tests in MetaTrader 5

Die Grundlagen für Tests in MetaTrader 5

MetaTrader 5Tester | 15 Januar 2016, 14:07
3 697 0
MetaQuotes
MetaQuotes

Warum braucht man einen Strategie-Tester?

Die Vorstellung des automatischen Handels ist sehr reizvoll, da ein Handels-Roboter ununterbrochen arbeiten kann - 24 Stunden pro Tag und 7 Tage die Woche. Ein Roboter wird niemals müde, unsicher oder verschreckt, da er psychologische Probleme schlicht weg nicht kennt. Ihm genügt es, wenn die Handelsregeln ausreichend formalisiert und in Algorithmen implementiert sind, dann legt der Roboter sofort unermüdlich los. Doch zuvor muss man sicherstellen, dass die folgenden wichtigen Bedingungen erfüllt sind:

  • Der Expert Advisor führt Handelsoperationen gemäß den Ergebnissen des Handelssystem aus.
  • Die in den EA implementierte Handelsstrategie weist einen Gewinn vor dem Hintergrund der History aus.

Um entsprechende Antworten zu bekommen, sehen wir uns den im MetaTrader 5 Client-Terminal enthaltenen Strategie-Tester an.


Modi zur Tick-Erzeugung (Preisänderung im Kurs)

Ein Expert Advisor ist ein in MQL5 geschriebenes Programm, das jedes Mal als Antwort auf ein Ereignis läuft Für jedes vordefinierte Ereignis hat der EA die Funktion, die diesem Ereignis entspricht (Ereignis-Handler).

Das wichtigste Ereignis für den Expert Advisor ist eine NewTick Preisänderung, und daher müssen wir, um den Expert Advisor zu testen, wir Tick-Sequenz erzeugen. Es gibt drei Modi zur Tick-Erzeugung im Strategie-Tester des MetaTrader 5 Client-Terminals:

  • Jeder Tick
  • 1 Minute OHLC (Open High Close Low Preise mit Minuten-Balken)
  • Nur Eröffnungspreise

Der Grund- und detaillierteste ist der "Jeder Tick"-Modus; die zwei anderen Modi sind die Vereinfachungen des Basismodus "Jeder Tick" und werden im Vergleich zum "Jeder Tick"-Modus beschrieben. Betrachten wir nun alle drei Modi, um die Unterschiede zwischen ihnen zu verstehen.


"Jeder Tick"

Die historische Quotendaten für Finanzinstrumente werden aus dem Handelsserver an den MetaTrader 5 Client-Terminal in Form von verpackten Blöcken von 1-Minute Balken übertragen. Für weitere Informationen über die Abfrage und das Bauen der gewünschten Zeitrahmen lesen Sie bitte das Hilfethema Datenzugriff organisieren in der MQL5 Dokumentation.

Das minimale Element der PreisHistory ist der 1-Minuten Balken, von dem Sie Informationen über die vier Werte der Preise bekommen können:

  • Open - Preis, zu dem der 1-Minute Balken eröffnet wurde;
  • High - das Maximum, das während dieses 1-Minute Balkens erreicht wurde;
  • Low - das Minimum, das während dieses 1-Minute Balkens erreicht wurde;
  • Close - Schlusspreis des Balkens.

Ein neuer 1-Minute-Balken öffnet sich nicht beim Start einer neuen Minute (Anzahl der Sekunden ist gleich 0), sondern wenn ein Tick eintritt - eine Preisänderung auf mindestens einem Punkt. Die Abbildung zeigt den ersten 1-Minute-Balken der neuen Handelswoche, die die Öffnungszeit 10. Januar 2011, 00:00 Uhr, hat. Der Preisunterschied zwischen Freitag und Montag, den wir auf dem Chart sehen, ist weit verbreitet, da Wechselkurse auch am Wochenende als Reaktion auf eingehende Nachrichten schwanken.

Abb. 1 Der Preisunterschied zwischen Freitag und Montag

Für diesen Balken wir wissen nur, dass der 1-Minute-Balken auf 10. Januar 2011 um 00 Stunden 00 Minuten geöffnet wurde, aber wir wissen nichts über die Sekunden. Er könnte am 00.00.12 oder 00.00.36 (12 oder 36 Sekunden nach dem Start eines neuen Tages) oder jedem anderen Zeitpunkt innerhalb dieser Minute geöffnet worden sein. Was wir jedoch wissen, ist, dass der Open-Preis von EURUSD bei Eröffnung des neuen 1-Minute-Balkens bei 1,28940 lag.

Ebenso wissen wir nicht die Sekunde, wann der Tick eintrat, der dem entsprechenden Schlusspreis dieses 1-Minute-Balkens entspricht. Wir kennen nur eines: den letzten Close-Preis auf diesem 1-Minute-Balken. Für diese Minute betrug er 1,28958. Die Zeit des Eintritts von High- und Low-Preisen ist ebenfalls unbekannt, aber wir wissen, dass die maximalen und minimalen Preise auf den Ebenen von 1,28958 bzw. 1,28940 lagen.

Um die Handelsstrategie zu testen, brauchen wir eine Abfolge von Ticks, auf der die Arbeit des Expert Advisors simuliert wird. Für jeden 1-Minute-Balken kennen wir also die vier Kontroll punkte, wo der Preis auf jeden Fall war. Wenn der Balken nur 4 Ticks hat, dann sind diese Informationen für einen Test ausreichend. In der Regel ist das Tick-Volumen jedoch mehr als 4.

Daher ist es notwendig, zusätzliche Kontrollpunkte für Ticks zu erzeugen, die zwischen den Open-, High-, Low- und Close-Preisen auftreten. Das Prinzip der Tick-Erzeugung im "Jeder Tick"-Modus wird in dem Artikel The Algorithm of Ticks’ Generation within the Strategie-Tester of the MetaTrader 5 Terminal beschrieben. Eine Abbildung daraus ist unten zu sehen.

Abb. 2 Algorithmus zur Tick-Erzeugung.

Beim Testen im "Jeder Tick"-Modus, wird die Funktion OnTick() des EA an jedem Kontrollpunkt aufgerufen. Jeder Kontrollpunkt ist ein Tick einer generierten Sequenz. . Der Expert Advisor erhält die Zeit und den Preis des simulierten Ticks, genauso wie wenn er Online arbeiten würde.

Wichtig: "Jeder Tick" ist der genaueste Test-Modus, doch zugleich auch der zeitaufwändigste. Für eine erste Auswertung der meisten Handelsstrategien genügt es oft, eine der beiden anderen Test-Modi zu verwenden.


"1 Minute OHLC"

"Jeder Tick" ist der genaueste der drei Modi, zugleich aber auch der langsamste. Der Lauf des OnTick()-Handler erfolgt bei jedem Tick, wenn das Tick-Volumen ziemlich groß sein kann. Für Strategien, bei der die Tick-Sequenz von Kursbewegungen während des Balkens keine Rolle spielt, gibt es einen schnelleren und gröberen Simulationsmodus - "1 Minute OHLC".

Im "1 Minute OHLC"-Modus wird die Tick-Sequenz nur auf Basis von OHLC-Preisen von 1-Minute-Balken gebaut, und die Anzahl der erzeugten Kontrollpunkte deutlich reduziert - damit natürlich auch die Testzeit. Die OnTick()-Funktion wird auf allen Kontrollpunkten gestartet, die auf die Preise OHLC von 1-Minute-Balken gebaut werden.

Die Weigerung, zusätzliche Ticks zwischen den Preisen von Open, High, Low und Close zu erzeugen, führt zu einem starren Determinismus in der Entwicklung des Preises in dem Augenblick, in dem der Open-Preis festgelegt wird. Somit wird es möglich, einen "Test-Gral" zu erstellen, der einen schönen aufsteigenden Graph des getesteten Saldos zeigt.

Ein Beispiel eins solchen Grals ist in der Code-Base verfügbar - Grr-al.

Abb. 3 Der Grr-al Expert ADvisor verwendet die speziellen Merkmale der OHLC-Preise.

Die Abbildung zeigt einen sehr attraktiven Test-Graphen dieses Expert Advisors. Wie wurde dies ereicht? Wir kennen 4 Preise für den 1-Minute-Balken, und wir wissen auch, dass der erste Preis der Open- und der letzte der Close-Preis ist. Zwischen ihnen liegen die High- und Low-Preise deren Abfolge ihres Auftretens nicht bekannt ist. Was jedoch bekannt ist, ist, dass der High-Preis größer oder gleich des Open-Preises ist (und Low kleiner oder gleich des Open-Preises).

Dies genügt, die Zeit des Erhalts des Open-Preises zu ermitteln, und dann den nächsten Tick zu analysieren, um festzustellen, ob davor ein High oder Low kommt. Liegt der Preis unter dem Open-Preis, haben wir einen Low und kaufen auf diesem Tick, und der nächste Tick wird dem High entsprechen, an dem wir schließen den Buy schließen und für Sell öffnen Sell. Der nächste Tick ist der letzte - der Close-Preis auf dem wir den Sell schließen. 

Wenn wir nach dem Preis einen Tick mit einem größeren Preis als den Eröffnungspreis erhalten, ist die Reihenfolge der Abschlüsse umgekehrt. Bearbeiten Sie einen 1-Minute-Balken in diesem "Schummel"-Modus und warten auf den nächsten.

Bei der Prüfung eines solchen Expert Advisors vor der History läuft alles gut, doch sobald wir ihn Online starten, kommt die Wahrheit ans Licht - die Saldo-Linie bleibt weiterhin gerade, verläuft jedoch nach unten. Um diesen Trick zu entlarven, müssen wir einfach den EA im "Jeder Tick"-Modus ausführen.

Hinweis: Wenn die Testergebnisse von EA in den gröberen Test-Modi ("1 Minute OHLC" und "Nur Eröffnungspreise") zu gut erscheinen, sollten Sie ihn auf jeden Fall auch im "Jeder Tick"-Modus testen.


Nur Eröffnungspreise

In diesem Modus werden Ticks auf Basis der OHLC-Preise im für den Test gewählten Zeitraum erzeugt. Die OnTick()-Funktion des Expert Advisors läuft nur am Anfang des Balkens am Eröffnungspreis. Aufgrund dieser Funktion können u.U. Stop-Levels und 'ausstehend' bei einem Preis ausgelöst werden, der vom festgelegten Preis abweicht (vor allem beim Testen bei höheren Zeitrahmen). Allerdings können wir hier schnell einen Bewertungstest des Expert Advisors laufen zu lassen.

Eine Ausnahme bei der Tick-Erzeugung im "Nur Eröffnungspreise"-Modus sind die W1 und MN1 Perioden: für diese Zeitrahmen werden für die OHLC-Preise jeden Tags erzeugt, und nicht OHLC-Preise der Woche oder des Monats.

Angenommen, wir wir einen Expert Advisor auf EURUSD H1 im "Nur Eröffnungspreise"-Modus. In diesem Fall ist die Gesamtzahl von Ticks (Kontrollpunkte) nicht mehr als 4*Anzahl der 1-Stunde-Balken innerhalb des Testintervalls. Aber der OnTick()-Handler wird nur bei der Öffnung des 1-Stunde-Balkens aufgerufen. Die zum exakten Testen notwendigen Prüfungen laufen auf den übrigen Ticks ab (die vor dem Expert Advisor "verborgen" sind).
  • Berechnung der Margin-Anforderungen;
  • Auslösen von Stop Loss- und Take Profit-Levels;
  • Auslösen von ausstehenden Orders;
  • Löschen von abgelaufenen ausstehenden Orders.

Wenn es keine offenen Positions oder ausstehende Orders gibt, brauchen wir diese Prüfungen bei verborgenen Ticks nicht, sodass die Verarbeitungsgeschwindigkeit erheblich schneller ist. Dieser "Nur Eröffnungspreise" Modus eignet sich gut zum Testen von Strategien, die Abschlüsse nur bei der Eröffnung des Balkens machen und keine ausstehenden Orders und auch keine sie StopLoss, TakeProfit Orders verwenden. Für die Klasse solcher Strategien ist die erforderliche Exaktheit der Tests gewährleistet.

Nehmen wir als Beispiel eines EA den Gleitenden Mittelwert Expert Advisor aus dem Standard-Paket, der in jedem Modus getestet werden kann. Die Logik dieses EAs ist so gebaut, dass alle Entscheidungen bei der Eröffnung des Balkens gemacht werden, und Abschlüsse sofort ohne Verwendung von ausstehenden Orders getätigt werden.

Starten wir einen Test des EA auf EURUSD H1 im Intervall von 01. 09. 2010 - bis 31. 12. 2010. und vergleichen die Charts. Die Abbildung zeigt den Saldo-Graph des Testberichts für alle drei Modi.


Abb. 4 Der Test der Moving Average.mq5 EA aus dem Standard-Paket ist unabhängig vom Test-Modus (zum Heranzoomen aufs Bild klicken)

Wie Sie sehen, sind die Graphen bei den verschiedenen Test-Modi die gleichen für den Moving Average EA aus dem Standard-Paket.

Der Modus "Nur Eröffnungspreise" unterliegt jedoch einigen Einschränkungen:

  • Sie können nicht den Ausführungsmodus zufällige Verzögerung verwenden.
  • Im getesteten EA haben Sie keinen Zugriff auf die Daten des Zeitrahmens, der niedriger als der für die Tests/Optimierung eingesetzte Zeitrahmen ist. Wenn der Test/Optimierung z.B. auf Zeitraum H1 durchgeführt wird, können Sie auf die Daten von H2, H3, H4, etc. zugreifen, nicht aber auf die Daten M30, M20, M10, etc. Darüber hinaus müssen die Zeiträume, je älter sie sind, ein Vielfache des Testzeitrahmens sein. So können Sie z.B. beim Test auf M20 nicht auf Daten von M30 zugreifen; die Daten aus H1 sind jedoch verfügbar. Diese Einschränkungen hängen mit der Unfähigkeit zusammen, Daten von jüngeren oder nicht 'vielfachen' Zeitrahmen aus den, während des Test/Optimierung erzeugten Bars, zu erhalten.
  • Einschränkungen beim Zugriff auf Daten anderer Zeitrahmen gelten auch für andere Symbole, deren Daten im Expert Advisor verwendet werden. In diesem Fall hängt die Einschränkung für jedes Symbol vom ersten Zeitrahmen ab, auf den während des Tests/der Optimierung zugegriffen wurde. Angenommen, ein EA greift während des Test bei EURUSD H1 auf Daten von GBPUSD M20 zu, kann der EA weitere Daten EURUSD H1, H2 usw. sowie auch GBPUSD M20, H1, H2 usw. zu verwenden.

Hinweis: Der Modus "Nur Eröffnungspreise" ist der schnellste, eignet sich jedoch nicht für alle Trading-Strategien. Wählen Sie den gewünschten Test-Modus auf Grundlage der Eigenschaften des Handelssystems. 

Machen wir zum Schluss dieses Abschnitts über Modi zu Tick-Erzeugung einen visuellen Vergleich der verschiedenen Arten der Tick-Erzeugung für EURUSD für zwei Balken M15 auf dem Intervall 11. 01. 2011, 21:00:00 bis 11. 01. 2011, 21:30:00

Die Ticks wurden in verschiedene Dateien mit Hilfe von Expert Advisor WriteTicksFromTester.mq5 gespeichert, und das Ende der Dateinamen sind in den Eingabeparametern filenamEveryTick, filenameOHLC und filenameOpenPrice angegeben.

Abb. 5 Wir können das Start- und Enddateum der Ticks (die Variablen Start und Ende) für den WriteTicksFromTester Expert Advisor angeben.

Um drei Dateien mit drei Tick-Sequenzen (für jeden der folgenden Modi "Jeder Tick", "1 Minute OHLC" und "Nur Eröffnungspreise") zu erhalten, wurde der Expert Advisor dreimal in den entsprechenden Modi mit der einzelnen Läufen gestartet. Dann wurden die Daten aus diesen drei Dateien mit Hilfe des Indikators TicksFromTester.mq5 auf dem Chart gezeigt. Der Indikator-Code findet sich im Anhang dieses Beitrags


Abb. 6 Die Tick-Sequenz im Strategie-Tester des MetaTrader 5 Terminals in drei unterschiedlichen Test-Modi.

Standardmäßig werden alle Dateioperationen in der MQL5 Sprache innerhalb der "Datei-Sandbox" ausgeführt. Der EA hat während der Tests nur Zugriff auf seine eigene "Dateisystem-Sandbox". Damit der Indikator und der EA beim Test mit Dateien von einem Ordner arbeiten können, haben wir wir die Flagge flag FILE_COMMON verwendet. Ein Code-Beispiel aus dem EA:

//--- open the file
   file=FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON,";");
//--- check file handle
   if(file==INVALID_HANDLE)
     {
      PrintFormat("Error in opening of file %s for writing. Error code=%d",filename,GetLastError());
      return;
     }
   else
     {
      PrintFormat("The file will be created in %s folder",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
     }

Um die Daten im Indikator lesen zu können, haben wir auch die Flagge FILE_COMMON verwendet. Dadurch könnten wir die manuelle Übertragung der notwendigen Dateien von einem Ordner zum anderen vermeiden.

//--- open the file
   int file=FileOpen(fname,FILE_READ|FILE_CSV|FILE_COMMON,";");
//--- check file handle
   if(file==INVALID_HANDLE)
     {
      PrintFormat("Error in open of file %s for reading. Error code=%d",fname,GetLastError());
      return;
     }
   else
     {
      PrintFormat("File will be opened from %s",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
     }


Simulation von Spread

Spread ist die Differenz zwischen Geld- und Briefkurs. Während Tests wird der Spread nicht als Modell gegeben, sondern historischen Daten entnommen. Ist der Spread in den hist. Daten weniger oder gleich Null, verwendet der Test-Agent den Spread für die Zeit der angeforderten historischen Daten.

Im Strategie-Tester wird der Spread immer als schwimmend betrachtet. Also liefert SymbolInfoInteger(symbol, SYMBOL_SPREAD_FLOAT) stets true.

Darüber hinaus enthalten die historischen Daten die Tick- und Handelsvolumen-Werte. Zum Speichern und Abrufen von Daten verwenden wir eine spezielle MqlRates Struktur:

struct MqlRates
  {
   datetime time;         // opening bar time
   double   open;         // opening price Open
   double   high;         // the highest price High
   double   low;          // the lowest price Low
   double   close;        // the closing price Close
   long     tick_volume;  // the tick volume
   int      spread;       // spread
   long     real_volume;  // market volume 
  };


Globale Variablen des Client-Terminals

Beim Testen werden die globalen Variablen des Client-Terminals auch emuliert, aber nicht mit den aktuellen globalen Variablen des Terminal in Beziehung gesetzt. Dies kann man sich im Terminal mittels der Taste F3 ansehen. Dies bedeutet, dass alle Operationen mit globalen Variablen beim Testen außerhalb des Client-Terminals (im Test-Agent) stattfinden.


Berechnung von Indikatoren während Tests

Im Echtzeit-Modus werden die Indikator-Werte bei jedem Tick berechnet. Der Strategie-Tester benutzt ein kostengünstiges Modell zur Indikatorberechnung - Indikatoren werden neu berechnet erst unmittelbar vor dem Start des EA. D.h., dass die Neuberechnung der Indikatoren vor dem Aufruf von OnTick(), OnTrade() und OnTimer() durchgeführt wird.

Es spielt keine Rolle, ob es einen Aufruf für den Indikator in einem bestimmten Event-Handler gibt oder nicht, es werden alle Indikatoren, deren Identifikatoren durch iCustom() oder IndicatorCreate() erstellt wurden, vor dem Aufruf des Event-Handlers neu berechnet.

Analog erfolgt beim Testen im "Jeder Tick" Modus die Berechnung der Indikatoren vor jedem Aufruf der OnTick() Funktion.

Wenn ein Timer im EA mittels der EventSetTimer() Funktion aktiviert ist, werden Indikatoren vor jedem Aufruf des OnTimer()-Handlers neu berechnet. Daher kann die Testzeit durch Verwendung eines Indikatoren, der in einer nicht optimalen Weise geschrieben ist, erheblich verzögert werden.


Herunterladen von History während der Tests

Die History eines getesteten Symbols wird vor dem Testprozess synchronisiert und vom Terminal aus dem Handelsserver geladen. Anfangs lädt das Terminal die komplette, verfügbare History eines Symbols, um dies nicht später abermals tun zu müssen. Später werden dann nur neue Daten geladen.

Ein Test-Agent erhält die History des getesteten Symbols vom Client-Terminal unmittelbar nach dem Start des Tests. Wenn Daten von anderen Instrumenten im Testprozess verwendet werden (z.B. bei einem Multi-Currency Expert Advisor), verlangt der Test-Agent die nötige History vom Client-Terminal beim ersten Anruf zu solchen Daten. Wenn historische Daten im Terminal verfügbar sind, werden sie sofort an den Test-Agenten übertragen. Sind sie nicht verfügbar, verlangt sie das Terminal, lädt sie vom Server und übergibt sie dann an den Agenten.

Daten von zusätzlichen Instrumenten sind ebenfalls zur Berechnung von Cross-Rates für Handelsoperationen erforderlich. So verlangt der Agent z.B. beim Testen einer Strategie auf EURCHF mit Depot-Währung in USD, vor der Verarbeitung des ersten Handel-Operation historische Daten von EURUSD und USDCHF vom Client-Terminal, obwohl die Strategie keinen direkten Aufruf dieser Symbolen verwendet.

Vor dem Testen einer Multi-Currency-Strategie, empfiehlt es sich, alle notwendigen historischen Daten auf den Cleint-Terminal herunter zu laden. Die hilft, Verzögerungen bei Tests/Optimierungen, die auf den Download der erforderlichen Daten angewiesen sind, zu vermeiden. Sie können z.B. History durch Öffnen des entsprechenden Charts und Scrollen zum Anfang der History herunterladen. Ein Beispiel für erzwungenes Laden der History in den Terminal finden Sie im Abschnitt Ordnung des Datenzugriffs der MQL5-Dokumentation.

Das Terminal lädt die History aus dem Handelsserver nur einmal, wenn der Agent die History für das zu testende Symbol zum ersten Mal vom Terminal anfordert Die History wird in komprimierter Form geladen, um Traffic zu reduzieren.
Test-Agenten erhalten ihrerseits History vom Terminal ebenfalls in der komprimierter Form. Während des nächsten Tests lädt der Tester keine History aus dem Terminal, da die erforderlichen Daten seit dem letzten Lauf des Testers bereits verfügbar sind.


Multi-Currency Tests

Mit dem Strategie-Tester können Sie Strategien, die auf mehreren Symbolen handeln, überprüfen. Diese EAs werden herkömmlicherweise Multi-Currency EAs genannt, da in den vorherigen Plattformen Tests ursprünglich nur für ein Symbol durchgeführt wurden. Im Strategie-Tester des MetaTrader 5 Terminals ist ein Handels-Modell für alle verfügbaren Symbole möglich.

Die History der verwendeten Symbole wird vom Tester aus dem Client-Terminal (nicht aus dem Handelsserver!) automatisch beim ersten Aufruf der Symboldaten geladen.

Der Agent lädt nur die fehlende History. mit einer geringen Marge, um die notwendigen Daten über die History für die Berechnung von Indikatoren zu Beginn des Tests zu haben. Der Mindestzeitraum der geladenen History für Zeitrahmen D1 und weniger, beträgt ein Jahr.

Starten wir daher Tests auf einem Intervall 01. 11. 2010 bis 01. 12. 2010 (als ein Monat als Intervall) mit der Periode von M15 (jeder Bar ist gleich 15 Minuten), fordert der Terminal die History des Instrumentes für das gesamte Jahr 2010 an. Für den 'wöchentlichen' Zeitrahmen wird die History von 100 Bars angefordert, was ungefähr zwei Jahren entspricht (à 52 Wochen pro Jahr). Für Tests im 'monatlichen' Zeitrahmen wird der Agent die History für 8 Jahre (12 Monate x 8 Jahre = 96 Jahre) anfordern.

Sollten nicht genügend Bars vorhanden sein, wird das Startdatum des Tests automatisch von der Vergangenheit zur Gegenwart verschoben, um die notwendige Reserve an Bars zu gewährleisten.

Während des Test wird auch "Markt-Beobachtung" emuliert, in der man die Informationen zu Symbolen erhalten kann.

Standardmäßig gibt es am Anfang des Tests nur ein Symbol in "Marktbeobachtung des Strategie-Testers - das Symbol, auf dem der Test gestartet wurde. Alle notwendigen Symbole werden bei Zugriff automatisch mit "Marktbeobachtung" des Strategie-Testers verknüpft (nicht des Terminals!).  

Vor Beginn des Tests eines Multi-Currency Expert Advisors ist es notwendig, die für das Testen erforderlichen Symbole in "Markt-Beobachtung" des Terminals auszuwählen und die erforderlichen Daten zu laden. Während des ersten Aufrufs eines "fremden" Symbols, wird seine History automatisch zwischen Test-Agenten und Client-Terminal synchronisiert. Das "fremde" Symbol ist ein Symbol, das anders ist als dasjenige, auf dem der Test abläuft.

Verweise auf Daten eines "fremden" Symbols passieren in den folgenden Fällen:

Im Moment des ersten Aufrufs eines "fremden Symbols wird der Testvorgang angehalten und die History für das Symbol/Zeitrahmen vom Terminal auf den Test-Agenten heruntergeladen. Gleichzeitig erfolgt die Erzeugung einer Tick-Sequenz für dieses Symbol.

Für jedes Symbol erfolgt eine individuelle Tick-Sequenz in Übereinstimmung mit dem gewählten Modus zur Tick-Erzeugung. Außerdem können Sie auch die History für die notwendigen Symbolen explizit anfordern, nämlich durch Aufruf der SymbolSelect() im OnInit()Handler - die History wird unmittelbar vor dem Test des Expert Advisors geladen.

Zur Ausführung von Multi-Currency Tests im Client-Terminal MetaTrader 5 müssen daher keine weiteren Anstrengungen unternommen werden. Wir müssen nur die Charts der entsprechenden Symbole im Client-Terminal öffnen. Die History der notwendigen Symbole wird automatisch vom Hadelsserver geladen, sofern er die entsprechenden Daten enthält.


Simulation von Zeit im Strategie-Tester

Beim Testen ist die lokale Zeit TimeLocal() immer gleich der Server-Zeit TimeTradeServer(). Im Gegenzug ist die Server-Zeit immer gleich der Zeit, die der GMT-Zeit entspricht - TimeGMT(). Somit zeigen all diese Funktionen beim Testen die gleiche Zeit.

Es wurde im Strategie-Tester bewusst darauf verzichtet, zwischen GMT, lokaler und Server-Zeit zu unterscheiden, falls die Verbindung zum Server einmal nicht besteht Die Testergebnisse sollten stets identisch sein, unabhängig von der Verbindung. Information über Server-Zeit wird nicht lokal gespeichert, sondern dem Server geholt entnommen.

 

Die OnTimer() Funktion im Strategie-Tester

MQL5 bietet die Möglichkeit Timer-Ereignisse zu bearbeiten. Der OnTimer() Handler wird unabhängig von Test-Modus aufgerufen.

D.h.: wenn ein Test im Modus "Nur Eröffnungspreise" für Zeitraum H4 gestartet wird, und innerhalb des Expert Advisors ein Timer auf einen Aufruf pro Sekunde eingestellt ist, wird der OnTick() Handler auf der Eröffnung jedes H4 Balkens einmal aufgerufen und der OnTimer() Handler 14400 Mal (3600 Sekunden x 4 Stunden) aufgerufen. Die Länge in der die Testzeit des Expert Advisors erhöht wird, hängt von der Logik des Expert Advisors ab.

Um die Abhängigkeit der Testzeit von der vorgegebenen Timer-Frequenz zu prüfen, wurde ein einfacher Expert Advisor ohne Handels-Operationen geschrieben.

//--- input parameters
input int      timer=1;              // timer value, sec
input bool     timer_switch_on=true; // timer on
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- run the timer if  timer_switch_on==true
   if(timer_switch_on)
     {
      EventSetTimer(timer);
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- stop the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
// take no actions, the body of the handler is empty
  }
//+------------------------------------------------------------------+

Die Testzeit wurde bei verschiedenen Werten des Timer-Parameters (Periodizität des Timer-Ereignis) gemessen. Aufgrund der erhaltenen Daten stellen wir die Testzeit als Funtkion des Timer-Zeitraums dar.

Abb. 7 Testzeit als Funktion des Timer-Zeitraums

Man sieht hier deutlich: je geringer der Timer-Parameter bei Initialisierung der EventSetTimer(Timer) Funktion ist, umso kleiner ist der Zeitraum (Period) zwischen den Aufrufen des OnTimer() Handlers, und umso größer ist die Testzeit T unter anderen, gleichen Bedingungen.


Die Sleep()-Funktion im Strategie-Tester

Mit der Sleep() Funktion können Sie im Expert Advisor oder Script die Ausführung des mql5-Programms für eine Zeit lang während der Arbeit am Graph aussetzen. Dies kann nützlich sein, wenn Sie irgendwelche Daten, die zum Zeitpunkt der Anfrage noch nicht verfügbar sind, anfordern und Sie auf ihre Bereitstellung warten müssen. Ein ausführliches Beispiel der Verwendung der Sleep() Funktion finden Sie im Abschnitt Ordnung des Datenzugriffs .

Der Testablauf wird durch Sleep() Aufrufe nicht aufgehalten.Beim Aufruf von Sleep() werden die erzeugten Ticks innerhalb der angegebenen Verzögerung "abgespielt", infolgedessen können ausstehende Aufträge, Stops usw. ausgelöst werden. Nach einem Sleep() Aufruf verlängert sich die im Strategie-Tester simulierte Zeit um das im Parameter der Sleep Funktion angegebene Intervall.

Wenn als Ergebnis der Ausführung der Sleep() Funktion die aktuelle Zeit im Tester über den Test-Zeitraum hinausgeht, erhalten Sie eine Fehlermeldung 'Endlosschleife in Sleep während des Tests entdeckt'. Wenn Sie diese Fehlermeldung erhalten, werden die Testergebnisse nicht abgelehnt. Alle Berechnungen werden in ihrem vollen Umfang (die Anzahl der Abschlüsse, Inanspruchnahme, usw.) durchgeführt und die Ergebnisse dieses Tests werden dem Terminal übertragen.

Die Sleep() Funktion funktioniert nicht in OnDeinit(), da nach ihrem Aufruf die Testzeit das Test-Intervall garantiert überschreiten wird.

Abb. 7 Verwendungsschema der Sleep()-Funktion im Strategie-Tester des MetaTrader 5 Terminals

Abb. 8 Verwendungsschema der Sleep()-Funktion im Strategie-Tester des MetaTrader 5 Terminals


Verwendung des Testers für Optimierungsprobleme in mathematischen Berechnungen

Der Tester im MetaTrader 5-Terminal kann nicht nur für Tests der Handelsstrategien, sondern auch für mathematische Berechnungen verwendet werden. Dafür muss man in den Einstellungen den Modus "Math Berechnungen" wählen:

In diesem Fall werden nur drei Funktionen aufgerufen:: OnInit(), OnTester(), OnDeinit(). Im Modus "Mathematische Berechnungen" erzeugt der Strategie-Tester keine Ticks, und lädt keine History herunter.

Der Strategie-Tester funktioniert im Modus "Mathematische Berechnungen" ebenfalls, wenn ein Startdatum eingegeben wird, das größer als das Enddatum ist.

Wenn Sie den Tester zur Lösung von mathematischen Problemen verwenden, finden weder History-Upload noch Tick-Erzeugung statt.

Ein typisches mathematisches Problem, das im MetaTrader 5 Strategie-Tester gelöst werden muss ist die Suche nach einem Extrem einer Funktion mit vielen Variablen.

Dazu müssen Sie folgendes tun:

  • Die Berechnung des Funktionswerts sollte sich in der OnTester() Funktion befinden;
  • Die Funktionsparameter müssen als Eingabevariablen des Expert Advisors definiert sein;

Erstellen Sie den EA und öffnen das "Strategie-Tester" Fenster. Wählen Sie im "Eingabeparameter"-Tab, die erforderlichen Eingabevariablen und definieren die Reihe von Parameterwerten durch Angabe der Start-, Stop- und Schrittwerte für jede der Funktionsvariablen.

Wählen Sie den Typ der Optimierung - "Langsamer kompletter Algorithmus" (Vollständige Suche des Parameterplatzes) oder "Schneller genetisch-basierter Algorithmus". Für eine einfache Suche des Extrems der Funktion, empfiehlt sich die schnelle Optimierung, wollen Sie jedoch die Werte für die gesamte Variablen-Reihe ausrechnen, verwendet man besser die langsame Optimierung.

Wählen Sie den Modus "Math Berechnungen" und klicken auf "Start", um den Optimierungsvorgang zu starten. Beachten Sie, dass bei Optimierung der Strategie-Tester immer nach den Maximalwerten der Funktion sucht. Um ein lokales Minimum zu finden, lassen Sie sich das Gegenteil des errechneten Funktionswert von der OnTester Funktion liefern:

return(1/function_value);

Dabei muss man selbständig überprüfen, dass der function_value nicht gleich Null ist, sonst erhält man einen schwerwiegenden Fehler aufgrund der Division durch Null.

Es gibt noch eine andere, bequemere Möglichkeit, die die Optimierungs-Ergebnisse nicht verzerrt. Sie wurde von den Lesern dieses Beitrags vorgeschlagen:

return(-function_value);

Hier muss man den function_value nicht auf seine Gleichheit mit Null überprüfen, und die Oberfläche der Optimierungsergebnisse in der 3D-Darstellung hat die gleiche Form, ist eben nur vom Original "gespieglet".

Nehmen wir die Funktion sink() als Beispiel:

Stellen wir den Code des Expert Advisors für die Suche des Extrems dieser Funktion in den OnTester():

//+------------------------------------------------------------------+
//|                                                         Sink.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input double   x=-3.0; // start=-3, step=0.05, stop=3
input double   y=-3.0; // start=-3, step=0.05, stop=3
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double sink=MathSin(x*x+y*y);
//---
   return(sink);
  }
//+------------------------------------------------------------------+
Führen wir eine Optimierung durch und stellen die Optimierungsergebnisse in einem 2D-Graph dar.

Abb. 9 Ergebnisse der kompletten Optimierung der sink (x*x+y*y) Funktion als 2D-Graph

Je besser der Wert für ein angegebenes Parameter-Paar (x, y) ist, desto fetter ist die Farbe. Wie aus der Ansicht der Form der sink() Formel erwartet wurde, bilden ihre Werte konzentrische Kreise mit Mittelpunkt (0,0). Wie man im 3D-Graph erkennen kann, existiert für die sink() Funktion kein absolutes Extrem:

3D-Graph der Sink Funktion


Synchronisierung von Bars im Modus "Nur offene Preise"

Der Tester im MetaTrader 5 Client-Terminal ermöglicht es Ihnen, sog. "Multi-Currency" Expert Advisors zu überprüfen. Ein Multi-Currency Expert Advisor ist ein Expert Advisor, der auf zwei oder mehr Symbole handelt.

Das Testen von Strategien, die auf mehreren Instrumenten handeln, stellt an den Tester einige zusätzliche technische Anforderungen:

  • Erzeugung der Ticks für diese Symbole;
  • Berechnung von Indikatorwerten für diese Symbole;
  • Berechnung von Margenanforderungen für diese Symbole;
  • Synchronisierung der erzeugten Tick-Sequenz für alle Handelssymbole.

Der Strategie-Tester erzeugt und spielt eine Tick-Sequenz für jedes Instrument in Übereinstimmung mit dem ausgewählten Handels-Modus ab. Zugleich wird für jedes Symbol ein neuer Bar geöffnet, unabhängig davon, wie der Bar auf einem anderen Symbol geöffnet wurde. Das heißt, dass beim Testen des Multi-Currency Expert Advisors der Fall auftreten kann (und es passiert tatsächlich oft), dass bereits ein neuer Bar für ein Instrument geöffnet wurde und für das andere eben nicht nicht. Sie sehen: bei Tests geschieht sich alles genauso wie in Echt.

Diese authentische Simulation der History im Tester verursacht keine Probleme, solange die Test-Modi "Jeder Tick" und "1 Minute OHLC" verwendet werden. Bei diesen Modi werden ausreichende Ticks innerhalb einer Kerze erzeugt, um solange warten zu können, bis die Synchronisation der Bars von verschiedenen Symbolen stattfindet. Wie kann man nun die Multi-Currency-Strategien im Modus "Nur Eröffnungspreise" testen, wenn die Synchronisation von Bars auf Handelsinstrumenten zwingend ist? In diesem Modus wird der Expert Advisor nur auf einen Tick aufgerufen, der der Öffnungszeit des Bar entspricht.

Sehen wir uns das an einem Beispiel an: Wenn wir den Expert Advisor auf EURUSD testen, und auf EURUSD eine neue stündliche Kerze geöffnet wurde, erkennen wir leicht folgendes - beim Testen im Modus "Nur Eröffnungspreise" entspricht das Ereignis NewTick dem Moment der Eröffnung der Bar auf den Test-Zeitraum. Aber dabei gibt es keine Garantie, dass die neue Kerze auf dem Symbol USDJPY geöffnet wurde, das im Expert Advisor verwendet wird.

Normalerweise ist es ausreichend, die Arbeit der OnTick() Funktion abzuschließen und auf das Erscheinen eines neuen Bars auf USDJPY beim nächsten Tick zu achten. Beim Testen im Modus "Nur Eröffnungspreise" gibt es aber keinen anderen Tick, sodass es so aussieht, als ob dieser Modus für Tests von Multi-Currency Expert Advisors nicht geeignet ist Stimmt aber nicht! Vergessen Sie nicht, dass sich der Tester in MetaTrader 5 genauso verhält wie in der Realität auch. Sie können warten bis ein neuer Bar auf anderen Symbolen mittels der Sleep() Funktion geöffnet wird!

Der Code des Expert Advisors Synchronize_Bars_Use_Sleep.mq5, der ein Beispiel der Synchronisation der Bars beim Testen im Modus "Nur Eröffnungspreise" zeigt, lautet folgendermaßen:

//+------------------------------------------------------------------+
//|                                   Synchronize_Bars_Use_Sleep.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input string   other_symbol="USDJPY";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- check symbol
   if(_Symbol==other_symbol)
     {
      PrintFormat("You have to specify the other symbol in input parameters or select other symbol in Strategy Tester!");
      //--- forced stop testing
      return(-1);
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- static variable, used for storage of last bar time
   static datetime last_bar_time=0;
//--- sync flag
   static bool synchonized=false;

//--- if static variable isn't initialized
   if(last_bar_time==0)
     {
      //--- it's first call, save bar time and exit
      last_bar_time=(datetime)SeriesInfoInteger(_Symbol,Period(),SERIES_LASTBAR_DATE);
      PrintFormat("The last_bar_time variable is initialized with value %s",TimeToString(last_bar_time));
     }

//--- get open time of the last bar of chart symbol
   datetime curr_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);
//--- if times aren't equal
   if(curr_time!=last_bar_time)
     {
      //--- save open bar time to the static variable
      last_bar_time=curr_time;
      //--- not synchronized
      synchonized=false;
      //--- print message
      PrintFormat("A new bar has appeared on symbol %s at %s",_Symbol,TimeToString(TimeCurrent()));
     }
//--- open time of the other symbol's bar
   datetime other_time;

//--- loop until the open time of other symbol become equal to curr_time
   while(!(curr_time==(other_time=(datetime)SeriesInfoInteger(other_symbol,Period(),SERIES_LASTBAR_DATE)) && !synchonized))
     {
      PrintFormat("Waiting 5 seconds..");
      //--- wait 5 seconds and call SeriesInfoInteger(other_symbol,Period(),SERIES_LASTBAR_DATE)
      Sleep(5000);
     }
//--- bars are synchronized
   synchonized=true;
   PrintFormat("Open bar time of the chart symbol %s: is %s",_Symbol,TimeToString(last_bar_time));
   PrintFormat("Open bar time of the symbol %s: is %s",other_symbol,TimeToString(other_time));
//--- TimeCurrent() is not useful, use TimeTradeServer()
   Print("The bars are synchronized at ",TimeToString(TimeTradeServer(),TIME_SECONDS));
  }
//+------------------------------------------------------------------+

Beachten Sie die letzte Zeile im Handler, die die aktuelle Zeit anzeigt, als die tatsächliche Synchronisation festgestellt wurde:

   Print("The bars synchronized at ",TimeToString(TimeTradeServer(),TIME_SECONDS));

Um die aktuelle Uhrzeit anzuzeigen, haben wir die Funktion TimeTradeServer () und nicht die Funktion TimeCurrent () verwendet. Die Funktion TimeCurrent() liefert nämlich die Zeit des letzten Ticks, die sich nach der Verwendung von Sleep() nicht ändert. Starten Sie den EA im Modus "Nur Eröffnungspreise" und Sie erhalten eine Meldung über Synchronization der Bars.


Verwenden Sie die Funktion TimeTradeServer() anstelle von TimeCurrent(), wenn Sie die aktuelle Serverzeit und nicht die Eingangszeit des letzten Ticks erhalten möchten.

Bars könne jedoch auch noch anders synchronisiert werden - mit Hilfe eines Timers. Ein Beispiel solchen Expert Advisors ist Synchronize_Bars_Use_OnTimer.mq5, der diesem Beitrag angehängt sit..


Die IndicatorRelease() Funktion im Tester

Nach dem Abschluss eines einzelnen Tests wird automatisch ein Chart des Instrumentes geöffnet, auf dem die abgeschlossenen Abschlüsse und die Indikatoren angezeigt werden, die in Expert Advisor verwendet wurden. Das hilft, die Eingangs- und des Ausgangspunkte visuell zu überprüfen und sie mit den Werten der Indikatoren zu vergleichen.  

Hinweis: Die Indikatoren, die auf dem, nach der Durchführung des Tests automatisch geöffneten Chart, angezeigt werden, werden nach Beendigung des Tests neu berechnet. Auch wenn diese Indikatoren im getesteten Expert-Advisor verwendet wurden.

Manchmal jedoch möchte der Programmierer die Informationen welche Indikatoren am Handelsalgorithmus beteiligt waren, ausblenden. Wenn z.B. der EA-Code vermietet oder als ausführbare Datei ohne Quellcode verkauft wird. Hierfür eignet sich die Funktion IndicatorRelease().

Wenn das Terminal ein Template mit dem Namen tester.tpl in the directory/profiles/templates des Client-Terminals anlegt, wird sie auf das geöffnete Chart angewendet. Gibt es das Template nicht, wird das Standard-Template angewendet. (default.tpl).

Die Funktion IndicatorRelease() wird für die Freigabe des Berechnungsteils des Indikators verwendet, wenn er nicht mehr gebraucht wird. So können Sie sowohl Speicherplatz als auch Prozessor-Ressourcen sparen, denn jeder Tick ruft eine Indikatorberechnung auf. Ihr zweiter Zweck ist das Verbot der Anzeige des Indikators auf dem Test-Chart nach einem einzelnen Lauf.

Um die Anzeige des Indikators auf dem Chart nach dem Test zu verbieten, rufen Sie IndicatorRelease() mit dem Indikator-Identifikator im Handler OnDeinit() auf. Die Funktion OnDeinit() wird immer nach Abschluss oder vor der Anzeige des Test-Charts aufgerufen.

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   bool hidden=IndicatorRelease(handle_ind);
   if(hidden) Print("IndicatorRelease() successfully completed");
   else Print("IndicatorRelease() returned false. Error code ",GetLastError());
  }
Um die Anzeige des Indikators auf dem Chart nach Abschluss eines einzelnen Tests zu verbieten, verwenden Sie die Funktion IndicatorRelease() im Handler OnDeinit().


Behandlung von Ereignissen im Tester

Das Vorhandensein des Handlers OnTick() im Expert Advisor ist nicht obligatorisch, damit er einen Test vor dem Hintergrund historischer Daten im MetaTrader 5 Tester durchläuft. Es genügt für den Expert Advisor wenigstens einen der folgenden Funktion-Handlers zu haben:

  • OnTick() - Ereignis-Handler dbei Auftauchen eines neuen Ticks;
  • OnTrade() - Handels-Ereignis Handler;
  • OnTimer() - Ereignis-Handler eines vom Timer ankommenden Signals;
  • OnChartEvent () - Handler für Client-Ereignisse.

Beim Testen in einem EA kann man die Benutzerereignisse mit Hilfe der Funktion OnChartEreignis() behandeln, in den Indikatoren wird diese Funktion im Tester jedoch nicht aufgerufen. Selbst wenn der Indikator den Ereignis-Handler OnChartEreignis() hat und dieser im getesteten Expert Advisor verwendet wird, wird der Indikator keine Benutzerereignisse bekommen.

Ein Indikator kann beim Testen die Benutzerereignisse mittels der Funktion EventChartCustom() erzeugen, und der Expert Advisor kann dieses Ereignis in OnChartEvent() bearbeiten.


Test-Agenten

Das Testen im MetaTrader 5 Client-Terminal wird außerhalb der Test-Agenten ausgeführt. Lokalen Agenten werden automatisch erstellt und aktiviert. Die Anzahl der lokalen Agenten entspricht standardmäßig der Anzahl der Rechnerkerne auf dem Computer.

Jeder Testagent hat seine eigene Kopie der globalen Variablen, die mit dem Client-Terminal nicht in Zusammenhang steht. Das Terminal selbst ist der 'Verteiler', der die Aufgaben an die lokalen und Remote-Agenten verteilt. Nach der Ausführung einer Aufgabe beim Test eines Expert Advisors mit den gegebenen Parametern, liefert der Agent die Ergebnisse an den Terminal. Bei einzelnen Tests wird nur einen Agenten verwendet.

Der Agent speichert die vom Terminal erhaltene History in einzelnen Ordnern, nach Namen des Instrumentes, d.h. die History für EURUSD wird in einem gesonderten Ordner mit dem Namen EURUSD abgelegt. Außerdem wird die History der Instrumente durch ihre Quellen aufgeteilt. Die Struktur für die Speicherung der History ist wie folgt:

tester_catalog\Agent-IPaddress-Port\bases\name_source\history\symbol_name

Die History für EURUSD von MetaQuotes-Demo-Server kann in einem Ordner tester_catalog\ Agent-127.0.0.1-3000\bases\MetaQuotes-Demo\EURUSD abgelegt werden.

Nach Abschluss des Tests befindet sich der lokale Agent im Bereitschaftsmodus und wartet 5 Minuten auf die nächste Aufgabe, um keine Zeit durch Starten des nächsten Aufrufs zu verschwenden. Er schaltet sich nur ab, wenn die Wartezeit vorbei ist und 'entlädt' sich aus dem Speicher des Computers.

Bei vorzeitiger Beendigung des Tests durch den Benutzer (Schaltfläche "Abbrechnen"), sowie auch bei Schließung des Client-Terminals, stellen alle lokalen Agenten ihre Arbeit sofort ein und werden aus dem Speicher entladen.


Datenaustausch zwischen Terminal und Agenten

Sobald Sie einen Test laufen lassen, bereitet der Client-Terminal einige Parameter-Blöcke zum das Senden an den Agenten vor:
  • Die Eingabeparameter des Tests (Simulationsmodus, Testintervall, Instrumente, Optimierungskriterium, usw.)
  • Die Liste der in "Markt-Beobachtung" ausgewählten Symbole
  • Die Spezifikation des Testsymbols (Kontraktgröße, vom Markt zur Einrichtung von StopLoss und TakeProfit, usw. zulässige Margen)
  • Den getesteten Expert-Advisor und die Werte seiner Eingabeparameter
  • Die Information über weitere Dateien (Bibliotheken, Indikatoren, Daten-Dateien - # property tester_ ...)

    tester_indicator

    string

    Name des Benutzerindikators im Format "indicator_name.ex5". Die Indikatoren, die getestet werden müssen, werden automatisch durch den Aufruf der Funktion iCustom() bestimmt, wenn der entsprechende Parameter durch einen konstanten String eingerichtet ist. In allen anderen Fällen (Verwendung der Funktion IndicatorCreate() oder Verwendung eines nicht konstanten Strings im Parameter, der den Namen des Indikator vorgibt) ist diese Eigenschaft erforderlich.

    tester_file

    string

    Dateiname für einen Tester mit der Erweiterung in doppelten Anführungszeichen (als konstanter String). Die angegebene Datei wird dem Tester übertragen. Die zu testenden Eingabeparameter (wenn sie notwendig sind) müssen immer angegeben werden

    tester_library

    string

    Name der Bibliothek mit der Erweiterung in doppelten Anführungszeichen. Bibliothek kann sowohl die Erweiterung dll oder ex5 haben. Die für Tests erforderlichen Bibliotheken werden automatisch bestimmt. Wird jedoch eine der Bibliotheken von einemangepassten Indikator verwendet, ist diese Eigenschaft obligatorisch.

Für jeden Parameter-Block wird ein digitaler Fingerabdruck in Form eines MD5-Hash erstellt, der an den Agenten gesendet wird. Ein MD5-Hash ist für jedes Set einmalig; sein Volumen ist um vieles kleiner als die Informationsmenge, auf deren Grundlage er berechnet wurde.

Der Agent erhält so einen 'Hash' von Blöcken und vergleicht sie mit denen, die er bereits hat. Wenn dem Agenten der Fingerabdruck des gegebenen Parameter-Blocks fehlt, oder der erhaltene Hash sich vom bestehenden unterscheidet, fordert der Agent diesen Parameter-Block an. So wird der Traffic zwischen Terminal und Agenten reduziert.

Nachdem der Test ausgeführt wurde, liefert der Agent dem Terminal alle Ergebnisse des Laufs, die dann auf den Tabs "Testergebnisse" und "Optimierungsergebnisse" angezeigt werden: der Gewinn, Anzahl der Abschlüsse, Sharpe-Koeffizient, Ergebnis der Funktion OnTester (), usw.

Während der Optimierung verteilt das Terminal die Testaufgaben in kleinen Pakete an die Agenten. Jedes Paket enthält mehrere Aufgaben (jede Aufgabe bedeutet einzelne Tests mit einem Eingabeparameter-Set). Dies senkt die Austausch-Zeit zwischen Terminal und Agenten.

Aus Gründen der Sicherheit werden Agenten die vom Terminal erhaltenen EX5-Dateien (Expert-Advisor, Indikatoren, Bibliotheken, usw.) nie auf der Festplatte speichern, damit ein Computer mit laufendem Agenten die gesendeten DAten nicht verwenden kann. Alle übrigen Dateien, einschließlich DLL, werden in der "Sandbox" gespeichert. In Remote-Agenten können Expert Advisors mittels DLL nicht getestet werden.

Die Testergebnisse werden in einem speziellen Ergebnis-Cache für ggf. den späteren schnellen Zugriff in addierter Form aufbewahrt. Für jedes Parameter-Set sucht das Terminals im Ergebniscache nach bereits vorliegenden Ergebnissen aus vorherigen Läufen, um 'Re-Runs' zu vermeiden. Wird kein Ergebnis für so ein Parameter-Set gefunden, wird dem Agenten die Aufgabe zur Ausführung des Tests übertragen.

Der gesamte Traffic zwischen Terminal und Agenten ist verschlüsselt.


Verwendung eines freigegebenen Ordners aller Client-Terminals

Alle Testagenten sind voneinander und vom Client-Terminal isoliert: jeder Agent hat einen eigenen Ordner, in dem seine Protokolle geschrieben werden. Außerdem finden alle Dateioperationen des Agenten während Tests im Ordern agent_name/MQL5/Files statt. Man kann jedoch eine Interaktion zwischen den lokalen Agenten und dem Client-Terminal über einen freigegebenen Ordner aller Client-Terminals implementieren, wenn Sie während des Öffnens der Datei die Flagge FILE_COMMON angeben:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- the shared folder for all of the client terminals
   common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- draw out the name of this folder
   PrintFormat("Open the file in the shared folder of the client terminals %s", common_folder);
//--- open a file in the shared folder (indicated by FILE_COMMON flag)
   handle=FileOpen(filename,FILE_WRITE|FILE_READ|FILE_COMMON);
   ... further actions
//---
   return(0);
  }


Verwendung von DLLs

Zur Beschleunigung der Optimierung können Sie nicht nur lokale sondern auch Remote Agenten verwenden. Dabei gibt es für Remote-Agenten einige Einschränkungen. Erstens geben Remote-Agenten in ihren Protokollen die Ergebnisse der Ausführung der Funktion Print(), Nachrichten über das Öffnen und Schließen von Positionen nicht aus. Im Protokoll werden Mindestinformationen ausgegeben, sodass falsch geschriebene Expert Advisors die Festplatte Ihres Computers auf dem der Remote-Agent arbeitet, nicht mit Meldungen zumüllen.

Und zweitens: das Verbot der Verwendung von DLL bei Expert Advisor Tests. Aus Sicherheitsgründen sind DLL-Aufrufe auf Remote-Agenten komplett verboten. Bei lokalen Agenten sind DLL-Aufrufe in getesteten EAs nur mit dem entsprechenden Vermerk "DLL-Import erlauben" gestattet.

Abb. 10 Die Option "DLL-Import erlauben" in mql5-Programmen

Hinweis: Bei der Verwendung der von Expert Advisors erhaltenen Informationen (Skripts, Indikatoren), die ein 'Erlauben' von DLL-Aufrufen benötigen, sollten Sie sich der Risiken bewusst sein, die bestehen, falls Sie diese Option in den Einstellungen des Terminals erlauben. Und zwar egal, wie der Expert-Advisor verwendet wird - fürTests oder für einen Lauf auf einem Chart.


Fazit

Dieser Beitrag beschäftigte sich mit Grundlagen, deren Kenntnis Ihnen helfen, die Tests des EAs im MetaTrader 5 Client-Terminal schnell zu beherrschen:

  • Drei Modi zur Tick-Erzeugung (Preisänderung im Kurs);
  • Berechnung von Indikatorwerten während Tests;
  • Multi-Currency Tests;
  • Zeit-Simulation während Tests;
  • Die Funktionsweise der OnTimer(), OnSleep() und IndicatorRelease() Funktionen im Strategie-Tester;
  • Die Funktionsweise von Test-Agenten während DLL-Aufrufen;
  • Verwendung eines freigegebenen Ordners aller Client-Terminals;
  • Synchronisierung von Bars im Modus "nur Offene Preise";
  • Behandlung von Ereignissen.

Die Hauptaufgabe des Strategie-Testers des Client-Terminals ist die Sicherstellung des MQL5-Programmierers der notwendigen Exaktheit aller Daten bei minimalstem Aufwand. Entwickler haben enorme Arbeit geleistet, damit Sie nicht jedes Mal Ihren Code neu schreiben müssen, wenn Sie Ihre Handelsstrategie vor dem Hintergrund historischer Daten testen wollen. Es genügt die Grundlagen der Tests zu kennen. Und ein exakt geschriebener Expert Advisor funktioniert ganz genauso gut im Strategie-Tester als auch im Online-Modus auf dem Chart.


Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/239

Verwendung von Ressourcen in MQL5 Verwendung von Ressourcen in MQL5
MQL5 Programme automatisieren nicht nur Routineberechnungen, sondern können auch vollfunktionale graphische Umgebungen erzeugen. Die Funktionen zur Erzeugung wirklich interaktiver Kontrollen sind nun virtuell genauso vollwertig wie in in klassischen Programmiersprachen. Wenn Sie ein voll funktionsfähiges, eigenständiges Programm in MQL5 schreiben wollen, dann sollten Sie seine Ressourcen verwenden. Programme mit Ressourcen sind leichter zu pflegen und zu verbreiten.
Handelsereignisse in MetaTrader 5 Handelsereignisse in MetaTrader 5
Eine Überwachung des aktuellen Status eines Handels-Account bedeutet offene Positions und Order kontrollieren zu können. Bevor ein Handelssignal zu einem Abschluss wird, sollte es vom Client-Terminal als Anfrage zum Handels-Server geschickt werden, wo es in eine Order-Warteschlange gestellt wird und auf seine Bearbeitung wartet. Eine Anfrage vom Handels-Server annehmen, sie löschen, wenn sie abläuft oder auf ihrer Grundlage einen Abschluss ausführen - alle diese Handlungen haben Handelsereignisse zur Folge, und der Handels-Server informiert das Terminal entsprechend darüber.
Wie die Testergebnisse des Experten selbstständig  bewerten Wie die Testergebnisse des Experten selbstständig bewerten
Im Artikel wurden Formel und die Berechnungsmethode der Daten angeboten, die im Testerbericht angezeigt werden.
Orders, Positions und Abschlüsse in MetaTrader 5 Orders, Positions und Abschlüsse in MetaTrader 5
Einen robusten Handelsroboter zu erzeugen geht nicht ohne das Verständnis der Mechanismen des MetaTrader 5 Handelssystems. Der Client-Terminal erhält vom Handelsserver Informationen über die Positions, Orders und Abschlüsse. Um diese Daten mittels MQL5 entsprechend verarbeiten zu können, ist ein gutes Verständnis der Interaktion zwischen dem mql5-Programm und dem Client-Terminal unabdingbar.