English Русский 日本語
preview
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 08): Perceptrons

MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 08): Perceptrons

MetaTrader 5Handelssysteme | 28 Februar 2024, 11:18
135 0
Stephen Njuki
Stephen Njuki

Einführung

Die Klasse Expert-Signal des MQL5-Assistenten wird mit einer Vielzahl von Beispielen im Ordner „Include\Expert\Signal“ ausgeliefert, die unabhängig voneinander verwendet oder miteinander kombiniert werden können, um einen Expert Advisor im Assistenten zusammenzustellen. In diesem Artikel geht es um die Erstellung und Verwendung einer solchen Datei in einem Expertenratgeber. Dieser Ansatz minimiert nicht nur den Aufwand für die Vorcodierung, sondern ermöglicht auch das Testen von mehr als einem Signal in einem einzigen Expert Advisor, indem jedem verwendeten Signal eine Gewichtung zugewiesen wird.

Die Klassen des Alglib-Perceptrons werden in umfangreichen und miteinander verknüpften Netzschnittstellen in der Datei „Include\Math\Alglib\dataanalysis.mqh“ dargestellt. Wenn Sie sich zum ersten Mal umsehen, können Sie leicht überwältigt werden, aber wir werden uns hier einige wichtige Klassen ansehen, die hoffentlich die Navigation in diesem Bereich erleichtern werden.

Die Hauptmotivation für die Verwendung dieser Alglib-Klassen zur Entwicklung eines Expert Advisors ist die gleiche wie bei der Verwendung des MQL5-Assistenten, nämlich das Testen von Ideen. Wie kann ich kurz und bündig feststellen, ob eine Idee x oder ein Eingabedatensatz y es wert ist, dass ich mich ernsthaft um die Weiterentwicklung zu einem Handelssystem bemühe? Was wir hier untersuchen, könnte zur Beantwortung dieser Frage beitragen.

bannr

Bevor wir uns jedoch in die Materie stürzen, ist es vielleicht hilfreich, einen breiteren Überblick darüber zu geben, warum Perceptrons und vielleicht auch neuronale Netze im Allgemeinen in vielen Kreisen großen Zulauf haben. Wenn wir uns auf das Finanzwesen und die Märkte konzentrieren, werden wir feststellen, dass die Vorhersage des Marktgeschehens mit einigen Herausforderungen verbunden ist, und die Grenzen der traditionellen Analyse sind hier wohl implizit.

Diese Herausforderungen bestehen, weil die Märkte sehr komplexe und oft dynamische Systeme sind, die von mehr als dem beeinflusst werden, was in den Nachrichten erscheint (öffentliche Informationen). Die Beziehungen zwischen den verschiedenen Marktvariablen sind zumeist nicht linear und sehr launisch. Herkömmliche Analysemethoden, die sich auf Linearität stützen, können diese Komplexität nicht wirksam erfassen und berücksichtigen. Beispiele für diese traditionellen Methoden sind Ansätze wie Korrelation, Hauptkomponentenanalyse oder die Lineare Regression. Das sind alles sehr vernünftige Taktiken, aber sie geraten zunehmend an ihre Grenzen. Hinzu kommt, dass Marktdaten von Natur aus verrauscht sind und die Marktbewegungen nicht nur von der Stimmung der Anleger, sondern auch von den Verhaltensweisen der Verbraucher beeinflusst werden. Die traditionelle technische Analyse wird daher dadurch eingeschränkt, dass sie sich auf diese historischen Daten stützt, ohne all diese Marktdynamiken angemessen zu berücksichtigen. Ebenso kann bis zu einem gewissen Grad argumentiert werden, dass die Fundamentalanalyse, die den inneren Wert gewichtet und eine langfristige Perspektive einnimmt, für kurzfristige Risiken anfällig ist, insbesondere was die Preisentwicklung betrifft. Obwohl Leverage in der Regel nicht von denjenigen eingesetzt wird, die sich auf die Fundamentalanalyse verlassen, würden die meisten zustimmen, dass es (Leverage) eine wichtige Komponente bei der Erhöhung der AUM und damit des Risikos auf lange Sicht ist, und dennoch kann Leverage nicht eingesetzt werden, wenn die kurzfristige Preisentwicklung ignoriert wird.

