English Русский 中文 Español 日本語 Português
Die praktische Verwendung eines neuronalen Kohonen-Netzes im algorithmischen Handel. Teil II. Optimierung und Vorhersage

Die praktische Verwendung eines neuronalen Kohonen-Netzes im algorithmischen Handel. Teil II. Optimierung und Vorhersage

MetaTrader 5Tester | 11 April 2019, 08:48
890 0
Stanislav Korotky
Stanislav Korotky

In diesem Artikel betrachten wir Kohonen-Netzwerke weiterhin als ein Werkzeug für Händler. In Teil I haben wir die öffentlich zugänglichen neuronalen Netzwerkklassen korrigiert und verbessert, indem wir notwendige Algorithmen hinzugefügt haben. Jetzt ist es an der Zeit, sie praktisch anzuwenden. In diesem Artikel werden wir Kohonen-Karten zur Lösung von Problemen verwenden, wie z.B. die Auswahl der optimalen EA-Parameter und die Vorhersage von Zeitreihen.


Suche nach den optimalen EA-Parametern

Gemeinsame Grundsätze

Für die Optimierung von Robotern bieten viele Handelsplattformen, darunter MetaTrader, geeignete Lösungen. Der integrierte Tester bietet eine Vielzahl von Tools, fortschrittliche Algorithmen, verteilte Berechnungen und feinkörnige statistische Auswertungen. Aus der Sicht des Benutzers gibt es jedoch immer eine kritischere letzte Phase der Optimierung, nämlich die Phase der Auswahl der endgültigen Arbeitsparameter, die auf der Analyse dieser Flut von Informationen basiert, die durch das Programm erzeugt werden. In den vorangegangenen Artikeln, die sich mit Kohonen-Karten befassen und auf dieser Website veröffentlicht wurden, wurden Beispiele für die visuelle Analyse der Optimierungsergebnisse gegeben. Dies deutet jedoch darauf hin, dass der Benutzer selbst eine Expertenanalyse durchführen muss. Im Idealfall möchten wir konkretere Empfehlungen aus dem neuronalen Netz erhalten. Alles in allem ist der algorithmische Handel der Handel eines Programms ohne Eingreifen des Benutzers.

Nach Abschluss der Optimierung erhalten wir in der Regel einen langen Testerbericht mit vielen Optionen. Abhängig von der zu sortierenden Spalte extrahieren wir aus ihrer Tiefe absolut unterschiedliche Einstellungen, die Optimalität für ein relevantes Kriterium bedeuten, wie Gewinn, Sharpe Ratio, etc. Wenn wir auch nur ein Kriterium bestimmt haben, dem wir am meisten vertrauen, bietet das System oft mehrere Einstellungen mit dem gleichen Ergebnis an. Wie kann man wählen?

Einige Händler praktizieren ihr eigenes synthetisches Kriterium, das mehrere Standardindizes in die Berechnungen einbezieht - mit diesem Ansatz ist es wirklich weniger möglich, gleiche Zeichenketten im Bericht zu erhalten. Allerdings übersetzen sie die Angelegenheit in den Bereich der Meta-Optimierung des genannten Kriteriums (wie kann man seine Formel richtig wählen?). Aber das ist ein eigenes Thema. Wir werden also wieder auf die Analyse der Ergebnisse der standardmäßig Optimierung zurückkommen.

Meiner Meinung nach muss die Auswahl des optimalen EA-Parametersatzes auf der Suche nach dem längsten "Plateau" im Bereich der Werte einer Zielfunktion mit dem voreingestellten Mindestwert dieses "Plateau" basieren, anstatt nach dem Maximum dieser Funktion zu suchen. Im Handelskontext kann das Niveau des "Plateaus" mit der durchschnittlichen Rentabilität verglichen werden, während seine Länge mit der Zuverlässigkeit, d.h. mit der Robustheit und Stabilität des Systems, verglichen werden kann.

Nachdem wir in Teil I einige Datenanalyseverfahren gezielt betrachtet haben, wird vorgeschlagen, dass solche "Plateaus" nach einer Haufenbildung (Clusters) durchsucht werden können.

Leider gibt es keine einheitlichen oder universellen Methoden, um Cluster mit den gewünschten Eigenschaften zu erhalten. Vor allem, wenn die Anzahl der Cluster "zu" groß ist, werden sie klein und zeigen alle Symptome des Wiedererlernens - sie verallgemeinern Informationen schlecht. Wenn es "zu" wenige Cluster gibt, dann sind sie eher untertrainiert, so dass sie die grundlegend unterschiedlichen Proben in sich aufnehmen. Der Begriff "auch" hat keine klaren Definitionen, da es für jede Aufgabe, Anzahl und Struktur von Daten einen bestimmten Schwellenwert gibt. Daher wird in der Regel vorgeschlagen, mehrere Experimente durchzuführen.

Die Anzahl der Cluster (Haufen) hängt logisch von der Größe der Karte und der angewandten Aufgabe ab. In unserem Fall funktioniert der erstgenannte Faktor nur in eine Richtung, da wir uns zuvor entschieden haben, die Größe durch Formel (7) einzustellen. Dementsprechend erhalten wir bei Kenntnis dieser Größe eine Obergrenze für die Anzahl der Cluster — es kann kaum mehr davon geben als die Größe einer Seite. Andererseits, basierend auf der angewandten Aufgabe, würde uns wahrscheinlich nur ein Cluster-Paar gefallen: "gute" und "schlechte" Einstellungen. Dies ist der Bereich, in dem Experimente durchgeführt werden können. All dies gilt nur für Algorithmen, die auf einer klaren Angabe der Anzahl der Cluster basieren, wie z.B. K-Means. Unser alternativer Algorithmus hat keine solche Einstellung, aber aufgrund der qualitativen Anordnung der Cluster können wir einfach alle Cluster mit Zahlen über dem gegebenen Wert von unserer Betrachtung ausschließen.

Dann werden wir versuchen, die Clusterbildung über das Kohonen-Netzwerk durchzuführen. Wir müssen jedoch einen genaueren Punkt besprechen, bevor wir in die Praxis gehen.

Viele Roboter werden über den sehr großen Bereich der Parameter optimiert. Daher wird die Optimierung durch einen genetischen Algorithmus durchgeführt. Es spart Zeit und Ressourcen. Sie hat jedoch eine Besonderheit, nämlich in profitable Bereiche zu "fallen". Im Prinzip war das die Absicht. Was die Kohonen-Karten betrifft, ist sie jedoch nicht sehr gut. Es geht darum, dass Kohonen-Karten empfindlich auf die Datenverteilung im Eingangsbereich reagieren und diese auch in der resultierenden Topologie widerspiegeln. Da die schlechten Versionen von Parametern in früheren Stadien von der Genetik ausgeschlossen werden, treten sie viel seltener auf als die guten, die von der Genetik in sehr vielen Details vererbt werden. Infolgedessen kann das Kohonen-Netzwerk es unterlassen, die gefährlichen Täler der Zielfunktion in der Nähe der angeblich guten gefundenen Versionen zu bemerken. Da die Markteigenschaften immer schwanken, ist es wichtig, solche Parameter zu vermeiden, bei denen ein linker oder rechter Schritt zu Verlusten führt.

Dies sind die Wege, um das Problem zu lösen:

  1. Um die genetische Optimierung zugunsten der vollen aufzugeben; da sie nicht immer in vollem Umfang möglich ist, ist es erlaubt, den hierarchischen Ansatz umzusetzen, d.h, um die genetische Optimierung mit einem großen Schritt durchzuführen, zuerst interessante Bereiche zu lokalisieren und dann die vollständige Optimierung in ihnen durchzuführen (und dann mit dem Kohonen-Netz zu analysieren); es wird auch angenommen, dass die Übererweiterung der Liste der zu optimierenden Parameter dem System die Anzahl der Freiheitsgrade liefert, durch die es zunächst instabil wird; und zweitens erzeugt die Optimierung eine Anpassung; daher wird empfohlen, permanente Werte für den größten Teil der Parameter basierend auf ihrer physikalischen Bedeutung und auf der Fundamentalanalyse auszuwählen (z.B. Zeitrahmen sollten entsprechend dem Strategietyp ausgewählt werden): Ein Tag für die Intraday-Strategien, eine Woche für die mittelfristigen Strategien, etc.); dann ist es möglich, den Optimierungsraum zu reduzieren und die Genetik aufzugeben;
  2. Um die genetische Optimierung mehrmals zu wiederholen, verwenden Sie als Kriterium sowohl Maxima als auch Minima und die Null der Zielfunktion; z.B. können Sie die Optimierung dreifach durchführen:
    • Nach Gewinnfaktor (profit factor, PF), wie üblich;
    • Durch seinen Kehrwert, 1/PF;
    • Nach der Formel (min(PF, 1/PF) / max(PF, 1/PF)), die Statistiken um 1 sammeln würde;
    Danach, um die Ergebnisse aller Optimierungen zu konsolidieren und sie durch das Netzwerk als ein einheitliches Ganzes zu analysieren;
  3. Eine halbe Maßnahme, aber immer noch lohnend, ist die Erstellung von Kohonen-Karten in einer Metrik, die einen optimierten Indikator (und grundsätzlich alle ökonomischen Indikatoren, die keine Expertenparameter sind) ausschließt. Mit anderen Worten, im Lernprozess des Netzwerks sollte das Maß der Ähnlichkeit zwischen den Gewichten der Neuronen und den Eingangsdaten nur für die ausgewählten Komponenten berücksichtigt werden, die den Parametern des Experten entsprechen. Die inverse Metrik ist auch interessant, wenn die Annäherungsmaße nur von ökonomischen Indikatoren betrachtet werden und wir wahrscheinlich die topologische Variation in den Ebenen der Parameter sehen, die auf die Instabilität des Systems hindeutet; In beiden Fällen wird die Einstellung der Gewichte von Neuronen vollständig vorgenommen - für alle Komponenten;

Die letzte Version N3 bedeutet, dass die Netzwerktopologie nur die Verteilung der EA-Parameter (oder ökonomische Indizes, je nach Richtung) widerspiegelt. In der Tat, wenn wir das Netzwerk auf die ganzen Zeilen aus der Optimierungstabelle trainieren, bilden die Spalten, wie Gewinn, Drawdown und Anzahl der Positionen, die Gesamtverteilung der Neuronen in dem Maße, wie nicht weniger als die der EA-Parameter. Dies kann gut sein, damit das Problem der visuellen Analyse zu einem allgemeinen Verständnis kommt und die Schlussfolgerungen gezogen werden können, welche Parameter sich am meisten auf welche Indizes auswirken. Aber das ist schlecht für die Analyse unserer Parameter, da ihre reale Verteilung durch ökonomische Indizes verändert wird.

Im Prinzip liegt es bei der Analyse der Optimierungsergebnisse nahe, den Eingangsvektor in zwei logisch getrennte Komponenten aufzuteilen: die EA-Inputs und ihre Indizes (Output). Wenn wir ein Kohonen-Netzwerk auf einem Vollvektor trainieren, versuchen wir, die Abhängigkeit von "Inputs" und "Outputs" (eine bidirektionale unbedingte Beziehung) zu identifizieren. Wenn das Netzwerk nur auf einem Teil der Merkmale trainiert wird, können wir versuchen, die gerichteten Beziehungen zu sehen: Wie "Ausgänge" geclustert werden, hängt von "Eingängen" ab oder umgekehrt, wie "Eingänge" geclustert werden, hängt von "Ausgängen" ab.Wir werden beide Optionen prüfen.


Weiterentwicklung des SOM-Explorer

Um diesen Lernmodus mit Maskierung einiger Merkmale zu implementieren, ist eine Weiterentwicklung der Klassen CSOM und CSOMNode erforderlich.

Die Abstände werden in der Klasse CSOMNode berechnet. Das Ausschließen bestimmter Komponenten von der Berechnung ist für alle Objekte der Klasse einheitlich, so dass wir die relevanten Variablen statistisch darstellen werden:

    static int dimensionMax;
    static ulong dimensionBitMask;

dimensionMax ermöglicht es, die maximale Anzahl der zu berechnenden Neuronengewichte einzustellen. Wenn beispielsweise die Raumdimensionalität 5 ist, dann soll die dimensionMax gleich 4 bedeuten, dass die letzte Komponente des Vektors von der Berechnung ausgeschlossen wird.

dimensionBitMask erlaubt es, die zufällig angeordneten Komponenten über eine Bitmaske auszuschließen: Wenn das i-te Bit gleich 1 ist, dann wird die i-te Komponente bearbeitet ist es gleich 0, dann wird sie ignoriert.

Lassen Sie uns die statische Methode zum Platzieren der Variablen hinzufügen:

static void CSOMNode::SetFeatureMask(const int dim = 0, const ulong bitmask = 0)
{
  dimensionMax = dim;
  dimensionBitMask = bitmask;
}

