Entwicklung eines Expert Advisors für mehrere Währungen (Teil 23): Ordnung in den Ablauf automatischer Projektoptimierungsstufe bringen (II)
Einführung
Einer der vorangegangenen Teile der Serie war bereits diesem Thema gewidmet. Dies ermöglichte es uns, einen korrekteren Vektor für die weitere Entwicklung des Projekts zu wählen. Anstatt alle Aufgaben, die innerhalb eines einzelnen Projekts durchgeführt werden, manuell in der Optimierungsdatenbank anzulegen, haben wir jetzt ein bequemeres Werkzeug – ein Skript zur Erstellung von Optimierungsprojekten. Genauer gesagt, handelt es sich eher um eine Vorlage, die leicht angepasst werden kann, um Projekte zur Optimierung verschiedener Handelsstrategien zu erstellen.
In diesem Artikel stellen wir eine voll funktionsfähige Lösung vor, die es uns ermöglicht, erstellte Optimierungsprojekte mit dem Export ausgewählter neuer Gruppen von Handelsstrategien direkt in eine neue Datenbank zu starten. Diese Datenbank wurde als EA-Datenbank bezeichnet, um sie von der Optimierungsdatenbank zu unterscheiden, die zuvor (in vollständiger und abgekürzter Form) verwendet wurde. Die EA-Datenbank kann von jedem endgültigen EA, der auf einem Handelskonto läuft, verwendet werden, indem die Einstellungen der verwendeten Handelssysteme ohne Neukompilierung aktualisiert werden. Wir müssen die Korrektheit dieses Mechanismus noch testen. Es lässt sich jedoch schon jetzt sagen, dass dieser Ansatz den Betrieb als Ganzes vereinfacht. Zuvor hatten wir geplant, die drei bestehenden Förderstufen um mehrere weitere Stufen (stages) zu ergänzen:
- Exportieren der Bibliothek, um ExportedGroupsLibrary.mqh im Datenordner zu erhalten (Stage4).
- Kopieren der Datei in den Arbeitsordner (Stage5, Python oder DLL) oder Ändern der vorherigen Stufe, um direkt in den Arbeitsordner zu exportieren.
- Kompilieren des endgültigen EA (Stage6, Python).
- Starten des Terminals mit der neuen Version des endgültigen EA.
Jetzt sind diese Stufen nicht mehr notwendig. Gleichzeitig haben wir auch einen großen Nachteil beseitigt: Es wäre unmöglich, das korrekte Funktionieren eines solchen automatischen Aktualisierungsmechanismus im Strategietester zu überprüfen. Das Vorhandensein einer Neukompilierungsphase ist unvereinbar mit der Tatsache, dass sich der kompilierte Code des EA während eines Testerdurchgangs nicht ändern kann.
Vor allem aber werden wir versuchen, einen wichtigen Schritt zur Vereinfachung der Verwendung des gesamten geschriebenen Codes für die Optimierung beliebiger Strategien zu machen, und wir werden versuchen, einen Schritt-für-Schritt-Algorithmus von Aktionen zu beschreiben.
Der Weg ist vorgezeichnet
Beginnen wir mit der Umsetzung längst überfälliger Änderungen an der Struktur der Projektdateien. Derzeit befinden sie sich in einem einzigen Ordner, was einerseits die Übertragung und Verwendung des gesamten Codes in einem neuen Projekt vereinfacht, andererseits aber im Zuge der kontinuierlichen Entwicklung zu mehreren fast identischen Projektordnern für verschiedene Handelsstrategien führt, die jeweils einzeln aktualisiert werden müssen. Daher werden wir den gesamten Code in einen Bibliotheksteil, der für alle Projekte gleich ist, und einen Projektteil, der projektspezifischen Code enthält, unterteilen.
Als Nächstes implementieren wir eine Prüfung, die sicherstellt, dass der endgültige EA die aktualisierten Parameter korrekt laden und seine Arbeit fortsetzen kann, wenn während seines Betriebs neue Strategiegruppen erscheinen. Beginnen wir, wie üblich, mit der Modellierung des gewünschten Verhaltens in einem EA, der im Strategietester läuft. Wenn die Ergebnisse dort zufriedenstellend sind, kann man dazu übergehen, sie in den endgültigen EAs zu verwenden, die im Testprogramm nicht mehr funktionieren.
Was brauchen wir dafür? Im vorangegangenen Abschnitt haben wir die Speicherung von Informationen über das Enddatum des Optimierungsintervalls und den Abschluss der Ausführung des Optimierungsförderers in der EA-Datenbank nicht implementiert. Jetzt brauchen wir diese Information, sonst kann der endgültige EA beim Ausführen des Testers nicht feststellen, ob diese Gruppe von Strategien bereits zu einem bestimmten simulierten Datum gebildet wurde oder nicht.
Der endgültige EA muss auch so geändert werden, dass er seine eigene Neuinitialisierung durchführen kann, wenn neue Strategiegruppen in seiner EA-Datenbank erscheinen. Gegenwärtig verfügt es einfach nicht über eine solche Funktion. Hier wäre es nützlich, zumindest einige Informationen über die aktuelle Gruppe von Handelsstrategien zu haben, damit man den erfolgreichen Übergang von einer Gruppe zur anderen klar erkennen kann. Es wäre bequemer, diese Informationen direkt auf dem Chart zu sehen, auf dem der EA läuft, aber Sie können natürlich auch die reguläre Ausgabe in das Terminalprotokoll für diesen Zweck verwenden.
Schließlich wird der allgemeine Algorithmus für die Arbeit mit den bisher entwickelten Werkzeugen beschrieben.
Fangen wir an!
Übergang zu einer anderen Dateistruktur
In allen bisherigen Teilen wurde die Entwicklung in einem Projektverzeichnis durchgeführt. Bestehende Dateien wurden geändert, und von Zeit zu Zeit wurden neue Dateien hinzugefügt. Manchmal wurden Dateien, die für das Projekt nicht mehr relevant waren, gelöscht oder „vergessen“. Dieser Ansatz war gerechtfertigt, wenn mit einer einzigen möglichen Handelsstrategie gearbeitet wurde (z. B. die in den Artikeln als Beispiel verwendete SimpleVolumes-Strategie). Bei der Ausweitung des automatischen Optimierungsmechanismus auf andere Handelsstrategien war es jedoch erforderlich, eine vollständige Kopie des Arbeitsordners des Projekts zu erstellen und dann nur einen kleinen Teil der darin enthaltenen Dateien zu ändern.
Da die Zahl der auf diese Weise verbundenen Handelsstrategien (und die Zahl der verschiedenen Arbeitsordner) zunahm, wurde es immer arbeitsintensiver, den Code in allen Ordnern auf dem neuesten Stand zu halten. Daher werden wir den Teil des Codes, der für alle Arbeitsordner gleich sein sollte, in einen separaten Bibliotheksordner in MQL5/Include verschieben. Der Name des gemeinsamen Ordners für Bibliotheksdateien wurde auf Advisor festgelegt, und um zu verhindern, dass er mit einem möglicherweise vorhandenen Ordner gleichen Namens in Konflikt gerät, wurde ihm eine eindeutige Komponente hinzugefügt. Die Bibliotheksdateien befinden sich nun in MQL5/Include/antekov/Advisor/.
Nachdem wir alle Dateien dorthin übertragen hatten, begannen wir mit der weiteren Systematisierung. Es wurde beschlossen, alle Dateien in Unterordner aufzuteilen, die einen gemeinsamen Zweck für die darin befindlichen Dateien widerspiegeln. Dies erforderte einige Arbeit mit den Direktiven zum Einfügen einiger Dateien in andere, da sich ihre relativen Positionen geändert hatten. Letztendlich ist es uns aber gelungen, sowohl die EAs als auch alle Bibliotheksdateien separat zu kompilieren.
So sieht die Dateistruktur nach der Änderung aus:

