English Русский 中文 Español 日本語 Português
preview
Neuronale Netze leicht gemacht (Teil 40): Verwendung von Go-Explore bei großen Datenmengen

Neuronale Netze leicht gemacht (Teil 40): Verwendung von Go-Explore bei großen Datenmengen

MetaTrader 5Experten | 31 Oktober 2023, 09:04
227 0
Dmitriy Gizlyk
Dmitriy Gizlyk

Einführung

Im vorherigen Artikel „Neuronale Netze leicht gemacht (Teil 39): Go-Explore, ein anderer Ansatz der Erkundung“ haben wir uns mit dem Go-Explore-Algorithmus und seiner Fähigkeit zur Erkundung der Umgebung vertraut gemacht. Wie Sie sich vielleicht erinnern, umfasst der Algorithmus 2 Stufen:

  • Phase 1 — Erkunden
  • Phase 2 — Policy Lernen anhand von Beispielen

In Phase 1 wählten wir zufällige Aktionen aus, um ein möglichst vollständiges Bild der Umgebung zu erhalten. Dieser Ansatz ermöglichte es uns, eine ausreichende Datenbank von Beispielen zu sammeln, um einen Agenten innerhalb eines Kalendermonats erfolgreich auf historischen Daten zu trainieren. Das von uns erstellte Modell war in der Lage, eine Strategie zu finden, mit der sich aus der Trainingsmenge ein Gewinn erzielen lässt.

Aber der Zeitraum von einem Kalendermonat ist zu kurz, um die Daten zusammenzufassen und eine Strategie zu entwickeln, die in absehbarer Zeit Gewinne abwirft. Um unsere Strategie zu finden, sind wir daher gezwungen, die Trainingszeit zu verlängern. Als wir den Trainingszeitraum auf drei Monate ausdehnten, stellten wir fest, dass die zufällige Aktionsauswahl keinen einzigen profitablen Durchgang ergab.

Erweiterte Trainingszeit Ergebnisse

Nach der Wahrscheinlichkeitstheorie ist dies ein durchaus zu erwartendes Ergebnis. Schließlich ist die Wahrscheinlichkeit eines Gesamtereignisses gleich dem Produkt der Wahrscheinlichkeiten aller seiner Komponenten. Da aber die Wahrscheinlichkeit jedes einzelnen Ereignisses kleiner als 1 ist, sinkt mit zunehmender Anzahl der Schritte die Wahrscheinlichkeit, einen gewinnbringenden Durchgang zu erhalten.

Außerdem kann es mit zunehmender Trainingszeit zu Veränderungen in der Umgebung kommen, die sich auf die Lernergebnisse des Agenten auswirken können. Daher ist es wichtig, die Leistung des Agenten regelmäßig zu überwachen und seine Leistung in den Zwischenphasen zu analysieren.

Um die Trainingsergebnisse über einen längeren Zeitraum zu verbessern, können verschiedene Optimierungsmethoden für den Go-Explore-Algorithmus angewandt werden, z. B. durch einen verbesserten Ansatz bei der Aktionsauswahl. Dieser Ansatz sollte den breiteren Kontext der Aufgabe berücksichtigen und dem Agenten ermöglichen, fundiertere Entscheidungen zu treffen.

In diesem Artikel werden wir uns mögliche Optimierungsmethoden für den Go-Explore-Algorithmus genauer ansehen, um seine Effizienz über längere Trainingsperioden zu verbessern.


1. Schwierigkeiten bei der Nutzung von Go-Explore mit zunehmender Dauer der Ausbildung

Mit zunehmender Trainingszeit des Go-Explore-Algorithmus treten gewisse Schwierigkeiten auf. Einige von ihnen sind:

  1. Fluch der Dimensionalität: Mit zunehmender Trainingszeit steigt die Anzahl der Zustände, die ein Agent besuchen kann, exponentiell an, sodass es schwieriger wird, die optimale Strategie zu finden.

  2. Umweltveränderungen: Mit zunehmender Dauer des Trainings können Veränderungen in der Umgebung auftreten, die sich auf die Lernergebnisse des Agenten auswirken können. Dies kann dazu führen, dass eine zuvor erfolgreiche Strategie unwirksam oder sogar unmöglich wird.

  3. Schwierigkeiten bei der Auswahl von Aktionen: Mit zunehmender Dauer des Trainings muss der Agent möglicherweise den breiteren Kontext der Aufgabe berücksichtigen, um fundierte Entscheidungen zu treffen. Dies kann die Auswahl der optimalen Aktion erschweren und komplexere Methoden zur Optimierung des Algorithmus erfordern.

  4. Erhöhte Ausbildungszeit: Mit zunehmender Trainingsdauer steigt auch der Zeitaufwand für die Sammlung ausreichender Daten und das Training des Modells. Dies kann die Effizienz und Geschwindigkeit der Agentenschulung verringern.

Mit zunehmender Trainingsdauer kann sich das Problem ergeben, dass die Dimension des zu untersuchenden Zustandsraums zunimmt. Dies kann zu dem Problem des „Fluches der Dimensionalität“ führen, bei dem die Anzahl der möglichen Zustände mit zunehmender Dimensionalität exponentiell ansteigt. Dies macht die Erkundung des Zustandsraums schwierig und kann dazu führen, dass der Algorithmus zu viel Zeit mit der Erkundung irrelevanter Zustände verbringt.

