English Русский 中文 Español 日本語 Português
preview
Kategorientheorie in MQL5 (Teil 21): Natürliche Transformationen mit LDA

Kategorientheorie in MQL5 (Teil 21): Natürliche Transformationen mit LDA

MetaTrader 5Handelssysteme | 19 Januar 2024, 16:05
152 0
Stephen Njuki
Stephen Njuki

Einführung

Bislang haben wir eine ganze Reihe von Themen der Kategorientheorie behandelt, die sich auch außerhalb des akademischen Umfelds leicht anwenden lassen. Wenn ich einige davon aufzählen darf: Mengen und Morphismen, Kommutation, Ontologieprotokolle, Produkte, Koprodukte, Limits, Colimits, Monoide, Gruppen, Graphen, Ordnungen, Funktoren und jetzt Natürliche Transformationen. Die Kategorientheorie ist viel umfassender als das, was wir hier betrachtet haben, und diese Themen wurden aufgrund ihrer einfachen Anwendbarkeit und Verwendung in anderen mit der Mathematik verbundenen Disziplinen ausgewählt. Wenn Sie an einem gründlicheren Überblick über das Thema interessiert sind, dürfte dieses Buch, das manche als die Bibel in diesen Fragen betrachten, interessant sein.

Im weiteren Verlauf unserer Betrachtung von Natürliche Transformation werden wir uns in diesem Artikel mit weiteren Anwendungen in der Zeitreihenprognose befassen. Natürliche Transformationen lassen sich oft aus zusammenhängenden Datensätzen ableiten, und damit wollen wir uns in diesem Artikel befassen.

Hier liegt also das Problem. Ein neu gegründetes Unternehmen erstellt eine Datenbank für seine Kunden, um deren Einkäufe im Laufe der Zeit zu verfolgen, und anfangs hat sie, sagen wir, 3 Spalten. Einen Primärschlüssel, eine Spalte mit dem Produktnamen und eine Spalte mit dem gezahlten Betrag. Mit der Zeit stellt das Unternehmen fest, dass sich ein bestimmtes Produkt in der Produktspalte häufig wiederholt, d. h. es wird häufig gekauft. Als Reaktion darauf wurde beschlossen, mehr Informationen über die Produkte zu erfassen, um die Vorlieben der Kunden besser zu erkennen und möglicherweise neue Produkte zu entwickeln, die in ihrem Portfolio noch fehlen. Zu diesem Zweck wird die Produktspalte in 3 Spalten aufgeteilt, nämlich: Version, Abonnementmodus, Build-Name. Oder das Unternehmen benötigt mehr Farben für die Zahlungsinformationen und beschließt, die Zahlungsspalte in drei Spalten zu unterteilen, z. B. eine Spalte für die Zahlungsart, die Währung (oder das Gebietsschema) und den Zahlungsbetrag. Auch hier wäre eine solche Aufteilung nicht erschöpfend, da zu einem späteren Zeitpunkt je nach den Käufen der Kunden und deren Präferenzen weitere Aufteilungen erforderlich sein könnten.

Jede dieser neu erstellten Spalten würde der alten Produktspalte zugeordnet. Und wenn wir zum Beispiel einige Schlüsselkorrelationen zwischen der alten Spalte „Einzelprodukt“ und der Spalte „gezahlter Betrag“ oder einer anderen Spalte in einer Tabelle innerhalb der Datenbank hergestellt haben, dann wäre es ein mühsamer Prozess, diese Korrelationen in der neuen Tabellenstruktur wieder herzustellen. Das Startup-Unternehmen hätte sicherlich viele Möglichkeiten, dies zu tun, aber Natürliche Transformationen bieten eine nahtlose Alternative.