Neue Alternativen zu diesen beiden traditionellen Ansätzen sind Verhaltensökonomik und AI-Techniken mit neuronalen Netzen. Während erstere Erkenntnisse aus der Psychologie und der Verhaltensökonomie einbeziehen, um das Verhalten von Anlegern zu verstehen, ist es eine bescheidene Form der letzteren, nämlich neuronale Netze, auf die wir hier eingehen.

In letzter Zeit haben die Finanzmärkte mit der Einführung von KI-Techniken einen Umbruch erlebt, da ChatGPT ins Leben gerufen wurde. Einige große Unternehmen haben sich daran beteiligt, zum Beispiel BloombergGPT und EinsteinGPT von Sales Force. Generativer vortrainierte Transformer (GPTs) sind hier nicht das Thema, sondern ihre stark vereinfachte Version, auch bekannt als Perceptrons.

Das steigende Interesse an KI-Techniken für Prognosen ist jedoch zum Teil auf die riesigen Mengen an Finanzdaten zurückzuführen, die heute in immer größeren Mengen erfasst und gespeichert werden. Erinnern Sie sich zum Beispiel an die Zeiten, als der Tagesschlusskurs eines Wertpapiers alles war, was technische Analysten interessierte? Heutzutage weiß jeder, dass die OHLC-Kurse eines einminütigen Balkens in der Regel das Minimum darstellen, und das, bevor man überhaupt über Ticks spricht, deren Häufigkeit von Broker zu Broker variiert.

Diese Datenflut geht einher mit einer Steigerung der Rechenleistung dank des gesunden Wettbewerbs zwischen den Chip-Anbietern. Gestern wurde bekannt gegeben, dass NVIDIA bald der größte Chiplieferant der Welt sein wird, was zum großen Teil auf die steigende Nachfrage nach Grafikprozessoren zurückzuführen ist, die jetzt mit GPTs in Mode sind. Die zunehmende Datenspeicherung und die steigenden Rechenkapazitäten führen also zu mehr algorithmischem Handel. Und obwohl der algorithmische Handel mit traditionellen technischen Analysen und Fundamentalanalysen durchgeführt werden kann, rücken KI-Techniken, die neuronale Netze nutzen, immer mehr ins Rampenlicht.

Neuronale Netze sind in der Regel besser in der Lage, große Datenmengen zu verarbeiten und komplexe nichtlineare Muster zu erkennen. Darüber hinaus neigen sie dazu, dies zu erreichen, während sie sich an sich verändernde Umgebungen anpassen, und zwar durch das, was oft als Deep Learning bezeichnet wird, ein Euphuismus für ein mehrschichtiges Netzwerk, bei dem bestimmte verborgene Schichten auf bestimmte Aufgaben spezialisiert werden, sodass die Vorhersage in typischen turbulenten/veränderlichen Umgebungen eine gute Verwendung für sie ist. Außerhalb des Finanzwesens können sie unstrukturierte Daten wie Nachrichtenartikel oder Beiträge in sozialen Medien analysieren und die Stimmung auf dem Markt einschätzen, bei der Bewertung der Wirksamkeit von klinischen Arzneimittelstudien helfen und eine Vielzahl anderer Fälle abdecken.


Übersicht über die Klassen von Alglib Perceptron

Die Alglib-Perceptron-Klassenhierarchie ist, wie bereits angedeutet, eine umfangreiche Bibliothek von Klassen, die neuronale Netze implementieren, von den einfachen Perceptrons, die wir in diesem Artikel betrachten, bis hin zu Ensembles, die gleichbedeutend mit Transformatoren sind und Stapel von neuronalen Netzen darstellen. Da wir uns jedoch nur mit dem grundlegenden neuronalen Netz beschäftigen, das als Perceptron bezeichnet wird, werden wir nur die Klassen „CMLPBase“, „CMLPTrain“, „CMLPTrainer“ und „CMultilayerPerceptron“ behandeln. Es gibt noch weitere kleinere Hilfsklassen, die wir verwenden werden, wie z. B. die Klasse, die Berichte bearbeitet, oder die Klasse, die bei der Normalisierung von Datensätzen hilft, aber dies sind die wichtigsten, die wir hervorheben werden.