Abb. 1. Dateistruktur der Advisor-Bibliothek
Wie Sie sehen, haben wir mehrere Dateigruppen ausgewählt und sie in den folgenden Unterordnern abgelegt:
- Basis. Basisklassen, von denen andere Projektklassen erben.
- Database. Dateien für den Umgang mit allen Arten von Datenbanken, die von Projekt-EAs verwendet werden.
- Experts. Dateien mit gemeinsamen Teilen der verwendeten EAs verschiedener Typen.
- Optimization. Klassen, die für die automatische Optimierung zuständig sind.
- Strategies. Beispiele für Handelsstrategien, die die Funktionsweise des Projekts veranschaulichen.
- Utils. Hilfsprogramme, Makros zur Code-Reduzierung.
- Virtual. Klassen zur Erstellung verschiedener Objekte, die durch die Verwendung eines Systems virtueller Handelsaufträge und -positionen miteinander verbunden sind.
Von allen oben aufgeführten Unterordnern sticht nur einer hervor und verdient besondere Erwähnung. Dies ist der Ordner der Experten. Wenn wir die Zusammensetzung der Dateien in Abb. 1 mit der Zusammensetzung der Dateien aus dem vorherigen Teil vergleichen, können wir feststellen, dass nur dieser Ordner Dateien enthält, die vorher nicht vorhanden waren. Auf den ersten Blick könnte man meinen, dass wir die Dateien der verwendeten EAs einfach teilweise umbenannt und hierher verschoben haben, aber beachten Sie, dass ihre Erweiterung nicht *.mq5, sondern *.mqh lautet. Doch bevor wir sie genauer betrachten, wollen wir uns ansehen, was im Ordner eines separaten Projekts für eine bestimmte Handelsstrategie verbleiben wird.
Wir erstellen einen separaten Ordner innerhalb von MQL5/Experts/ und benennen ihn nach Belieben. Sie enthält die Dateien aller verwendeten EAs:

Abb. 2. Dateistruktur eines Projekts, das die EA-Bibliothek verwendet
Der Zweck dieser Dateien ist der folgende:
- Der EA CreateProject.mq5 erstellt ein Auto-Optimierungsprojekts in der Optimierungsdatenbank. Jedes Projekt in der Datenbank wird in drei Stufen dargestellt, die aus einer oder mehreren Aufgaben bestehen. Jeder Auftrag besteht aus einer oder mehreren Optimierungsaufgaben, die von den Stage EAs ausgeführt werden.
- Der EA HistoryReceiverExpert.mq5 für die Reproduktion des zuvor gespeicherten Transaktionsverlaufs. Wir haben ihn schon lange nicht mehr verwendet, da er nur zu dem Zweck erstellt wurde, die Wiederholbarkeit der Ergebnisse bei einem Maklerwechsel zu überprüfen. Sie ist für die automatische Optimierung nicht erforderlich, Sie können sie also getrost entfernen.
- Der EA Optimization.mq5 führt die Aufgaben eines Auto-Optimierungsprojekts aus. Wir haben den Prozess der sequentiellen Durchführung solcher Aufgaben als Auto-Optimierungsband bezeichnet.
- SimpleVolumes.mq5 – ein endgültiger EA, der viele einzelne Instanzen von Handelsstrategien des Typs SimpleVolumes kombiniert. Die Informationen über die Zusammensetzung dieser Exemplare werden aus der Datenbank der EA übernommen. Diese Informationen werden wiederum von der dritten Stufe des automatischen Optimierungsprogramms in die Datenbank des EA eingegeben.
- Der EA Stage1.mq5 ist der der ersten Stufe des automatischen Optimierungsförderers. Sie optimiert eine einzelne Instanz einer Handelsstrategie.
- Der EA Stage2.mq5 ist der der zweiten Stufe des automatischen Optimierungsförderers. Während der Optimierung wählt er aus vielen guten Einzelinstanzen, die in der ersten Stufe gewonnen wurden, eine kleine Gruppe von Instanzen (normalerweise 8 oder 16) aus, die zusammen die besten Ergebnisse in Bezug auf den standardisierten Gewinn zeigen.
- Der EA Stage3.mq5 ist der der dritten Stufe des automatischen Optimierungsförderers. Es kombiniert alle in der zweiten Stufe erhaltenen Gruppen, normalisiert die Positionsgrößen und speichert die resultierende Gruppe mit einem in den Einstellungen angegebenen Skalierungsfaktor in der EA-Datenbank.
Von den aufgelisteten EA-Dateien hat nur CreateProject.mq5 seinen Inhalt gespeichert. Alle anderen EAs enthalten im Grunde nur einen Befehl zum Einbinden der entsprechenden mqh-Datei aus der Bibliothek Advisor, die sich in MQL5/Include/antekov/Advisor/Experts befindet. Insbesondere SimpleVolumes.mq5 und HistoryReceiverExpert.mq5 verwenden dieselbe Include-Datei Expert.mqh. Wie die Praxis zeigt, ist es nicht erforderlich, für unterschiedliche Handelsstrategien unterschiedlichen Code für EAs der zweiten und dritten Stufe zu schreiben. Für den EA der ersten Stufe besteht der einzige Unterschied in den verschiedenen Eingaben und der Erstellung des erforderlichen Initialisierungsstrings aus deren Werten. Auch sonst bleibt alles beim Alten.
Nur die Datei CreateProject.mq5 muss bei einem Wechsel zu einem Projekt mit einer anderen Handelsstrategie in größerem Umfang geändert werden. In Zukunft werden wir versuchen, auch den gemeinsamen Teil daraus zu extrahieren.
Sehen wir uns nun an, welche Änderungen an den Bibliotheksdateien vorgenommen werden müssen, um die automatische Aktualisierung des endgültigen EA zu implementieren.
Daten für die Ausführung
Erinnern wir uns, dass wir im vorigen Teil vier fast identische Optimierungsprojekte gestartet haben. Der Unterschied zwischen ihnen lag im Enddatum des Optimierungsintervalls der einzelnen Instanzen der Handelsstrategien. Die Zusammensetzung der Handelsinstrumente, die Zeitrahmen und andere Parameter unterschieden sich nicht. Als Ergebnis erschienen die folgenden Einträge in der Tabelle strategy_groups der EA-Datenbank:

Da wir dem Gruppennamen das Enddatum des Optimierungsintervalls hinzugefügt haben, können wir anhand dieser Information nachvollziehen, welche Gruppe welchem Enddatum entspricht. Aber auch das sollte der EA verstehen können. Wir haben speziell zwei Felder in dieser Tabelle erstellt, um diese Daten zu speichern, die bei der Erstellung von Datensätzen ausgefüllt werden müssen, und sogar eine Stelle im Code vorbereitet, an der dies geschehen muss:
//+------------------------------------------------------------------+ //| Export an array of strategies to the specified EA database | //| as a new group of strategies | //+------------------------------------------------------------------+ void CTesterHandler::Export(CStrategy* &p_strategies[], string p_groupName, string p_advFileName) { // Connect to the required EA database if(DB::Connect(p_advFileName, DB_TYPE_ADV)) { string fromDate = ""; // Start date of the optimization interval string toDate = ""; // End date of the optimization interval // Create an entry for a new strategy group string query = StringFormat("INSERT INTO strategy_groups VALUES(NULL, '%s', '%s', '%s', NULL)" " RETURNING rowid;", p_groupName, fromDate, toDate); ulong groupId = DB::Insert(query); // ... } }
Das Start- und Enddatum des Optimierungsintervalls wird in der Tabelle stages in der Datenbank gespeichert. Daher können wir sie von dort abrufen, indem wir die entsprechende SQL-Abfrage an dieser Stelle des Codes ausführen. Dieser Ansatz erwies sich jedoch als nicht optimal, da wir bereits den Code implementiert hatten, der eine SQL-Abfrage ausführt, um unter anderem Informationen über diese Daten zu erhalten. Dies geschah im automatischen Optimierungs-EA. Er sollte von der Datenbank Informationen über die nächste Optimierungsaufgabe erhalten. Diese Informationen müssen die von uns benötigten Daten enthalten. Das sollten wir uns zunutze machen.
Wir müssen ein Objekt der Klasse COptimizerTask erstellen, indem wir den Namen der Optimierungsdatenbank an ihren Konstruktor übergeben. Sie ist im statischen Klassenfeld CTesterHandler::s_fileName enthalten. Ein weiteres statisches Feld CTesterHandler::s_idTask enthält die ID der aktuellen Optimierungsaufgabe. Wir übergeben sie an die Methode zum Laden der Daten des Optimierungsproblems. Danach können die erforderlichen Daten aus den entsprechenden Feldern der Struktur m_params des Aufgabenobjekts entnommen werden.
//+------------------------------------------------------------------+ //| Export an array of strategies to the specified EA database | //| as a new group of strategies | //+------------------------------------------------------------------+ void CTesterHandler::Export(CStrategy* &p_strategies[], string p_groupName, string p_advFileName) { // Create an optimization task object COptimizerTask task(s_fileName); // Load the data of the current optimization task into it task.Load(CTesterHandler::s_idTask); // Connect to the required EA database if(DB::Connect(p_advFileName, DB_TYPE_ADV)) { string fromDate = task.m_params.from_date; // Start date of the optimization interval string toDate = task.m_params.to_date; // End date of the optimization interval // Create an entry for a new strategy group string query = StringFormat("INSERT INTO strategy_groups VALUES(NULL, '%s', '%s', '%s', NULL)" " RETURNING rowid;", p_groupName, fromDate, toDate); ulong groupId = DB::Insert(query); // ... } }
Speichern wir die Änderungen an der Datei TesterHandler.mqh im Unterordner Virtual der Bibliothek.
Lassen Sie uns mehrere Projekte mit Hilfe von CreateProject.ex5 EA neu erstellen. Um den Prozess zu beschleunigen, werden wir das Optimierungsintervall klein halten (4 Monate). Wir werden den Beginn und das Ende des Optimierungsintervalls für jedes nachfolgende Projekt um einen Monat vorverlegen. Daraus ergibt sich Folgendes:

Wie Sie sehen können, enthält jede Gruppe in der EA-Datenbank nun das Enddatum des Optimierungsintervalls. Beachten Sie, dass dieses Datum dem Intervall für die Aufgabe der dritten Stufe entnommen ist. Damit alles korrekt ist, müssen die Daten der Intervalle aller drei Stufen übereinstimmen. Dies ist in der EA zur Projekterstellung vorgesehen.
Änderung des endgültigen EA
Bevor wir mit der Implementierung von automatischen Aktualisierungen der im endgültigen EA verwendeten Strategiegruppe beginnen, sollten wir uns die Änderungen ansehen, die durch den Übergang zur neuen Projektdateistruktur verursacht werden. Wie bereits erwähnt, wird die endgültige Fassung des Umweltgutachtens nun in Form von zwei Dateien vorgelegt. Die Hauptdatei befindet sich im Projektordner und heißt SimpleVolumes.mq5. Hier ist der vollständige Code:
//+------------------------------------------------------------------+ //| SimpleVolumes.mq5 | //| Copyright 2024-2025, Yuriy Bykov | //| https://www.mql5.com/de/users/antekov | //+------------------------------------------------------------------+ #property copyright "Copyright 2024-2025, Yuriy Bykov" #property link "https://www.mql5.com/de/articles/16913" #property description "The final EA, combining multiple instances of trading strategies:" #property description " " #property description "Strategies open a market or pending order when," #property description "the candle tick volume exceeds the average volume in the direction of the current candle." #property description "If orders have not yet turned into positions, they are deleted at expiration time." #property description "Open positions are closed only by SL or TP." #property version "1.22" #include <antekov/Advisor/Experts/Expert.mqh> //+------------------------------------------------------------------+
In diesem Code gibt es im Wesentlichen nur einen Befehl zum Importieren der Bibliotheksdatei des endgültigen EA. Das ist genau dann der Fall, wenn das, was nicht ist, wichtiger ist als das, was ist. Vergleichen wir dies mit dem Code des zweiten EA HistoryReceiverExpert.mq5:
//+------------------------------------------------------------------+ //| HistoryReceiverExpert.mq5 | //| Copyright 2024-2025, Yuriy Bykov | //| https://www.mql5.com/de/users/antekov | //+------------------------------------------------------------------+ #property copyright "Copyright 2024-2025, Yuriy Bykov" #property link "https://www.mql5.com/de/articles/16913" #property description "The EA opens a market or pending order when," #property description "the candle tick volume exceeds the average volume in the direction of the current candle." #property description "If orders have not yet turned into positions, they are deleted at expiration time." #property description "Open positions are closed only by SL or TP." #property version "1.01" //+------------------------------------------------------------------+ //| Declare the name of the final EA. | //| During the compilation, the function of generating | //| the initialization string from the current file will be used | //+------------------------------------------------------------------+ #define __NAME__ MQLInfoString(MQL_PROGRAM_NAME) //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input group "::: Testing the deal history" input string historyFileName_ = "SimpleVolumesExpert.1.19 [2021.01.01 - 2022.12.30]" " [10000, 34518, 1294, 3.75].history.csv"; // File with history //+------------------------------------------------------------------+ //| Function for generating the strategy initialization string | //| from the inputs | //+------------------------------------------------------------------+ string GetStrategyParams() { return StringFormat("class CHistoryStrategy(\"%s\")\n", historyFileName_); } #include <antekov/Advisor/Experts/Expert.mqh> //+------------------------------------------------------------------+
Die drei Blöcke, die nicht in der Datei SimpleVolumes.mq5 enthalten sind, sind farblich hervorgehoben. Ihr Vorhandensein wird in der Bibliotheksdatei Experts/Expert.mqh des endgültigen EA berücksichtigt: Wenn keine Konstante mit dem Namen des endgültigen EA angegeben ist, wird eine Funktion zur Erzeugung des Initialisierungsstrings deklariert, die diesen aus der Datenbank des EA erhält. Wenn der Name angegeben ist, muss eine solche Funktion in der übergeordneten Datei, in die die Bibliotheksdatei eingebunden ist, deklariert sein.
// If the constant with the name of the final EA is not specified, then #ifndef __NAME__ // Set it equal to the name of the EA file #define __NAME__ MQLInfoString(MQL_PROGRAM_NAME) //+------------------------------------------------------------------+ //| Function for generating the strategy initialization string | //| from the default inputs (if no name was specified). | //| Import the initialization string from the EA database | //| by the strategy group ID | //+------------------------------------------------------------------+ string GetStrategyParams() { // Take the initialization string from the new library for the selected group // (from the EA database) string strategiesParams = CVirtualAdvisor::Import( CVirtualAdvisor::FileName(__NAME__, magic_), groupId_ ); // If the strategy group from the library is not specified, then we interrupt the operation if(strategiesParams == NULL && useAutoUpdate_) { strategiesParams = ""; } return strategiesParams; } #endif
Anschließend wird in der EA-Initialisierungsfunktion der Bibliotheksdatei Experts/Expert.mqh eine der möglichen Optionen für die Funktion zur Erzeugung der Initialisierungszeichenfolge verwendet:
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // ... // Initialization string with strategy parameter sets string strategiesParams = NULL; // Take the initialization string from the new library for the selected group // (from the EA database) strategiesParams = GetStrategyParams(); // If the strategy group from the library is not specified, then we interrupt the operation if(strategiesParams == NULL) { return INIT_FAILED; } // ... // Successful initialization return(INIT_SUCCEEDED); }
So können wir, falls gewünscht, einen endgültigen EA erstellen, der das Laden der Initialisierungszeichenfolge aus der EA-Datenbank nicht benötigt. Dazu deklarieren wir die Konstante __NAME__ und die Signaturfunktion in der *.mq5-Datei.
string GetStrategyParams() Jetzt können wir mit der automatischen Aktualisierung fortfahren.
Automatische Aktualisierungen
Die erste Option für die Implementierung automatischer Aktualisierungen ist vielleicht nicht die schönste, aber für den Anfang ist sie ausreichend. Die Hauptsache ist, dass es funktioniert. Die erforderlichen Änderungen an der endgültigen EA-Bibliotheksdatei bestanden aus zwei Teilen.
Zunächst haben wir die Zusammensetzung der Eingaben geringfügig geändert, indem wir die Enumeration mit der Gruppennummer aus der alten Bibliothek entfernt und durch die Gruppen-ID aus der EA-Datenbank ersetzt und einen logischen Parameter hinzugefügt haben, der die automatische Aktualisierung ermöglicht:
//+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input group "::: Use a strategy group" sinput int groupId_ = 0; // - ID of the group from the new library (0 - last) sinput bool useAutoUpdate_ = true; // - Use auto update? input group "::: Money management" sinput double expectedDrawdown_ = 10; // - Maximum risk (%) sinput double fixedBalance_ = 10000; // - Used deposit (0 - use all) in the account currency input double scale_ = 1.00; // - Group scaling multiplier // ...
Zweitens haben wir den folgenden Code in die neue Tick-Handling-Funktion eingefügt, und zwar nach der hervorgehobenen Zeichenfolge:
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { expert.Tick(); // If both are executed at the same time: if(groupId_ == 0 // - no specific group ID specified && useAutoUpdate_ // - auto update enabled && IsNewBar(Symbol(), PERIOD_D1) // - a new day has arrived && expert.CheckUpdate() // - a new group of strategies discovered ) { // Save the current EA state expert.Save(); // Delete the EA object delete expert; // Call the EA initialization function to load a new strategy group OnInit(); } }
Die automatische Aktualisierung funktioniert also nur, wenn groupId_=0 und useAutoUpdate_=true. Wenn wir eine Gruppen-ID ungleich Null angeben, wird diese Gruppe während des gesamten Testintervalls verwendet. In diesem Fall gibt es keine Einschränkung, wann der endgültige EA Handel treiben kann.
Wenn die automatische Aktualisierung aktiviert ist, führt der resultierende EA nur Handelsgeschäfte nach dem Enddatum des Optimierungsintervalls der frühesten in der EA-Datenbank vorhandenen Gruppe aus. Dieser Mechanismus wird in der neuen Methode der Klasse CVirtualAdvisor::CheckUpdate() implementiert:
//+------------------------------------------------------------------+ //| Check the presence of a new strategy group in the EA database | //+------------------------------------------------------------------+ bool CVirtualAdvisor::CheckUpdate() { // Request to get strategies of a given group or the last group string query = StringFormat("SELECT MAX(id_group) FROM strategy_groups" " WHERE to_date <= '%s'", TimeToString(TimeCurrent(), TIME_DATE)); // Open the EA database if(DB::Connect(m_fileName, DB_TYPE_ADV)) { // Execute the request int request = DatabasePrepare(DB::Id(), query); // If there is no error if(request != INVALID_HANDLE) { // Data structure for reading a single string of a query result struct Row { int groupId; } row; // Read data from the first result string while(DatabaseReadBind(request, row)) { // Remember the strategy group ID // in the static property of the EA class return s_groupId < row.groupId; } } else { // Report an error if necessary PrintFormat(__FUNCTION__" | ERROR: request \n%s\nfailed with code %d", query, GetLastError()); } // Close the EA database DB::Close(); } return false; }
Bei dieser Methode wird aus der EA-Datenbank die größte Gruppen-ID ermittelt, bei der das Enddatum des Optimierungsintervalls nicht größer ist als das aktuelle Datum. Selbst wenn also ein Eintrag bereits physisch in der Datenbank vorhanden ist, aber der Zeitpunkt seines Erscheinens (>= Endzeitpunkt des Optimierungsintervalls) in der Zukunft liegt, bezogen auf die aktuelle simulierte Zeit des Strategietesters, wird er nicht als Ergebnis der verwendeten SQL-Abfrage erhalten.
Bei der Initialisierung speichert der EA die ID der geladenen Strategiegruppe in dem statischen Feld der Klasse CVirtualAdvisor::s_groupId. Daher können wir das Erscheinen einer neuen Gruppe erkennen, indem wir die gerade aus der EA-Datenbank erhaltene ID mit der ID der zuvor geladenen Gruppe vergleichen. Ist die erste Gruppe größer, so ist eine neue Gruppe entstanden.
In der Methode zur Beschaffung des Initialisierungsstrings aus der EA-Datenbank, die bereits direkt mit der Datenbank interagiert, verwenden wir dieselbe Bedingung für das Enddatum des Gruppentestintervalls mit aktivierter automatischer Aktualisierung:
//+------------------------------------------------------------------+ //| Get the strategy group initialization string | //| from the EA database with the given ID | //+------------------------------------------------------------------+ string CVirtualAdvisor::Import(string p_fileName, int p_groupId = 0) { string params[]; // Array for strategy initialization strings // Request to get strategies of a given group or the last group string query = StringFormat("SELECT id_group, params " " FROM strategies" " WHERE id_group = %s;", (p_groupId > 0 ? (string) p_groupId : "(SELECT MAX(id_group) FROM strategy_groups WHERE to_date <= '" + TimeToString(TimeCurrent(), TIME_DATE) + "')")); // Open the EA database if(DB::Connect(p_fileName, DB_TYPE_ADV)) { // ... } // Strategy group initialization string string groupParams = NULL; // Total number of strategies in the group int totalStrategies = ArraySize(params); // If there are strategies, then if(totalStrategies > 0) { // Concatenate their initialization strings with commas JOIN(params, groupParams, ","); // Create a strategy group initialization string groupParams = StringFormat("class CVirtualStrategyGroup([%s], %.5f)", groupParams, totalStrategies); } // Return the strategy group initialization string return groupParams; }
Der letzte Punkt, der hier zu erwähnen ist, ist die Hinzufügung einer Methode zum Laden des EA-Status nach dem Wechsel zu einer neuen Gruppe von Strategien. Der Punkt ist, dass neue Strategien aus der neuen Gruppe ihre Einstellungen nicht in der EA-Datenbank finden, da die Methode Save() für sie noch nicht aufgerufen wurde, und den Download-Fehler melden. Dieser Fehler sollte jedoch ignoriert werden.
Ein weiterer Zusatz bezieht sich auf die Notwendigkeit, virtuelle Positionen alter Strategien unmittelbar nach dem Laden neuer Strategien zu schließen. Dazu ist es notwendig und ausreichend, Symbol-Empfänger-Objekte für alle von den alten Strategien verwendeten Symbole anzulegen. Diese Objekte korrigieren die Volumina der offenen Positionen auf den nächsten Tick. Wenn dies nicht geschieht, wird die Volumenkorrektur nur dann erfolgen, wenn virtuelle Positionen mit neuen Strategien eröffnet werden. Wenn neue Strategien aufhören, eines der zuvor verwendeten Symbole zu verwenden, bleiben die Positionen für dieses Symbol offen.
//+------------------------------------------------------------------+ //| Load status | //+------------------------------------------------------------------+ bool CVirtualAdvisor::Load() { bool res = true; ulong groupId = 0; // Load status if: if(true // file exists && FileIsExist(m_fileName, FILE_COMMON) // currently, there is no optimization && !MQLInfoInteger(MQL_OPTIMIZATION) // and there is no testing at the moment or there is a visual test at the moment && (!MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_VISUAL_MODE)) ) { // If the connection to the EA database is established if(CStorage::Connect(m_fileName)) { // If the last modified time is loaded and less than the current time if(CStorage::Get("CVirtualReceiver::s_lastChangeTime", m_lastSaveTime) && m_lastSaveTime <= TimeCurrent()) { PrintFormat(__FUNCTION__" | LAST SAVE at %s", TimeToString(m_lastSaveTime, TIME_DATE | TIME_MINUTES | TIME_SECONDS)); // If the saved strategy group ID is loaded if(CStorage::Get("CVirtualAdvisor::s_groupId", groupId)) { // Load all strategies ignoring possible errors FOREACH(m_strategies, { res &= ((CVirtualStrategy*) m_strategies[i]).Load(); }); if(groupId != s_groupId) { // Actions when launching an EA with a new group of strategies. PrintFormat(__FUNCTION__" | UPDATE Group ID: %I64u -> %I64u", s_groupId, groupId); // Reset a possible error flag when loading strategies res = true; string symbols[]; // Array for symbol names // Get the list of all symbols used by the previous group CStorage::GetSymbols(symbols); // For all symbols, create a symbolic receiver. // This is necessary for the correct closing of virtual positions // of the old strategy group immediately after loading the new one FOREACH(symbols, m_receiver[symbols[i]]); } // ... } } else { // If the last modified time is not found or is in the future, // then start work from scratch PrintFormat(__FUNCTION__" | NO LAST SAVE [%s] - Clear Storage", TimeToString(m_lastSaveTime, TIME_DATE | TIME_MINUTES | TIME_SECONDS)); CStorage::Clear(); m_lastSaveTime = 0; } // Close the connection CStorage::Close(); } } return res; }
Danach können Sie mit der Überprüfung der Funktionalität des automatischen Ladens neuer Gruppen beginnen. Leider stellte sich der Erfolg nicht sofort ein, da die aufgetretenen Fehler korrigiert werden mussten. Es stellte sich zum Beispiel heraus, dass der EA in eine Endlosschleife gerät, wenn die EA-Datenbank plötzlich leer ist. Oder ein Test beginnt nicht, wenn das Datum des Testbeginns sogar einen Tag vor dem Datum des Erscheinens der ersten Gruppe von Strategien festgelegt wird. Schließlich wurden alle gefundenen Fehler korrigiert.
Schauen wir uns nun den Algorithmus für die Verwendung der erstellten Bibliothek als Ganzes und die Ergebnisse der automatischen Aktualisierungsprüfung an.
Algorithmus für die Verwendung der Advisor-Bibliothek
Dieses Mal werden wir den Algorithmus zur Verwendung der Bibliothek Advisor für die automatische Optimierung der Modellstrategie SimpleVolumes beschreiben, die Teil der Bibliothek ist und im Tester des endgültigen EA gestartet wird.
- Wir setzen die Bibliothek auf Include (Abb. 1).
- Wir erstellen einen Projektordner und übertragen die EA-Dateien dorthin (Abb. 2).
- Wir nehmen Änderungen an den Dateien des EA der ersten Stufe und der Datei des EA der Projekterstellung vor. Bei Verwendung einer Modellstrategie sind keine Änderungen erforderlich, da sie auf dem neuesten Stand sind. Wir kompilieren alle EAs im Projektordner.
- Wir starten den EA zur Projekterstellung und stellen die gewünschten Parameterwerte ein (Wir können die Standardwerte beibehalten).
Die Ausgabe sollte eine Optimierungsdatenbank sein, die mit Aufgaben für das Projekt im gemeinsamen Terminaldatenordner gefüllt ist. Sie können in der Projektbeschreibung beliebige Angaben machen, z. B. das Start- und Enddatum des Optimierungsintervalls. Im Moment wird lediglich eine Aufgabe zum Starten des Förderers erstellt. Der Start wird von einem anderen EA durchgeführt. - Falls gewünscht, können wir den vorherigen Schritt beliebig oft wiederholen und dabei die Parameter ändern. Wir können z. B. mehrere Projekte für die automatische Optimierung in unterschiedlichen Zeitabständen anlegen.
- Wir starten den Optimierungs-EA und warten. Die Zeit, die benötigt wird, um alle zur Optimierungsdatenbank hinzugefügten Projekte abzuschließen, hängt von ihrer Anzahl sowie von der Anzahl der Symbole und Zeitrahmen in den Projekten, von der Dauer des Test-/Optimierungszeitintervalls und von der Komplexität der implementierten Handelsstrategie ab. Diese Zeit hängt auch von der Anzahl der an der Optimierung beteiligten Test-Agenten ab.
Die Ausgabe ist eine Datei mit der EA-Datenbank in einem gemeinsamen Ordner. Sein Name stammt von den Einstellungen.
Die EA-Datenbank wird gespeicherte Strategiegruppen enthalten. - Starten wir den letzten EA. Es ist wichtig, dass der Name und die magische Zahl mit den Angaben bei der Optimierung übereinstimmen. Andernfalls wird eine leere EA-Datenbank erstellt und darauf gewartet, dass etwas darin erscheint. Wenn der endgültige EA seine Basis findet, versucht er, die Strategiegruppe mit der angegebenen ID zu laden oder die zuletzt hinzugefügte Gruppe, wenn die ID 0 ist. Wenn die Option „Automatische Aktualisierung“ aktiviert ist, prüft der EA einmal täglich, ob eine neue Gruppe von Strategien, die nach Datum verfügbar sind, in der EA-Datenbank erschienen ist. Wenn sie erscheint, ersetzt sie die zuvor verwendete Gruppe.
Automatische Aktualisierungen testen
Nachdem die Optimierung aller in die Datenbank aufgenommenen Projekte mit unterschiedlichen Fertigstellungsterminen abgeschlossen ist, werden wir also eine EA-Datenbank mit mehreren Gruppen von Strategien unterschiedlicher Zusammensetzung haben. Sie unterscheiden sich auch durch das Enddatum des Optimierungsintervalls. Und wir haben einen endgültigen EA, der im Laufe der Tests eine neue Gruppe von Strategien aus der Datenbank nehmen kann, wenn die simulierte aktuelle Zeit die Endzeit des Optimierungsintervalls für diese neue Gruppe überschreitet.
Bitte beachten Sie, dass das Speichern und Laden von EA-Parametern nur funktioniert, wenn der EA auf einem Chart oder im visuellen Testmodus gestartet wird. Um die automatische Aktualisierung im Prüfgerät zu überprüfen, ist es daher notwendig, den visuellen Modus zu verwenden.
Führen wir den letzten EA aus und geben dabei eine bestimmte Gruppe groupId_=1 an. In diesem Fall wird, unabhängig vom Wert des Parameters useAutoUpdate_, nur diese Gruppe verwendet. Er wurde für das Intervall 2022.09.01 – 2023.01.01 optimiert, sodass wir den Tester ab dem Datum 2022.09.01 (dem Hauptzeitraum) starten und ab dem Datum 2023.01.01 den Vorwärtszeitraum bis 2024.01.01 beginnen werden.

Hauptzeitraum 2022.09.01 – 2023.01.01

Vorwärtstest 2023.01.01 – 2024.01.01

Abb. 3. Ergebnisse der endgültigen EA mit den Parametern groupId_=1 im Intervall 2022.09.01 – 2024.01.01
Wie wir sehen können, zeigt der EA gute Ergebnisse in der Hauptperiode, die mit dem Optimierungsintervall zusammenfällt, aber in der Vorwärtsperiode ist das Bild völlig anders. Es gibt einen viel größeren Drawdown und kein signifikantes Wachstum der Kapitalkurve. Natürlich würde ich gerne etwas Schöneres sehen, aber dieses Ergebnis ist nicht unerwartet. Schließlich haben wir bei der Optimierung ein sehr kleines Intervall, wenige Symbole und wenige Zeitrahmen verwendet. Daher haben wir festgestellt, dass in einem bekannten Abschnitt die Parameter für diesen speziellen kurzen Abschnitt zu gut gewählt waren. Die EA war nicht in der Lage, sich auf diese Weise in einem unbekannten Gebiet zu bewähren.
Schauen wir uns an, ob ein ähnliches Muster bei einer anderen Gruppe von Handelsstrategien zu beobachten ist, die von Interesse ist. Führen wir den resultierenden EA unter Angabe der groupId_=3 aus. Diese Gruppe wurde für das Intervall 2022.11.01 – 2023.03.01 optimiert, sodass wir den Tester ab 2022.11.01 (Hauptperiode) starten und ab dem Datum 2023.03.01 auch den Vorwärtstest bis 2024.01.01 durchführen.

Hauptzeitraum 2022.11.01 – 2023.03.01

Vorwärtstest 2023.03.01 – 2024.01.01

Abb. 4. Ergebnisse des endgültigen EA mit den Parametern groupId_=3 im Zeitraum 2022.11.01 – 2024.01.01
Ja, die Ergebnisse waren die gleichen wie bei der ersten Gruppe. Für beide Gruppen ist im Mai-Juni ein starker Rückgang zu beobachten. Man könnte meinen, dass dies eine unglückliche Zeit für die Strategie ist. Wenn wir aber eine Gruppe nehmen, die auf diesen Bereich optimiert wurde, werden wir sehen, dass auch hier die gleichen Parameter der Strategien aus der Gruppe erfolgreich ausgewählt wurden. Es zeigt das gleiche sanfte und schöne Wachstum des Charts.
Wenn wir den endgültigen EA ab dem Datum 2023.01.01 mit den Parametern groupId_=0, useAutoUpdate=false laufen lassen, dann erhalten wir das gleiche Ergebnis wie in der Forward-Periode für die erste Gruppe, da in diesem Fall die erste Gruppe geladen wird (sie „existiert“ bereits ab dem Startdatum des Durchgangs). Da die automatische Aktualisierung jedoch deaktiviert ist, wird sie nicht durch Gruppen mit einer späteren Erscheinungszeit ersetzt.
Und schließlich lassen wir den endgültigen EA auf dem Intervall 2023.01.01 – 2024.01.01 mit automatischer Aktualisierung laufen, indem wir die groupId_=0, useAutoUpdate=true angeben.


Abb. 5. Ergebnisse des finalen EA mit den Parametern groupId_=0, useAutoUpdate=true im Intervall 2023.01.01 – 2024.01.01
Die Handelsergebnisse selbst sind nicht von Interesse, denn um die Zeit für die automatische Optimierung zu verkürzen, wurde ein sehr kurzer Optimierungszeitraum verwendet (nur 4 Monate). Jetzt wollen wir nur noch die Funktionalität des Mechanismus zur automatischen Aktualisierung der verwendeten Strategiegruppen demonstrieren. Und nach den Protokolleinträgen und der automatischen Schließung der Positionen zu Beginn eines jeden Monats zu urteilen, funktioniert dies wie vorgesehen:
SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualReceiver::Get | OK, Strategy orders: 3 from 144 total SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualStrategyGroup::CVirtualStrategyGroup | Scale = 2.44, total strategies = 1 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualStrategyGroup::CVirtualStrategyGroup | Scale = 48.00, total groups = 48 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualStrategyGroup::CVirtualStrategyGroup | Scale = 1.00, total groups = 1 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualRiskManager::UpdateBaseLevels | DAILY UPDATE: Balance = 0.00 | Equity = 0.00 | Level = 0.00 | depoPart = 0.10 = 0.10 * 1.00 * 1.00 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualAdvisor::Load | LAST SAVE at 2023.01.31 20:32:00 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:00 CVirtualAdvisor::Load | UPDATE Group ID: 1 -> 2 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:00:59 CSymbolNewBarEvent::IsNewBar | Register new event handler for GBPUSD PERIOD_D1 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:01:00 CSymbolNewBarEvent::IsNewBar | Register new event handler for EURUSD PERIOD_D1 SimpleVolumes (GBPUSD,H1) 2023.02.01 00:01:00 CSymbolNewBarEvent::IsNewBar | Register new event handler for EURGBP PERIOD_D1
Schlussfolgerung
Lassen Sie uns einige Ergebnisse zusammenfassen. Schließlich haben wir den gesamten wiederverwendbaren Code in Form der Bibliothek Advisor im Ordner Include abgelegt. Jetzt wird es möglich sein, sie mit Projekten zu verbinden, die mit verschiedenen Handelsstrategien arbeiten. Spätere Aktualisierungen der Bibliothek werden automatisch an alle Projekte verteilt, in denen sie verwendet wird.
Es wird immer einfacher, ein Autooptimierungsprojekt zu erstellen und zu starten. Wir haben nun den Mechanismus zur Umsetzung der Optimierungsergebnisse in den endgültigen EA vereinfacht. Geben Sie einfach den gewünschten EA-Datenbanknamen in den Einstellungen für die dritte Optimierungsstufe an, und die Ergebnisse werden dort gespeichert, wo der endgültige EA sie abrufen kann.
Es gibt jedoch noch einige Punkte, die beachtet werden müssen. Eine davon ist die Entwicklung eines Algorithmus für das Hinzufügen einer neuen Art von Handelsstrategie und die Aufnahme von Gruppen mit verschiedenen Arten von Handelsstrategien in den endgültigen EA. Aber dazu beim nächsten Mal mehr.
Vielen Dank für Ihre Aufmerksamkeit! Bis bald!
Wichtige Warnung
Alle in diesem Artikel und in allen vorangegangenen Artikeln dieser Reihe vorgestellten Ergebnisse beruhen lediglich auf historischen Testdaten und sind keine Garantie für zukünftige Gewinne. Die Arbeiten im Rahmen dieses Projekts haben Forschungscharakter. Alle veröffentlichten Ergebnisse können von jedermann auf eigenes Risiko verwendet werden.
Inhalt des Archivs
| # | Name | Version | Beschreibung | Jüngste Änderungen |
|---|---|---|---|---|
| MQL5/Experts/Article.16913 | Projektarbeitsordner | |||
| 1 | CreateProject.mq5 | 1.01 | EA-Skript zur Erstellung eines Projekts mit Stufen, Aufträgen und Optimierungsaufgaben. | Teil 23 |
| 2 | HistoryReceiverExpert.mq5 | 1.01 | EA für die Wiedergabe der Historie von Geschäften mit dem Risikomanager | Teil 23 |
| 3 | Optimization.mq5 | 1.00. | EA für Projekte Auto-Optimierung | Teil 23 |
| 4 | SimpleVolumesExpert.mq5 | 1.22 | Endgültiger EA für den Parallelbetrieb mehrerer Gruppen von Modellstrategien. Die Parameter werden aus der integrierten Gruppenbibliothek übernommen. | Teil 23 |
| 5 | Stage1.mq5 | 1.22 | Handelsstrategie Einzelinstanzoptimierung EA (stage 1) | Teil 23 |
| 6 | Stage2.mq5 | 1.00. | Handelsstrategien Instanzen Gruppe Optimierung EA (stage 2) | Teil 23 |
| 7 | Stage3.mq5 | 1.00. | Der EA, der eine generierte standardisierte Gruppe von Strategien in einer EA-Datenbank mit einem bestimmten Namen speichert. | Teil 23 |
| MQL5/Include/antekov/Advisor/Base | Basisklassen, von denen andere Projektklassen erben | |||
| 8 | Advisor.mqh | 1.04 | EA-Basisklasse | Teil 10 |
| 9 | Factorable.mqh | 1.05 | Basisklasse von Objekten, die aus einer Zeichenkette erstellt werden | Teil 22 |
| 10 | Interface.mqh | 1.01 | Basisklasse zur Visualisierung verschiedener Objekte | Teil 4 |
| 11 | Receiver.mqh | 1.04 | Basisklasse für die Umwandlung von offenen Volumina in Marktpositionen | Teil 12 |
| 12 | Strategy.mqh | 1.04 | Handelsstrategie-Basisklasse | Teil 10 |
| MQL5/Include/antekov/Advisor/Database | Dateien für den Umgang mit allen Arten von Datenbanken, die von Projekt-EAs verwendet werden | |||
| 13 | Database.mqh | 1.10 | Klasse für den Umgang mit der Datenbank | Teil 22 |
| 14 | db.adv.schema.sql | 1.00. | Endgültige Datenbankstruktur von EA | Teil 22 |
| 15 | db.cut.schema.sql | 1.00. | Struktur der verkürzten Optimierungsdatenbank | Teil 22 |
| 16 | db.opt.schema.sql | 1.05 | Optimierung der Datenbankstruktur | Teil 22 |
| 17 | Storage.mqh | 1.01 | Klasse zur Handhabung der Schlüssel-Wert-Speicherung für den endgültigen EA in der EA-Datenbank | Teil 23 |
| MQL5/Include/antekov/Advisor/Experts | Dateien mit gemeinsamen Teilen der verwendeten EAs verschiedener Typen | |||
| 18 | Expert.mqh | 1.22 | Die Bibliotheksdatei für den endgültigen EA. Gruppenparameter können aus der EA-Datenbank übernommen werden | Teil 23 |
| 19 | Optimization.mqh | 1.04 | Bibliotheksdatei für den EA, der den Start von Optimierungsaufgaben verwaltet | Teil 23 |
| 20 | Stage1.mqh | 1.19 | Bibliotheksdatei für die Einzelinstanz der Handelsstrategieoptimierung EA (Stufe 1) | Teil 23 |
| 21 | Stage2.mqh | 1.04 | Bibliotheksdatei für den EA, der eine Gruppe von Handelsstrategieinstanzen optimiert (Stufe 2) | Teil 23 |
| 22 | Stage3.mqh | 1.04 | Bibliotheksdatei für den EA, die eine generierte standardisierte Gruppe von Strategien in einer EA-Datenbank mit einem bestimmten Namen speichert. | Teil 23 |
| MQL5/Include/antekov/Advisor/Optimization | Für die automatische Optimierung zuständige Klassen | |||
| 23 | Optimizer.mqh | 1.03 | Klasse für den Projektautooptimierungsmanager | Teil 22 |
| 24 | OptimizerTask.mqh | 1.03 | Klasse der Optimierungsaufgaben | Teil 22 |
| MQL5/Include/antekov/Advisor/Strategies | Beispiele für Handelsstrategien, die die Funktionsweise des Projekts veranschaulichen | |||
| 25 | HistoryStrategy.mqh | 1.00. | Klasse der Handelsstrategie für die Wiederholung der Handelshistorie | Teil 16 |
| 26 | SimpleVolumesStrategy.mqh | 1.11 | Klasse der Handelsstrategie mit Tick-Volumen | Teil 22 |
| MQL5/Include/antekov/Advisor/Utils | Hilfsprogramme, Makros zur Code-Reduzierung | |||
| 27 | ExpertHistory.mqh | 1.00. | Klasse für den Export der Handelshistorie in eine Datei | Teil 16 |
| 28 | Macros.mqh | 1.05 | Nützliche Makros für Array-Operationen | Teil 22 |
| 29 | NewBarEvent.mqh | 1.00. | Klasse zur Definition eines neuen Balkens für ein bestimmtes Symbol | Teil 8 |
| 30 | SymbolsMonitor.mqh | 1.00. | Klasse zur Beschaffung von Informationen über Handelsinstrumente (Symbole) | Teil 21 |
| MQL5/Include/antekov/Advisor/Virtual | Klassen zur Erstellung verschiedener Objekte, die durch ein System virtueller Handelsaufträge und -positionen verbunden sind | |||
| 31 | Money.mqh | 1.01 | Basisklasse für das Geldmanagement | Teil 12 |
| 32 | TesterHandler.mqh | 1.07 | Klasse zur Behandlung von Optimierungsereignissen | Teil 23 |
| 33 | VirtualAdvisor.mqh | 1.10 | Klasse des EA, der virtuelle Positionen (Aufträge) bearbeitet | Teil 23 |
| 34 | VirtualChartOrder.mqh | 1.01 | Grafische virtuelle Positionsklasse | Teil 18 |
| 35 | VirtualFactory.mqh | 1.04 | Objekt-Fabrik-Klasse | Teil 16 |
| 36 | VirtualHistoryAdvisor.mqh | 1.00. | Die Klasse des EA zur Wiederholung des Handelsverlaufs | Teil 16 |
| 37 | VirtualInterface.mqh | 1.00. | EA GUI-Klasse | Teil 4 |
| 38 | VirtualOrder.mqh | 1.09 | Klasse der virtuellen Aufträge und Positionen | Teil 22 |
| 39 | VirtualReceiver.mqh | 1.04 | Klasse für die Umwandlung von offenen Volumina in Marktpositionen (Empfänger) | Teil 23 |
| 40 | VirtualRiskManager.mqh | 1.04 | Klasse Risikomanagement (Risikomanager) | Teil 23 |
| 41 | VirtualStrategy.mqh | 1.09 | Klasse einer Handelsstrategie mit virtuellen Positionen | Teil 23 |
| 42 | VirtualStrategyGroup.mqh | 1.02 | Klasse der Handelsstrategien Gruppe(n) | Teil 23 |
| 43 | VirtualSymbolReceiver.mqh | 1.00. | Symbol-Empfängerklasse | Teil 3 |
| MQL5/Common/Files | Gemeinsamer Terminal-Ordner | |||
| 44 | SimpleVolumes-27183.test.db.sqlite | – | EA-Datenbank mit hinzugefügten Strategiegruppen |
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/16913
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
Marktsimulation (Teil 09): Sockets (III)
Eine alternative Log-datei mit der Verwendung der HTML und CSS
Von der Grundstufe bis zur Mittelstufe: Ereignisse (I)
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.