Nun werden wir die Abstandsberechnung mittels der neuen Variablen abändern:

double CSOMNode::CalculateDistance(const double &vector[]) const
{
  double distSqr = 0;
  if(dimensionMax <= 0 || dimensionMax > m_dimension) dimensionMax = m_dimension;
  for(int i = 0; i < dimensionMax; i++)
  {
    if(dimensionBitMask == 0 || ((dimensionBitMask & (1 << i)) != 0))
    {
      distSqr += (vector[i] - m_weights[i]) * (vector[i] - m_weights[i]);
    }
  }
  return distSqr;
}

Nun müssen wir nur noch sicherstellen, dass die Klasse CSOM die Beschränkungen in den Neuronen korrekt platziert. Ergänzen wir CSOM um eine entsprechende 'public-Methode:

void CSOM::SetFeatureMask(const int dim, const ulong bitmask)
{
  m_featureMask = 0;
  m_featureMaskSize = 0;
  if(bitmask != 0)
  {
    m_featureMask = bitmask;
    Print("Feature mask enabled:");
    for(int i = 0; i < m_dimension; i++)
    {
      if((bitmask & (1 << i)) != 0)
      {
        m_featureMaskSize++;
        Print(m_titles[i]);
      }
    }
  }
  CSOMNode::SetFeatureMask(dim == 0 ? m_dimension : dim, bitmask);
}

Im Test-EA erstellen wir den Parameter FeatureMask (Merkmalsmaske, eine Zeichenkette), mit der der vom Nutzer die Eigenschaftsmaske bestimmt und die nach '0' und '1' analysiert werden kann.

    ulong mask = 0;
    if(FeatureMask != "")
    {
      int n = MathMin(StringLen(FeatureMask), 64);
      for(int i = 0; i < n; i++)
      {
        mask |= (StringGetCharacter(FeatureMask, i) == '1' ? 1 : 0) << i;
      }
    }
    KohonenMap.SetFeatureMask(0, mask);

All dies geschieht unmittelbar vor der Einführung der Trainingsmethode und wirkt sich daher auf die Berechnung der Abstände sowohl während des Lernens als auch in der Phase der Berechnung von U-Matrix und Clustern aus. In einigen Fällen wird es jedoch für uns interessant sein, die Clusterbildung nach anderen Regeln durchzuführen, wie z.B. das Trainieren des Netzwerks ohne Maske und die Anwendung der Maske, um nur Cluster zu finden. Zu diesem Zweck werden wir zusätzlich den Steuerparameter ApplyFeatureMaskAfterTraining einführen, der standardmäßig dem Wert "false" entspricht. Wenn er jedoch auf 'true' gesetzt ist, werden wir SetFeatureMask nach dem Training aufrufen.

Während wir unsere Werkzeuge noch einmal verbessern, werden wir auf einen weiteren Punkt eingehen, der sich darauf bezieht, dass wir die Arbeitseinstellungen von Handelsrobotern als Inputvektoren verwenden werden.

Es wäre bequem, die Werte der EA-Parameter in das Netzwerk hochzuladen, um sie direkt aus der Set-Datei zu analysieren. Zu diesem Zweck schreiben wir die folgende Funktion:

bool LoadSettings(const string filename, double &v[])
{
  int h = FileOpen(filename, FILE_READ | FILE_TXT);
  if(h == INVALID_HANDLE)
  {
    Print("FileOpen error ", filename, " : ",GetLastError());
    return false;
  }
  
  int n = KohonenMap.GetFeatureCount();
  ArrayResize(v, n);
  ArrayInitialize(v, EMPTY_VALUE);
  int count = 0;

  while(!FileIsEnding(h))
  {
    string line = FileReadString(h);
    if(StringFind(line, ";") == 0) continue;
    string name2value[];
    if(StringSplit(line, '=', name2value) != 2) continue;
    int index = KohonenMap.FindFeature(name2value[0]);
    if(index != -1)
    {
      string values[];
      if(StringSplit(name2value[1], '|', values) > 0)
      {
        v[index] = StringToDouble(values[0]);
        count++;
      }
    }
  }
  
  Print("Settings loaded: ", filename, "; features found: ", count);
  
  ulong mask = 0;
  for(int i = 0; i < n; i++)
  {
    if(v[i] != EMPTY_VALUE)
    {
      mask |= (1 << i);
    }
    else
    {
      v[i] = 0;
    }
  }
  if(mask != 0)
  {
    KohonenMap.SetFeatureMask(0, mask);
  }
 
  FileClose(h);
  return count > 0;
}

Darin analysieren wir die Zeichenketten der Set-Datei und finden in ihnen die Namen von Parametern, die den Eigenschaften eines trainierten Netzwerks entsprechen. Die übereinstimmenden Einstellungen werden im Vektor gespeichert, während die nicht übereinstimmenden Einstellungen übersprungen werden. Die Merkmalsmaske ist nur für die verfügbaren Komponenten mit Einheiten gefüllt. Die Funktion gibt das logische Merkmal der Tatsache zurück, dass die Einstellungen gelesen wurden.

Wenn wir nun diese Funktion zur Verfügung haben, um die Parameter aus den Einstellungsdateien herunterzuladen, werden wir die folgenden Zeichenketten in den Zweig des Operators 'if' einfügen, in dem die Überprüfung von DataFileName != "" stattfindet:

      // process.set: Datei, als Sonderfall des Musters
      if(StringFind(DataFileName, ".set") == StringLen(DataFileName) - 4)
      {
        double v[];
        if(LoadSettings(DataFileName, v))
        {
          KohonenMap.AddPattern(v, "SETTINGS");
          ArrayPrint(v);
          double y[];
          CSOMNode *node = KohonenMap.GetBestMatchingFeatures(v, y);
          Print("Matched Node Output (", node.GetX(), ",", node.GetY(),
            "); Hits:", node.GetHitsCount(), "; Error:", node.GetMSE(),
            "; Cluster N", node.GetCluster(), ":");
          ArrayPrint(y);
          KohonenMap.CalculateOutput(v, true);
          hasOneTestPattern = true;
        }
      }

Die Einstellungen werden mit SETTINGS gekennzeichnet.


Arbeits-EA

Nun nähern wir uns dem Problem der Auswahl der optimalen Parameter.

Um die Theorien der Clusterbildung der Optimierungsergebnisse zu testen, müssen wir zunächst einen funktionierenden EA erstellen. Ich habe es mit dem MQL5 Wizard und einigen Standardmodulen erstellt und es WizardTest genannt (sein Quellcode ist am Ende dieses Artikels angehängt). Hier ist die Liste der Eingaben:

input string             Expert_Title                 ="WizardTest"; // Dokumentenname
ulong                    Expert_MagicNumber           =17897;        // 
bool                     Expert_EveryTick             =false;        // 
//--- inputs for main signal
input int                Signal_ThresholdOpen         =10;           // Signal-Schwellenwert für die Eröffnung [0...100]
input int                Signal_ThresholdClose        =10;           // Signal-Schwellenwert für das Schließen  [0...100]
input double             Signal_PriceLevel            =0.0;          // Preis für die Ausführung eines Deals
input double             Signal_StopLevel             =50.0;         // Stop-Loss (in Points)
input double             Signal_TakeLevel             =50.0;         // Take-Profit (in Points)
input int                Signal_Expiration            =4;            // Verfallszeit von Pending-Orders (in Bars)
input int                Signal_RSI_PeriodRSI         =8;            // Relative Strength Index(8,...) Berechnungsperioden
input ENUM_APPLIED_PRICE Signal_RSI_Applied           =PRICE_CLOSE;  // Relative Strength Index(8,...) Zweitreihe der Preise
input double             Signal_RSI_Weight            =1.0;          // Relative Strength Index(8,...) Gewicht [0...1.0]
input int                Signal_Envelopes_PeriodMA    =45;           // Envelopes(45,0,MODE_SMA,...) Glättungslänge
input int                Signal_Envelopes_Shift       =0;            // Envelopes(45,0,MODE_SMA,...) Zeitversatz
input ENUM_MA_METHOD     Signal_Envelopes_Method      =MODE_SMA;     // Envelopes(45,0,MODE_SMA,...) Glättungsverfahren
input ENUM_APPLIED_PRICE Signal_Envelopes_Applied     =PRICE_CLOSE;  // Envelopes(45,0,MODE_SMA,...) Zeitreihe der Preise
input double             Signal_Envelopes_Deviation   =0.15;         // Envelopes(45,0,MODE_SMA,...) Abweichung
input double             Signal_Envelopes_Weight      =1.0;          // Envelopes(45,0,MODE_SMA,...) Gewicht [0...1.0]
input double             Signal_AO_Weight             =1.0;          // Awesome Oscillator Gewicht [0...1.0]
//--- Eingabeparameter für das Trailing
input double             Trailing_ParabolicSAR_Step   =0.02;         // Geschwindigkeitserhöhung
input double             Trailing_ParabolicSAR_Maximum=0.2;          // Maximalwert
//--- Eingabeparameter des Geldes
input double             Money_FixRisk_Percent=5.0;          // Risikoprozentsatz

Für unsere Studienzwecke genügt es, nur ein paar Parameter zu optimieren und nicht alle.

Signal_ThresholdOpen
Signal_ThresholdClose
Signal_RSI_PeriodRSI
Signal_Envelopes_PeriodMA
Signal_Envelopes_Deviation
Trailing_ParabolicSAR_Step
Trailing_ParabolicSAR_Maximum

Ich habe die genetische Optimierung des EA von Januar bis Juni 2018 (20180101-20180701) auf EURUSD D1, M1 OHLC, mit Gewinn durchgeführt. Die Set-Datei mit den Einstellungen der zu optimierenden Parameter ist am Ende dieses Artikels beigefügt (WizardTest-1.set). Die Optimierungsergebnisse wurden in der Datei Wizard2018plus.csv (auch im Anhang) gespeichert, von der Ausreißer ausgeschlossen sind, insbesondere solche mit der Anzahl der Positionen unter 5 und mit den himmelhohen, irrealen Sharpe-Faktoren. Da die genetische Optimierung per Definition eine Verschiebung zu profitablen Passagen ergab, entschied ich mich außerdem, die Verlierer vollständig auszuschließen und behielt die Einträge nur dort, wo der Gewinn mindestens 10.000 gemacht hatte.

Ich habe auch ein Paar Indexspalten entfernt, da sie tatsächlich von anderen abhängen, wie z.B. dem Saldo oder dem erwarteten Auszahlungsbetrag, und es gibt einige andere Kandidaten, wie z.B. PF (Profit Factor), RF (Rally Factor) und Sharpe Factor — hochgradig interkorreliert, außerdem ist RF umgekehrt mit dem Drawdown korreliert, aber ich habe sie an Ort und Stelle gehalten, um diese Abhängigkeit von den Karten zu zeigen.

Die Auswahl der Struktur der Eingänge mit einem Minimum an unabhängigen Komponenten, die das Maximum an Informationen tragen könnten, ist eine kritische Voraussetzung für die effiziente Nutzung neuronaler Netze.

Nachdem wir die csv-Datei mit den Optimierungsergebnissen geöffnet haben, werden wir diese fragwürdige Angelegenheit sehen, die ich oben erwähnt habe: Eine große Anzahl von Zeichenketten, die gleichermaßen profitable Indizes und verschiedene Parameter enthalten. Wir werden versuchen, eine begründbare Auswahl zu treffen.

Um einen Anhaltspunkt für die Bewertung unserer ausgewählten Option in Zukunft zu erhalten, betrachten wir den Vorwärtstest für den Parametersatz von der ersten Zeichenkette der Optimierungsergebnisse an (siehe WizardTest-1.set). Testzeitraum ist vom 1. Juli 2018 bis 1. Dezember 2018.

Testerbericht über die erste aufgelistete Auswahl der Einstellungen

Testerbericht über die erste aufgelistete Auswahl der Einstellungen

Erinnern Sie sich an diese eigentlich nicht sehr guten Zahlen, die wir mit ins Netz nehmen werden.


Analyse neuronaler Netze

Die Anzahl der Einträge in der csv-Datei beträgt ca. 2.000. Daher ist die nach Formel (7) berechnete Kohonen-Netzwerkgröße 15.

Wir starten den CSOM-Explorer, weisen DataFileName den Dateinamen (Wizard2018plus.csv) zu, geben 15 für CellsX und CellsY an und setzen die EpochNumber auf 100. Um alle Ebenen gleichzeitig zu betrachten, wählen wir kleine Bilder aus: 210 für jedes von ImageW und ImageH und 6 für MaxPictures. Als Ergebnis der EA-Operation werden wir im Wesentlichen das Folgende erhalten:

Trainieren des Kohonen-Netzwerks mit die Ergebnisse der EA-Optimierung

Trainieren des Kohonen-Netzwerks mit die Ergebnisse der EA-Optimierung