Die Klasse „CMLPBase“ wird zur Initialisierung des Netzes verwendet, indem sie die Anzahl der versteckten Schichten des Netzes sowie die Anzahl der Neuronen auf jeder Schicht festlegt. Die Klasse „CMLPTrain“ initialisiert die Trainerklasse, indem sie die Anzahl der Eingänge, die das Netz annehmen wird, sowie die Anzahl seiner Ausgänge festlegt. Außerdem wird der Trainer mit dem Trainingsdatensatz befüllt, der in Matrixform vorliegen sollte, wobei die ersten Spalten die unabhängigen Variablen und die letzte Spalte den Regressor oder Klassifikator enthalten, je nach Art des verwendeten Netzes. In unserem Fall wird es sich um einen Klassifikator handeln, da Perceptrons in der Regel boolesche Ergebnisse liefern. Die Klasse „CMLPTrainer“ wird beim Training verwendet, wenn die Funktion „MLPTrainNetwork“ der Klasse „CMLPTrain“ aufgerufen wird. Es gibt alternative, sehr interessante Trainingsmethoden wie das Bootstrap-Aggregieren, das mit der Funktion „MLPEBaggingLM“ aufgerufen wird, aber diese können nur mit Ensembles (Stapeln von Netzen) eingesetzt werden. Darüber hinaus können auch Algorithmen wie Early Stopping, LBFGS und Levenberg-Marquadt zum Training eines Netzes verwendet werden.

Die von diesen Klassen verwendeten Methoden umfassen den typischen Weg neuronaler Netze vom Laden der Trainingsdaten über die Durchführung des eigentlichen Trainings bis hin zur Vorwärtsbewegung auf dem aktuellen Datensatz zur Vorhersage.

Die Klassen sind also so kodiert, wie ein neuronales Netz funktioniert. Im Betrieb werden die Eingabedaten durch das Netz weitergeleitet, beginnend mit der ersten Schicht, die in diesen Klassen als Eingabeschicht bezeichnet wird, über die verborgenen Schichten bis hin zur Ausgabeschicht. Darüber hinaus wird die Aktivierung der Werte in der Regel an jedem Neuron durchgeführt, und es ist diese Aktivierung, die es den Netzen ermöglicht, komplexe Beziehungen zu verarbeiten, die über die linearen hinausgehen, indem sie als Filter fungieren, der es ermöglicht, dass ausgewählte Werte in die nächste Schicht gelangen. Dieser Prozess ist iterativ, aber relativ einfach, da es sich fast immer um eine Multiplikation und Addition handelt, wobei das Ergebnis in der Ausgabeschicht hauptsächlich durch die Gewichte und Verzerrungen in jeder Schicht beeinflusst wird. Es sind diese Gewichte und Verzerrungen, die daher den Kern neuronaler Netze bilden, und der Prozess ihrer Anpassung ist nicht nur rechenintensiv, sondern hat auch zur Entwicklung verschiedener Ansätze geführt, da er nicht so einfach ist wie der Vorwärtsdurchlauf und keine einzige Methode am besten für die verschiedenen Arten von Netzen geeignet ist, da neuronale Netze mehrere Anwendungen haben.

Damit heißt die Vorwärtskopplungsfunktion für Netzwerke in AlgLib „MLPProcess“. Es gibt verschiedene Varianten, aber im Prinzip werden die Eingabedaten in einem Vektor oder Array gespeichert und die Werte der Ausgabeschicht typischerweise ebenfalls in einem Vektor oder Array bereitgestellt. Es gibt Netze mit einem einzigen Neuron auf der Ausgabeschicht und in diesen Fällen gibt es eine Überladung dieser Funktion, die einen einzelnen Wert anstelle eines Arrays zurückgibt.