Um dies zu verstehen, sollten wir versuchen, die Sache zunächst in zwei Kategorien zu betrachten. In der Domain-Kategorie hätten wir die Liste der Tabellen des Startup-Unternehmens in seiner Datenbank, und in der Codomain-Kategorie hätten wir die beiden Versionen der Kundeninformationstabellen. Wenn wir der Einfachheit halber die Liste als ein einziges Objekt in der Domäne und jede unserer Tabellen als separate Objekte in der Codomäne betrachten, dann implizieren zwei Funktoren von der Liste zu jeder Tabelle eine Natürliche Transformation zwischen den beiden Tabellen. Ein Funktor würde also alte Tabellen abbilden, in unserem Fall die einfache 3-Spalten-Tabelle, während der zweite Funktor eine Änderung in der Tabellenstruktur abbilden würde. Wenn dies die Revision 1 ist, bildet der zweite Funktor die 5-Spalten-Tabelle ab.

Die Implikation einer Natürlichen Transformation bedeutet nicht nur, dass wir die Unterschiede zwischen diesen beiden Tabellen über eine algorithmische Mapping-Funktion wie lineare Gleichung, quadratische Gleichung, Multi-Layer-Perceptron, Random Distribution Forest oder lineare Diskriminanzanalyse quantifizieren können; sie bedeutet auch, dass wir diese Gewichte verwenden können, um frühere Korrelationen mit der alten Tabelle wiederherzustellen und neue für die erstellten Spalten zu entwickeln.


Hintergrund

Um es kurz zusammenzufassen: Natürliche Transformationen sind der Unterschied zwischen den Zielobjekten von zwei Funktoren. Die Verwendung dieses Unterschieds wurde in diesen Serien mit dem Natürlichen Quadrat hervorgehoben, einer kommutativen Komposition von Objekten in der Codomain-Kategorie dieser Funktoren. Wir haben dies in Artikel 18 eingeführt und uns in Artikel 19 weitere Beispiele für die Induktion mit dem Natürlichen Quadrat angesehen.

Das Konzept der Zeitreihendaten ist den meisten Händlern nicht fremd, da viele von uns nicht nur mit den Preisdiagrammen und den eingebauten Indikatoren des MetaTrader-Terminals vertraut sind, sondern viele Händler programmieren ihre eigenen nutzerdefinierten Indikatoren und entwickeln auch ihre Expert Advisors. Die meisten Menschen haben also schon einige Vorarbeiten zu diesen und anderen Themen geleistet. Nichtsdestotrotz ist der Preis eines Devisenpaares, wie er auf einem Chart zu sehen ist, eine diskrete Zeitreihe, da wir in jedem Intervall einen bestimmten Preis haben, und das trotz der Tatsache, dass sich dieser Preis immer ändert, wenn die Märkte geöffnet sind, was die meiste Zeit der Woche der Fall ist, was bedeutet, dass es sich um eine zeitlich kontinuierliche Serie handelt. Daher wird die Ansicht der diskreten Zeitreihen als Hilfe bei der Analyse verwendet.

Die Fähigkeit, Analysen durchzuführen, beruht also darauf, dass für ein bestimmtes Wertpapier zu einem bestimmten Zeitpunkt „Konsens“-Preise vorliegen. Und wenn man versucht, Prognosen zu erstellen, was in der Regel das Ziel der meisten Prognosen ist, wird die Untersuchung verschiedener Reihen zu verschiedenen Zeitepochen wichtig. Aus diesem Grund kann die Betrachtung und der Vergleich von Daten mit einer zeitlichen Verzögerung als konstruktiver angesehen werden, um genaue Ergebnisse zu erhalten.

Daher werden wir in diesem Artikel zwei Datensätze betrachten, die, wie in der Einleitung angedeutet, ähnlich sind, wobei der eine einfach umfangreicher ist als der andere. Mit diesen beiden Sätzen werden wir sie in einer verzögerten Natürlichen Transformation haben, um die Erstellung von Projektionen zu erleichtern. Unsere beiden Datensätze, die als Tabellen dargestellt werden können, werden sehr einfach sein. Der erste enthält die Werte des gleitenden Durchschnitts, der zweite die Preise, aus denen sich dieser Durchschnitt zusammensetzt.


Beschreibung der Datensätze