Die obere Reihe besteht vollständig aus den Karten der Wirtschaftsindizes, die zweite Reihe und die erste Karte der dritten Reihe sind die Arbeitsparameter des EA, und schließlich sind die letzten 5 Karten spezielle Karten, die in Teil I erstellt wurden.

Lassen Sie uns einen genaueren Blick auf die Karten werfen:

Gewinn, PF, RF und die ersten drei Parameter des Arbeits-EAs

Gewinn, PF, RF und die ersten drei Parameter des Arbeits-EAs

Sharpe Ratio, Drawdown, die Anzahl der Positionen und zweiten drei Parameter des EAs

Sharpe Ratio, Drawdown, die Anzahl der Positionen und zweiten drei Parameter des EAs

Die letzten drei Parameter des EAs und die Anzahl der Treffer, U-Matrix, Quantisierungsfehler, Clusters und Netzwerk-Outputs

Die letzten drei Parameter des EAs und die Anzahl der Treffer, U-Matrix, Quantisierungsfehler, Clusters und Netzwerk-Outputs

Lassen Sie uns die Expertenanalyse der erhaltenen Karten sozusagen manuell durchführen.

Auf der Ertragsseite sehen wir zwei geeignete Bereiche mit den etwa gleichen Werten (rot) in der rechten oberen und linken oberen Ecke, wobei der rechte Bereich größer und intensiver hervorgehoben ist. Die parallele Analyse der Ebenen mit PF-, RF- und Sharpe-Ratio überzeugt uns jedoch davon, dass die rechte obere Ecke die beste Wahl ist. Dies wird auch durch ein geringeres Drawdown bestätigt.

Gehen wir zu den Komponenten, die für die EA-Parameter relevant sind, und achten wir dabei auf die rechte obere Ecke. In den Karten der ersten fünf Parameter ist dieser Punkt stabil gefärbt, was es uns ermöglicht, die optimalen Werte vertrauensvoll zu benennen (zeigen Sie mit dem Mauszeiger auf das obere rechte Neuron in jeder Karte, um den entsprechenden Wert in der Spitze zu sehen):

Signal_ThresholdOpen = 40
Signal_ThresholdClose = 85
Signal_RSI_PeriodRSI = 73
Signal_Envelopes_PeriodMA = 20
Signal_Envelopes_Deviation = 0.5

Die Karten der beiden verbleibenden Parameter ändern ihre Farbe aktiv in der rechten oberen Ecke, so dass unklar ist, welche Werte gewählt werden sollen. Nach der Bewertung der Ebenen hinsichtlich der Trefferzahl ist das oberste rechte Neuron vorzuziehen. Es ist auch sinnvoll, darauf zu achten, dass es eine "ruhige Atmosphäre" dafür auf U-Matrix und auf der Fehlerkarte existiert. Da dort alles in Ordnung ist, wählen wir diese Werte aus:

Trailing_ParabolicSAR_Step = 0.15
Trailing_ParabolicSAR_Maximum = 1.59

Lassen Sie uns den EA mit diesen Parametern (siehe WizardTest-plus-allfeatures-manual.set) in der gleichen Vorwärts-Periode bis zum 1. Dezember 2018 laufen. Wir werden das folgende Ergebnis erzielen.

Testerbericht über die gewählten Einstellungen basierend auf der visuellen Analyse von Kohonen-Karten.

Testerbericht über die gewählten Einstellungen basierend auf der visuellen Analyse von Kohonen-Karten.

Das Ergebnis ist deutlich besser als das, das nach dem Zufallsprinzip aus der ersten Zeichenkette ausgewählt wurde. Allerdings kann es die Fachleute immer noch enttäuschen, so dass es sich lohnt, hier eine Bemerkung zu machen.

Dies ist ein Test-EA, kein Gral. Seine Aufgabe ist es, Quelldaten zu generieren, um zu zeigen, wie neuronale, netzwerkbasierte Algorithmen funktionieren. Nach der Veröffentlichung des Artikels wird es möglich sein, die Tools auf einer großen Anzahl von realen Handelssystemen zu testen und vielleicht für eine bessere Nutzung anzupassen.

Vergleichen wir das aktuelle Ergebnis mit den Durchschnittsindikatoren, die für alle Optionen aus der csv-Datei im selben Datumsbereich abgerufen werden können.

Ergebnisse aller Vorwärtsprüfungen

Ergebnisse aller Vorwärtsprüfungen

Statistische Verteilung des Gewinns im Vorwärtstest

Statistische Verteilung des Gewinns im Vorwärtstest

Die Statistiken sind wie folgt zu lesen: Der Mittelwert ist 1.007, die Standardabweichung ist 1.444, der Median ist 1.085, und der niedrigste und der höchste Wert sind -3.813,78 bzw. 4.202,82. So haben wir mit Hilfe der Expertenbewertung den Gewinn sogar noch höher als der Mittelwert plus Standardabweichung erzielt.

Unsere Aufgabe ist es, zu lernen, wie man automatisch die gleiche oder eine qualitativ ähnliche Wahl trifft. Dazu werden wir die Clusterbildung verwenden. Da die Cluster in der Reihenfolge ihrer bevorzugten Verwendung nummeriert sind, werden wir den Cluster 0 berücksichtigen (obwohl die Cluster 1-5 grundsätzlich für den Handel mit einem Portfolio von Einstellungen verwendet werden können).

Die Farben der Cluster auf der Karte beziehen sich immer auf ihre Indizes, wie unten aufgeführt:

{clrRed, clrGreen, clrBlue, clrYellow, clrMagenta, clrCyan, clrGray, clrOrange, clrSpringGreen, clrDarkGoldenrod}

Dies kann helfen, sie auf kleineren Bildern zu identifizieren, bei denen es schwierig ist, die Zahlen zu unterscheiden.

Der SOM-Explorer zeigt im Protokoll die Koordinaten von Clusterzentren an, z.B. für die aktuelle Karte:

Clusters [20]:
[ 0] "Profit"                        "Profit Factor"                 "Recovery Factor"               "Sharpe Ratio"                 
[ 4] "Equity DD %"                   "Trades"                        "Signal_ThresholdOpen"          "Signal_ThresholdClose"        
[ 8] "Signal_RSI_PeriodRSI"          "Signal_Envelopes_PeriodMA"     "Signal_Envelopes_Deviation"    "Trailing_ParabolicSAR_Step"   
[12] "Trailing_ParabolicSAR_Maximum"
N0 [3,2]
[0] 18780.87080     1.97233     3.60269     0.38653    16.76746    63.02193    20.00378
[7]    65.71576    24.30473    19.97783     0.50024     0.13956     1.46210
N1 [1,4]
[0] 18781.57537     1.97208     3.59908     0.38703    16.74359    62.91901    20.03835
[7]    89.61035    24.59381    19.99999     0.50006     0.12201     0.73983
...

Am Anfang steht die Merkmalsbeschreibung. Dann gibt es für jeden Cluster seine Anzahl, die X- und Y-Koordinaten und die Werte der Merkmale.

Hier, für den Cluster 0, haben wir die folgenden funktionierenden EA-Parameter:

Signal_ThresholdOpen=20
Signal_ThresholdClose=66
Signal_RSI_PeriodRSI=24
Signal_Envelopes_PeriodMA=20
Signal_Envelopes_Deviation=0.5
Trailing_ParabolicSAR_Step=0.14
Trailing_ParabolicSAR_Maximum=1.46

Wir werden einen Vorwärtstest mit diesen Parametern durchführen (WizardTest plus alle Features-auto-nomasks.set) und erhalten folgenden Bericht:

Testerbericht für die automatisch aus den Clustern der Kohonen-Karten ausgewählten Einstellungen ohne Funktionsmaske

Testerbericht für die automatisch aus den Clustern der Kohonen-Karten ausgewählten Einstellungen ohne Funktionsmaske

Das Ergebnis ist nicht viel besser als das der ersten Stichprobe, und es ist bemerkenswert schlechter als der Experten-Test. Es geht um die Qualität der Clusterbildung. Im Moment wird sie von allen Merkmalen auf einmal durchgeführt, einschließlich der Wirtschaftsindizes und der EA-Parameter. Wir sollten jedoch in Bezug auf die Handelszahlen nach dem "Plateau" suchen. Wenden wir uns bei der Clusterbildung der Merkmalsmaske zu, die nur sie berücksichtigt, d.h. die ersten sechs. Um dies zu tun, setzen wir:

FeatureMask=1111110000000
FeatureMaskAfterTraining=true

Und dann starten wir das Training erneut. Die Clusterbildung im SOM-Explorer wird als letzte Lernphase durchgeführt, und die erhaltenen Cluster werden in der Netzwerkdatei gespeichert. Dies ist notwendig, damit das später geladene Netzwerk sofort zum "Erkennen" neuer Stichproben verwendet werden kann. Solche Stichproben können nicht alle Indizes enthalten (d.h. der Vektor kann unvollständig sein), wie z.B. bei der Analyse der Set-Dateien — sie enthalten nur die Parameter der EA, aber es gibt keine wirtschaftlichen Indizes (es macht ja keinen Sinn). Daher wird für solche Beispiele in der Funktion LoadSettings eine eigene Merkmalsmaske konstruiert, die den vorhandenen Komponenten des Vektors entspricht, und dann wird diese Maske auf das Netzwerk angewendet. Die Maske für die Clusterbildung muss also implizit im Netzwerk vorhanden sein, um nicht mit der Maske des zu "erkennenden" Vektors in Konflikt zu geraten.

Aber kommen wir zurück zum Lernen mit der neuen Maske. Es wird die Ebene der U-Matrix und der Cluster verändern. Das Muster der Cluster ändert sich erheblich (das linke Bild ist vor dem Anwenden der Maske, während das rechte Bild nach dem Anwenden der Maske ist).

Cluster auf Kohonen-Karten, die ohne (links) und mit (rechts) Anwendung der Maske nach Wirtschaftsindizes konstruiert wurden.

Cluster auf Kohonen-Karten, die ohne (links) und mit (rechts) Anwendung der Maske nach Wirtschaftsindizes konstruiert wurden.

Nun sind die Werte der Null-Cluster verschieden.

N0 [14,1] 
[0] 17806.57263     2.79534     6.78011     0.48506    10.70147    49.90295    40.00000
[7]    85.62392    73.51490    20.00000     0.49750     0.13273     1.29078

Wenn Sie sich erinnern, haben wir in unserer Expertenbewertung das Neuron ausgewählt, das sich in der rechten oberen Ecke befindet, d.h. das die Koordinaten[14,0] hat. Nun bietet uns das System das benachbarte Neuron[14,1] an. Ihre Gewichte sind nicht sehr unterschiedlich. Lassen Sie uns die vorgeschlagenen Einstellungen in die Parameter des funktionierenden EA verschieben.

Signal_ThresholdOpen=40
Signal_ThresholdClose=86
Signal_RSI_PeriodRSI=74
Signal_Envelopes_PeriodMA=20
Signal_Envelopes_Deviation=0.5
Trailing_ParabolicSAR_Step=0.13
Trailing_ParabolicSAR_Maximum=1.29

Wir erhalten folgendes Ergebnis:

Testerbericht für die automatisch aus den Clustern der Kohonen-Karten ausgewählten Einstellungen unter Verwendung der Maske der Wirtschaftsindizes.

Testerbericht für die automatisch aus den Clustern der Kohonen-Karten ausgewählten Einstellungen unter Verwendung der Maske der Wirtschaftsindizes.

Sie sind identisch mit den Expertenergebnissen, unabhängig von einigen Unterschieden in den Parametern.

Um das Verschieben der Ergebnisse der Clusterbildung in die EA-Einstellungen zu erleichtern, werden wir eine Hilfsfunktion schreiben, die die Set-Datei mit den Namen und Werten der Merkmale des ausgewählten Clusters erzeugt (standardmäßig Null). Die Funktion heißt SaveSettings und beginnt zu arbeiten, wenn der neue Parameter SaveClusterAsSettings den Index des zu exportierenden Clusters enthält. Standardmäßig enthält dieser Parameter -1, d.h. es ist nicht notwendig, die Set-Datei zu generieren. Es ist klar, dass diese Funktion den angewandten Sinn der Merkmale nicht "kennt" und sie alle in der Set-Datei genannten speichert, so dass auch Handelsindizes wie Profit, Profit Factor usw. vorhanden sind. Der Benutzer kann aus der erzeugten Datei nur Funktionen kopieren, die den realen Parametern des EA entsprechen. Die Werte der Parameter werden als reelle Zahlen gespeichert, so dass sie für die ganzzahligen Parameter korrigiert werden müssen.