Um dieses Problem zu lösen, können Techniken zur Dimensionalitätsreduktion eingesetzt werden, zum Beispiel PCA. Sie ermöglichen es, die Dimensionalität des Zustandsraums zu reduzieren und gleichzeitig Informationen über die Datenstruktur zu erhalten. Wir können auch wichtige Techniken zur Auswahl von Merkmalen verwenden, um die Dimensionalität des Zustandsraums zu reduzieren und uns auf die wichtigsten Aspekte des Problems zu konzentrieren.

Außerdem können wir zusätzliche Methoden wie die Optimierung auf der Grundlage von evolutionären oder genetischen Algorithmen verwenden, die es uns ermöglichen, in großen Zustandsräumen nach optimalen Lösungen zu suchen. Diese Methoden ermöglichen es uns, verschiedene Optionen für das Agentenverhalten zu untersuchen und die optimalsten Lösungen für eine bestimmte Aufgabe auszuwählen.

Es können auch verschiedene Ansätze zur Handlungsauswahl verwendet werden, wie z. B. vertrauensbasierte Explorationsmethoden, die es dem Agenten ermöglichen, neue Regionen des Zustandsraums zu erkunden, wobei nicht nur die Wahrscheinlichkeit, eine Belohnung zu erhalten, sondern auch das Vertrauen in sein Wissen über die Aufgabe berücksichtigt wird. Dies kann dazu beitragen, das Problem des Verharrens in lokalen Optima zu vermeiden und eine effizientere Erkundung des Zustandsraums zu ermöglichen.

Bei Demonstrationen des Verstärkungslernens (Reinforcement Learning, RL) werden in der Regel Computerspiele oder andere künstlich simulierte Umgebungen verwendet, die stationär sind, d. h. sich im Laufe der Zeit nicht verändern. In realen Anwendungen kann sich die Umgebung jedoch im Laufe der Zeit verändern, was sich auf die Lernergebnisse des Agenten auswirken kann.

Bei der Verwendung des Go-Explore-Algorithmus, der einen Schritt zur Erkundung der Umgebung beinhaltet, um historische Daten zu erhalten, können Veränderungen in der Umgebung zu unerwarteten Ergebnissen führen, wenn der Agent anschließend anhand historischer Daten trainiert wird.

Wenn der Agent beispielsweise mehrere Monate lang mit Daten trainiert wurde und sich in dieser Zeit die Umgebung verändert hat, z. B. durch Änderungen der Spielregeln oder das Auftauchen neuer Objekte, kann es sein, dass der Agent mit der neuen Umgebung nicht zurechtkommt und seine zuvor erfolgreiche Strategie unwirksam oder sogar unmöglich wird.

Um die Auswirkungen von Umweltveränderungen auf die Trainingsergebnisse des Agenten zu reduzieren, ist es notwendig, die Umwelt regelmäßig zu überwachen und ihre Veränderungen während des Trainings des Agenten zu analysieren. Werden signifikante Veränderungen in der Umgebung festgestellt, muss der Ausbildungsprozess des Agenten mit aktualisierten Daten und Algorithmen neu gestartet werden.

Wir können auch Trainingsmethoden verwenden, die Veränderungen in der Umgebung während des Trainings berücksichtigen, wie z. B. modellbasierte Methoden des Verstärkungslernens (RL), die ein Modell der Umgebung erstellen und dieses zur Vorhersage zukünftiger Zustände und Belohnungen verwenden. Dadurch kann sich der Agent an Veränderungen in der Umgebung anpassen und fundiertere Entscheidungen treffen.

Es können auch andere Optimierungstechniken eingesetzt werden, wie z. B. die Änderung der Hyperparameter des Algorithmus oder Änderungen am Algorithmus selbst, um effizienter zu trainieren.

Im Allgemeinen kann die Verwendung des Go-Explore-Algorithmus zum Training von Agenten über längere Zeiträume recht komplex sein und erfordert viele technische Lösungen und Verbesserungen.

Daher kann die Verwendung des Go-Explore-Algorithmus recht komplex sein und erfordert viele technische Lösungen und Verbesserungen. Der Go-Explore-Algorithmus ist ein leistungsfähiges Werkzeug zur Erkundung komplexer Umgebungen und zum Training von Agenten in Aufgaben mit einer großen Anzahl von Zuständen und Aktionen. Seine Wirksamkeit kann jedoch mit zunehmender Trainingsdauer und wechselnden Aufgabenbedingungen abnehmen. Daher ist es notwendig, verschiedene Optimierungsmethoden und Parametereinstellungen zu verwenden, um die besten Ergebnisse zu erzielen. Dies könnte eine sehr nützliche und vielversprechende Richtung für die Forschung sein.


2. Optionen zur Optimierung des Ansatzes

