English
preview
MQL5-Assistent-Techniken, die Sie kennen sollten (Teil 22): Conditional GANs

MQL5-Assistent-Techniken, die Sie kennen sollten (Teil 22): Conditional GANs

MetaTrader 5Handelssysteme | 8 Juli 2024, 11:03
52 0
Stephen Njuki
Stephen Njuki

Einführung

Conditional Generative Adversariale Netze (cGAN) sind eine Art von GAN, die eine Anpassung an die Art der Eingabedaten in ihrem generativen Netzwerk ermöglichen. Wie aus dem gemeinsamen Link und der Lektüre des Themas hervorgeht, handelt es sich bei GANs um ein Paar neuronaler Netze: einen Generator und einen Diskriminator. Beide werden trainiert oder trainieren sich gegenseitig, wobei der Generator die Erzeugung einer Zielausgabe verbessert, während der Diskriminator auf die Identifizierung von Daten (auch bekannt als die gefälschten Daten) vom Generator trainiert wird.

Die Anwendung ist typischerweise in der Bildanalyse, wo ein Generator-Netzwerk verwendet wird, um Bilder zu erzeugen, und das Diskriminator-Netzwerk identifiziert, ob das Bild, das es als Eingabe erhält, entweder vom Generator-Netzwerk erfunden wurde oder real ist. Das gegenseitige Training erfolgt, indem die Bilder des Diskriminator-Generators abwechselnd mit realen Bildern gefüttert werden und, wie in jedem Netzwerk, würde Backpropagation die Gewichte des Diskriminators entsprechend anpassen. Der Generator hingegen wird bei nicht bedingten oder typischen Einstellungen mit zufälligen Eingangsdaten gefüttert und soll unabhängig davon möglichst realistische Bilder erzeugen.

Bei einem Conditional GAN (cGAN) nehmen wir eine kleine Änderung vor, indem wir das generative Netz mit einer bestimmten Art von Daten als Eingabe füttern und nicht mit Zufallsdaten. Dies ist anwendbar oder nützlich in Situationen, in denen die Art der Daten, die wir dem Diskriminator zuführen, gepaart ist oder aus zwei Teilen besteht und das Ziel des Diskriminator-Netzwerks darin besteht, zu erkennen, ob die eingegebenen gepaarten Daten gültig oder erfunden sind.

Die meisten Anwendungen von GAN und cGAN scheinen in der Bilderkennung oder -verarbeitung zu liegen, aber in diesem Artikel untersuchen wir, wie ein sehr einfaches Modell für die Vorhersage von Finanzzeitreihen mit ihnen aufgebaut werden kann. Wie bereits im Titel erwähnt, werden wir ein cGAN im Gegensatz zu einem GAN verwenden. Um den Unterschied zwischen diesen beiden zu verdeutlichen, können wir die beiden folgenden Diagramme betrachten:

Quelle



Quelle

Beide Bilder, deren Links oben angegeben sind, zeigen Aufbauten, bei denen der Ausgang eines Generatornetzes zu Test- oder Prüfzwecken in ein Diskriminatornetz eingespeist wird. GANs sind insofern kontraproduktiv, als der Generator darauf trainiert wird, den Diskriminator besser zu täuschen, während der Diskriminator darauf trainiert wird, den Generator-Output aus realen oder Nicht-Generator-Netzwerkdaten zu erkennen. Der Hauptunterschied zwischen diesen beiden Ansätzen besteht darin, dass bei GANs das Generatornetz zufällige Eingabedaten nimmt und diese verwendet, um Daten zu erzeugen, die der Diskriminator nicht von echten Daten unterscheiden kann. Für unsere Zwecke der finanziellen Zeitreihenprognose ist dies nur begrenzt anwendbar und nützlich.