Es ist wichtig zu erwähnen, dass, obwohl wir ein einschichtiges Perzeptron kodieren und verwenden, unsere Referenzklasse als mehrschichtiges Perzeptron bezeichnet wird, weil es skalierbar ist, da die Anzahl der versteckten Schichten für jedes initialisierte Netz zur Laufzeit eingestellt werden kann und von 0 bis 2 reicht.

Wenn wir versuchen, die Funktionsweise eines typischen Feedforwards etwas näher zu betrachten, können wir uns die Funktion „MLPInternalProcessVector“ ansehen. Eine der ersten Maßnahmen für diese Funktion besteht darin, die Eingabedatenzeile zu normalisieren, sodass alle Werte dieses Eingabefeldes besser vergleichbar sind.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CBdSS::DSNormalize(CMatrixDouble &xy,const int npoints,
                        const int nvars,int &info,CRowDouble &means,
                        CRowDouble &sigmas)
  {
//--- function call
   DSNormalizeC(xy,npoints,nvars,info,means,sigmas);
//--- calculation
   for(int j=0; j<nvars; j++)
     {
      //--- change values
      for(int i=0; i<npoints; i++)
         xy.Set(i,j,(xy.Get(i,j)-means[j])/sigmas[j]);
     }
  }

Dazu müssen der Mittelwert und die Standardabweichung (Sigma) jeder Spalte innerhalb eines Eingabevektors verwendet werden, um Werte im Bereich von 0 bis 1 zu erhalten. Die Mittelwerte und Sigmas müssen daher manuell aus Trainingsdatensätzen bestimmt und dann dem Netz zugewiesen werden. Es gibt bereits Funktionen, die diese Berechnung in derselben Alglib-Datei durchführen können, „DSNormalize“, wie in diesem Listing gezeigt:

//+------------------------------------------------------------------+
//| Normalize                                                        |
//+------------------------------------------------------------------+
void CBdSS::DSNormalize(CMatrixDouble &xy,const int npoints,
                        const int nvars,int &info,double &means[],
                        double &sigmas[])
  {
   CRowDouble Means,Sigmas;
   DSNormalize(xy,npoints,nvars,info,Means,Sigmas);
   Means.ToArray(means);
   Sigmas.ToArray(sigmas);
  }

Erwähnenswert ist auch das Array „m_structinfo“, in dem wichtige Informationen über das Netz gespeichert werden, z. B. die Gesamtzahl der Neuronen, die Art der zu verwendenden Aktivierung, die Gesamtzahl der Gewichte, die Anzahl der Neuronen in der Eingabeschicht und die Anzahl der Neuronen in der Ausgabeschicht.

Nach der Normalisierung werden die Daten in das Netz eingespeist, wobei jedes Neuron auf jeder Schicht seine eigene Aktivierungsfunktion haben kann. Diese Anpassung kann durch die Funktion „MLPSetNeuronInfo“ definiert werden, die leicht als Vorteil beim Aufbau des Netzes genutzt werden kann.

Die Vorwärtsspeisung eines Perzeptrons ist im Vergleich zum Training, also der Anpassung der Netzgewichte, relativ einfach. Alglib bietet hauptsächlich 2 Ansätze für das Training, nämlich Levenberg Marquadt und LBFGS.

Der Levenberg-Marquardt-Algorithmus vereint bei der Suche nach einer nichtlinearen Lösung der kleinsten Quadrate die Geschwindigkeit des Gauß-Newton-Algorithmus und die Geschicklichkeit des Gradientenabstiegs-Algorithmus an stark gekrümmten Punkten der Lösung. Dabei wird die Hesse-Matrix verwendet, um die Oberflächenkrümmung zu protokollieren und abzuschätzen, wie nahe sie der Lösung kommt. Seine Anwendungen sind vor allem in neuronalen Netzen, wo es wirksam im Umgang mit nicht-konvexen Fehleroberflächen vor allem in Situationen, in denen kleine Datensätze sind mit relativ einfachen Netzwerk-Architektur (en) im Spiel sind, weil die Hessian Matrix Berechnung ist anstrengend.