In Anbetracht dessen, was oben gesagt wurde, erfordert die Verlängerung des Trainingszeitraums ein sorgfältigeres Vorgehen als die einfache Angabe neuer Daten im Strategietester und das Laden zusätzlicher historischer Daten. Um eine echte Handelsstrategie zu entwickeln, muss das Modell mit möglichst vielen historischen Daten trainiert werden. Nur so können wir ein Modell schaffen, das auch in Zukunft Gewinne abwirft.

In diesem Artikel wollen wir das Modell nicht komplizierter machen. Stattdessen werden wir mehrere einfache Ansätze verwenden, die dazu beitragen, die Tiefe der historischen Daten für das Modelltraining mit dem Go-Explore-Algorithmus zu erweitern.

Bevor ein bereits erstellter Algorithmus optimiert wird, müssen seine Engpässe analysiert werden.

Der erste Schritt besteht darin, die Konstanten in der Zellstruktur zu ändern. Diese Struktur wird verwendet, um einen separaten Zustand des Systems und den eingeschlagenen Weg zu speichern. Aus technischen Gründen sind wir gezwungen, in dieser Struktur nur statische Arrays zu verwenden. Mit zunehmender Trainingszeit des Modells nimmt auch die Größe des Weges zum beschriebenen Zustand zu. Wir haben bereits eine Konstante erstellt, die die Größe des Arrays angibt. Nun sollten wir den Wert dieser Konstante so ändern, dass genügend Platz vorhanden ist, um den gesamten Weg des Agenten vom Anfang bis zum Ende der Trainingsperiode aufzuzeichnen.

Um den Wert der Konstante zu bestimmen, verwenden wir einfache mathematische Methoden. Im Durchschnitt umfasst ein Kalendermonat 21-22 Arbeitstage. Um Fehler zu vermeiden, verwenden wir den Höchstwert von 22 Arbeitstagen. In 4 Monaten gibt es 88 Arbeitstage.

Beim Testen der Modelle wird der H1-Zeitrahmen verwendet. Ein Tag hat 24 Stunden. Um das Modell zu trainieren, benötigen wir also einen Puffer von 2112 Elementen (88 * 24). Diese Berechnungen berücksichtigen mögliche Maximalwerte und übersteigen die tatsächliche Anzahl der Balken geringfügig, sodass ein kritischer Fehler durch Überschreitung der Feldgröße nicht zu befürchten ist. Wenn jedoch Kurse trainiert werden, die Wochenenden einschließen (z. B. Kryptowährungen), sollten Kalendertage zur Berechnung der Puffergröße verwendet werden, wobei der gesamte Trainingszeitraum und die Merkmale der Instrumentenkurse zu berücksichtigen sind.

#define                    Buffer_Size  2112

Der zweite Engpass ist das Sortieren der Beispiele vor dem Speichern. In der Praxis hat sich gezeigt, dass das Sortieren von Daten mehr Zeit in Anspruch nehmen kann als die Durchsicht historischer Daten und die Erfassung dieser Zustände. Mit zunehmender Trainingszeit steigt auch die Menge der zu sortierenden Daten. Deshalb haben wir beschlossen, auf die Datensortierung zu verzichten. Infolgedessen erhielt die Funktion OnTesterDeinit im Experten Berater Faza1.mq5 die folgende Form:

//+------------------------------------------------------------------+
//| TesterDeinit function                                            |
//+------------------------------------------------------------------+
void OnTesterDeinit()
  {
//---
   int total = ArraySize(Total);
   printf("total %d", total);
   Print("Saving...");
   SaveTotalBase();
   Print("Saved");
  }

Beim Testen wurde festgestellt, dass der EA oft mehrere Positionen öffnet und diese lange offen hält. Wir wollten dieses Problem mit einem ganzheitlichen Ansatz angehen und haben mehrere Änderungen an der Funktionsweise der Probenerhebung EA vorgenommen.

Eine der Änderungen bezieht sich auf die Definition der Vergütung. Bisher haben wir die Veränderung des Kapitals als Belohnung verwendet. Dieser Ansatz ermöglichte es dem Modell, Veränderungen bei akkumulierten und nicht erfassten Gewinnen zu berücksichtigen, wodurch Drawdowns bestraft und die Akkumulation von Gewinnen auf profitablen Positionen gefördert wurden. Dieser Ansatz schränkte jedoch die Möglichkeiten der Gewinnmitnahme ein. Wir wollten nicht auf den Vorteil des Einsatzes von Kapital verzichten, aber wir wollten auch eine Belohnung für die Gewinnmitnahme hinzufügen.

Wir haben eine Kompromisslösung gefunden, bei der das arithmetische Mittel aus der Veränderung des Kapitals und des Kontostands verwendet wird. Wenn ein Gewinn oder Verlust aus einer offenen Position entsteht, ändert sich das Kapital, aber der Kontostand bleibt unverändert. Der Agent erhält eine Belohnung oder Strafe in Höhe der Hälfte der Veränderung des Kapitals. Wenn ein Gewinn oder Verlust verbucht wird, ändert sich das Kapital nicht, aber der kumulierte Betrag wird in den Kontostand aufgenommen. Der Agent erhält die andere Hälfte der ausstehenden Belohnung oder Strafe. Daher ist der Agent mehr daran interessiert, Positionen mit Gewinn zu schließen und ist weniger geneigt, offene Positionen zu halten.

      Base[action_count - 1].value = ( Base[action_count - 1].state[241] - state[241] + 
                                       Base[action_count - 1].state[240] - state[240] ) / 2.0f;