Die einfache Tabelle wird also nur zwei Spalten haben. Eine Spalte mit einem Zeitstempel und eine Spalte mit einem gleitenden Durchschnitt. Die Anzahl der Zeilen in dieser und der zusammengesetzten Tabelle wird vom Nutzer mit dem Eingabeparameter "m_data" festgelegt. Diese einfache Tabelle wird gegenüber der zusammengesetzten Tabelle um die Größe der verwendeten gleitenden Durchschnittsperiode zeitlich nach vorne versetzt. Wenn die Periode des gleitenden Durchschnitts also 5 beträgt, dann sind die Werte in dieser Tabelle 5 Zeitbalken der zusammengesetzten Tabelle.

Die zusammengesetzte Tabelle, die der Nachzügler ist, hat auch eine Zeitstempelspalte und mehrere Spalten mit jeweils einem Preis zu einem anderen Zeitpunkt. Die Anzahl dieser zusätzlichen Spalten jenseits des Zeitstempels wird durch den Zeitraum des gleitenden Durchschnitts festgelegt. Wenn also unser gleitender Durchschnitt über 5 Kursbalken geht, wird diese Tabelle eine Zeitstempelspalte und 5 Kursspalten haben.

Diese beiden Datensätze, die eine Abbildung einer Natürlichen Transformation haben, können auf verschiedene Weise definiert werden, wie bereits in der Einleitung erwähnt. In diesem Artikel werden wir eine Methode verwenden, die wir in diesen Reihen noch nicht berücksichtigt haben, nämlich die lineare Diskriminanzanalyse (LDA). Ich hatte in diesem Artikel gezeigt, wie dies mit dem MQL5-Assistenten und der Alglib-Bibliothek verwendet werden kann, dennoch kann es hilfreich sein, dies hier zu wiederholen.

Eine genauere Definition findet sich hier, aber im Großen und Ganzen ist LDA ein Klassifikator. Ein typischer Trainingsdatensatz enthält immer unabhängige Variablen (Werte, von denen angenommen wird, dass sie das Endergebnis beeinflussen) und eine oder mehrere Klassifizierungsvariablen, die als „Endergebnis“ dienen. Mit LDA haben wir die Möglichkeit, dieses Endergebnis in bis zu n Klassen einzuteilen, wobei n eine natürliche Zahl ist. Dieser von Sir Ronald Aylmer Fisher entwickelte Algorithmus gibt einen Vektor von Gewichten aus, die dazu beitragen, den Hauptschwerpunkt jedes Klassifikators zu definieren, und kann auch die Position eines unbekannten Schwerpunkts (neuer oder unbekannter Datenpunkt) schätzen. Mit dieser Information kann man einfach die Position des unbekannten Schwerpunkts mit der des bekannten vergleichen, um zu wissen, welchem Schwerpunkt er näher liegt und wie er daher einzuordnen ist. Zur Veranschaulichung könnte man sich einen „Vektor der Gewichte“ als Gleichung für eine Linie vorstellen, die Punkte trennt, die nur 2 Klassifikatoren haben. Wenn die Klassifikatoren drei sind, handelt es sich um die Gleichung einer Ebene. Wenn ja, dann sind es die Koordinaten auf einer Zahlengeraden. In beiden Szenarien können Sie zwischen einem Trainingsdatensatz unterscheiden, indem Sie jedem Datenpunkt einen Satz von Koordinaten zuweisen.


Natürliche Transformation für Zeitreihenprognosen

Wie bereits in den Artikeln 18 und 19 erwähnt, kommt es bei der Betrachtung von Natürlichen Quadraten in der Regel nur auf die Codomain-Objekte an, und deshalb haben wir in diesem Artikel, in dem wir zeigen, wie zwei verschiedene Datensätze von Kursen und gleitenden Durchschnitten eine Natürliche Transformation teilen können, nichts über die Kategorie oder das/die Objekt(e) des Funktors gesagt. Sie sind nicht kritisch. Wenn wir jedoch mehrere Objekte in der Quellkategorie haben, würden wir mehrere anteilige Instanzen sowohl des einfachen Datensatzes als auch des zusammengesetzten Datensatzes erwarten. Dies wurde deutlich, als wir in Artikel 19 das natürliche Quadrat in der Induktion sahen.