Nachdem wir nun in der Lage sind, die gefundenen Einstellungen in portabler Form zu speichern, lassen Sie uns Einstellungen für den Cluster 0 (Wizard2018plusCluster0.set) erstellen und in den SOM-Explorer zurückladen (es sei daran erinnert, dass unser Dienstprogramm bereits Set-Dateien lesen konnte). Im Parameter NetFileName muss der Name des Netzwerks angegeben werden, das in der vorherigen Lernphase erstellt wurde (es muss Wizard2018plus.som sein, da wir die Daten von Wizard2018plus.csv verwendet haben — bei jedem Lernzyklus wird es in der Datei gespeichert, deren Name der Name des eingegebenen Netzwerks ist, jedoch mit der Erweiterung .som). Im Parameter DataFileName geben wir den Namen der erzeugten Set-Datei an. Markierte SETTINGS wird mit der Mitte des Clusters C0 überlagert.

Wir werden die Som-Datei mit dem Netzwerk umbenennen, damit sie bei den nachfolgenden Experimenten nicht neu geschrieben wird.

Das erste Experiment wird wie folgt sein. Wir werden das Netzwerk mit einer "umgekehrten" Maske trainieren — anhand der EA-Parameter, wobei die Handelszahlen ausgeschlossen sind. Um dies zu tun, werden wir die Datei Wizard2018plus.csv im Parameter DataFileName erneut angeben, den Parameter NetFileName löschen und setzen 

FeatureMask=0000001111111

Bitte beachten Sie, dass FeatureMaskAfterTraining immer noch auf 'true' gesetzt ist, d.h. die Maske wirkt sich nur auf die Clusterbildung aus.

Nach Abschluss des Lernens laden wir das trainierte Netzwerk und testen die Set-Datei darauf. Dazu weisen wir den Namen der erstellten Netzwerkdatei Wizard2018plus.som dem Parameter NetFileName und Wizard2018plusCluster0.set DataFileName zu. Der gesamte Kartensatz bleibt unverändert, während U-Matrix und damit die Cluster sich verändern.

Das Ergebnis der Clusterbildung ist in der Abbildung unten links dargestellt:

Cluster in Kohonen-Netzwerken, die mit einer Maske für die EA-Parameter konstruiert wurden: Nur in der Phase der Clusterbildung (links) und in der Netzwerk-Lern- und Clusterbildungsphase (rechts).

Cluster auf Kohonen-Karten, die mit einer Maske für die EA-Parameter konstruiert wurden: Nur in der Clusterbildungsphase (links) und in der Netzwerk-Lern- und Clusterbildungsphase (rechts).

Die Auswahl der Einstellungen wird dadurch bestätigt, dass sie zum Null-Cluster gelangen und größer sind.

Als zweites Experiment werden wir das Netzwerk noch einmal mit der gleichen Maske (durch die EA-Parameter) trainiert. Wir werden es aber auch auf die Trainingsphase ausdehnen:

FeatureMaskAfterTraining=false

Der gesamte Kartensatz ist unten dargestellt, während die Änderungen der Cluster im oberen Bild rechts in größerem Maßstab dargestellt werden. Hier werden die Neuronen nur durch die Ähnlichkeit der Parameter gebündelt. Diese Karten sollten wie folgt gelesen werden: Welche Wirtschaftsindizes werden für die ausgewählten Parameter erwartet? Obwohl die Testeinstellungen im Cluster Nummer 2 gefallen sind (es ist schlechter als 2, aber nicht viel), ist seine Größe eine der größten, was ein positives Merkmal ist.

Kohonen-Karten, die mit einer Maske aus den EA-Parametern erstellt wurden.

Kohonen-Karten, die mit einer Maske aus den EA-Parametern erstellt wurden.

Ein interessierter Leser wird feststellen, dass die Karten mit ökonomischen Indizes nicht mehr so ausgedrückt topologischer Natur sind. Dies ist jedoch jetzt nicht mehr notwendig, da die Essenz der Überprüfung darin besteht, die Struktur der Cluster anhand der Parameter zu identifizieren und sicherzustellen, dass die ausgewählten Einstellungen in diesem System von Clustern gut platziert sind.

Eine "umgekehrte" Untersuchung wäre das vollständige Lernen und die Clusterbildung mit der Maske durch ökonomische Indizes:

FeatureMask=1111110000000
FeatureMaskAfterTraining=false

Dies ist das Ergebnis:

Kohonen-Karten, die mit einer Maske der Wirtschaftsindikatoren erstellt wurden.

Kohonen-Karten, die mit einer Maske der Wirtschaftsindikatoren erstellt wurden.

Nun sind die Kontrastfarben auf die ersten sechs Ebenen der ökonomischen Indizes konzentriert, während die Parameterkarten eher amorph sind. Insbesondere können wir sehen, dass sich die Werte der Parameter Trailing_ParabolicSAR_Step und Trailing_ParabolicSAR_Maximum praktisch nicht ändern (die Karten sind monoton), d.h. sie können von der Optimierung ausgeschlossen werden, wenn sie auf einem Durchschnittswert wie 0,11 bzw. 1,14 basieren. Unter den Parametern hebt sich Signal_ThresholdOpen durch seinen Kontrast ab, und es wird deutlich, dass es notwendig ist, Signal_ThresholdOpen gleich 0,4 zu wählen, um erfolgreich zu handeln. Die Karte U-Matrix ist offensichtlich in zwei "Pools" unterteilt, den oberen und den unteren, wobei der obere für den Erfolg und der untere für den Misserfolg steht. Die Karte der Treffer ist sehr knapp und uneinheitlich (der größte Teil des Raums sind Lücken, während aktive Neuronen einen großen Wert des Zählers haben), da die Gewinne nach mehreren offensichtlichen Ebenen im untersuchten EA gruppiert sind.

Diese Karten sollten wie folgt gelesen werden: Welche Parameter werden für die ausgewählten Wirtschaftsindizes erwartet?

Schließlich werden wir für das letzte Experiment den SOM-Explorer leicht weiterentwickeln, um Cluster sinnvoll benennen zu können. Schreiben wir die Funktion SetClusterLabels, die die Werte der spezifischen Komponenten von Codevektoren innerhalb jedes Clusters analysiert und mit dem Wertebereich dieser Komponenten vergleicht. Sobald sich der Gewichtswert in einem Neuron dem höchsten oder niedrigsten Wert nähert, ist dies der Grund, ihn mit dem Namen der jeweiligen Komponente zu markieren. Wenn beispielsweise das Gewicht der 0-ten Beziehung (entsprechend dem Gewinn) die Gewichte in anderen Clustern übersteigt, bedeutet dies, dass dieser Cluster durch hohen Gewinn gekennzeichnet ist. Es ist zu beachten, dass das Vorzeichen des Extrems, maximal oder minimal, durch die Bedeutung der Angabe bestimmt wird: Für den Gewinn gilt: Je höher der Wert, desto besser; für den Drawdown ist es umgekehrt. In diesem Zusammenhang stellen wir einen speziellen Input, FeatureDirection, vor, in dem wir die Indikationen mit positiver Wirkung mit dem Zeichen "+" und die mit negativer Wirkung mit dem Zeichen "-" markieren, während diejenigen, die nicht wichtig sind oder keinen Sinn haben, mit dem Zeichen "-" übersprungen werden. Beachten Sie, dass es in unserem Fall sinnvoll wäre, nur ökonomische Indizes zu kennzeichnen, da die Werte der Arbeitsparameter des EA überhaupt sein können und je nach ihrer Nähe zu den Grenzen des Definitionsbereichs nicht als gut oder schlecht interpretiert werden. Daher sollten wir den Wert von FeatureDirection nur für die ersten sechs Features festlegen:

FeatureDirection=++++-+

So sehen die Labels aus für das Netzwerk mit Lernen auf dem Vollvektor und der Clusterbildung nach Wirtschaftsindizes (links) und für das Netzwerk mit Lernen und Clusterbildung mit einer Maske auf den EA-Parametern.

Cluster-Labels, die in den Fällen von: Verwendung einer Maske nach ökonomischen Indizes in der Clusterbildungsphase (links) und einer Maske nach Parametern in der Lern- und Clusterbildungsphase (rechts).

Cluster-Labels, die in den Fällen von: Verwendung einer Maske nach ökonomischen Indizes in der Clusterbildungsphase (links) und einer Maske nach Parametern in der Lern- und Clusterbildungsphase (rechts).

Wir können sehen, dass in beiden Fällen, die gewählten Einstellungen fallen in den Clustern von Profit Factor, so können wir die höchste Effizienz in dieser Indikation erwarten. Dabei ist jedoch zu berücksichtigen, dass hier alle Labels positiv sind, da die Quelldaten aus der Genoptimierung stammen, die als Filter für die Auswahl akzeptabler Optionen dient. Wenn die Daten der vollständigen Optimierung analysiert werden, dann können wir Cluster identifizieren, die von Natur aus negativ sind.

So haben wir die Suche nach den optimalen Parametern von EA mittels Clusterbildung auf Kohonen-Karten allgemein betrachtet. Da dieser Ansatz flexibel ist, ist er kompliziert. Er beinhaltet die Verwendung verschiedener Clusterbildungs- und Netzwerklehrmethoden sowie die Vorverarbeitung der Eingaben. Die Suche nach optimalen Optionen hängt auch sehr stark von der Spezifität des Arbeitsroboters ab. Das vorgestellte Tool, SOM-Explorer, ermöglicht es uns, diesen Teil der Datenverarbeitung zu untersuchen, zu erweitern und zu verbessern.


Farbige Klassifizierung der Optimierungsergebnisse

Da die Methoden und die Qualität der Clusterbildung die korrekte Suche nach den optimalen Einstellungen des EA stark beeinflussen, sollten wir versuchen, das gleiche Problem mit einer einfacheren Methode zu lösen, ohne die Nähe von Neuronen zu bewerten.

Lassen Sie uns die Gewichte der Merkmale auf einer Kohonen-Karte im RGB-Farbmodell anzeigen und den hellsten Punkt auswählen. Da das RGB-Farbmodell aus drei Ebenen besteht, können wir auf diese Weise genau 3 Merkmale visualisieren. Wenn es mehr oder weniger davon gibt, dann zeigen wir die Helligkeit in Graustufen statt in RGB-Farben, finden aber immer noch den hellsten Punkt.

Es sei daran erinnert, dass es bei der Auswahl der Merkmale wünschenswert ist, die unabhängigsten zu wählen (was hier bereits erwähnt wurde).

Bei der Umsetzung des neuen Ansatzes werden wir gleichzeitig die Möglichkeit demonstrieren, die Klassen CSOM mit unseren eigenen zu erweitern. Erstellen wir die Klasse CSOMDisplayRGB, in der wir gerade einige virtuelle Methoden der übergeordneten Klasse CSOMDisplay überschreiben und dadurch erreichen, dass die RGB-Karte anstelle der letzten DIM_OUTPUT-Ebene angezeigt wird.

class CSOMDisplayRGB: public CSOMDisplay
{
  protected:
    int indexRGB[];
    bool enabled;
    bool showrgb;

    void CalculateRGB(const int ind, const int count, double &sum, int &col) const;
  
  public:
    void EnableRGB(const int &vector[]);
    void DisableRGB() { enabled = false; };
    virtual void RenderOutput() override;
    virtual string GetNodeAsString(const int node_index, const int plane) const override;
    virtual void Reset() override;
};

Der vollständige Code ist beigefügt.

Um diese Version zu verwenden, erstellen wir eine Modifikation des SOM-Explorer-RGB und nehmen die folgenden Änderungen vor.

Wir fügen Sie einen Eingabeparameter hinzu, um den RGB-Modus zu aktivieren:

input bool ShowRGBOutput = false;

Das Karten-Objekt wird zu einer abgeleiteten Klasse:

CSOMDisplayRGB KohonenMap;

Wir werden die direkte Anzeige der RGB-Ebene implementieren in eigenen Zweig des Codes:

  if(ShowRGBOutput && StringLen(FeatureDirection) > 0)
  {
    int rgbmask[];
    ArrayResize(rgbmask, StringLen(FeatureDirection));
    for(int i = 0; i < StringLen(FeatureDirection); i++)
    {
      rgbmask[i] = -(StringGetCharacter(FeatureDirection, i) - ',');
    }
    KohonenMap.EnableRGB(rgbmask);
    KohonenMap.RenderOutput();
    KohonenMap.DisableRGB();
  }

Es verwendet den uns bereits bekannten Parameter FeatureDirection. Auf diese Weise können wir die spezifischen Funktionen (der gesamten Reihe von Funktionen) auswählen, die in den RGB-Raum aufgenommen werden sollen. Beispielsweise reicht es in unserem Beispiel mit Wizard2018plus aus, zu schreiben:

FeatureDirection=++,,-

für die ersten beiden Merkmale, Gewinn und PF, um direkt in die Karte zu gelangen (sie entsprechen den Zeichen von '+'), während das fünfte Merkmal, Drawdown, ein invertierter Wert ist (es entspricht dem Zeichen von '-'). Merkmale, die mit ',' übereinstimmen, werden übersprungen. Alle nachfolgenden werden ebenfalls nicht berücksichtigt. Die Datei WizardTest-rgb.set mit den Einstellungen ist angehängt (die Netzwerkdatei Wizard2018plus.som soll seit der letzten Stufe verfügbar gewesen sein).