Wir haben außerdem beschlossen, das maximale Volumen offener Positionen zu begrenzen, um deren Anzahl zu verringern. Bei der Erstellung von Beispielen und beim Testen des Modells haben wir ein festes Mindestvolumen für jeden Handel verwendet. Eine Begrenzung des Volumens offener Positionen ist daher völlig identisch mit einer Begrenzung der Anzahl offener Positionen. Bei der Beschreibung des aktuellen Zustands des Systems sammeln wir jedoch Informationen über das Volumen der offenen Positionen und die kumulierten Gewinne/Verluste. Um zusätzliche Berechnungen zu vermeiden, verwenden wir das Volumen der offenen Position, um das maximale Volumen zu begrenzen. Wir haben den Wert des maximal möglichen Volumens einer offenen Position in externe Variablen verschoben, was uns erlaubt, Experimente mit verschiedenen Werten durchzuführen.

input double               MaxPosition = 0.1;

Das ultimative Ziel unserer Begrenzung des maximalen Volumens offener Positionen ist es, die Anzahl offener Positionen auf dem Konto zu reduzieren und die Anhäufung von Handelsgeschäften in einer positiven oder negativen Blockade zu vermeiden. Zu diesem Zweck prüfen wir das Limit für Kauf- und Verkaufsgeschäfte getrennt, ohne deren Unterschied zu berücksichtigen.

Es ist wichtig anzumerken, dass wir die Beschränkungen unseres Modells nicht explizit angeben. Stattdessen beschränken wir das maximale Volumen der offenen Positionen in der Phase der Erstellung von Beispielen, die zum Trainieren des Modells verwendet werden. Anschließend verwenden wir diese Beispiele, um das Modell zu trainieren, und es selbst entwickelt seine Strategie auf der Grundlage der erhaltenen Beispiele. Dank dieses Ansatzes kann sich das Modell an sich verändernde Marktsituationen anpassen und die wirksamsten Maßnahmen auswählen.

Es ist jedoch zu bedenken, dass in dem Fall, in dem wir eine Aktion zur Eröffnung einer Position generieren, diese aber aufgrund der auferlegten Beschränkungen nicht ausgeführt werden kann, der nachfolgende Zustand des Systems und die Belohnung nicht mit der generierten Aktion übereinstimmen werden. Um dieses Problem zu lösen, speichern wir in der Beispieldatenbank eine Aktion, die der Erwartung (kein Handel) entspricht, für den Fall, dass die generierte Aktion nicht ausgeführt wurde. Dies gewährleistet die Übereinstimmung zwischen Aktion und Belohnung und stellt sicher, dass das Modell korrekt trainiert wird.

   switch(act)
     {
      case 0:
         if(buy_value >= MaxPosition || !Trade.Buy(Symb.LotsMin(), Symb.Name()))
            act = 3;
         break;
      case 1:
         if(sell_value >= MaxPosition || !Trade.Sell(Symb.LotsMin(), Symb.Name()))
            act = 3;
         break;
      case 2:
         for(int i = PositionsTotal() - 1; i >= 0; i--)
            if(PositionGetSymbol(i) == Symb.Name())
               if(!Trade.PositionClose(PositionGetInteger(POSITION_IDENTIFIER)))
                 {
                  act = 3;
                  break;
                 }
         break;
     }

Da wir unter den Bedingungen riskanter Markttransaktionen tätig sind, besteht unsere Aufgabe nicht nur darin, Gewinne zu erzielen, sondern auch mögliche Verluste zu minimieren. Zu diesem Zweck fügen wir unserem Modell ein Limit für die maximale Zeit hinzu, die eine offene Position gehalten werden kann.

Diese Begrenzung ist eine ganzzahlige, externe Variable, die die maximale Anzahl von Balken angibt, die eine offene Position halten können. 

input int                  MaxLifeTime = 48;

Wir legen die Lebensdauer der ältesten Position fest, und wenn sie den Grenzwert erreicht, schließen wir zwangsweise alle Positionen.

Dies ist notwendig, damit wir offene Positionen nicht zu lange halten, was zu großen Verlusten führen kann. Bei der Erhebung von Informationen über den aktuellen Kontostand und offene Positionen berücksichtigen wir diese Einschränkung, um die maximale Haltedauer nicht zu überschreiten.

   int total = PositionsTotal();
   datetime time_current = TimeCurrent();
   int first_order = 0;
   for(int i = 0; i < total; i++)
     {
      if(PositionGetSymbol(i) != Symb.Name())
         continue;
      switch((int)PositionGetInteger(POSITION_TYPE))
        {
         case POSITION_TYPE_BUY:
            buy_value += PositionGetDouble(POSITION_VOLUME);
            buy_profit += PositionGetDouble(POSITION_PROFIT);
            break;
         case POSITION_TYPE_SELL:
            sell_value += PositionGetDouble(POSITION_VOLUME);
            sell_profit += PositionGetDouble(POSITION_PROFIT);
            break;
        }
      first_order = MathMax((int)(PositionGetInteger(POSITION_TIME) - time_current) / PeriodSeconds(TimeFrame), first_order);
     }