Aus der Perspektive der Chartabbildung sollte unsere Natürliche Transformation also nicht übermäßig kompliziert sein. Die Zeitstempelspalten der Datensätze würden miteinander verknüpft, und alle Preisspalten im zusammengesetzten Datensatz würden der Spalte für den gleitenden Durchschnitt im einfachen Datensatz zugeordnet. Zur Veranschaulichung und aus logischen Gründen wird dies in der Regel in MQL5-Code dargestellt, und zu diesem Zweck haben wir Instanzen des einfachen Datensatzes und des zusammengesetzten Datensatzes als "m_o_s" bzw. "m_o_c" deklariert. Diese Klasseninstanzen werden nun als „Objekte“ und nicht mehr als „Domänen“ bezeichnet, da der Begriff „Domäne“ eine Eigenschaft eines mit einem Morphismus verbundenen Objekts und nicht unbedingt ein Substantiv an sich ist. (falls das Sinn macht). Was ich in den meisten unserer früheren Artikel als Domäne bezeichnet habe, wird im Allgemeinen als Objekt bezeichnet. Ich hatte auf die Verwendung von „Objekt“ verzichtet, um Verwechslungen mit den eingebauten Klassen von MQL5 zu vermeiden. Dieser Ansatz ist weniger fehleranfällig für Logikfehler, die leicht gemacht werden könnten, wenn wir direkter vorgehen und die Preisdaten direkt in unsere Mapping-Funktion kopieren würden. Das sind die Art von Fehlern, die auch beim Testen des Experten nicht auftauchen, weil er normal kompiliert. Wir demonstrieren das hier nur, um zu zeigen, was möglich ist.

Die Natürliche Transformation wird also mit Hilfe von LDA durchgeführt, und die kritische Abbildung erfolgt von den nachlaufenden Preispunkten auf den zukünftigen gleitenden Durchschnittspreiswert. Die Spalte mit dem Zeitstempel wird nicht verwendet, wird aber der Vollständigkeit halber erwähnt, damit der Leser einen Eindruck von der Struktur der Daten erhält. Die oben angegebene Zeitspanne entspricht der Länge des gleitenden Durchschnitts. Beim Training würden wir also Kurse verwenden, die n Balken vom Startindex zurückliegen, wobei n die Länge der Periode des gleitenden Durchschnitts ist. Das bedeutet auch, dass wir bei der Vorhersage natürlich die neuesten Preise verwenden, aber unsere Vorhersage würde sich auf n Takte in der Zukunft beziehen. Nicht der unmittelbare gleitende Durchschnitt.


Anwendung der natürlichen Transformation für die Vorhersage

Der Code hierfür wird in erster Linie von zwei Funktionen innerhalb der Signalklasse gehandhabt, da wir, wie bereits erwähnt, nicht mit den gesamten Klassenstrukturen kodieren, die typischerweise Kategorien umreißen, d. h. Morphismen oder Funktoren, wie wir es in der Vergangenheit getan haben; stattdessen werden wir nur die Klassen Objekte und Elemente verwenden, um abzubilden, was in der Codomain-Kategorie ist. Das Endergebnis sollte identisch sein, wobei der hier gewählte Ansatz effizienter mit den Computerressourcen umgeht und daher einfacher mit dem Strategietester zu testen ist. Dies erfordert jedoch mehr Sorgfalt, um Fehler in der Logik der Kategorien und ihrer Funktoren zu vermeiden, da Fehler beim Kompilieren oder bei der Durchführung von Strategietests nicht auffallen. Unsere Aktualisierungsfunktion sieht also folgendermaßen aus:

//+------------------------------------------------------------------+
//| Refresh function to update objects.                              |
//+------------------------------------------------------------------+
void CSignalCT::Refresh(int DataPoints=1)
   {
      m_time.Refresh(-1);
      m_close.Refresh(-1);
      
      for(int v=0;v<DataPoints;v++)
      {
         m_e_s.Let(); m_e_s.Cardinality(2);
         m_e_c.Let(); m_e_c.Cardinality(m_independent+1);
         
         m_e_s.Set(0,TimeToString(m_time.GetData(v)));
         m_e_c.Set(0,TimeToString(m_time.GetData(v)));
      
         double _s_unit=0.0;
         //set independent variables..
         for(int vv=0;vv<m_independent;vv++)
         {
            double _c_unit=m_close.GetData(StartIndex()+v+vv+m_independent);
            
            m_e_c.Set(vv+1,DoubleToString(_c_unit));
         }
         
         m_o_c.Set(0,m_e_c);
         
         //get dependent variable, the MA..
         for(int vv=v;vv<v+m_independent;vv++)
         {
            _s_unit+=m_close.GetData(StartIndex()+vv);
         }
         
         _s_unit/=m_independent;
         
         m_e_s.Set(1,DoubleToString(_s_unit));
         
         m_o_s.Set(0,m_e_s);
      }
   }


Diese Aktualisierungsfunktion wird von der Funktion „get direction“ aufgerufen, deren Auflistung wie folgt aussieht:

//+------------------------------------------------------------------+
//| Get Direction function from implied naturality square.           |
//+------------------------------------------------------------------+
double CSignalCT::GetDirection()
   {
      double _da=0.0;
      
      int _info=0;
      CMatrixDouble _w,_xy,_z;
      _xy.Resize(m_data,m_independent+1);
      
      double _point=0.00001;
      if(StringFind(m_symbol.Name(),"JPY")>=0){ _point=0.001; }
      
      for(int v=0;v<m_data;v++)
      {
         Refresh(v+1);
         
         ...
         
         //training classification
         _xy.Set(v,m_independent,(fabs(_ma-_lag_ma)<=m_regularizer*_point?1:(_ma-_lag_ma>0.0?2:0)));
      }
      
      m_lda.FisherLDAN(_xy,m_data,m_independent,__CLASSES,_info,_w);
      
      if(_info>0)
      {
         double _centroids[__CLASSES],_unknown_centroid=0.0; ArrayInitialize(_centroids,0.0);
         
         _z.Resize(1,m_independent+1);
         
         m_o_c.Get(0,m_e_c);
         
         for(int vv=0;vv<m_independent;vv++)
         {
            string _c="";
            m_e_c.Get(vv+1,_c);
            
            double _c_value=StringToDouble(_c);
            _z.Set(0,vv,_c_value);
         }
         
         for(int v=0;v<m_data;v++)
         {
            for(int vv=0;vv<m_independent;vv++)
            {
               _centroids[int(_xy[v][m_independent])]+= (_w[0][vv]*_xy[v][vv]);
            }
         }
         
         // best vector is the first 
         for(int vv=0;vv<m_independent;vv++){ _unknown_centroid+= (_w[0][vv]*_z[0][vv]); }
         
         
... 
      }
      else
      {
         
... 
      }
      
      return(_da);
   }

Unsere Prognose bezieht sich auf eine Veränderung des zukünftigen gleitenden Durchschnittspreises, sodass eine negative Veränderung auf eine Baisse, eine positive Veränderung auf eine Hausse und „keine Veränderung“ auf einen stagnierenden Markt hinweisen würde. Schließlich gibt es zur Quantifizierung von „keine Änderung“ einen Regulierungsparameter, "m_regulizer", der die Mindestgröße der Prognose festlegt, damit sie als Änderung für Baisse oder Hausse gilt. Es handelt sich um eine ganze Zahl, die wir durch Multiplikation mit der Punktgröße des Symbols quantifizieren.

Dies ist also die Zusammenfassung unseres Codes, der die Transformation implementiert. Die Deklaration der kritischen Variablen erfolgt wie immer im Klassenmanifest. Neben den typischen Deklarationen für eine Signalklasse fügen wir für unsere spezielle Klasse Deklarationen für Instanzen eines einfachen Elements, eines zusammengesetzten Elements, eines einfachen Elements, eines zusammengesetzten Elements und einer Instanz unserer linearen Diskriminantenklasse hinzu.