Beim cGAN handelt es sich jedoch bei dem, was im Diagramm als Rauschen bezeichnet wird, im Wesentlichen um unabhängige Daten oder um Daten, für die der Generator versucht, ein Label zu generieren (in unserem Anpassungsfall). Wir geben keine Bezeichnungen in das Generatornetzwerk ein, wie im obigen Diagramm dargestellt, aber das Diskriminatornetzwerk empfängt ein Datenpaar aus Rauschen (oder unabhängigen Daten) und der entsprechenden Bezeichnung und versucht dann zu erkennen, ob dieses Paar aus echten Daten stammt oder ob die Bezeichnung, die den unabhängigen Daten zugewiesen wurde, von einem Generator stammt.

Was sind die Vorteile von cGAN für die Prognose von Finanzzeitreihen? Wie man so schön sagt, liegt der Beweis im Ergebnis, weshalb wir gegen Ende dieses Artikels einige Tests durchführen werden, wie es üblich ist. In der Bilderkennung haben GANs jedoch sicherlich eine gewisse Schlagkraft, auch wenn sie nicht so gut abschneiden wie CNNs oder ViTs aufgrund ihres Rechenaufwands. Berichten zufolge sind sie jedoch besser in der Bildsynthese und -vergrößerung.


Einrichten der Umgebung

Zum Aufbau unseres cGAN-Modells verwenden wir das mehrschichtige Perzeptron-Netzwerk, in diesem Artikel als Basisklasse vorgestellt wurde. Diese Basisklasse stellt alle „Werkzeuge und Bibliotheken“ dar, die wir benötigen, um unser cGAN zum Laufen zu bringen, da sowohl das Generatornetz als auch das Diskriminatornetz einfach wie Instanzen eines mehrschichtigen Perzeptrons behandelt werden. Diese Basisklasse hat lediglich 2 Hauptfunktionen: die Vorwärtsmethode „Forward()“ und die Rückwärtsfunktion „Backward()“. Es gibt natürlich den Klassenkonstruktor, der die Einstellungen des Netzes übernimmt, und einige Haushaltsmethoden, die es ermöglichen, die trainierten Gewichte als Datei zu speichern, sowie einige andere Funktionen, die Trainingsziele setzen und Feed-Forward-Ergebnisse lesen.

Obwohl wir unsere typische mehrschichtige Perceptron-Basisklasse für dieses cGAN verwenden, müssen wir einige GAN-spezifische Änderungen in der Art und Weise vornehmen, wie das generative Netz seine Backpropagation durchführt oder lernt. Der Verlustgenerator lässt sich anhand der folgenden Formel berechnen:

−log(D(G(zy)y))

wobei:

  • D() ist die Ausgangsfunktion des Diskriminators.
  • G() ist die Ausgangsfunktion des Generators.
  • .z sind die unabhängigen Daten
  • y sind die abhängigen Daten oder die gekennzeichneten oder Prognosedaten.

Dieser Wert des Verlustgenerators, der je nach Größe der Ausgabe typischerweise in Vektorform vorliegt, dient also als Gewichtung des Fehlerwerts aus jedem Vorwärtsdurchlauf, wenn der Rückwärtsdurchgang gestartet wird. Wir nehmen diese Änderungen in unserer Netzklasse wie folgt vor:

//+------------------------------------------------------------------+
//| Backward pass through the neural network to update weights       |
//| and biases using gradient descent                                |
//+------------------------------------------------------------------+
void Cgan::Backward(vector<double> &DiscriminatorOutput, double LearningRate = 0.05)
{  if(target.Size() != output.Size())
   {  printf(__FUNCSIG__ + " Target & output size should match. ");
      return;
   }
   if(ArraySize(weights) != hidden_layers + 1)
   {  printf(__FUNCSIG__ + " weights matrix array size should be: " + IntegerToString(hidden_layers + 1));
      return;
   }

        ...

// Update output layer weights and biases
   vector _output_error = -1.0*MathLog(DiscriminatorOutput)*(target - output);//solo modification for GAN
   Back(_output_error, LearningRate);
}