So erscheint der RGB-Raum für diese Einstellungen (links).

RGB-Raum für Merkmale (Gewinn, PF und Drawdown) und (PF, Drawdown und Deals)

RGB-Raum für Merkmale (Gewinn, PF und Drawdown) und (PF, Drawdown und Deals)

Die Farben sind für die Merkmale in der Prioritätsreihenfolge relevant: Der Gewinn ist rot, die PF ist grün und der Drawdown ist blau. Das hellste Neuron ist mit 'RGB' markiert.

Im Protokoll werden die Koordinaten des 'blassesten' Neurons und die Werte seiner Merkmale angezeigt, die als Option für die besten Einstellungen dienen können.

Da Gewinn und PF stark korreliert sind, werden wir die Maske durch eine andere ersetzen:

FeatureDirection=,+,,-+

In diesem Fall wird der Gewinn übersprungen, aber die Anzahl der Positionen wird hinzugefügt (einige Broker bieten Boni für Volumina an). Das Ergebnis ist im obigen Bild (rechts). Hier ist die Farbübereinstimmung unterschiedlich: PF ist rot, der Drawdown ist grün und die Anzahl der Positionen ist blau.

Wenn wir nur die Merkmale PF und Drawdown auswählen, erhalten wir eine Karte in Graustufen (links):

RGB-Raum der Merkmale (PF und Drawdown) und (Gewinn)

RGB-Raum der Merkmale (PF und Drawdown) und (Gewinn)

Zur Überprüfung können wir nur ein Merkmal auswählen, wie z.B. Gewinn, und sicherstellen, dass der Schwarz-Weiß-Modus mit der ersten Ebene übereinstimmt (siehe oben, rechts).


Analyse von Vorwärtstests

MetaTrader Tester ist bekannt dafür, dass er es ermöglicht, die EA-Optimierung durch Vorwärtstests auf die ausgewählten Einstellungen zu ergänzen. Es wäre töricht, diese Informationen nicht für die Analyse mit Kohonen-Karten zu verwenden und die spezifische Option für Einstellungen auf diese Weise auszuwählen. Konzeptionell müssen Cluster oder farbige Flächen im Querschnitt hoher Gewinne in der Vergangenheit und in der Zukunft Rahmenbedingungen beinhalten, die das stabilste Einkommen bieten.

Nehmen wir dazu die Optimierungsergebnisse von WizardTest zusammen mit Vorwärtstests (ich erinnere Sie daran, dass die Optimierung für die Gewinne im Zeitraum 20180101-20180701 durchgeführt wurde, während die Vorwärtstests entsprechend 2018.07.01-2018.12.01 durchgeführt wurden), entfernen alle Hinweise daraus, mit Ausnahme der Gewinne in der Vergangenheit und in der Zukunft, und erhalten die neue Eingabedatei für das Netzwerk — Wizard2018-with-forward.csv (siehe Anhang). Die Datei mit den Einstellungen, WizardTest-with-forward.set, ist ebenfalls angehängt.

Das Trainieren des Netzwerks durch alle Funktionen, einschließlich der EA-Parameter, liefert das folgende Ergebnis:

Kohonen-Karten mit der Analyse des Vorwärtstests nach allen Merkmalen, d. h. Profitabilitätsfaktoren und die EA-Parameter

Kohonen bildet mit der Analyse des Vorwärtstests nach allen Merkmalen, d.h. Wirtschaftlichkeitsfaktoren und den EA-Parametern, ab.

Wir sehen, dass das Gebiet mit dem zukünftigen Gewinn deutlich kleiner ist als das mit dem historischen Gewinn, und der Null-Cluster (rot) enthält diesen Standort. Außerdem habe ich die Farbanalyse durch die Maske von zwei Indikationen (FeatureDirection=++) aufgenommen, und der hellste Punkt auf der letzten Karte kommt auch in diesen Cluster. Allerdings enthalten weder das Clusterzentrum noch der helle Punkt superprofitable Einstellungen — obwohl die Testergebnisse positiv sind, sind sie doppelt so schlimm wie die zuvor.

Versuchen wir, eine Kohonen-Karte mit Hilfe der Maske auf den ersten beiden Merkmalen zu erstellen, da nur diese Indikationen sind. Dazu wenden wir die anderen Einstellungen mit FeatureMask=11000000000 an (siehe WizardTest-with-forward-mask11.set) und trainieren das Netzwerk erneut. Das Ergebnis ist wie folgt.

Kohonen bildet mit Vorwärts-Testanalyse nach dem Profit-Faktor ab.

Kohonen bildet mit Vorwärts-Testanalyse nach dem Profit-Faktor ab.

Hier sehen wir, dass die ersten beiden Ebenen die am besten ausgedrückte räumliche Struktur haben und die Bereiche mit hohen Werten (Gewinnen) in der linken unteren Ecke überquert haben, die auch in der letzten Karte hervorgehoben sind. Nachdem wir die Einstellungen aus diesem Neuron übernommen haben, erhalten wir folgendes Ergebnis:

Testerbericht für die nach dem Prinzip der "Profit-Stabilität" ausgewählten Einstellungen

Testerbericht für die nach dem Prinzip der "Profit-Stabilität" ausgewählten Einstellungen

Auch dies ist schlechter als der zuvor erzielte Gewinn.

Dieses praktische Experiment hat es uns also nicht ermöglicht, optimale Einstellungen zu finden. Gleichzeitig scheint die Einbeziehung der Vorwärts-Testergebnisse in die Analyse des neuronalen Netzes korrekt zu sein und sollte wahrscheinlich zu einem empfehlenswerten Ansatz werden. Welche Nuancen genau fehlten, um erfolgreich zu sein, und ob der Erfolg in allen Fällen garantiert ist, schlagen wir vor, in den Kommentaren zu diskutieren. Vielleicht bezeugt das erzielte Ergebnis nur, dass unser Test EA nicht für einen stabilen Handel geeignet ist.


Vorhersage der Zeitreihen

Übersicht

Kohonen-Netzwerke werden am häufigsten eingesetzt, um die visuelle Analyse und Clusterbildung von Daten durchzuführen. Sie können aber auch für die Vorhersage verwendet werden. Dieses Problem impliziert, dass der Eingangsdatenvektor Tic-Marken repräsentiert und dass sein Hauptteil in normaler Größe (n - 1), wobei n die Vektorgröße ist, verwendet werden sollte, um das Ende vorherzusagen, das normalerweise die neueste Tic-Marke ist. Im Wesentlichen ist dieses Problem ähnlich wie bei der Wiederherstellung des Rauschens oder teilweise verlorener Daten. Das hat jedoch eine eigene Besonderheit.

Es gibt verschiedene Ansätze für die Vorhersage mit Kohonen-Netzen. Hier sind nur einige davon.

Ein Kohonen-Netzwerk (A) lernt auf den Daten mit unvollständigen Vektoren der Größe (n - 1), d.h. ohne die letzte Komponente. Für jedes Neuron i des ersten Netzwerks wird eine zusätzliche Kohonen-Karte (Bi) für einen abgeschnittenen Satz von vollständigen Vektoren der Größe n eingelernt, die den unvollständigen Vektoren entsprechen, die in diesem Neuron i des Netzwerks A angezeigt wurden. Basierend auf Neuronen im Netzwerk Bi wird die Wahrscheinlichkeit der spezifischen Werte der letzten Koordinate n berechnet. Später, in der Betriebsphase, wird die zukünftige Tick-Marke gemäß den Wahrscheinlichkeiten aus dem Netzwerk Bi simuliert, sobald der zu prognostizierende Vektor in das Neuron i des Netzwerks A gelangt.

Eine andere Möglichkeit. Auf Kohonen wird Karte A mit den vollen Vektoren trainiert. Die zweite Kohonen-Karte (B) wird auf modifizierten Vektoren trainiert, bei denen anstelle der Werte Inkremente genommen werden, d.h,

yk = xk+1 - xk, k = 1 .. n - 1

wobei yk und xk die Komponenten des Anfangsvektors bzw. des modifizierten Vektors sind. Offensichtlich ist die Größe des modifizierten Vektors um 1 kleiner als die des ursprünglichen. Dann, den Eingang beider Netzwerke mit den Lehrdaten fütternd, berechnen wir die Anzahl der gleichzeitigen Anzeigen des Vollvektors zum Neuron i im ersten Netzwerk und zum Neuron j im zweiten Netzwerk. So erhalten wir die bedingten Wahrscheinlichkeiten pij des Vektors y, der in das Neuron j (im Netzwerk B) gelangt, vorausgesetzt, dass der für ihn relevante Vektor x in das Neuron i (im Netzwerk A) gelangt ist. In der Betriebsphase wird dem Netzwerk A der unvollständige Vektor x- (ohne die letzte Komponente) zugeführt, das nächstgelegene Neuron i* von (n - 1) Komponenten gefunden und dann wird das potenzielle Inkrement gemäß den Wahrscheinlichkeiten pi* erzeugt. Diese Methode, wie einige andere, ist mit der Monte-Carlo-Methode verbunden, bei der es darum geht, Zufallswerte für die zu prognostizierende Komponente zu erzeugen und das wahrscheinlichste Ergebnis gemäß der Statistik der Besetzung der Neuronen mit den Daten aus der Trainingsauswahl zu finden.

Diese Liste kann noch viel länger dauern, da sie sowohl die sogenannten parametrisierten SOMs und autoregressiven Modelle auf den SOM-Neuronen als auch die Clusterbildung stochastischer Attraktoren im Rahmen der Einbettung beinhaltet.

Alle von ihnen basieren jedoch mehr oder weniger auf dem Phänomen der Vektorquantisierung, das die Kohonen-Netzwerke charakterisiert. Während das Netzwerk trainiert wird, neigen die Gewichte der Neuronen asymptotisch zu den Mittelwerten der Klassen (Teilmengen von Inputs), die sie repräsentieren. Jeder dieser Mittelwerte liefert die beste Bewertung der fehlenden (oder zukünftigen, im Falle von Prognosen) Werte in den neuen Daten mit dem gleichen statistischen Gesetz wie in der Unterrichtsauswahl. Je kompakter und besser aufgeteilt die Klassen sind, desto genauer ist die Auswertung.

Wir werden die einfachste Prognosemethode verwenden, die auf der Quantisierung der Vektoren basiert, die die einzelne Instanz des Kohonen-Netzwerks umfasst. Aber auch hier gibt es einige Schwierigkeiten.

Wir werden den Netzwerkeingang mit den vollen Vektoren einer Zeitreihe versorgen. Die Abstände werden jedoch nur für die ersten (n - 1) Komponenten berechnet. Die Gewichte werden vollständig und für alle Komponenten angepasst. Dann, zum Zwecke der Vorhersage, werden wir den Netzwerkeingang mit dem unvollständigen Vektor versorgen, das beste Neuron für die Komponente (n - 1) finden und den Gewichtswert der letzten n-ten Synapse ablesen. Das wird die Prognose sein.

Dafür haben wir in der Klasse CSOM alles vorbereitet. Es gibt dort die Methode SetFeatureMask, die die Maske auf die Abmessungen des Raumes der Merkmale setzt, die an der Berechnung der Abstände beteiligt sind. Bevor wir jedoch den Algorithmus implementieren, sollten wir entscheiden, was genau wir prognostizieren werden.


Die Einheit des Cluster-Indikators

Unter den Händlern werden die Zeitreihen der Kurse als nicht-triviale Zeitprozesse anerkannt. Sie enthält viel Zufälligkeit, häufige Phasenwechsel und eine Vielzahl von Einflussfaktoren, und das ist im Prinzip ein offenes System.

Um das Problem zu vereinfachen, werden wir einen der größeren Zeitrahmen, den täglichen, zur Analyse auswählen. In diesem Zeitrahmen bietet das Rauschen einen geringeren Einfluss als in kleineren Zeitfenstern. Außerdem werden wir für die Prognose des/der Instrumente wählen, bei denen die starken fundamentalen Nachrichten, die den Markt unberechenbar bewegen können, relativ selten auftreten. Meiner Meinung nach sind die besten Metalle, d.h. Gold und Silber. Da sie kein Zahlungsinstrument eines bestimmten Landes sind und sowohl als Rohstoff als auch als sichere Anlageform fungieren, sind sie einerseits weniger volatil, andererseits sind sie untrennbar mit Währungen verbunden.

Theoretisch sollten ihre zukünftigen Bewegungen die aktuellen Kurse berücksichtigen und auf Forex-Kurse reagieren.