Bei jedem neuen Balken aktualisieren wir dann die Werte dieser Elemente und damit ihre Objekte durch die Refresh-Funktion. Dies beinhaltet die Zuweisung unabhängiger Variablen, d. h. einfach die Zuweisung einer Anzahl von Preisen, deren Anzahl der Länge der gleitenden Durchschnittsperiode der Eingabe entspricht. Wir geben diese Preise also an das zusammengesetzte Element und die Objekte weiter. Wir verwenden 3 Klassifikatoren für unseren LDA, wobei 2 für einen Aufwärts-, 1 für einen Seitwärts- und 0 für einen Abwärts-Markt stehen. Jedem Trainingsdatenpunkt wird also eine Klassifizierung zugewiesen, die auf der Differenz zwischen dem aktuellen gleitenden Durchschnitt (basierend auf dem Index im Trainingssatz) und dem nachlaufenden gleitenden Durchschnitt basiert. Beide Mittelwerte werden über eine gleiche Länge genommen, die der bereits erwähnten Eingabe entspricht, und die Verzögerung ist ebenfalls gleich dieser Länge.

Die Zuordnung von Klassifikatoren kommt bei dieser Alglib-Implementierung der linearen Diskriminanzanalyse einem Training gleich. Erwähnenswert ist vielleicht auch unser Regularisierungsregime, das einfach festlegt, welche Signale zu ignorieren sind, d.h. was ist weißes Rauschen? Bei der Beantwortung dieser Frage nehmen wir jede Differenz zwischen den beiden gleitenden Durchschnitten, die kleiner ist als der Eingabeparameter "m_regularizer", der eine ganze Zahl ist, die wir mit der Punktgröße des Symbols multiplizieren, um sie mit der Spanne des gleitenden Durchschnitts des Preises vergleichbar zu machen.

Damit führen wir die Fischer-Funktion aus, um eine Matrix von Koeffizienten (oder Gewichten), "w", auszugeben, die, wie besprochen, die Gleichung für die definierende Ebene zwischen unseren Klassifikatoren bildet.

Die Z-Matrix, die die aktuellen Preispunkte für die nächste Prognose darstellt, wird mit der letzten Preisreihe gefüllt und erhält dann ein Punktprodukt mit der W-Matrix aus der Fischer-Funktion, um den durch die W-Matrix definierten Schwerpunktwert zu erhalten. Dieser Wert ist unser unbekannter Schwerpunkt.

Auch die Schwerpunktwerte unserer 3 Klassifikatoren werden mit dem Punktprodukt von dieser Matrix mit der Matrix der unabhängigen Variablen gefüllt.

Mit allen 3 Klassifikator-Schwerpunktwerten und dem Schwerpunktwert unserer Unbekannten geht es nun darum, diese Unbekannte mit den 3 Klassifikatoren zu vergleichen und zu sehen, welcher unserer Unbekannten am nächsten liegt.


Anwendung in der realen Welt

Für eine „Fallstudie“ haben wir den GBPUSD von Anfang dieses Jahres bis zum ersten Juni getestet. Daraus ergibt sich der nachstehende Bericht:

r1


Wenn wir bis August weitergehen, erhalten wir negative Ergebnisse, die in dem unten stehenden Bericht aufgeführt sind:

r2


Die Vorhersagegenauigkeit auf der Grundlage des Walk-Forward-Berichts scheint fraglich zu sein, was auf einen unvollständigen Optimierungslauf (nur für die ersten drei Generationen) oder ein zu kleines Testfenster zurückzuführen sein könnte, da wir nur drei Jahre betrachtet haben und zuverlässige Systeme längere Zeiträume benötigen. Der Quellcode ist beigefügt, sodass der Leser diese Frage klären kann. Wie in allen Artikeln dieser Reihe wird jedoch auch hier das Potenzial für die Entwicklung von Handelssystemen aufgezeigt.


Schlussfolgerung