Unsere Funktion „Backward ()“ wird überladen, da eine Variante typischerweise die Diskriminatorausgabe als Eingabe nimmt und beide überladenen Funktionen dann eine „Back()“-Funktion aufrufen, die im Wesentlichen den meisten Code enthält, den wir in der alten Backpropagation-Funktion hatten, und hier eingeführt wird, um Doppelarbeit zu vermeiden. Durch diese Gewichtung wird jedoch sichergestellt, dass wir beim Training des Generators nicht nur besser darin werden, die nächste nahe Preisänderung vorherzusagen, sondern auch darin, den Diskriminator zu täuschen, damit er glaubt, dass die Daten des Generators echt sind. In der Zwischenzeit trainiert der Diskriminator „in die entgegengesetzte Richtung“, indem er versucht, gut darin zu sein, Generatordaten von den echten Daten zu unterscheiden.

Wenn wir dagegen diese Einrichtung in einer Anwendung eines Drittanbieters implementieren würden, würden wir ein ähnliches Netzwerk mit Tensor-Fflow  in Python müsste jede Schicht mit einem separaten Befehl oder einer Codezeile hinzugefügt werden. Diese Python-Option bietet natürlich mehr Anpassungsmöglichkeiten, die unsere Basisklasse nicht bietet, aber als Prototyping-Tool, um cGANs in der MQL5-Umgebung auszuprobieren, sollte sie nicht die bevorzugte Wahl sein. Ganz zu schweigen davon, dass die Verwendung von Python und einer seiner Bibliotheken für neuronale Netze das Vorhandensein von „Adaptern“ wie ONNX oder eine äquivalente, nutzerdefinierte Implementierung, die es ermöglicht, Trainingsergebnisse zurück nach MQL5 zu exportieren. Diese haben sicherlich ihre Vorteile, wenn das Modell so konzipiert ist, dass es einmal in der Entwicklung trainiert und dann eingesetzt wird, oder dass es regelmäßig trainiert wird, aber offline (nicht im Einsatz).

In Szenarien, in denen das Training eines neuronalen Netzes live oder während des Einsatzes durchgeführt werden muss, können die vielen „Adapter“ zu und von Python unhandlich werden, obwohl es immer noch möglich ist.


Entwurf der nutzerdefinierten Signalklasse

Signalklassen verfügen, wie wir in der Serie gesehen haben, über Standardfunktionen zur Initialisierung, Validierung und Bewertung von Marktbedingungen. Darüber hinaus kann eine unbegrenzte Anzahl von Funktionen hinzugefügt werden, um das eigene Signal anzupassen, sei es mit einem nutzerdefinierten Indikator oder einer Kombination von typischen Indikatoren, die bereits in der MQL5-Bibliothek verfügbar sind. Da wir einen cGAN bauen, der auf mehrschichtigen Perceptrons basiert, werden wir mit einer zusätzlichen Anzahl von Funktionen beginnen, ähnlich denen, die wir in diesem früheren Artikel, in dem ebenfalls unsere Perceptron-Basisklasse verwendet wurde.

Dies sind die Funktionen „GetOutput()“, „Setoutput()“ und „Norm()“. Ihre Rolle wird hier sehr ähnlich zu der sein, die wir in diesem früheren Artikel hatten, indem die get-Funktion die Ankerfunktion sein wird, die für die Bestimmung der Marktbedingungen verantwortlich ist, während die set-Funktion, wie zuvor, zur Verfügung stehen wird, um die Netzwerkgewichte nach jedem Trainingsdurchgang zu schreiben, während die norm-Funktion die entscheidende Rolle der Normalisierung unserer Eingabedaten vor der Weiterleitung spielt.

Für die nutzerdefinierte Signalklasse cGAN führen wir 3 neue Funktionen ein, die mit der Trennung der Verarbeitung des Generatornetzes vom Diskriminatornetz zu tun haben.