So brauchen wir eine Möglichkeit, synchrone Veränderungen der Preise von Metallen und Basiswährungen, die in der Summe dargestellt werden, zu erhalten. Zu einem bestimmten Zeitpunkt muss dies ein Vektor mit n Komponenten sein, die jeweils den relativen Kosten einer Währung oder eines Metalls entsprechen. Und das Ziel der Vorhersage besteht darin, mit einem solchen Vektor den nächsten Wert einer der Komponenten vorherzusagen.

Zu diesem Zweck wurde der ursprüngliche Cluster-Indikator Einheit erstellt (sein Quellcode ist beigefügt). Das Wesentliche seiner Funktionsweise wird mit dem folgenden Algorithmus beschrieben. Betrachten wir es als so einfach wie möglich, d.h. ein Währungspaar, EURUSD, und Gold, XAUUSD.

Jede Tic-Marke (aktuelle Preise zu Beginn/Ende des Tages) wird durch offensichtliche Formeln beschrieben:

EUR / USD = EURUSD

XAU / USD = XAUUSD

wobei die Variablen EUR, USD und XAU bestimmte unabhängige "Kosten" der Anlagen sind, während EURUSD und XAUUSD Konstanten (die bekannten Kurse) sind.

Um die Variablen zu finden, lassen Sie uns eine weitere Gleichung zum System hinzufügen, die die Summe der Quadrate der Variablen durch eine Einheit begrenzt hat:

EUR*EUR + USD*USD + XAU*XAU = 1

Daraus ergibt sich der Name des Indikators, Einheit.

Durch einfache Substitution erhalten wir:

EURUSD*USD*EURUSD*USD + USD*USD + XAUUSD*USD*XAUUSD*USD = 1

und so finden wir auch USD:

USD = sqrt(1 / (1 + EURUSD*EURUSD + XAUUSD*XAUUSD))

und dann all die anderen Variablen.

Oder, allgemeiner dargestellt:

x0 = sqrt(1 / (1 + sum(C(xi, x0)**2))), i = 1..n

xi = C(xi, x0) * x0, i = 1..n

wobei n die Nummer der Variablen ist, C(xi,x0) ist der Kurs des ithe Paars mit den relevanten Variablen. Beachten Sie, dass die Anzahl der Variablen um 1 höher ist als die der Instrumente.

Da es sich bei den an der Berechnung beteiligten Koeffizienten C um Angebote handelt, die in der Regel stark variieren; im Indikator werden sie zusätzlich mit der Vertragsgröße multipliziert: So entstehen Werte, die mehr oder weniger vergleichbar sind (oder zumindest von gleicher Größe sind). Um sie im Anzeigefenster zu sehen (nur zur Information), gibt es ein Eingabeparameter namens AbsoluteValues, der auf 'true' gesetzt werden sollte. Standardmäßig ist er natürlich gleichbedeutend mit falsch, und der Indikator berechnet immer die Inkremente der Variablen:

yi = xi0 / xi1 - 1,

wobei xi0 und xi1 die Werte der letzten und vorletzten Bars sind.

Wir werden die technischen Besonderheiten der Indikatorimplementierung hier nicht berücksichtigen — Sie können dessen Quellcode selbst studieren.

So erhalten wir die folgenden Ergebnisse:

Cluster (multicurrency) Indikator Unity, XAUUSD

Cluster (multicurrency) Indikator Unity, XAUUSD

Die Linien der Anlagen, die das Arbeitsinstrument des aktuellen Diagramms bilden (in diesem Fall XAU und USD), werden breit dargestellt, während andere Linien eine normale Dicke aufweisen.

Die folgenden Angaben sind unter anderem zu den Eingaben des Indikators zu nennen:

  • Instrumente — eine kommagetrennten Zeichenkette mit den kommagetrennten Namen der Arbeitsinstrumente; es ist notwendig, dass entweder die Basis- oder die Notierungswährung aller Instrumente gleich sind;
  • BarLimit — Anzahl der Bars für Berechnungen; sobald wir es zum Trainieren des neuronalen Netzes geschafft haben, wird dies die Größe der Einrichtungsauswahl sein;
  • SaveToFile — Name der csv-Datei, in die der Indikator die Werte exportiert, die anschließend in das neuronale Netzwerk geladen werden sollen; die Dateistruktur ist einfach: Die erste Spalte ist Datum, alle folgenden sind die Werte der entsprechenden Indikatorpuffer;
  • ShiftLastBuffer — Flag zum Umschalten des Modus, in dem die csv-Datei erzeugt wird; wenn die Option falsch ist, werden die Daten der gleichen Bar in jeder Zeichenkette in der Datei angezeigt, die Anzahl der Spalten ist gleich der Anzahl der Instrumente plus eines durch Unterteilung der Ticker in Komponenten und plus eine weitere Spalte, die allererste für das Datum; Namen der Spalten entsprechen Währungen und Metallen; wenn die Option wahr ist, wird eine zusätzliche Spalte mit dem Namen FORECAST hinzugefügt, in der die Werte aus der Spalte mit dem letzten Vermögenswert einen Tag vorwärts verschoben gespeichert werden; so sehen wir in jeder Zeichenkette sowohl alle Daten des aktuellen Tages als auch die morgige Änderung im letzten Instrument.

Um beispielsweise eine Datei mit den Daten für die Prognose von Änderungen des Goldpreises vorzubereiten, sollten Sie im Parameter Instrumente angeben: "EURUSD,GBPUSD,USDCHF,USDJPY,AUDUSD,USDCAD,NZDUSD,XAUUSD" (es ist wichtig, XAUUSD als letztes anzugeben), während "true" im ShiftLastBuffer angegeben sein muss. Wir werden eine csv-Datei mit im Wesentlichen der folgenden Struktur erhalten:

           datetime;      EUR;     USD;      GBP;      CHF;      JPY;      AUD;      CAD;      NZD;      XAU; FORECAST
2016.12.20 00:00:00; 0.001825;0.000447;-0.000373; 0.000676;-0.004644; 0.003858; 0.004793; 0.000118;-0.004105; 0.000105
2016.12.21 00:00:00; 0.000228;0.003705;-0.001081; 0.002079; 0.002790;-0.002885;-0.003052;-0.002577; 0.000105;-0.000854
2016.12.22 00:00:00; 0.002147;0.003368;-0.003467; 0.003427; 0.002403;-0.000677;-0.002715; 0.002757;-0.000854; 0.004919
2016.12.23 00:00:00; 0.000317;0.003624;-0.002207; 0.000600; 0.002929;-0.007931;-0.003225;-0.003350; 0.004919; 0.004579
2016.12.27 00:00:00;-0.000245;0.000472;-0.001075;-0.001237;-0.003225;-0.000592;-0.005290;-0.000883; 0.004579; 0.003232

Bitte beachten Sie, dass die letzten beiden Spalten die gleichen Zahlen enthalten, mit einer Verschiebung um eine Zeile. So können wir in der Zeichenkette vom 20. Dezember 2016 sowohl den Anstieg von XAU an diesem Tag als auch seinen Anstieg am 21. Dezember in der Spalte PROGNOSE sehen.


SOM-Prognose

Es ist an der Zeit, die Prognosemaschine auf Basis des Kohonen-Netzes zu implementieren. Um zu verstehen, wie es funktioniert, werden wir zunächst auf dem bereits bekannten SOM-Explorer aufbauen und ihn an das Prognoseproblem anpassen.

Die Änderungen konzentrieren sich auf die Eingaben. Lassen Sie uns alles entfernen, was mit dem Setzen der Masken zusammenhängt: FeatureMask, ApplyFeatureMaskAfterTraining und FeatureDirection, da die Maske für die Vorhersage bekannt ist - wenn die vektoriellen n tic-Marken verfügbar sind, sollten nur die ersten (n - 1) an der Berechnung der Entfernung beteiligt sein. Aber wir werden eine spezielle logische Option, ForecastMode, hinzufügen, die es uns ermöglichen würde, diese Maske bei Bedarf zu deaktivieren und die klassisch dargestellten analytischen Fähigkeiten des Kohonen-Netzwerks zu nutzen. Wir werden dies brauchen, um den Markt bzw. das System der in Unity spezifizierten Instrumente im statischen Zustand zu erforschen, d.h. Zusammenhänge noch am selben Tag zu sehen.

Wenn der ForecastMode gleich "true" ist, setzen wir die Maske. Ist sie 'false', gibt es keine Maske.

    if(ForecastMode)
    {
      KohonenMap.SetFeatureMask(KohonenMap.GetFeatureCount() - 1, 0);
    }

Sobald das Netzwerk bereits trainiert ist und die csv-Datei mit den Testdaten im Input DataFileName angegeben wurde, werden wir die Prognosegüte im ForecastMode wie folgt überprüfen:

      if(ForecastMode)
      {
        int m = KohonenMap.GetFeatureCount();
        KohonenMap.SetFeatureMask(m - 1, 0);
        
        int n = KohonenMap.GetDataCount();
        double vector[];
        double forecast[];
        double future;
        int correct = 0;
        double error = 0;
        double variance = 0;
        for(int i = 0; i < n; i++)
        {
          KohonenMap.GetPattern(i, vector);
          future = vector[m - 1]; // Sichern der Zukunft
          vector[m - 1] = 0;      // Zukunft für das Netz unbekannt machen (wird aufgrund der Maske sowieso nicht verwendet)
          KohonenMap.GetBestMatchingFeatures(vector, forecast);
          
          if(future * forecast[m - 1] > 0) // Prüfen, ob die Richtung stimmt
          {
            correct++;
          }
          
          error += (future - forecast[m - 1]) * (future - forecast[m - 1]);
          variance += future * future;
        }
        Print("Correct forecasts: ", correct, " out of ", n, " => ", DoubleToString(correct * 100.0 / n, 2), "%, error => ", error / variance);
      }

Hier wird jeder Testvektor dem Netzwerk mit GetBestMatchingFeatures präsentiert, und die Antwort ist der Prognose-Vektor. Seine letzte Komponente wird mit dem korrekten Wert aus dem Prüfvektor verglichen. Die übereinstimmenden Richtungen werden in der Variablen "correct" gezählt, der gesamte Prognosefehler "error" wird kumuliert, bezogen auf die Streuung der Daten selbst.

Wird der Validierungssatz (Parameter ValidationSetPercent ist gefüllt) zum Lernen angegeben und die ReframeNumber ist über Null, wird die neue CSOM-Klassenfunktion TrainAndReframe in Betrieb genommen. Es ermöglicht uns, die Netzwerkgröße stufenweise zu erhöhen und, indem wir die Änderungen des Lernfehlers auf dem Validierungssatz verfolgen, diesen Prozess zu stoppen, sobald der Fehler nicht mehr fällt und zu wachsen beginnt. Dies ist der Moment, in dem die Anpassung der Gewichte an bestimmte Vektoren, aufgrund der Verbesserung der Rechenleistung des Netzwerks, dazu führt, dass es seine Fähigkeit zur Verallgemeinerung und Arbeit mit unbekannten Daten verliert.

Nachdem wir die Größe ausgewählt haben, setzen wir ValidationSetPercent und ReframeNumber auf 0 zurück und unterrichten das Netzwerk wie gewohnt mit der Methode Train.

Schließlich werden wir die Funktion SetClusterLabels für die Kennzeichnung in Clustern leicht verändern. Da Vermögenswerte die Merkmale sein werden und jeder von ihnen sowohl das positive als auch das negative Extremum zeigen kann, werden wir das Bewegungssymbol in das Etikett aufnehmen. So kann ein und dasselbe Merkmal zweimal auf der Karte gefunden werden, sowohl mit Plus als auch mit Minus.

void SetClusterLabels()
{
  const int nclusters = KohonenMap.GetClusterCount();

  double min, max, best;
  
  double bests[][3]; // [][0 - Wert; 1 - Merkmalsindex; 2 - Richtung]
  ArrayResize(bests, nclusters);
  ArrayInitialize(bests, 0);
  
  int n = KohonenMap.GetFeatureCount();
  for(int i = 0; i < n; i++)
  {
    int direction = 0;
    KohonenMap.GetFeatureBounds(i, min, max);
    if(max - min > 0)
    {
      best = 0;
      double center[];
      for(int j = nclusters - 1; j >= 0; j--)
      {
        KohonenMap.GetCluster(j, center);
        double value = MathMin(MathMax((center[i] - min) / (max - min), 0), 1);
        
        if(value > 0.5)
        {
          direction = +1;
        }
        else
        {
          direction = -1;
          value = 1 - value;
        }
        
        if(value > bests[j][0])
        {
          bests[j][0] = value;
          bests[j][1] = i;
          bests[j][2] = direction;
        }
      }
    }
  }

  // ...
  
  for(int j = 0; j < nclusters; j++)
  {
    if(bests[j][0] > 0)
    {
      KohonenMap.SetLabel(j, (bests[j][2] > 0 ? "+" : "-") + KohonenMap.GetFeatureTitle((int)bests[j][1]));
    }
  }
}

Betrachten wir also die SOM-Prognose als fertiggestellt. Wir werden nun versuchen, die Werteingabe des Indikators Unity damit zu füttern.