Zusammenfassend lässt sich sagen, dass unsere Datenbanktabellen oder Formate zur Speicherung von Daten im Alltag häufig nicht nur an Größe, sondern auch an Komplexität zunehmen. Dieser letzte Punkt wird hier anhand eines Datensatzes veranschaulicht, der mit dem Hinzufügen von Datenspalten immer komplexer wird. Wir haben versucht, dies für unsere Zwecke zu nutzen, indem wir zeitlich gestaffelte Datensätze in Betracht zogen, um Prognosen zu erstellen. Während die Optimierungsergebnisse bei einem Durchlauf von nur 3 Generationen Potenzial zeigten, konnten diese Läufe nicht vorwärts gehen. Dies könnte durch die Kopplung dieser Signalklasse mit einer anderen Signalklasse behoben werden, oder es könnten umfangreichere Tests über längere Zeiträume durchgeführt werden.

Zum Thema des Artikels: Natürliche Transformationen eignen sich sehr gut für den Umgang mit unterschiedlichen Datenstrukturen, und zwar nicht nur in Fällen, in denen sich ein Datensatz aufgrund von Geschäfts- oder Analyseerfordernissen entwickelt, sondern möglicherweise auch in Fällen, in denen ein Vergleich erforderlich ist und die Dimensionen (Anzahl der Spalten) der beiden Datensätze standardmäßig nicht gleich sind. Dies ist eine Funktion, die sich sicherlich in einigen Disziplinen als nützlich erweisen wird.


Referenzen

Wie immer stammen die meisten Referenzen von Wikipedia. Bitte beachten Sie die Links in diesem Artikel.

Die beigefügte Signaldatei muss mit dem MQL5-Assistenten erstellt werden. Dieser Artikel kann als Orientierung dienen, wenn jemand mit den Assistenten-Klassen nicht vertraut ist.


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

Beigefügte Dateien |
ct_21.mqh (31.39 KB)
SignalCT_21_r2.mqh (11.52 KB)
Kategorientheorie in MQL5 (Teil 22): Ein anderer Blick auf gleitende Durchschnitte Kategorientheorie in MQL5 (Teil 22): Ein anderer Blick auf gleitende Durchschnitte
In diesem Artikel versuchen wir, die in dieser Reihe behandelten Konzepte zu vereinfachen, indem wir uns auf einen einzigen Indikator beschränken, der am häufigsten vorkommt und wahrscheinlich am leichtesten zu verstehen ist. Der gleitende Durchschnitt. Dabei betrachten wir die Bedeutung und die möglichen Anwendungen von vertikalen natürlichen Transformationen.
Neuronale Netze leicht gemacht (Teil 55): Contrastive Intrinsic Control (CIC) Neuronale Netze leicht gemacht (Teil 55): Contrastive Intrinsic Control (CIC)
Das kontrastive Training ist eine unüberwachte Methode zum Training der Repräsentation. Ziel ist es, ein Modell zu trainieren, das Ähnlichkeiten und Unterschiede in Datensätzen aufzeigt. In diesem Artikel geht es um die Verwendung kontrastiver Trainingsansätze zur Erkundung verschiedener Fähigkeiten des Akteurs (Actor skills).
GUI: Tipps und Tricks zur Erstellung Ihrer eigenen Grafikbibliothek in MQL GUI: Tipps und Tricks zur Erstellung Ihrer eigenen Grafikbibliothek in MQL
Wir gehen die Grundlagen von GUI-Bibliotheken durch, damit Sie verstehen, wie sie funktionieren, oder sogar anfangen können, Ihre eigenen zu erstellen.
Neuronale Netze leicht gemacht (Teil 54): Einsatz von Random Encoder für eine effiziente Forschung (RE3) Neuronale Netze leicht gemacht (Teil 54): Einsatz von Random Encoder für eine effiziente Forschung (RE3)
Wann immer wir Methoden des Verstärkungslernens in Betracht ziehen, stehen wir vor dem Problem der effizienten Erkundung der Umgebung. Die Lösung dieses Problems führt häufig dazu, dass der Algorithmus komplizierter wird und zusätzliche Modelle trainiert werden müssen. In diesem Artikel werden wir einen alternativen Ansatz zur Lösung dieses Problems betrachten.