Der Algorithmus Limited-memory BFGS, was für Broyden-Fletcher-Goldfarb-Shanno-Algorithmus mit begrenztem Speicherplatz steht, berechnet die hessische Matrix nicht, sondern approximiert sie mit begrenztem Speicherplatz, indem er die letzten Aktualisierungen der Netzwerkgewichte protokolliert, was ihn insgesamt sehr rechen- und speichereffizient macht. Zu diesem Zweck eignet es sich besser für große Datenmengen und relativ komplexe Netzarchitektur(en).

Dabei sprechen die Konvergenzeigenschaften der beiden eher für Levenberg-Marquadt, da es selbst in Situationen, in denen die anfängliche Schätzung weit daneben lag (z. B. wenn ein Netz mit Zufallsgewichten initialisiert wird), schnell zur genauen Lösung konvergieren kann. Hinzu kommt, dass es weniger anfällig für das Hängenbleiben an lokalen Minima ist als der Gradientenabstieg, was es etwas robuster macht, auch dank der Verwendung des Dämpfungsfaktor. Andererseits wird LBFGS zwangsläufig stärker von der anfänglichen Schätzung (in unserem Fall den anfänglichen Netzgewichten) beeinflusst und konvergiert langsamer oder bleibt in lokalen Minima stecken.


Kodierung einer Instanz der Klasse Expertensignal

Nach dieser kurzen Einführung in die Funktionsweise von Perceptrons (weitere Lektüre und Referenzen finden Sie hier) können wir uns an die Programmierung einer Instanz machen. Die Erstellung eines neuen Expert Advisors mit dem MQL5-Assistenten erfordert die Kenntnis der drei typischen Klassen, die diesen auf dem Assistenten basierenden Expertenberater definieren, nämlich die Signalklasse, auf die wir uns in diesem Artikel konzentrieren, die Trailing-Klasse, die vorgibt, wie offene Positionen und Stop-Loss gesetzt werden, und die Money-Management-Klasse, die bei der Festlegung der Handelslosgrößen hilft. Dies wurde bereits in früheren Artikeln angesprochen. Alle drei müssen während der Montage im Assistenten definiert und ausgewählt werden. Auch wenn die Geldmanagementklasse ein größenoptimiertes Handelsvolumen bietet, könnte eine zusätzliche vierte Assistenten-Klasse eingerichtet werden, die das Risiko berücksichtigt, d. h. die Frage, wie sicher es für einen Expert Advisor ist, mehrere Aufträge innerhalb einer einzigen Position zu platzieren, und die auch auf der Handelshistorie oder einem Indikator basieren könnte.

Um eine Instanz der Alglib-Perceptron-Klassen als einlagiges Perceptron zu implementieren, deklarieren wir zunächst unsere Schlüsselklasseninstanzen in der Schnittstelle unserer nutzerdefinierten Expertensignalklasse. Die Signalklassendateien haben immer eine Funktion „LongCondition“ (Kauf) und eine Funktion „ShortCondition“ (Verkauf), und die zusätzliche Funktion, die wir hinzufügen würden, um bei der Berechnung oder Verarbeitung des Signals vom Perzeptron zu helfen, wäre die einzige andere kritische Methode, die wir neben den Initialisierungs- und Validierungsfunktionen benötigen.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CSignalPerceptron          : public CExpertSignal
  {
protected:
   
   int                           m_hidden;                              // 
   int                           m_features;                            // 
   int                           m_hidden_1_size;                       //
   int                           m_hidden_2_size;                       //  
   int                           m_training_points;                     //
   int                           m_training_restarts;                   //
   int                           m_activation_type;                     // 
   double                        m_hidden_1_bias;                       //
   double                        m_hidden_2_bias;                       //
   double                        m_output_bias;                         //

public:

...

protected:

   CBdSS                         m_norm;
   CMLPBase                      m_base;
   CMLPTrain                     m_train;
   CMatrixDouble                 m_xy;
   CMLPReport                    m_report;
   CMLPTrainer                   m_trainer;
   CMultilayerPerceptron         m_network;
   
   bool                          m_in_training;
      
   int                           m_inputs;
   int                           m_outputs;
   
   double                        m_last_long_y;
   double                        m_last_short_y;
   
   bool                          ReadWeights();
   bool                          WriteWeights(CRowDouble &Export);
   
   void                          Process(double &Y);
  };