Wenn wir jedoch zulassen, dass dieser Grenzwert überschritten wird, sollten geeignete Maßnahmen ergriffen werden. In diesem Fall schließen wir nicht einfach eine Position nach Ablauf der Zeit, sondern geben die Aktion zum Schließen aller Positionen an und schließen sie alle. Auf diese Weise können wir eine Entsprechung zwischen der abgeschlossenen Aktion, dem neuen Zustand und der Belohnung aufrechterhalten, was für das korrekte Funktionieren des Modells wichtig ist.

   int act = (first_order < MaxLifeTime ? SampleAction(4) : 2);

Somit ist die Verwendung einer maximalen Frist für das Halten einer offenen Position ein weiterer Mechanismus in unserem Modell, der uns hilft, Risiken zu kontrollieren und stabilere Ergebnisse im Falle unsicherer Marktbedingungen zu erzielen.

Wir haben Ansätze zur Optimierung des Algorithmus beschrieben, die auf den während der Modellprüfung festgestellten Mängeln basieren. Nun gehen wir dazu über, das Modell mit einer größeren Menge an historischen Daten zu trainieren. Betrachten wir die Möglichkeit, eine große Trainingsmenge in kleinere Teile aufzuteilen und einen Agenten in jedem dieser Teile zu trainieren. Wir können davon ausgehen, dass ein Algorithmus, der über kleine Zeiträume gut funktioniert, auch über längere Zeiträume gut funktionieren kann. Daher können wir diesen Ansatz nutzen, um die Modellschulung bei großen Datenmengen zu verbessern.

Dieser Ansatz ermöglicht es dem Modell, Markttrends effektiver zu erfassen, und erhöht seine Widerstandsfähigkeit gegenüber Veränderungen der externen Faktoren. Dies ist besonders wichtig, wenn das Modell für den Handel auf realen Märkten verwendet wird, wo die Vorhersage von Trendänderungen entscheidend ist. Darüber hinaus ermöglicht dieser Ansatz dem Modell eine effektivere Nutzung aller verfügbaren Daten und nicht nur der neuesten Beobachtungen, was wiederum die Qualität der Prognosen verbessert.

Es ist wichtig zu beachten, dass die Aufteilung des Trainingssatzes in kleinere Zeiträume unter Berücksichtigung der chronologischen Reihenfolge der Daten erfolgen sollte, um Datenüberschneidungen und Verzerrungen bei der Vorhersage zu vermeiden. Bei der Aufteilung der Daten in kleinere Segmente muss auch berücksichtigt werden, dass die Menge der für das Training verfügbaren Daten in jedem Segment geringer ist, was zu einer Verringerung der Vorhersagegenauigkeit des Modells führen kann.

Die Aufteilung der Trainingsmenge in kleinere Zeitsegmente ist daher ein wirksamer Ansatz zur Optimierung des Algorithmus und kann die Vorhersagequalität des Modells erheblich verbessern.

Wenn wir die Trainingsmenge in kleinere Episoden unterteilen, müssen wir eine allgemeine Strategie entwickeln, die es uns ermöglicht, die gesamte Trainingsmenge erfolgreich zu durchlaufen. Dazu können wir eine Kombination aus Zufallsstichproben und gezieltem Schritt-für-Schritt-Training verwenden, die uns helfen wird, die erfolgreichste und profitabelste Strategie zu finden.

Die Idee besteht darin, kleine Episoden nacheinander durchzuspielen, wobei in jeder Episode eine zufällige Auswahl von Aktionen erfolgt. Dann wählen wir die profitabelsten Durchläufe aus und verwenden sie als Ausgangspunkt für die nächste Episode. Wir gehen also nacheinander die gesamte Trainingsmenge durch und sammeln Beispiele für eine profitable Strategie.

Dieser Ansatz kombiniert scheinbar gegensätzliche Ideen: Zufallsstichproben und gezieltes Training. Mit Hilfe von Zufallsstichproben erkunden wir die Umgebung, und das gezielte Durchlaufen der Trainingsstichprobe hilft uns, die erfolgreichste Strategie zu finden. Als Ergebnis können wir eine allgemeinere und profitablere Strategie für unseren Agenten entwickeln.

Die Kombination von Zufallsstichproben und gezieltem Training ermöglicht es uns, die optimale Strategie für das Bestehen der Trainingsstichprobe zu finden, indem wir sowohl den Zufall als auch die bereits gesammelten Erfahrungen mit erfolgreichen Aktionen nutzen.

Um diesen Ansatz umzusetzen, werden wir 3 externe Variablen einführen:

  • MinStartSteps — Mindestanzahl von Schritten vor Beginn der Stichprobe
  • MaxSteps — Höchstzahl von Schritten in der Stichprobe (Schrittweite)
  • MinProfit — Mindestgewinn für die Speicherung in der Beispieldatenbank.

input int                  MinStartSteps = 96;
input int                  MaxSteps = 120;
input double               MinProfit = 10;