Analyse

Zuerst versuchen wir, den gesamten Markt (die Menge der ausgewählten Vermögenswerte) statisch, oder besser gesagt im statistischen Kontext, zu analysieren. D.h., auf die vom Indikator Einheit streng nach Tagen exportierten Daten — jede Zeichenkette entspricht den Angaben auf einer D1-Bar, ohne zusätzliche Spalte aus der "Zukunft".

Zu diesem Zweck geben wir im Indikator den Satz der Deviseninstrumente Gold und Silber und den Dateinamen in SaveToFile an, während wir ShiftLastBuffer auf "false" setzen. Eine so erhaltene exemplarische Datei, unity500-noshift.csv, ist am Ende dieses Artikels beigefügt.

Nachdem wir das Netzwerk mit SOM-Prognose (siehe som-forecast-unity500-noshift.set) auf diese Daten trainiert haben, erhalten wir die folgende Karte:

Visuelle Analyse des Devisenmarktes, von Gold und Silber auf Kohonen-Karten nach Indikator Unity für D1

Visuelle Analyse des Devisenmarktes, von Gold und Silber auf Kohonen-Karten nach Indikator Unity für D1

Zwei obere Reihen sind die Karten der Assets. Der Vergleich ermöglicht es uns, die permanenten Links zu identifizieren, die seit mindestens 500 Tagen funktionieren. Besonders zwei mehrfarbige Flecken in den Zentren fallen ins Auge: Er ist blau für GBP und gelb für AUD. Dies bedeutet, dass sich diese Vermögenswerte oft in der umgekehrten Phase befanden, was sich nur auf starke Bewegungen bezieht, d.h. die GBPAUD-Umsätze konnten sich beim Durchbruch des durchschnittlichen Varianzniveaus am Markt durchsetzen. Dieser Trend kann sich fortsetzen und bietet die Möglichkeit, ausstehende Aufträge in diese Richtung zu platzieren.

In der rechten oberen Ecke ist ein Wachstum der XAG zu beobachten, während der CHF dort fällt. Und umgekehrt ist es in der linken unteren Ecke: CHF wächst, und XAG fällt. Diese Vermögenswerte unterscheiden sich immer bei starken Bewegungen, so dass wir sie durch einen Durchbruch in beide Richtungen handeln können. Wie erwartet, sind EUR und CHF ähnlich.

Einige weitere spezifische Funktionen finden Sie auf den Karten. Tatsächlich hatten wir schon vor Beginn der Prognose die Chance, etwas nach vorne zu schauen.

Lassen Sie uns einen genaueren Blick auf die Cluster werfen.

Forex-, Gold- und Silber-Cluster auf Kohonen-Karten nach Indikator Unity für D1

Forex-, Gold- und Silber-Cluster auf Kohonen-Karten nach Indikator Unity für D1

Sie liefern auch einige Informationen, z.B. darüber, was normalerweise nicht passiert (oder selten der Fall ist), nämlich: Der EUR wächst nicht, wenn JPY oder CAD fallen. GBP wächst oft gleichzeitig mit dem Fall des CHF und umgekehrt.

Nach Clustergrößen zu urteilen, sind die Währungen EUR, GBP und CHF am volatilsten, d.h., ihre Bewegungen ersetzen häufiger die Bewegungen anderer Währungen), während der USD in dieser Hinsicht überraschend sowohl gegenüber JPY als auch gegenüber CAD verliert (um daran zu erinnern, dass wir die Veränderungen in % berechnen). Wenn wir davon ausgehen, dass auch die Anzahl der Cluster wichtig ist (wir haben unsere Cluster sortiert), dann sind die ersten drei, also d.h., +CHF, -JPY und +GBP, beschreiben anscheinend die häufigsten täglichen Bewegungen (nicht Trend, aber genau die Häufigkeit ist gemeint, da auch während der "flachen" Periode eine größere Anzahl von "Schritten" nach oben durch einen großen "Schritt" nach unten ausgeglichen werden kann).

Nun kommen wir endlich zum Prognoseproblem.


Vorhersagen

Geben wir den Satz von Instrumenten an, einschließlich Devisen und Gold ("EURUSD,GBPUSD,USDCHF,USDJPY,AUDUSD,USDCAD,NZDUSD,XAUUSD") im Indikator, die Anzahl der Bars in BarLimit (standardmäßig 500), den Dateinamen in SaveToFile (z.B. unity500xau.csv), und setzen wir das Flag ShiftLastBuffer auf 'true' (Modus zum Erstellen einer zusätzlichen Spalte für die Prognose). Da es sich um einen Multiwährungsindikator handelt, ist die Anzahl der verfügbaren Daten auf die kürzeste Historie aller Instrumente beschränkt. Auf dem Server von MetaQuotes-Demo gibt es eine völlig ausreichende Anzahl von Bars, mindestens 2.000 Bars, für den Zeitrahmen D1. Hier wäre es also hilfreich, einen anderen Punkt zu berücksichtigen: Ob es sinnvoll ist, das Netzwerk so tief zu trainieren, da sich der Markt höchstwahrscheinlich stark verändert hat. 2-3 Jahre Geschichte oder sogar 1 Jahr (250 bar auf D1) wären wahrscheinlich besser geeignet, um die aktuellen Regelmäßigkeiten zu identifizieren.

Eine Beispieldatei unity500xau.csv ist am Ende dieser Datei angehängt.

Um es in SOM-Forecast zu laden, werden wir die folgenden Eingaben vornehmen: DataFileName - unity500xau, ForecastMode - true, ValidationSetPercent - 10, und, was wichtig ist: ReframeNummer - 10. Auf diese Weise werden wir sowohl das Trainieren des Netzwerks der Größe 10*10 (Standardwerte) ausführen als auch die Überprüfung des Fehlers bei einer Validierungsauswahl und das weitere Trainieren mit allmählicher Vergrößerung der Netzwerkgröße ermöglichen, während sich der Fehler verringert. Bis zu 10 Vergrößerungen werden bei der Methode TrainAndReframe stattfinden, 2 Neuronen in jeder Dimension. So werden wir die optimale Netzwerkgröße für Eingaben ermitteln. Die Datei mit den Einstellungen (som-forecast-unity500xau.set) ist angehängt.

Während des schrittweisen Trainierens und Erhöhens des Netzwerks wird im Wesentlichen Folgendes im Protokoll angezeigt (in gekürzter Form):

FileOpen OK: unity500xau.csv
HEADER: (11) datetime;EUR;USD;GBP;CHF;JPY;AUD;CAD;NZD;XAU;FORECAST
Training 10*10 hex net starts
...
Exit by validation error at iteration 104; NMSE[old]=0.4987230270708455, NMSE[new]=0.5021707785446128, set=50
Training stopped by MSE at pass 104, NMSE=0.384537545433749
Training 12*12 hex net starts
...
Exit by validation error at iteration 108; NMSE[old]=0.4094350709134669, NMSE[new]=0.4238670029035179, set=50
Training stopped by MSE at pass 108, NMSE=0.3293719049246978
...
Training 24*24 hex net starts
...
Exit by validation error at iteration 119; NMSE[old]=0.3155973731785412, NMSE[new]=0.3177587737459486, set=50
Training stopped by MSE at pass 119, NMSE=0.1491464262340352
Training 26*26 hex net starts
...
Exit by validation error at iteration 108; NMSE[old]=0.3142964426509741, NMSE[new]=0.3156342534501801, set=50
Training stopped by MSE at pass 108, NMSE=0.1669971604289485
Exit map size increments due to increased MSE
...
Map file unity500xau.som saved

Somit stoppte der Prozess bei dem Netzwerk in der Größe 26*26. Anscheinend sollten wir 24*24 wählen, wo der Fehler am geringsten war. Aber tatsächlich, wenn wir mit neuronalen Netzen arbeiten, spielen wir immer mit Chancen. Wenn Sie sich erinnern, war einer der Parameter, RandomSeed, für die Initialisierung des Zufallsdatengenerators verantwortlich, der für die Einstellung der Anfangsgewichte im Netzwerk verwendet wurde. Jedes Mal, wenn wir RandomSeed ändern, erhalten wir ein neues Netzwerk mit neuen Eigenschaften. Und da alle anderen Faktoren gleich sind, wird es besser oder schlechter trainieren als andere Instanzen. Daher müssen wir, um die Netzwerkgröße sowie andere Einstellungen, einschließlich der Größe der Wahl des Trainings, auszuwählen, in der Regel viele Versuche durchführen und viele Fehler machen. Dann werden wir diesem Prinzip folgen, um die Auswahl der Unterrichtsdaten zu verringern und die Netzwerkgröße auf 15*15 zu reduzieren. Darüber hinaus verwende ich manchmal die nicht-kanonische Modifikation der beschriebenen Methode der zeitlichen Quantisierung von Vektoren. Die Modifikation besteht darin, das Netzwerk mit deaktiviertem Flag ForecastMode zu trainieren und es nur bei der Prognose zu aktivieren. In einigen Fällen führt dies zu einem positiven Effekt. Die Arbeit mit dem neuronalen Netzwerk schlägt nie Fertiggerichte vor, sondern nur Rezepte. Und Experimente sind nicht verboten.

Vor dem Trainieren sollte die Quelldatei (in unserem Fall unity500xau.csv) in 2 Dateien unterteilt werden. Es geht darum, dass wir beim Unterricht die Prognosegüte einiger Daten überprüfen müssen. Es macht keinen Sinn, dies mit den gleichen Daten zu tun, die vom Netzwerk zum Lernen verwendet werden (genauer gesagt, es ist sinnvoll, sich selbst davon zu überzeugen, dass der Prozentsatz der richtigen Antworten unwirklich hoch ist - das können Sie überprüfen). Lassen Sie uns daher 50 Vektoren kopieren, um sie in einer separaten Datei zu testen, während wir das neue Netzwerk mit den ruhenden Vektoren unterrichten. Im Anhang finden Sie die entsprechenden Dateien, unity500xau-training.csv und unity500xau-validation.csv.

Geben wir unity500xau-training im Parameter DataFileName an (die Erweiterung .csv ist impliziert), die Werte von CellsX und CellsY sollten jeweils 24 sein, ValidationSetPercent ist 0, ReframeNumber ist 0, und ForecastMode ist immer noch 'true' (siehe som-forecast-unity500xau-training.set). Als Ergebnis des Trainings erhalten wir Folgendes:

Kohonen-Netzwerk zur Prognose der Goldveränderungen auf D1

Kohonen-Netzwerk zur Prognose der Goldveränderungen auf D1

Dies ist noch keine Prognose, sondern eine visuelle Bestätigung, dass das Netzwerk etwas gelernt hat. Was genau, werden wir überprüfen, nachdem wir die Eingabe mit unserer Validierungsdatei eingegeben haben.

Dazu nehmen wir die folgenden Einstellungen vor. Der Dateiname unity500xau-training wird nun in den Parameter NetFileName übertragen (dies ist der Name der Datei für das bereits trainierte Netzwerk, dessen Datei die implizite Erweiterung von .som hat). Im Parameter DataFileName geben wir unity500xau-validation an. Das Netzwerk wird für alle Vektoren eine Prognose erstellen und Statistiken im Protokoll anzeigen:

Map file unity500xau-training.som loaded
FileOpen OK: unity500xau-validation.csv
HEADER: (11) datetime;EUR;USD;GBP;CHF;JPY;AUD;CAD;NZD;XAU;FORECAST
Correct forecasts: 24 out of 50 => 48.00%, error => 1.02152123166208

Leider liegt die Vorhersagegenauigkeit auf dem Niveau des zufälligen Schätzens. Könnte aus einer so einfachen Auswahl von Eingaben ein Gral entstehen? Unwahrscheinlich. Außerdem haben wir die Historietiefe auf einen Blick gewählt, wobei auch diese Angelegenheit untersucht werden muss. Wir sollten auch mit dem Instrumentarium spielen, wie z.B. Silber hinzufügen, und im Allgemeinen klären, welches der Vermögenswerte mehr von den anderen abhängt, um die Prognose zu erleichtern. Im Folgenden betrachten wir ein Beispiel für die Verwendung von Silber.

Um mehr Kontext in die Eingaben einzubringen, habe ich in den Indikator Unity die Option hinzugefügt, einen Vektor zu bilden, der sowohl auf einem Tag als auch auf mehrere letzte Tage basiert. Zu diesem Zweck wurde der Parameter BarLookback hinzugefügt, der standardmäßig gleich 1 ist, was dem vorherigen Modus entspricht. Wenn wir jedoch hier z.B. 5 eingeben, enthält der Vektor die Tic-Marken aller Assets über 5 Tage (grundsätzlich ist eine Woche eine der Basisperioden). Bei 9 Assets (8 Währungen und Gold) werden 46 Werte in jeder Zeichenkette der csv-Datei gespeichert. Es summiert sich zu einer ganzen Menge, die Berechnungen werden langsamer und die Analyse der Karten wird schwieriger: Selbst kleine Karten passen kaum in den Bildschirm, während die größeren die Historie auf der Karte verkürzen können.