Die Validierungsfunktion dient als unsere Defacto-Initialisierungsfunktion innerhalb dieser Instanz der Expertensignalklasse und ja, es gibt eine eingebaute Initialisierungsfunktion, aber die Verwendung der Validierung dient uns besser. Darin sind einige Dinge enthalten, die erledigt werden müssen und die es wert sind, näher betrachtet zu werden. Zunächst legen wir die Anzahl der Eingänge und Ausgänge für unser Perzeptron fest. Die Anzahl der Eingaben kann optimiert werden, sodass sie aus einem Parameter gelesen wird. Da es sich um eine Klassifizierung und nicht um eine Regression handelt, muss die Anzahl der Ausgaben mindestens 2 betragen.

Um die Dinge einfach zu halten, werden wir 2 als Ausgänge zuweisen. Anschließend wird die Größe der Trainingsdatenmatrix so angepasst, dass die Zeilen der Anzahl der Trainingspunkte entsprechen, die wir bei der Verarbeitung der Richtung auf jedem Balken berücksichtigen. Seine Spalten sollten der Summe der Anzahl der Ein- und Ausgänge entsprechen. Die Ausgabe von 2 steht beim Training für zwei Gewichtungen in Richtung Kauf oder Verkauf, und ein Forward-Pass liefert ebenfalls zwei Wahrscheinlichkeiten, eine für eine Kauf- und eine für eine Verkaufsposition, die sich beide zu eins summieren. Danach erstellen wir einen Trainer, indem wir die Anzahl der Eingänge und Ausgänge festlegen.

   m_train.MLPCreateTrainerCls(m_inputs,m_outputs,m_trainer);

Danach folgt die Erstellung des Netzes, und je nach der Anzahl der gewählten versteckten Schichten werden wir dazu eine andere Funktion verwenden, wobei jede Funktion die Definition der Anzahl der Eingangsneuronen, der Anzahl der Neuronen in jeder versteckten Schicht (falls sie verwendet werden) und schließlich der Anzahl der Neuronen in der Ausgabeschicht ermöglicht.

   if(m_hidden==0)
   {
      m_base.MLPCreateC0(m_inputs,m_outputs,m_network);
   }
   else if(m_hidden==1)
   {
      m_base.MLPCreateC1(m_inputs,m_hidden_1_size,m_outputs,m_network);
   }
   else if(m_hidden==2)
   {
      m_base.MLPCreateC2(m_inputs,m_hidden_1_size,m_hidden_2_size,m_outputs,m_network);
   }
   else if(m_hidden>2||m_hidden<0)
   {
      printf(__FUNCSIG__+" invalid number of hidden layers should be 0, 1, or 2. ");
      return(false);
   }

Abschließend werden die Aktivierungsfunktionen für die versteckte Schicht und die Ausgabeschicht sowie die Biases der Schichten festgelegt. Die Alglib-Klassen sind recht vielseitig, sodass die Aktivierungsfunktionen und Verzerrungen nicht nur für jede Schicht, sondern tatsächlich für jedes Neuron angepasst werden können. In diesem Artikel geht es jedoch um etwas Vereinfachtes.

Neben der Initialisierung und Validierung unseres Netzes müssen wir geeignete Vorkehrungen treffen, um die idealen Gewichte des Netzes durch ein System zu erlernen, in dem sie gespeichert und bei Bedarf ausgelesen werden. Hier sind verschiedene Ansätze denkbar, aber wir schreiben einfach eine Datei in ein Array der Netzgewichte nach einem Testdurchlauf, bei dem das Testkriterium des Expert Advisors einen vorherigen Benchmark übertrifft. Beim nächsten Durchlauf initialisiert sich unser Netz mit diesen Gewichten, und mit jedem weiteren Training werden sie verbessert. Das Schreiben der Gewichte in die Datei und das Lesen der Gewichte erfolgt mit den Funktionen „WriteWeights“ und „ReadWeights“.