Bei der Diskussion über die Optimierung von Algorithmen haben wir festgestellt, dass das Sortieren von Beispielen vor dem Speichern ineffizient ist. Stattdessen haben wir beschlossen, die Variable MinProfit zu verwenden, um den Mindestgewinn zu bestimmen, der für die Aufnahme von Beispielen in die Datenbank erforderlich ist. Auf diese Weise können wir die Beispiele priorisieren, die als Ausgangspunkte für die nachfolgenden Stichproben verwendet werden. Zusätzlich verwenden wir die Variable MinStartSteps, um die Mindestanzahl von Schritten im Beispiel festzulegen, die erforderlich ist, um es als Ausgangspunkt zu verwenden. So können wir vermeiden, dass wir bei der Probenahme in Zwischenschritten stecken bleiben und zur nächsten Episode übergehen.

Wir verwenden auch die Variable MaxSteps, die die maximale Episodenlänge bestimmt. Sobald dieser Wert überschritten wird, ist das Sampling nicht mehr effektiv und wir müssen den verwendeten Pfad speichern. Auf diese Weise können wir die Ressourcen effizienter nutzen und das Training beschleunigen.

In der Methode OnInit des EA Faza1.mq5 werden nach dem Laden der zuvor erstellten Beispieldatenbank zunächst Beispiele ausgewählt, die die Anforderung an die Anzahl der absolvierten Schritte erfüllen.

   if(LoadTotalBase())
     {
      int total = ArraySize(Total);
      Cell temp[];
      ArrayResize(temp, total);
      int count = 0;
      for(int i = 0; i < total; i++)
         if(Total[i].total_actions >= MinStartSteps)
           {
            temp[count] = Total[i];
            count++;
           }

Wählen Sie dann aus den ausgewählten Beispielen ein Beispiel nach dem Zufallsprinzip aus. Dieses nach dem Zufallsprinzip ausgewählte Beispiel wird als Ausgangspunkt für die Stichprobe verwendet.

      if(count > 0)
        {
         count = (int)(((double)(MathRand() * MathRand()) / MathPow(32768.0, 2.0)) * (count - 1));
         StartCell = temp[count];
        }
      else
        {
         count = (int)(((double)(MathRand() * MathRand()) / MathPow(32768.0, 2.0)) * (total - 1));
         StartCell = Total[count];
        }
     }

In der Methode OnTick unseres EAs führen wir zunächst den gesamten Pfad bedingungslos aus, bis wir den Startpunkt unserer Episode erreichen.

void OnTick()
  {
//---
   if(!IsNewBar())
      return;
   bar++;
   if(bar < StartCell.total_actions)
     {
      switch(StartCell.actions[bar])
        {
         case 0:
            Trade.Buy(Symb.LotsMin(), Symb.Name());
            break;
         case 1:
            Trade.Sell(Symb.LotsMin(), Symb.Name());
            break;
         case 2:
            for(int i = PositionsTotal() - 1; i >= 0; i--)
               if(PositionGetSymbol(i) == Symb.Name())
                  Trade.PositionClose(PositionGetInteger(POSITION_IDENTIFIER));
            break;
        }
      return;
     }

Wir gehen erst nach dem Beginn unserer Episode zu den Aktionsprobenahmen über. Gleichzeitig kontrollieren wir die Anzahl der durchgeführten Zufallsaktionen. Ihre Anzahl sollte die maximale Episodenlänge nicht überschreiten.

Wenn die maximale Anzahl von Schritten erreicht ist, wird zunächst eine Aktion zur Schließung aller Positionen durchgeführt.

   int act = (action_count < MaxSteps || first_order < MaxLifeTime ? SampleAction(4) : 2);

Nach einem Zug leiten wir das Ende der Arbeit des EA ein.

   if(action_count > MaxSteps)
      ExpertRemove();

Nach Abschluss dem Durchlauf im Strategietester überprüfen wir die Höhe des Gewinns, den wir durch den Durchlauf erhalten haben. Wenn die Bedingung des Erreichens der Mindestrentabilitätsschwelle erfüllt ist, übertragen wir die Daten, die in die Beispieldatenbank aufgenommen werden sollen.

//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret = 0.0;
//---
   double profit = TesterStatistics(STAT_PROFIT);
   action_count--;
   if(profit >= MinProfit)
      FrameAdd(MQLInfoString(MQL_PROGRAM_NAME), action_count, profit, Base);
//---
   return(ret);
  }

Hier werden nur geringfügige Änderungen am EA-Code, der im vorherigen Artikel ausführlich beschrieben wurde, vorgenommen und erläutert. Der vollständige Code des EAs befindet sich im Anhang.


3. Test

Wie im vorangegangenen Artikel werden wir Beispiele für das Training des Modells anhand historischer Daten zum EURUSD H1 sammeln. Dieses Mal werden wir jedoch historische Daten für 4 Monate des Jahres 2023 verwenden.

Traingszeit

Um die Umwelt möglichst effektiv zu erforschen, ist es notwendig, bei der Stichprobe eine Vielzahl externer Parameterwerte zu verwenden. In diesem Fall werden wir diese Parameter als optimierte Parameter verwenden, die es uns ermöglichen, ihre Werte für jeden Durchgang zu ändern.