Anmerkung. Wenn Sie eine so große Anzahl von Karten im Modus von Objekten wie OBJ_BITMAP (MaxPictures = 0) betrachten, gibt es möglicherweise nicht genügend Bars auf dem Diagramm: Sie sind ausgeblendet, werden aber dennoch zum Verknüpfen von Bildern verwendet.

Um die Leistung der Methode zu demonstrieren, entschied ich mich für 3 Tage Rückblick und im Netzwerk von 15*15. Die Dateien unity1000xau3-training.csv und unity1000xau3-validation.csv fonden Sie im Anhang. Nachdem wir das Netzwerk auf die erste Datei trainiert und mit die zweite Datei validiert haben, werden wir 58 % der genauen Prognosen erhalten.

Map file unity1000xau3-training.som loaded
FileOpen OK: unity1000xau3-validation.csv
HEADER: (29) datetime;EUR3;USD3;GBP3;CHF3;JPY3;AUD3;CAD3;NZD3;XAU3;EUR2;USD2;GBP2;CHF2;JPY2;AUD2;CAD2;NZD2;XAU2;EUR1;USD1;GBP1;CHF1;JPY1;AUD1;CAD1;NZD1;XAU1;FORECAST
Correct forecasts: 58 out of 100 => 58.00%, error => 1.131192104823076

Das ist gut genug, aber wir sollten nicht den zufälligen Charakter der Prozesse in Netzwerken vergessen: Mit anderen Eingaben und einer weiteren Initialisierung werden wir großartige Ergebnisse erzielen, ebenso wie sie schlechter sein können. Das gesamte System muss mehrfach überprüft und neu konfiguriert werden. In der Praxis werden mehrere Instanzen erzeugt und dann die besten ausgewählt. Darüber hinaus können wir bei unseren Entscheidungen eine 'Mehrheitsentscheidung' und nicht nur de eines einzigen Netzwerks verwenden.


Vorhersage von Unity

Für die Vorhersage ist es nicht notwendig, die Karten auf dem Bildschirm anzuzeigen. In MQL-Programmen, wie EAs oder Indikatoren, können wir die Klasse CSOM anstelle von CSOMDisplay verwenden. Lassen Sie uns den Indikator Unity-Forecast erstellen, der ähnlich wie Unity ist, aber einen zusätzlichen Puffer zur Anzeige der Prognose hat. Das Kohonen-Netzwerk, das zum Erhalten der "Zukunftswerte" verwendet wird, kann separat (in SOM-Prognose) trainiert und dann in den Indikator geladen werden. Oder wir trainieren das Netzwerk zeitgleich, direkt im Indikator. Lassen Sie uns beide Modi implementieren.

Um das Netzwerk zu laden, fügen wir die Eingabeparameter NetFileName hinzu. Um das Netzwerk zu trainieren, fügen wir die Parametergruppe ähnlich der in SOM-Forecast enthaltenen hinzu: CellsX, CellsY, HexagonalCell, UseNormalization, EpochNumber, ShowProgress und RandomSeed.

Wir benötigen hier keinen Parameter AbsoluteValues, also ersetzen wir ihn durch die Konstante 'false'. ShiftLastBuffer macht auch keinen Sinn, da der neue Indikator immer eine Vorhersage bedeutet. Der Export in eine CSV-Datei ist ausgeschlossen, daher entfernen wir den Parameter SaveToFile. Stattdessen werden wir das Flag SaveTrainedNetworks hinzufügen: Wenn es "wahr" ist, speichert der Indikator die trainierten Netzwerke in Dateien, damit wir ihre Karten in SOM-Forecast studieren können.

Der Parameter BarLimit wird sowohl als Anzahl der Bars verwendet, die beim Start angezeigt werden sollen, als auch als Anzahl der Bars, die zum Trainieren des Netzwerks verwendet werden.

Der neue Parameter RetrainingBars erlaubt es, die Anzahl der Bars anzugeben, nach deren Ablauf das Netzwerk umgeschult werden muss.

Binden wir eine Header-Datei ein:

#include <CSOM/CSOM.mqh>

Lassen Sie uns im Tick-Prozessor eine neue Bar auf Verfügbarkeit prüfen (die Synchronisation durch Bars in allen Instrumenten ist erforderlich — in diesem Demoprojekt wird dies nicht durchgeführt) und, wenn es an der Zeit ist, das Netzwerk zu ändern, laden Sie ihn aus der Datei NetFileName oder lernen Sie ihn über die Daten des Indikators selbst in der Funktion TrainSOM. Danach werden wir die Vorhersage mit der Funktion ForecastBySOM durchführen.

  if(LastBarCount != rates_total || prev_calculated != rates_total)
  {
    static int prev_training = 0;
    if(prev_training == 0 || prev_calculated - prev_training > RetrainingBars)
    {
      if(NetFileName != "")
      {
        if(!KohonenMap.Load(NetFileName))
        {
          Print("Map loading failed: ", NetFileName);
          initDone = false;
          return 0;
        }
      }
      else
      {
        TrainSOM(BarLimit);
      }
      prev_training = prev_calculated > 0 ? prev_calculated : rates_total;
    }
    ForecastBySOM(prev_calculated == 0);
  }

Die Funktionen TrainSOM and ForecastBySOM sind unten aufgeführt (in vereinfachter Form) Der komplette Code befindet sich im Anhang.

CSOM KohonenMap;

bool TrainSOM(const int limit)
{
  KohonenMap.Reset();

  LoadPatterns(limit);
  
  KohonenMap.Init(CellsX, CellsY, HexagonalCell);
  KohonenMap.SetFeatureMask(KohonenMap.GetFeatureCount() - 1, 0);
  KohonenMap.Train(EpochNumber, UseNormalization, ShowProgress);

  if(SaveTrainedNetworks)  
  {
    KohonenMap.Save("online-" + _Symbol + CSOM::timestamp() + ".som");
  }
  
  return true;
}

bool ForecastBySOM(const bool anew = false)
{
  double vector[], forecast[];
  
  int n = workCurrencies.getSize();
  ArrayResize(vector, n + 1);
  
  for(int j = 0; j < n; j++)
  {
    vector[j] = GetBuffer(j, 1); // 1ste Bar ist die letzte, vollständige Bar
  }
  vector[n] = 0;
  
  KohonenMap.GetBestMatchingFeatures(vector, forecast);
  
  buffers[n][0] = forecast[n];
  if(anew) buffers[n][1] = GetBuffer(n - 1, 1);
  
  return true;
}

Bitte beachten Sie, dass wir tatsächlich den Schlusskurs der aktuellen 0. Bar zum Zeitpunkt der Eröffnung prognostizieren. Daher gibt es keine Verschiebung des "Zukunftspuffers" im Indikator, wie bei anderen Puffern.

Diesmal versuchen wir, das Verhalten von Silber vorherzusagen und den gesamten Prozess im Tester zu visualisieren. Der Indikator wird zeitgleich während der letzten 250 Tage (1 Jahr) trainiert und erneut alle 20 Tage (1 Monat) trainiert. Die Datei mit den Einstellungen, unity-forecast-xag.set, finden Sie am Ende dieses Artikels. Es ist wichtig zu beachten, dass die Zahl der Instrumente erweitert wird: EURUSD,GBPUSD,USDCHF,USDJPY,AUDUSD,USDCAD,NZDUSD,XAUUSD,XAGUSD. Daher sagen wir XAG auf der Grundlage von Devisenkursen voraus, Silber selbst und Gold.

So sieht der Test im Zeitraum vom 1. Juli 2018 bis 1. Dezember 2018 aus.

Unity-Forecast: Vorhersage der Bewegungen von Silber auf dem Forex- und Gold-Cluster im MetaTrader 5 Tester

Unity-Forecast: Vorhersage der Bewegungen von Silber auf dem Forex- und Gold-Cluster im MetaTrader 5 Tester

Zeitweise erreicht die Genauigkeit 60 %. Wir können feststellen, dass im Grunde genommen die Methode funktioniert, wenn das aber auch die grundlegende Auswahl des Prognose-Objekts, die Vorbereitung der Eingaben und die langfristige, sorgfältige Konfiguration erfordert.

Achtung! Das Training eines Netzwerks in einer zeitgleichen Trainingsform blockiert den Indikator (sowie andere Indikatoren mit dem gleichen Symbol/Zeitrahmen), was nicht empfohlen wird. In der Realität sollte dieser Code in einem EA ausgeführt werden. Hier wird er zur Veranschaulichung in einem Indikator ausgeführt. Um das Netzwerk in der Anzeige zu aktualisieren, können Sie einen Behelfs-EA verwenden, der die Karten nach Zeitplan generiert, während dieser Indikator sie unter dem in NetFileName angegebenen Namen neu lädt.

Die folgenden Optionen können zur Verbesserung der Prognosequalität in Betracht gezogen werden: Hinzufügen externer Faktoren, wie z.B. Wochentagszahlen zu den Eingaben oder Implementieren anspruchsvollerer Methoden, die auf mehreren Kohonen-Netzwerken oder auf einem Kohonen-Netzwerk zusammen mit den Netzwerken anderer Typen basieren.


Schlussfolgerung

Dieser Artikel beschäftigt sich mit dem praktischen Einsatz von Kohonen-Netzwerken bei der Lösung einiger Probleme der Händler. Die neuronale, netzwerkbasierte Technologie ist ein leistungsstarkes und flexibles Werkzeug, mit dem Sie verschiedene Datenverarbeitungsmethoden einsetzen können. Gleichzeitig erfordern sie eine sorgfältige Auswahl von Eingangsvariablen, Historientiefen und Parameterkombinationen, so dass ihr erfolgreicher Einsatz weitgehend von den Kenntnissen und Fähigkeiten des Benutzers bestimmt wird. Die hierin betrachteten Klassen ermöglichen es Ihnen, Kohonen-Netzwerke in der Praxis zu testen, die notwendigen Erfahrungen im Umgang mit ihnen zu sammeln und sie an Ihre eigenen Aufgaben anzupassen.


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

Beigefügte Dateien |
Kohonen2MQL5.zip (302.62 KB)
Die praktische Anwendung von Korrelationen im Handel Die praktische Anwendung von Korrelationen im Handel
In diesem Artikel werden wir das Konzept der Korrelation zwischen Variablen analysieren, sowie Methoden zur Berechnung von Korrelationskoeffizienten und deren praktische Anwendung im Handel. Eine Korrelation ist eine statistische Beziehung zwischen zwei oder mehreren zufälligen Variablen (oder Größen, die mit einem gewissen Maß an Genauigkeit als zufällig angesehen werden können). Ändert sich eine oder ändern sich mehrere Variablen, führt das zu systematischen Änderungen der anderen gekoppelten Variablen.
Die Anwendung der Monte Carlo Methode beim Reinforcement-Learning Die Anwendung der Monte Carlo Methode beim Reinforcement-Learning
Im Artikel werden wir das Reinforcement-Learning (Verstärkungslernen) anwenden, um selbstlernende Expert Advisors zu entwickeln. Im vorherigen Artikel haben wir den Algorithmus Random Decision Forest betrachtet und einen einfachen, selbstlernenden EA geschrieben, der auf dem Reinforcement-Learning basiert. Die Hauptvorteile eines solchen Ansatzes (Einfachheit der Entwicklung von Handelsalgorithmen und hohe "Trainings"-Geschwindigkeit) wurden erläutert. Reinforcement-Learning (RL) lässt sich leicht in jedes Trading EA integrieren und beschleunigt dessen Optimierung.
Martingale als Basis für eine langfristige Handelsstrategie Martingale als Basis für eine langfristige Handelsstrategie
In diesem Artikel werden wir uns ausführlich mit dem Martingal-System befassen. Wir werden prüfen, ob dieses System im Handel eingesetzt werden kann und wie es zur Risikominimierung eingesetzt werden kann. Der Hauptnachteil dieses einfachen Systems ist die Wahrscheinlichkeit, dass die gesamte Einlage verloren geht. Diese Tatsache muss berücksichtigt werden, wenn Sie sich entscheiden, mit der Martingaltechnik zu handeln.
Horizontale Diagramm auf den Charts des MеtaTrader 5 Horizontale Diagramm auf den Charts des MеtaTrader 5
Horizontale Diagramme sind in den Terminalcharts nicht üblich, können aber dennoch für eine Reihe von Aufgaben nützlich sein, z.B. bei der Entwicklung von Indikatoren, die Volumen- oder Preisverteilung für einen bestimmten Zeitraum anzeigen, bei der Erstellung verschiedener Versionen der Markttiefe usw. Der Artikel betrachtet die Erstellung und Verwaltung horizontaler Diagramme als Arrays von grafischen Primitiven.