Schließlich wird die Funktion „Process“ bei jedem neuen Balken ausgeführt, um unser Netzwerk mit neuen Daten zu trainieren und dann das aktuelle Signal, das als Variable „Y“ bezeichnet wird, zu verarbeiten. Zunächst muss die Testdatenmatrix „m_xy“ spaltenweise normalisiert werden, sodass jeder Wert in der Matrix im Bereich von -1,0 bis +1,0 liegt. Dies kann, wie oben angedeutet, durch andere Funktionen innerhalb der Alglib-Klassen geschehen, die aus derselben Datei wie die Perceptron-Klassen stammen. Natürlich könnte man diesen Ansatz anpassen, um ihn für die eigene Situation besser geeignet zu machen, aber für unsere Zwecke werden die eingebauten Funktionen verwendet.

      //normalise data
      CRowDouble _means,_sigmas;
      m_norm.DSNormalize(m_xy,m_training_points,m_inputs,_info,_means,_sigmas);

Zweitens erfolgt das Training des Netzes durch zwei Funktionen, je nachdem, ob wir gerade mit dem Trainingsprozess beginnen oder bereits einen Trainingslauf durchgeführt haben. Sobald wir mit dem Training beginnen, können wir die im vorherigen Durchgang gelernten Gewichte beibehalten und das Training mit ihnen fortsetzen, damit wir nicht wieder mit zufälligen Gewichten arbeiten müssen. Die Standardfunktion trainiert die Gewichte immer nach dem Zufallsprinzip, und wenn wir sie verwenden würden, würden wir unsere Gewichte bei jedem neuen Balken nach dem Zufallsprinzip ändern!

      m_train.MLPSetDataset(m_trainer,m_xy,m_training_points);
      //
      if(!m_in_training)
      {
         m_train.MLPStartTraining(m_trainer,m_network,false);
         m_in_training=true;
      }
      else if(m_in_training)
      {
         while(m_train.MLPContinueTraining(m_trainer,m_network))
         {
            //
         }
      }

Die Integration dieser fertigen Signalklasse mit der Trailing-Klasse und der Money-Management-Klasse in einen Expert Adviser ist dank des Assistenten nahtlos.

Wenn wir die Schritte befolgen, die in den Bildern unten dargestellt sind, sollten wir am Ende einen Expert Advisor haben, dessen Include-Header wie aufgeführt ist:

//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\My\SignalPerceptron.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedMargin.mqh>

Zusammenstellen und Testen des Expert Advisors

Das Zusammenstellen unserer nutzerdefinierten Expertensignalklasse zu einem Experten mit dem Assistenten ist also ganz einfach, wie die Screenshots zeigen.

s_1


s_4


s_5


s_6


s_7


Wenn wir einen Backtest mit unserem kompilierten Experten vor der Optimierung durchführen, erhalten wir folgenden Bericht:

init_pass

Wenn wir Optimierungen unseres Expert Advisors mit einem Walk-Forward-Fenster durchführen, erhalten wir die folgenden Ergebnisse:

back_pass

forward_pass

Wir haben unser Perzeptron trainiert und seine Gewichte auf der Grundlage der Optimierungskriterien unseres Expert Advisors exportiert. Eine prägnantere Vorgehensweise wäre die Verwendung der eingebauten Kreuzvalidierungsfunktionen oder sogar etwas Einfacheres wie der Wert des mittleren quadratischen Fehlers des Berichts, wenn kein Bagging verwendet wird. In beiden Szenarien werden Gewichte gespeichert, die mit größerer Wahrscheinlichkeit mit den Trainingsklassifikatoren übereinstimmen. Unsere Tests haben gezeigt, dass das Netzwerk vielversprechend ist, aber wie immer sollte man beim Testen über längere Zeiträume mit den Tickdaten des Brokers und anderen Überlegungen mehr Sorgfalt walten lassen.


Schlussfolgerung