Die Architektur des generativen Netzes ist willkürlich gewählt und besteht aus 7 Schichten, darunter eine Eingabeschicht, 5 versteckte Schichten und eine Ausgabeschicht. Dies lässt sich mit einer neuronalen Architektursuche ermitteln, die wir uns in diesem Artikel behandelt haben, aber für unsere Zwecke hier reichen diese Annahmen aus, um ein cGAN zu demonstrieren. Diese Netzwerkeinstellungen werden in einem Array „settings“ definiert, das wir zur Initialisierung einer Instanz einer Netzwerkklasse verwenden, die wir „GEN“ nennen.

Unser generatives Netzwerk hat frühere Änderungen des Schlusskurses als Eingaben und eine einzige prognostizierte Änderung des Schlusskurses als Ausgabe. Dies unterscheidet sich nicht sehr von der Implementierung, die wir bei der Suche in der neuronalen Architektur in dem bereits erwähnten Artikel gesehen haben. Die Output-Prognose ist die Änderung des Schlusskurses, die sich aus den 4 Änderungen ergibt, die als Input dienen.

Die Verknüpfung dieser 4 früheren Änderungen mit dem Prognosewert bildet also die Eingabedaten für das Diskriminatornetz, das wir uns später ansehen werden. Die von uns verwendete Netzwerk-Basisklasse führt ihre Aktivierung durch Softplus durch, das fest eingestellt ist. Da der vollständige Quelltext zur Verfügung gestellt wird, können die Leser diesen leicht an ihre eigenen Bedürfnisse anpassen. Die einzigen einstellbaren Parameter für unsere Signalklasse sind daher die Lernrate, die Anzahl der Trainingsepochen und die Größe des Trainingsdatensatzes. Diesen werden die Namen „m_learning_rate“, „m_epochs“ bzw. „m_train_set“ zugewiesen. Mit der Funktion „get output“ werden die Eingabedaten des Netzes geladen und das Netz auf jeden neuen Balken trainiert:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CSignalCGAN::GetOutput(double &GenOut, bool &DisOut)
{  GenOut = 0.0;
   DisOut = false;
   for(int i = m_epochs; i >= 0; i--)
   {  for(int ii = m_train_set; ii >= 0; ii--)
      {  vector _in, _out;
         vector _in_new, _out_new, _in_old, _out_old;
         _in_new.CopyRates(m_symbol.Name(), m_period, 8, ii + 1, __GEN_INPUTS);
         _in_old.CopyRates(m_symbol.Name(), m_period, 8, ii + 1 + 1, __GEN_INPUTS);
         _in = Norm(_in_new, _in_old);
         GEN.Set(_in);
         GEN.Forward();
         if(ii > 0)// train
         {  _out_new.CopyRates(m_symbol.Name(), m_period, 8, ii, __GEN_OUTPUTS);
            _out_old.CopyRates(m_symbol.Name(), m_period, 8, ii + 1, __GEN_OUTPUTS);
            _out = Norm(_out_new, _out_old);
            
                ...

         }
         else if(ii == 0 && i == 0)
         { 
                ...
         }
      }
   }
}

Unser GAN ist konditional, weil die Eingaben in das Generatornetz nicht zufällig sind und die des Diskriminatornetzes zweifach sind, indem sie die Eingabe in den Generator und dessen Ausgabe erfassen. Die Aufgabe des Diskriminatornetzes besteht also darin, festzustellen, ob seine Eingabedaten aus einer realen Zeitserienfolge von 5 aufeinanderfolgenden Schlusskursänderungen stammen ODER ob es sich um eine Paarung der Dateneingabe des Generatornetzes mit seiner Ausgabe handelt. Mit anderen Worten, sie stellt fest, ob die Eingabedaten „echt“ oder „gefälscht“ sind.