Um den Optimierungsprozess zu beginnen, wählen wir zwei Parameter: MaxSteps und MaxLifeTime. Der erste Parameter bestimmt die maximale Länge einer Episode, nach der das Sammeln von Beispielen unwirksam wird. Der zweite Parameter gibt den maximalen Zeitraum an, in dem eine Position in einer Episode gehalten werden kann. Durch die Verwendung unterschiedlicher Werte für diese Parameter bei der Sammlung von Beispielen können wir die Umwelt so umfassend wie möglich untersuchen.

Durch die Verwendung der unterschiedlichen Werte für MaxSteps und MaxLifeTime können wir zum Beispiel Beispiele für unterschiedliche Dauer und Zeiträume des Positionshaltens sammeln. Auf diese Weise erhalten wir Beispiele für eine Vielzahl von Situationen, die in der Umwelt auftreten können. Auf diese Weise können wir ein universelleres und effektiveres Schulungsmodell erstellen, das viele verschiedene Szenarien berücksichtigt.

Parameter des ersten Optimierungsdurchgangs

Wir setzen den Schwellenwert für den Gewinn nahe bei 0 an. Schließlich ist dies der erste Durchgang und wir müssen nur einen kleinen Gewinn erzielen.

Als Ergebnis des ersten Durchgangs des Optimierungsprozesses sehen wir mehrere erfolgreiche Durchgänge, die in den ersten zwei Wochen des Januar 2023 einen Gewinn von 46 USD erreichen. Der Gewinnfaktor solcher Durchläufe erreicht 1,55

Erste Optimierungsergebnisse

Bevor wir die Optimierung durchführen, werden wir einige Änderungen an den Parametern vornehmen. Um sicherzustellen, dass Beispiele in unterschiedlichen Zeitintervallen gesammelt werden, fügen wir unserer optimierten Variable eine Mindestanzahl von Schritten hinzu, bevor die Stichprobe beginnt. Die Werte für diese Variable variieren von 1 bis 3 Wochen in wöchentlichen Abständen. Darüber hinaus werden wir die Ergebnisse verbessern, indem wir die Gewinnschwelle auf 40 USD anheben.

Parameter für den zweiten Optimierungsdurchgang

Auf der Grundlage der Ergebnisse des zweiten Optimierungsdurchgangs sehen wir für Januar 2023 einen Anstieg des Gewinns auf 84 USD. Obwohl der Gewinnfaktor auf 1,38 gesunken ist.

Ergebnisse des zweiten Optimierungsdurchgangs

Trotzdem sehen wir, dass unsere Bemühungen zur Optimierung der Stichprobe erste Früchte tragen. Obwohl wir noch keinen endgültigen Erfolg erzielt haben, entspricht der allgemeine Trend der Ereignisse unseren Zielen und Erwartungen. 

Erhöhen wir die Mindestanzahl der Schritte, bevor die Stichprobe in der zweiten Januarwoche 2023 beginnt, und führen wir einen weiteren Optimierungsprozess durch. Dieses Mal werden wir die Mindestrentabilität auf 80 USD erhöhen. Schließlich sind wir bestrebt, die profitabelste Strategie zu finden.

Parameter für den dritten Optimierungsdurchgang

Wie erwartet haben wir durch die nachträgliche Optimierung des Beispielsammelprozesses eine noch höhere Rentabilität erreicht. Das Gesamteinkommen des erfolgreichsten Durchlaufs ist auf 125 USD gestiegen. Gleichzeitig ging der Gewinnfaktor leicht zurück und lag bei 1,36, was immer noch bedeutet, dass die Gewinne die Kosten übersteigen. Es ist wichtig, darauf hinzuweisen, dass diese Rentabilitätssteigerung durch Verbesserungen bei der Sammlung von Beispielen erreicht wurde, und wir können von ihrer Wirksamkeit überzeugt sein. Es ist jedoch wichtig zu bedenken, dass der Lernprozess noch nicht abgeschlossen ist und wir ihn fortsetzen werden.

Ergebnisse des dritten Optimierungsdurchgangs

Wir setzten das Sammeln von Beispielen im Optimierungsmodus des Strategietesters fort, indem wir den Startpunkt der Stichprobenziehung und die Gewinnschwelle nach und nach veränderten. Auf diese Weise konnten wir Beispiele für mehrere erfolgreiche Durchläufe durch die gesamte Trainingsmenge erhalten. Die profitabelsten von ihnen brachten 281 USD an Einnahmen bei einem Gewinnfaktor von 1,5. Diese Ergebnisse bestätigen, dass sich unsere Strategie zur Optimierung des Sammelprozesses positiv auswirkt und dazu beiträgt, höhere Gewinnspannen zu erzielen. Wir sind uns jedoch bewusst, dass der Prozess noch nicht abgeschlossen ist und weiterer Optimierung und Verbesserung bedarf.

Ergebnisse der Sammlung von Beispielen

Sobald das Sammlen von Beispielen abgeschlossen ist, wird das Modell mit Hilfe des Algorithmus Go-Explore auf der Grundlage der gewonnenen Daten trainiert. Anschließend trainieren wir das Modell mit Hilfe von Verstärkungstrainingsmethoden neu, um seine Leistung weiter zu verbessern.