Zusammenfassend haben wir uns angeschaut, wie Perceptrons dank der Alglib Code-Klassen mit minimalem Code auf Seiten des Anwenders implementiert werden können. Wir haben einige vorbereitende Schritte, wie die Normalisierung von Datensätzen, hervorgehoben, die unternommen werden müssen, bevor sich Perceptrons zum Testen und Lernen eignen. Darüber hinaus haben wir zusätzliche Maßnahmen aufgezeigt, die es wert sind, in Betracht gezogen zu werden, sobald Sie testbereite Perceptrons haben. All diese Schritte und zusätzliche Maßnahmen, wie der Export von einstellbaren Parametern, werden von Zusatzcode aus den Alglib-Klassen übernommen.

Die Vorteile der Verwendung von Alglib-Klassen liegen also in erster Linie in der Minimierung der Codemenge und der Zeit, die man braucht, um ein testbares System zu haben. Aber es gibt auch Nachteile, vor allem wenn es um die individuelle Anpassung geht. Unsere Perceptrons können zum Beispiel nicht mehr als 2 versteckte Schichten haben. In Szenarien, in denen komplexe Datensätze modelliert werden, würde dies einen Engpass darstellen.


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

Beigefügte Dateien |
MQL5.zip (11.41 KB)
Datenwissenschaft und maschinelles Lernen (Teil 16): Ein frischer Blick auf die Entscheidungsbäume Datenwissenschaft und maschinelles Lernen (Teil 16): Ein frischer Blick auf die Entscheidungsbäume
Tauchen wir ein in die komplizierte Welt der Entscheidungsbäume in der neuesten Folge unserer Serie über Datenwissenschaft und maschinelles Lernen. Dieser Artikel ist auf Händler zugeschnitten, die nach strategischen Einsichten suchen, und dient als umfassende Zusammenfassung, die die wichtige Rolle von Entscheidungsbäumen bei der Analyse von Markttrends beleuchtet. Wir erforschen die Wurzeln und Äste dieser algorithmischen Bäume und erschließen Sie deren Potenzial zur Verbesserung Ihrer Handelsentscheidungen. Erleben Sie mit uns eine erfrischende Perspektive auf Entscheidungsbäume und entdecken Sie, wie sie Ihnen bei der Navigation durch die Komplexität der Finanzmärkte behilflich sein können.
Wie man einen einfachen Multi-Currency Expert Advisor mit MQL5 erstellt (Teil 4): Triangulärer gleitender Durchschnitt — Indikatorensignale Wie man einen einfachen Multi-Currency Expert Advisor mit MQL5 erstellt (Teil 4): Triangulärer gleitender Durchschnitt — Indikatorensignale
Der Multi-Currency Expert Advisor in diesem Artikel ist ein Expert Advisor oder Handelsroboter, der mehr als nur ein Symbolpaar von dessen Symbolchart handeln kann (Aufträge öffnen, schließen und verwalten oder zum Beispiel Trailing Stop Loss und Trailing Profit). Dieses Mal werden wir nur 1 Indikator verwenden, nämlich den Triangulären gleitenden Durchschnitt in Multi-Timeframes oder Single-Timeframes.
Filterung und Merkmalsextraktion von Frequenzen Filterung und Merkmalsextraktion von Frequenzen
In diesem Artikel untersuchen wir die Anwendung digitaler Filter auf Zeitreihen, die im Frequenzbereich dargestellt werden, um einzigartige Merkmale zu extrahieren, die für Vorhersagemodelle nützlich sein können.
Entwurfsmuster in der Softwareentwicklung und MQL5 (Teil 3): Verhaltensmuster 1 Entwurfsmuster in der Softwareentwicklung und MQL5 (Teil 3): Verhaltensmuster 1
Ein neuer Artikel aus der Reihe der Artikel über Entwurfmuster. Wir werden einen Blick auf einen seiner Typen werfen, nämlich den Verhaltensmuster, um zu verstehen, wie wir Kommunikationsmethoden zwischen erstellten Objekten effektiv aufbauen können. Durch die Vervollständigung dieser Verhaltensmuster werden wir in der Lage sein zu verstehen, wie wir eine wiederverwendbare, erweiterbare und getestete Software erstellen und aufbauen können.