Dies bedeutet, dass die Ausgabe des Diskriminatornetzes sehr einfach ist, nämlich boolesch. Entweder stammen die Eingabedaten vollständig von den Märkten (wahr) oder sie wurden teilweise vom Generator erzeugt (falsch). Wir stellen dies mit 1 bzw. 0 dar, und bei Testläufen nach dem Training ist der zurückgegebene Wert eine Gleitkommazahl zwischen 0,0 und 1,0. Um unser Diskriminator-Netzwerk zu trainieren, füttern wir es also abwechselnd mit realen Schlusskursänderungen in Form von 5 Datenpunkten (d. h. 5 aufeinanderfolgenden Änderungen) und 5 weiteren Schlusskursänderungen, von denen nur 4 real sind und die 5. die Prognose des Generator-Netzwerks darstellt. Das Training mit realen Daten wird zum Teil von der R-Funktion übernommen, deren Code unten zu sehen ist:

//+------------------------------------------------------------------+
//| Process Real Data in Discriminator                               |
//+------------------------------------------------------------------+
void CSignalCGAN::R(vector &IN, vector &OUT)
{  vector _out_r, _out_real, _in_real;
   _out_r.Copy(OUT);
   _in_real.Copy(IN);
   Sum(_in_real, _out_r);
   DIS.Set(_in_real);
   DIS.Forward();
   _out_real.Resize(__DIS_OUTPUTS);
   _out_real.Fill(1.0);
   DIS.Get(_out_real);
   DIS.Backward(m_learning_rate);
}

und für das Training der gefälschten Daten die Funktion „F“, deren Code hier ebenfalls angegeben ist:

//+------------------------------------------------------------------+
//| Process Fake Data in Discriminator                               |
//+------------------------------------------------------------------+
void CSignalCGAN::F(vector &IN, vector &OUT)
{  vector _out_f, _out_fake, _in_fake;
   _out_f.Copy(OUT);
   _in_fake.Copy(IN);
   Sum(_in_fake, _out_f);
   DIS.Set(_in_fake);
   DIS.Forward();
   _out_fake.Resize(__DIS_OUTPUTS);
   _out_fake.Fill(0.0);
   DIS.Get(_out_fake);
   DIS.Backward(m_learning_rate);
}

Diese beiden Funktionen werden innerhalb der Funktion „get output“ aufgerufen, wie unten dargestellt:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CSignalCGAN::GetOutput(double &GenOut, bool &DisOut)
{  GenOut = 0.0;
   DisOut = false;
   for(int i = m_epochs; i >= 0; i--)
   {  for(int ii = m_train_set; ii >= 0; ii--)
      {  
                ...

         if(ii > 0)// train
         {  _out_new.CopyRates(m_symbol.Name(), m_period, 8, ii, __GEN_OUTPUTS);
            _out_old.CopyRates(m_symbol.Name(), m_period, 8, ii + 1, __GEN_OUTPUTS);
            _out = Norm(_out_new, _out_old);
            //
            int _dis_sort = MathRand()%2;
            if(_dis_sort == 0)
            {  F(_in, GEN.output);
               GEN.Get(_out);
               GEN.Backward(DIS.output, m_learning_rate);
               R(_in, _out);
            }
            else if(_dis_sort == 1)
            {  R(_in, _out);
               GEN.Get(_out);
               GEN.Backward(DIS.output, m_learning_rate);
               F(_in, GEN.output);
            }
         }
         else if(ii == 0 && i == 0)
         {  GenOut = GEN.output[0];
            DisOut = (((DIS.output[0] >= 0.5 && GenOut >= 0.5)||(DIS.output[0] < 0.5 && GenOut < 0.5)) ? true : false);
         }
      }
   }
}

Wir verwenden die Funktion „Sum“, um 4 Schlusskursänderungen entweder mit der nächsten Schlusskursänderung zu verknüpfen, wenn wir an echten Daten interessiert sind, oder mit der Prognose des Generators, wenn wir an „gefälschten“ Daten interessiert sind. Nach einem weiteren Training wird der Generator also, wie man es von jedem Perzeptron erwarten würde, besser in der Lage sein, Prognosen zu erstellen, die wir dann bei der Bewertung der Marktbedingungen verwenden können. Aber was machen wir dann mit den Trainingsbemühungen des Diskriminators?