Um die Qualität und Effizienz des trainierten Modells zu überprüfen, testen wir es an Trainings- und Testproben. Es ist wichtig anzumerken, dass unser Modell in der Lage war, mit den historischen Daten der ersten Maiwoche 2023, die nicht im Trainingssatz enthalten waren, sondern direkt darauf folgten, einen Gewinn zu erzielen.

Prüfmuster (Mai 2023) Testmuster (Mai 2023)


Schlussfolgerung

In diesem Artikel haben wir uns mit einfachen, aber effektiven Methoden zur Optimierung des Algorithmus Go-Explore befasst, die es ermöglichen, ihn für das Training von Modellen mit großen Mengen an Trainingsdaten einzusetzen. Unser Modell wurde auf der Grundlage von 4 Monaten historischer Daten trainiert, aber dank der Verwendung von Optimierungsmethoden kann der Go-Explore-Algorithmus auch für das Training von Modellen über längere Zeiträume verwendet werden. Wir haben das Modell auch an Trainings- und Testproben getestet, was seine hohe Effizienz und Qualität bestätigte.

Insgesamt eröffnet der Go-Explore-Algorithmus neue Möglichkeiten für das Training von Modellen auf Big Data und kann zu einem leistungsstarken Werkzeug für verschiedene Anwendungen im Bereich der künstlichen Intelligenz werden.

Es ist jedoch zu bedenken, dass die Finanzmärkte sehr dynamisch sind und plötzlichen Veränderungen unterliegen, sodass selbst das beste Modell keine 100%ige Erfolgsgarantie bieten kann. Deshalb müssen wir die Veränderungen auf dem Markt ständig beobachten und unser Modell entsprechend anpassen.


Links

  1. Go-Explore: a New Approach for Hard-Exploration Problems
  2. Neuronale Netze leicht gemacht (Teil 35): Modul für intrinsische Neugierde
  3. Neuronale Netze leicht gemacht (Teil 36): Relationales Verstärkungslernen
  4. Neuronale Netze leicht gemacht (Teil 37): Sparse Attention (Verringerte Aufmerksamkeit)
  5. Neuronale Netze leicht gemacht (Teil 38): Selbstüberwachte Erkundung bei Unstimmigkeit (Self-Supervised Exploration via Disagreement)
  6. Neuronale Netze leicht gemacht (Teil 39): Go-Explore, ein anderer Ansatz der Erkundung

Programme, die im diesem Artikel verwendet werden

# Name Typ Beschreibung
1 Faza1.mq5 Expert Advisor Erste Phase EA
2 Faza2.mql5 Expert Advisor Zweite Phase EA
3 GE-lerning.mq5 Expert Advisor Feinabstimmung der Politik EA
4 Cell.mqh Klassenbibliothek Struktur der Systemzustandsbeschreibung
5 FQF.mqh Klassenbibliothek Klassenbibliothek zur Organisation der Arbeit eines vollständig parametrisierten Modells
6 NeuroNet.mqh Klassenbibliothek Eine Bibliothek von Klassen zur Erstellung eines neuronalen Netzes
7 NeuroNet.cl Code Base Die Bibliothek des Programmcodes von OpenCL

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

Beigefügte Dateien |
MQL5.zip (90.76 KB)
Neuronale Netze leicht gemacht (Teil 41): Hierarchische Modelle Neuronale Netze leicht gemacht (Teil 41): Hierarchische Modelle
Der Artikel beschreibt hierarchische Trainingsmodelle, die einen effektiven Ansatz für die Lösung komplexer maschineller Lernprobleme bieten. Hierarchische Modelle bestehen aus mehreren Ebenen, von denen jede für verschiedene Aspekte der Aufgabe zuständig ist.
Neuronale Netze leicht gemacht (Teil 39): Go-Explore, ein anderer Ansatz zur Erkundung Neuronale Netze leicht gemacht (Teil 39): Go-Explore, ein anderer Ansatz zur Erkundung
Wir setzen die Untersuchung der Umgebung in Modellen des verstärkten Lernens fort. Und in diesem Artikel werden wir uns einen weiteren Algorithmus ansehen – Go-Explore. Er ermöglicht es Ihnen, die Umgebung in der Phase der Modellbildung effektiv zu erkunden.
Neuronale Netze leicht gemacht (Teil 42): Modell der Prokrastination, Ursachen und Lösungen Neuronale Netze leicht gemacht (Teil 42): Modell der Prokrastination, Ursachen und Lösungen
Im Kontext des Verstärkungslernens kann die Prokrastination (Zögern) eines Modells mehrere Ursachen haben. Der Artikel befasst sich mit einigen der möglichen Ursachen für Prokrastination bei Modellen und mit Methoden zu deren Überwindung.
Entwicklung eines Replay-Systems — Marktsimulation (Teil 08): Sperren des Indikators Entwicklung eines Replay-Systems — Marktsimulation (Teil 08): Sperren des Indikators
In diesem Artikel werden wir uns ansehen, wie man den Indikator sperren kann, indem man einfach die Sprache MQL5 verwendet, und zwar auf eine sehr interessante und erstaunliche Weise.