English Русский 中文 Español 日本語 Português
preview
Entwicklung eines Expert Advisors für mehrere Währungen (Teil 23): Ordnung in den Ablauf automatischer Projektoptimierungsstufe bringen (II)

Entwicklung eines Expert Advisors für mehrere Währungen (Teil 23): Ordnung in den Ablauf automatischer Projektoptimierungsstufe bringen (II)

MetaTrader 5Tester |
25 0
Yuriy Bykov
Yuriy Bykov

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.

  1. Wir setzen die Bibliothek auf Include (Abb. 1).

  2. Wir erstellen einen Projektordner und übertragen die EA-Dateien dorthin (Abb. 2).

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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
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

Beigefügte Dateien |
MQL5.zip (421.44 KB)
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Marktsimulation (Teil 09): Sockets (III) Marktsimulation (Teil 09): Sockets (III)
Der heutige Artikel ist eine Fortsetzung des vorangegangenen Artikels. Wir werden uns die Implementierung eines Expert Advisors ansehen und uns dabei vor allem darauf konzentrieren, wie der Servercode ausgeführt wird. Der im vorigen Artikel beschriebene Code reicht nicht aus, damit alles wie erwartet funktioniert. Daher ist es notwendig, beide Artikel zu lesen, um besser zu verstehen, was passieren wird.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Von der Grundstufe bis zur Mittelstufe: Ereignisse (I) Von der Grundstufe bis zur Mittelstufe: Ereignisse (I)
In Anbetracht dessen, was bisher gezeigt wurde, denke ich, dass wir jetzt damit beginnen können, eine Art Anwendung zu implementieren, um ein Symbol direkt auf dem Chart auszuführen. Zunächst müssen wir jedoch über ein Konzept sprechen, das für Anfänger ziemlich verwirrend sein kann. Es ist die Tatsache, dass Anwendungen, die in MQL5 entwickelt wurden und für die Anzeige in einem Chart bestimmt sind, nicht auf die gleiche Weise erstellt werden, wie wir es bisher gesehen haben. In diesem Artikel werden wir beginnen, dies ein wenig besser zu verstehen.