Wie bereits erwähnt, trägt das Training dazu bei, die Gewichte des Generatorennetzes zu schärfen, da wir das Gewicht des Verlustgenerators verwenden, um den Verlustwert anzupassen, der bei der Backpropagierung des Generatorennetzes verwendet wird. Zweitens kann der Diskriminator auch nach dem Training und dem Einsatz des Netzes noch zur Überprüfung der Generatorprognosen verwendet werden. Wenn nicht festgestellt werden kann, dass sie sich in der Nähe des Generators befinden, dient dies als Bestätigung dafür, dass unser Generatorennetzwerk seine Aufgabe gut erfüllt.


Integration von cGAN mit der Signalklasse MQL5

Damit dies in einer Signalklasse funktioniert, müssen wir die langen und kurzen Bedingungsfunktionen so kodieren, dass sie die Funktion „GetOutput()“ aufrufen, die 2 Dinge zurückgibt. Die geschätzte Änderung des Schlusskurses, die durch die double-Variable „GenOut“ erfasst wird, und die boolesche Variable „DisOut“, die angibt, ob diese Änderung der Schlusskursvorhersage das Diskriminatornetz täuschen konnte oder nicht. Es steht dem Leser frei, Konfigurationen auszuprobieren, bei denen nur die Ausgabe des Generators zur Bestimmung der Marktbedingungen herangezogen wird, wie dies typischerweise bei der Bilderzeugung der Fall ist, die die häufigste Anwendung von GANs ist. Die Überprüfung dieser Vorhersagen durch das Diskriminatorennetz ist jedoch ein zusätzlicher Sicherheitsschritt bei der Bewertung der Bedingungen, und deshalb ist sie hier enthalten.

Die Eingabewerte des Netzes sind alle auf einen Wert zwischen -1,0 und +1,0 normiert, und ebenso würden wir erwarten, dass die Ausgaben größtenteils in einem ähnlichen Bereich liegen. Das bedeutet, dass unser Generator eine prognostizierte, prozentuale Veränderung des Schlusskurses liefert. Da es sich um Prozentsätze handelt, können wir sie mit 100 multiplizieren, um einen Wert zu erhalten, der 100 nicht überschreitet. Das Vorzeichen dieses Wertes, ob positiv oder negativ, würde darauf hinweisen, ob wir kaufen oder verkaufen sollten. Um also Bedingungen zu verarbeiten und eine ganzzahlige Ausgabe im Bereich von 0 bis 100 zu erhalten, wie es von den langen und kurzen Bedingungsfunktionen erwartet wird, haben wir unsere langen Bedingungsfunktionen wie unten angegeben:

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CSignalCGAN::LongCondition(void)
{  int result = 0;
   double _gen_out = 0.0;
   bool _dis_out = false;
   GetOutput(_gen_out, _dis_out);
   _gen_out *= 100.0;
   if(_dis_out && _gen_out > 50.0)
   {  result = int(_gen_out);
   }
   //printf(__FUNCSIG__ + " generator output is: %.5f, which is backed by discriminator as: %s", _gen_out, string(_dis_out));
   return(result);
}

Die kurze Bedingung ist sehr ähnlich, mit der Ausnahme, dass der prognostizierte Prozentsatz negativ sein muss, damit dem Ergebnis ein Wert ungleich Null zugewiesen wird, und dass dieser Wert der absolute Betrag des prognostizierten Prozentsatzes nach Multiplikation mit 100 ist.


Tests und Validierung

Wenn wir Testläufe mit einem Expert Advisor durchführen, der über den MQL5-Assistenten zusammengestellt wurde (Richtlinien hierfür finden Sie hier und hier), erhalten wir in einem der Läufe die folgenden Ergebnisse:

r2

c2

Bei der Verarbeitung der Signale, um diese Läufe zu erhalten, wird die Reihenfolge, in der das Diskriminatornetz trainiert wird, randomisiert, d. h. manchmal trainieren wir zuerst mit echten Daten und manchmal zuerst mit gefälschten Daten. Dadurch wird das Diskriminatornetzwerk nicht immer nur zu einer Seite geneigt, wie z. B. nur kaufen oder nur verkaufen, da eine strenge Testreihenfolge das Diskriminatornetzwerk verzerrt. Und wie bereits erwähnt, ist für die typische Verwendung von GANs keine Überprüfung des Diskriminatorennetzes erforderlich, wir haben uns hier nur entschieden, dies zu übernehmen, um sorgfältiger zu sein.

Aufgrund dieser zusätzlichen Verifizierung sind unsere Ergebnisse nicht ohne weiteres bei jedem Testlauf wiederholbar, vor allem, weil unsere Netzwerkarchitektur sehr klein ist, da wir nur 5 versteckte Schichten und jede mit einer Größe von nur 5 verwendet haben. Wenn man mit dieser Überprüfung durch das Diskriminatornetz konsistentere Ergebnisse anstrebt, sollte man Netze mit 5 - 25 versteckten Schichten trainieren, wobei die Größe der einzelnen Schichten wahrscheinlich nicht unter 100 liegen sollte. Eher die Größe der Schichten als die Anzahl der Schichten ist ein Schlüsselfaktor für zuverlässigere Netzwerkergebnisse.

Wenn wir jedoch auf die Überprüfung des Diskriminatorennetzes verzichten, dann sollte unser Netz weniger unbeständige Testergebnisse liefern, wenn auch mit einigen Leistungseinbußen. Ein Kompromiss könnte darin bestehen, einen zusätzlichen Eingabeparameter hinzuzufügen, mit dem der Nutzer wählen kann, ob die Überprüfung des Diskriminatornetzwerks eingeschaltet ist oder nicht.


Schlussfolgerung

Zusammenfassend haben wir gesehen, wie Conditional Generative Adversarial Networks (cGANs) zu einer nutzerdefinierten Signalklasse entwickelt werden können, die dank des MQL5-Assistenten in einen Expert Advisor eingebaut werden kann. Das cGAN ist eine Abwandlung des GAN, da es beim Training des Generatornetzes nicht-zufällige Daten verwendet und die Eingabedaten für die Diskriminatordaten in unserem Fall eine Paarung dieser Generatornetz-Eingabedaten mit den Generator-Ausgabedaten waren, wie bereits gezeigt. Neuronale Netze lernen beim Training Gewichte, und daher ist es eine gute Praxis, Vorkehrungen zu treffen und zu verwenden, um diese Gewichte eines Netzes zu protokollieren, wenn ein Trainingsprozess abgeschlossen ist. Wir haben diese Vorteile bei den für diesen Artikel durchgeführten Testläufen nicht berücksichtigt oder erforscht.

Darüber hinaus haben wir nicht die potenziellen Vorteile und Kompromisse untersucht, die sich aus dem Einsatz verschiedener Netzwerktrainingsverfahren ergeben. In diesem Artikel wird das Netzwerk beispielsweise bei jedem neuen Balken trainiert, was eine größere Flexibilität und Anpassungsfähigkeit des Netzwerks und des Handelssystems an sich möglicherweise ändernde Marktbedingungen ermöglichen soll. Ein entgegengesetztes und wahrscheinlich glaubwürdiges Argument dagegen könnte jedoch sein, dass ein Netzwerk, das immer bei jedem neuen Balken trainiert wird, unnötigerweise auf Rauschen trainiert wird; im Gegensatz dazu könnte ein System, bei dem das Training beispielsweise alle sechs Monate durchgeführt wird, sodass nur die entscheidenden „langfristigen“ Aspekte der Märkte als Trainingsdatenpunkte verwendet werden, nachhaltigere Ergebnisse liefern.

Darüber hinaus wurde die stets wichtige Vorfrage nach der Suche nach der neuronalen Architektur übersprungen, da dies nicht unser Hauptthema war. Jeder, der mit Netzwerken vertraut ist, weiß jedoch, dass dies ein sehr leistungsempfindlicher Aspekt neuronaler Netzwerke ist, der eine gewisse Sorgfalt erfordert, bevor ein Netzwerk trainiert und schließlich eingesetzt wird. Diese drei Schlüsselaspekte wurden also nicht angemessen berücksichtigt, obwohl sie wichtig sind, was bedeutet, dass der Leser dazu angehalten ist, sie als Ausgangspunkt für die Entwicklung und Weiterentwicklung dieser cGAN-Klasse zu nutzen, bevor sie als handelswürdig angesehen werden kann. Wie immer handelt es sich hierbei nicht um eine Anlageberatung, und es wird erwartet, dass der Leser alle in diesem Artikel geäußerten Ideen vor der weiteren Verwendung mit unabhängiger Sorgfalt prüft. Viel Spaß bei der Suche.

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15029

Beigefügte Dateien |
cgan.mq5 (6.54 KB)
SignalWZ_22_1.mqh (11.53 KB)
Cgan.mqh (12.51 KB)
DoEasy. Steuerung (Teil 33): Vertikale Bildlaufleiste DoEasy. Steuerung (Teil 33): Vertikale Bildlaufleiste
In diesem Artikel werden wir die Entwicklung der grafischen Elemente der DoEasy-Bibliothek fortsetzen und das vertikale Scrollen von Formularobjekt-Steuerelementen sowie einige nützliche Funktionen und Methoden hinzufügen, die in Zukunft benötigt werden.
Eine Schritt-für-Schritt-Anleitung zum Handel mit der Break of Structure (BoS)-Strategie Eine Schritt-für-Schritt-Anleitung zum Handel mit der Break of Structure (BoS)-Strategie
Ein umfassender Leitfaden für die Entwicklung eines automatisierten Handelsalgorithmus auf der Grundlage der Break of Structure (BoS)-Strategie. Detaillierte Informationen zu allen Aspekten der Erstellung eines Advisors in MQL5 und dessen Test in MetaTrader 5 - von der Analyse von Preisunterstützung und -widerstand bis hin zum Risikomanagement
Entwicklung eines Replay Systems (Teil 39): Den Weg ebnen (III) Entwicklung eines Replay Systems (Teil 39): Den Weg ebnen (III)
Bevor wir zur zweiten Stufe der Entwicklung übergehen, müssen wir einige Ideen überarbeiten. Wissen Sie, wie Sie MQL5 dazu bringen können, das zu tun, was Sie brauchen? Haben Sie jemals versucht, über das hinauszugehen, was in der Dokumentation enthalten ist? Wenn nicht, dann machen Sie sich bereit. Denn wir werden etwas tun, was die meisten Menschen normalerweise nicht tun.
Integration von Hidden-Markov-Modellen in MetaTrader 5 Integration von Hidden-Markov-Modellen in MetaTrader 5
In diesem Artikel zeigen wir, wie mit Python trainierte Hidden Markov Modelle in MetaTrader 5 Anwendungen integriert werden können. Hidden-Markov-Modelle sind ein leistungsfähiges statistisches Instrument zur Modellierung von Zeitreihendaten, bei denen das modellierte System durch nicht beobachtbare (verborgene) Zustände gekennzeichnet ist. Eine grundlegende Prämisse von HMMs ist, dass die Wahrscheinlichkeit, sich zu einem bestimmten Zeitpunkt in einem bestimmten Zustand zu befinden, vom Zustand des Prozesses im vorherigen Zeitfenster abhängt.