English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
Creating Neural Network EAs Using MQL5 Wizard and Hlaiman EA Generator

Creating Neural Network EAs Using MQL5 Wizard and Hlaiman EA Generator

MetaTrader 5Experten | 27 Juni 2016, 13:43
1 390 2
Ivan Negreshniy
Ivan Negreshniy

Einleitung

Nahezu jeder Trader weiß um die Existenz neuronaler Netzwerke. Jedoch handelt es sich für die meisten von ihnen um ein Mysterium. Sie haben lediglich etwas davon gehört, dass neuronale Netzwerke Muster erkennen können, über eine assoziative Suche und die Fähigkeit zum Lernen verfügen sowie, dass sie das Verhalten des Marktes erahnen können und dass sie sich zum automatisierten Trading eignen. Viele Informationsquellen, die sich mit der Anwendung neuronaler Netzwerke befassen, sprechen von der Schwierigkeit, dass jemand sehr viel Zeit und Energie opfern muss, wenn er tatsächlich gewillt ist, neuronale Netzwerke zu verstehen und einzusetzen.

Dieser Artikel erhebt den Anspruch, diese Aussage zu widerlegen und zu bestätigen, dass fortgeschrittene, automatisierte Methoden existieren, die Trader in die Lage versetzen, ohne große Zeiteinbußen direkt mit neuronalen Netzwerken zu hantieren. Es ist überhaupt nicht schwer, eigene erste Erfahrungen mit neuronalen Netzwerken zu sammeln. Es ist auf jeden Fall einfacher als eine technische Analyse.

Dies im Hinterkopf behaltend, werden wir uns einer Methode zur automatischen Generierung von EAs mit einem neuronalen Netzwerk via folgender Werkzeuge zuwenden: MQL5-Assistent und Hlaiman EA Generator.

Die Wahl der Werkzeuge, um diese Aufgabe zu bewältigen, erfolgt dabei keinesfalls zufällig:

  1. Mit dem MQL5-Assistenten steht uns das aktuell schnellste und effizienteste Programm zur MQL5-Codegenerierung zur Verfügung, dessen erstellter Code mit der Unterstützung zusätzlicher Module noch weiter angepasst werden kann.
  2. Hlaiman EA-Generator ist das Triebwerk eines neuronalen Netzwerks, das einen flexiblen Mechanismus zur Integration von Objekten aufweist und das direkt mit dem MQL5-Code eines EAs programmierbar ist.

Die Abkürzung „EA“ wurde absichtlich zum Namen des Expert Adivisors hinzugefügt, da menschliche Eigenschaften, die mit Lernen und Erkennen zusammenhängen, bei EAs, die auf einem neuronalen Netzwerk basieren, vorherrschen - im Gegensatz zu andern Fällen, in denen die Benutzung der Buchstaben „EA“ im Namen oft in die Irre führt.


Generelles

Aufgrund des oben genannten Grundes werden Sie in diesem Artikel keine theoretischen Informationen, Klassifikationen oder Strukturen neuronaler Netzwerke sowie finanzmarktbezogene Recherchedaten antreffen. Diese Informationen und Daten finden Sie in anderen Quellen. In diesem Artikel werden wir uns bewusst auf das Konzept eines neuronalen Netzwerks als Black Box beschränken - eine Black Box, die in der Lage ist, assoziativ zu denken und Markteinträge auf der Basis der Erkennung grafischer Kursmuster vorherzusagen. Aus dem gleichen Grunde werden wir die simpelste Grundidee eines Musters verwenden: eine kontinuierliche Sequenz von Balken in einem Chart für Handelsinstrumente, die einer profitablen Kursbewegung vorausgeht.

Einige wenige Worte in Bezug auf Tools zur Problemlösung. Im Gegensatz zu Hlaiman wurde der MQL-Assisstent - ebenso wie MetaTrader 5 - bereits hinreichend mit Artikeln und Dokumentationen bedacht. Das sozialorientierte Projekt Hlaiman hat das Ziel, die Entwicklung und Verbreitung von Mehrzwecksoftware in Form von Plugins wie zum Beispiel EA Generator voranzutreiben. Wie bereits erwähnt, repräsentiert EA Generator eine neuronale-Netzwerk-Engine mit einem integrierten Mechanismus.

Hlaiman EA Generator schließt die Exe <hlaim.exe> mit ein: eine Hülle, die eine Windows-basierte grafische Benutzeroberfläche mit einem Multi-Dokument-Interface und Plugins in Form von dynamisch ladbaren Komponentenbibliotheken repräsentiert. Das System erlaubt eine großen Menge an manuellen wie auch algorithmischen Einstellungen und Methoden zur Kontrolle von Komponenten, die beides sein können - standardisiert oder als Teil eines Plugins ladbar. Im Rahmen der Systemoperationen können Sie eine komplexe Hierarchie von Objekten anlegen und Sie haben eine äußerst flexible Kontrolle über deren Methoden und Eigenschaften, indem Sie Objektinspektoren und automatisierte Softwaretools (wie beispielsweise Skripte) verwenden.

Die Integration von Hlaiman EA Generator in MQL5 umfasst ferner den Objekt-Pascal-Script-Interpreter, während der Source Code via Named Pipes weitergegeben wird. Als primäre neuronale-Netzwerk-Komponente dient hier ein Multilayer Perceptron (MLP).

Hlaiman EA Generator ist im MQL5-Assistenten mithilfe des Signalbibliotheksmoduls SignalHNN.mqh integriert. Sobald automatisch generiert, kann dem Expert Advisor das Wissen vermittelt werden, wie er mit Instrumenten und Zeitrahmen tradet, ungeachtet deren Anzahl. Im MetaTrader-5-Terminal können Signale signalisieren Pfeile entweder im Kurs-Chart manuell via Grafikobjekte oder mittels des Skripts TeachHNN.mq5 gezeichnet werden, das gleichzeitig den Lehrprozess eines EAs einleitet.

Hiermit endet diese theoretische Einlassung. Wir kommen nun zum praktischen Teil, der sich in zwei Abschnitte gliedert - Operationsprinzipien und Umsetzung.

Der zweite Abschnitt zielt auf Softwareentwickler ab und wird an dieser Stelle lediglich angeführt, um der Webseite ihren Respekt zu zollen. Er ist daher natürlich auch nur optional. Dies gilt besonders für Trader, die wenig oder auch gar kein Interesse daran haben, Programmierfähigkeiten zu entwickeln, die aber dennoch EAs kreieren wollen, die auf neuronalen Netzwerken basieren, um deren Effizienz und Nutzen in Bezug auf Trading zu testen.


Operationsprinzipien

Ich glaube, es ist selbstredend, dass Sie in MQL5.community ein MetaTrader-5-Terminal benötigen, um fortzufahren. Falls es sich noch nicht auf Ihrem Gerät befinden sollte, hier der entsprechende Link zum Download. Wenn Sie schon dabei sind, sollten Sie sich ferner die Hlaiman-EA-Generator-Demoversion herunterladen.

Führen Sie das MetaTrader-5-Terminal aus und starten Sie MetaEditor. Öffnen Sie den MQL5-Assistenten. Benutzen Sie hierfür entweder die Option „Neu“ in der Standard-Taskleiste oder im Dateimenü sowie den Befehl „Strg+N“.

Wählen Sie dann im Fenster des MQL5-Assistenten „Expert Advisor (generieren)“ und klicken Sie auf „Weiter“.

Abb. 1 Erstellung eines Expert Advisors mithilfe des MQL5-Assistenten

Abb. 1. Erstellung eines Expert Advisors mithilfe des MQL5-Assistenten

Spezifizieren Sie den Ort und den Namen des Expert Advisors (Beispiel: 'Experts\SampleHNN‘) und klicken Sie auf „Weiter“.

Abb. 2 Allgemeine Parameter des EAs

Abb. 2 Allgemeine Parameter des EAs

Gehen Sie auf den „Hinzufügen“-Button. Nun sehen Sie das Fenster „Parameter des Signalmoduls“. Wählen Sie aus der hier befindlichen Dropdown-Auswahl „Mustersignale-Hlaiman-Neural-Network-EA-Generator' aus und gehen Sie auf „OK“.

Abb. 3 Auswahl des Handelssignalmoduls des Hlaiman-Neural-Network-EA-Generators

Abb. 3 Auswahl des Handelssignalmoduls des Hlaiman-Neural-Network-EA-Generators

Wenn Sie mit den Standardeinstellungen zufrieden sein sollten, so können Sie einfach alle weiteren Fenster des MQL5-Assistenten mit „Weiter“ bestätigen. Jedoch können Sie sich auch die Zeit für eine fortgeschrittene Installation nehmen und entsprechende Installationsänderungen vornehmen.

Nachdem der Code vollständig generiert wurde, gehen Sie bitte auf „Kompilieren“ und schließen Sie das Fenster von MetaEditor. Der neu erstelle Expert Advisor sollte sich nun eigentlich unter „Expert Advisors“ im Navigationsmenü von MetaTrader 5 befinden.

Abb. 4 Der SampleHNN-Expert Advisor

Abb. 4 Der SampleHNN-Expert Advisor

Bevor wir dem EA allerdings erste Anweisungen geben, müssen wir im Terminal noch einen Chart mit den benötigten Symbolen und Zeitrahmen öffnen. Hierfür muss die Hlaiman-EA-Generator-Applikation ausgeführt werden und im Hintergrund aktiv sein.

Abb. 5  Vorbereitungen, um einem neuronalen Netzwerk etwas beizubringen

Abb. 5 Vorbereitungen, um einem neuronalen Netzwerk etwas beizubringen

Um dem Expert Advisor etwas beizubringen, wählen Sie bitte im Navigationsmenü des Terminals „TeachHNN“ unter „Skripte“ aus und aktivieren Sie es für den entsprechenden Chart.

Bevor Sie das Skript „TeachHNN“ ausführen, sollten Sie zunächst sicherstellen, dass das Skript die entsprechenden Einstellungen aufweist. Folgenden Parameter stehen zur Auswahl:

  • Dokumentenname: Name des zu unterrichtenden Expert Advisors;
  • Neurale Schichten - Anzahl der neuralen Netzwerkschichten;
  • Mittlere Neuronen - Anzahl der Neuronen;
  • Lehrepochen - Anzahl der Lehrepochen
  • Musterbalken - Anzahl der Balken in einem Muster
  • Ein Netzwerk unterrichten - startet den Unterweisungsprozess eines neuronalen Netzwerks (oder einfach: die Signalgenerierung);
  • SignaleKreieren - zur automatischen Generierung von grafischen Signalbildern;
  • SignaleBalkenpunkte - Schwellenwert der Signalgenerierung in Punkten;
  • SignaleBalkenzahl - Anzahl der Balken zur Berechnung von Punkten;
  • SignaleStartzeit, SignaleEndzeit - Beginn und Ende der Periode zur Signalgenerierung;
  • SignaleLöschen - löscht nach abgeschlossenem Lehrprozess automatisch die Signalbilder.

Abb. 6 Die Parameter des TeachHNN-Skripts

Abb. 6 Die Parameter des TeachHNN-Skripts

Sobald alles bereit ist, klicken Sie bitte auf „OK“, um den Lehrprozess zu starten. Hierdurch wird die automatische Generierung grafischer Muster für ein jedes der verfügbaren Chartsignale eingeleitet.

Die relevanten Informationen erscheinen im „Experten“-Tab in der „Toolbox“-Anzeige des Terminals, während die damit zusammenhängenden Objekte im Fenster von Hlaiman EA Generator erscheinen.

Nachdem das Muster vollständig generiert wurde, beginnt schließlich der Wissensvermittlungsprozess. Dieser Vorgang kann im Lehrprozessbalken, der auf dem Bildschirm erscheint, eingesehen werden.

Hlaiman EA Generator Wissen vermitteln

Abb. 7 Lehrprozessfortschrittsanzeige

Warten Sie bis der Prozess vollständig abgeschlossen ist. Der Prozess kann frühzeitig beendet werden, indem Sie auf den Fortschrittsbalken mit einem Rechtsklick klicken und die entsprechende Option im Kontextmenü auswählen.

Sobald der Lehrprozess als auch die Skriptoperation beendet worden ist, wird eine entsprechende Nachricht im Log des „Experts“-Tab hinzugefügt. Beispiel: „Neuronales Netzwerk erfolgreich angelegt!“. Die 431 Muster weisen darauf hin, dass der EA in Bezug auf 431 Signale erfolgreich instruiert worden ist.

Diese Nachrichten geben an, wie viele Muster im Wissensvermittlungsprozess involviert waren und wie man die Zahl der Muster herausfinden kann. Was insbesondere Kaufen und Verkaufen betrifft, so werden diese Signale mithilfe von Nachrichten folgenden Typs bestimmt: „Verkaufen-Signal bei Muster #211 entdeckt“.

Abb. 8 TeachHNN-Skriptnachrichten während des Lehrprozesses

Abb. 8 TeachHNN-Skriptnachrichten während des Lehrprozesses

Die Gründe, warum der Lehrprozess eines EAs mit einem Fehler beginnt, könnten sein:

  1. Die Applikation Hlaiman wurde nicht - wie benötigt - vor dem Prozess ausgeführt. In diesem Fall wird man mit folgender Fehlermeldung konfrontiert werden: „CSignalHNN::InitHNN: Fehler! Pipeserver-Initialisierung (mögliche Gründe: DIE APPLIKATION HLAIMAN WIRD NICHT AUSGEFÜHRT!)".
  2. Die Abwesenheit von Pfeilen, die Signale im Chart andeuten, gemäß der Deaktivierung der automatischen Generierung von Signalen (die Variable SignalsCreate = falsch). In diesem Fall wird folgende Fehlermeldung eingeblendet werden: „OnStart: Fehler, Anweisungspfeile nicht gefuden!“ Falls die automatische Generierung von Signalen aktiviert ist (die Variable SignalsCreate = wahr), kann ein Fehler durch die Abwesenheit von Grafikobjekten im Chart hervorgerufen werden, da benutzerspezifische Markierungen innerhalb des Programms nicht durcheinandergeworfen werden sollten. Ich empfehle daher, alle Charts separat zu öffnen, um eine automatische Generierung von Signalen einzuleiten.

Sobald der Lehrprozess des EAs abgeschlossen ist, können Sie die entsprechenden Ergebnisse einsehen, indem Sie in die grafische Benutzeroberfläche von Hlaiman wechseln und die entsprechenden Objekte / Visualisierungspanels auswählen.

Abb. 9 „Text“-Tab der Hlaiman-Applikation

Abb. 9 „Text“-Tab der Hlaiman-Applikation


Abb. 10 „Graphen“-Tab der Hlaiman-Applikation

Abb. 10 „Graphen“-Tab der Hlaiman-Applikation

Nachdem wir den EA in mindestens einem Handelsinstrument geschult haben, können wir mit dem Testen und der Optimierung weitermachen.

Hierfür wählen wir den Namen dieses EAs sowie Symbol, Zeitrahmen, Intervall und Testparameter im Strategietester aus. Stellen Sie - falls nötig - die externen Variablen ein und führen Sie den Test durch.

Abb. 11 Einstellungen des SampleHNN-Expert-Advisors für den Backtest

Abb. 11 Einstellungen des SampleHNN-Expert Advisor für den Backtest


Abb. 12 Externe Variablen des SampleHNN-Expert-Advisors können modifizert werden

Abb. 12 Externe Variablen des SampleHNN-Expert-Advisors können modifiziert werden.

Unten finden Sie ein Beispiel des EA-Operationsberichts des Strategietesters. Dem EA wurde beigebracht, automatisch generierte Signale zu verwenden, bei denen alle externen Parameter (Lehrskript) auf Standard eingestellt sind. Dauer des Lehrprozesses: 01.01.2010-07.01.2013, Instrument: EURUSD H4.


Strategietesterprüfbericht

Expert Advisor:SampleHNN
Symbol EURUSD
Zeitraum: H4 (01.01.2010-12.07.2013)
Währung: USD
Anfangseinlage: 10.000,00
Leverage: 0,111111111
Backtesting
Verlaufsdatenqualität: 100%
Balken: 5497
Gesamtnettogewinn: 9.159,58
Bruttogewinn: 29.735,97
Bruttoverlust: -20.576,39
Gewinnfaktor: 1,45
Erholungsfaktor: 12,81
AHPR: 1,0005 (0,05%)
GHPR: 1,0005 (0,05%)
Abschlüsse insgesamt: 1417
Abschlüsse insgesamt: 2246
Kursänderungen (Ticks): 60211228
Absoluter Wertverlust des Kontos: 0,00
Maximaler Wertverlust des Kontos: 679,98 (3,81%)
Relativer Wertverlust des Kontos: 4.00% (715.08)
Erwartete Auszahlung 6,46
Sharpe-Ratio: 0,16
LR-Korrelation 0,98
LR-Standardfehler 595,06
Kurzfristige (short) Abschlüsse (mit Gewinn %): 703 (56,61%)
Mit Gewinn (in % aller Abschlüsse) 793 (55,96%)
Größter Abschluss mit Gewinn: 53,00
Durchschnittlicher Abschluss mit Gewinn: 37,50
Größte Anzahl ununterbrochener Gewinne (Gesamtgewinn in $): 9 (450,38)
Größte Anzahl ununterbrochener Verluste (Gesamtverlust in $): 450,38 (9)
Durchschnittlich ununterbrochene Gewinne: 2
Symbole: 1
Absoluter Wertverlust des Kapitals: 6,60
Maximaler Wertverlust des Kapitals: 715,08 (4,00%)
Relativer Wertverlust des Kapitals: 4.00% (715.08)
Gewinnspanne: 6929,24%
Z-Konto: -1,24 (78,50%)
OnTester-Ergebnis: 0
Langfristige (long) Abschlüsse (mit Gewinn %): 714 (55,32%)
Mit Verlust (in % aller Abschlüsse) 624 (44,04%)
Größter Abschluss mit Verlust: -53,30
Durchschnittlicher Abschluss mit Verlust: -32,97
Größte Anzahl ununterbrochener Verluste (Gesamtverlust in $): 9 (-234,00)
Größte Anzahl ununterbrochener Verluste (Gesamtverlust in $): -276,67 (7)
Durchschnittlich ununterbrochene Verluste: 2

Abb. 13. Backtesting-Ergebnisse des Expert Advisors SampleHNN

Abb. 13 Backtesting-Ergebnisse des Expert Advisors SampleHNN


Abb. 14 Markteintrittsstatistiken des Expert Advisors SampleHNN

Abb. 14 Markteintrittsstatistiken des Expert Advisors SampleHNN


Abb. 15 Korrelation zwischen Gewinn und MFE/MAE des SampleHNN-Expert-Advisors

Abb. 15 Korrelation zwischen Gewinn und MFE/MAE des SampleHNN-Expert-Advisors


Abb. 16 Anlagedauerstatistiken des SampleHNN-Expert-Advisors

Abb. 16 Anlagedauerstatistiken des SampleHNN-Expert-Advisors

Umsetzung

Die wichtigstes Komponente bei der MQL5-Implementation ist die Klasse CSignalHNN, die im SignalHNN.mqh-Signalmodul bezeichnet wird. Diese Klasse entstammt der Basisklasse CExpertSignal und enthält alle wichtigen Datenfelder und Methoden zur Integration von Hlaiman, als auch für das Arbeiten mit vom MQL5-Assistenten generierten Expert Advisors.

Die Klassen-Mustervorlage sieht wie folgt aus:

//+------------------------------------------------------------------+
//| Class CSignalHNN.                                                |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Hlaiman EA Generator Neural Net' indicator.        |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalHNN :public CExpertSignal
  {
protected:
   //--- variables
   int               m_hnn;                   // handle of HNN connect
   string            hnn_path;                // MT5 Terminal data path
   string            hnn_fil;                 // HNN file w neural net 
   string            hnn_nam;                 // Expert name
   string            hnn_sym;                 // Symbol name
   string            hnn_per;                 // Period name
   ENUM_TIMEFRAMES   hnn_period;              // Period timeframe
   int               hnn_index;               // Index ext multinet
   int               hnn_bar;                 // index of last bar
   int               hnn_in;                  // input layer 
   int               hnn_out;                 // output layer
   int               hnn_layers;              // layers count
   int               hnn_neurons;             // neurons count
   int               hnn_epoch;               // learn epoch
   double            hnn_signal;              // value of last signal
   double            pattern[];               // values of the pattern
   bool              hnn_norm;                // normalize pattern

public:
                     CSignalHNN(void);        // class constructor
                    ~CSignalHNN(void);        // class destructor
   //--- methods of setting adjustable parameters
   void              PatternBarsCount(int value) { hnn_in = value; ArrayResize(pattern, value + 1);  }
   void              LayersCount(int value)      { hnn_layers = value;  }
   void              NeuronsCount(int value)     { hnn_neurons = value;  }
   void              EpochCount(int value)       { hnn_epoch = value;  }
   void              Normalize(bool value)       { hnn_norm = value;  }
   //--- method of verification of settings
   virtual bool      ValidationSettings(void);
   //--- method of creating the indicator and timeseries
   virtual bool      InitIndicators(CIndicators *indicators);
   //--- methods of checking conditions of entering the market
   virtual double    Direction(void);

   bool              FillPattern(datetime tim = 0);      // prepare pattern
   bool              AddPattern(string name, int ptype);  // add new pattern
   bool              TeachHNN(void);                     // learn neural net
   bool              SaveFileHNN(void);                  // neural net file
   double            CalculateHNN(void);                 // calc neural signal

                                                        //protected:
   //--- method of initialization of the Hlaiman Application
   bool              InitHNN(bool openn);                // Hlaiman App Init
   void              FreeHNN(void)
     {                     // Hlaiman App Deinit
      if(m_hnn!=0 && m_hnn!=INVALID_HANDLE)
        {
         FileClose(m_hnn);
         m_hnn=0;
        }
     };
  };

Nach der Generierung der Klasseninstanzen durch den Konstruktor, kann dieses Objekt in folgenden zwei Modi operieren:

  1. Lehrmodus: Dieser Muster dient der Sammlung von Marktmustern und der Wissensvermittlung.
  2. Indikatormodus: In diesem Modus wird das Signal des neuronalen Netzwerks mithilfe des aktuellen Musters kalkuliert.

Dieses Modus ist dadurch gekennzeichnet, dass der Initialisierungsmodus InitHNN mithilfe des Boolean-Parameters oppenn aufgerufen wird. Der wahre Wert dieses Parameters initiiert die Suche nach den und das Öffnen, das Laden und das Operieren der Datei des lernenden neuronalen Netzwerks (im Indikatormodus (2)). Dieser Modus wird als Operationsmodus angesehen und kommt bei EAs dann zum Einsatz, wenn Sie traden.

Im Gegensatz zum Lehrmodus (1), der initialisiert wird, wenn die Methode InitHNN mit openn=falsch aufgerufen wird, gilt der Indikatormodus als Vorbereitung für den EA und kommt immer dann zum Einsatz, wenn eine Lehrskript abgearbeitet werden soll.

Die Initialisierungsmethode wird wie folgt umgesetzt:

//+------------------------------------------------------------------+
//| Initialize HNN                                                   |
//+------------------------------------------------------------------+
bool CSignalHNN::InitHNN(bool openn)
  {
//--- initialize Hlaiman Application
   int num=0;
   ulong res=0;
   if(m_symbol!=NULL)
     {
      hnn_sym=m_symbol.Name();
      hnn_period=m_period;
        } else {
      hnn_sym=_Symbol;
      hnn_period=_Period;
     }
   hnn_per = string(PeriodSeconds(hnn_period) / 60);
   hnn_fil = hnn_nam + NAME_DELIM + hnn_sym + hnn_per + NAME_DELIM + string(hnn_index) + TYPE_NEURO;
   if(m_hnn== 0|| m_hnn == INVALID_HANDLE)
      m_hnn=FileOpen(HLAIMAN_PIPE,FILE_READ|FILE_WRITE|FILE_BIN);
   if(m_hnn!=0 && m_hnn!=INVALID_HANDLE)
     {
      string source,result="";
      if(openn==true)
        {
         result=CON_OPENN+CON_TRUE;
         if(!FileIsExist(hnn_fil,FILE_READ))
           {
            if(FileIsExist(hnn_fil,FILE_READ|FILE_COMMON))
               hnn_fil=TerminalInfoString(TERMINAL_COMMONDATA_PATH)+PATH_FILES+hnn_fil;
            else
              {
               //              hnn_fil = hnn_path + PATH_MQL5 + PATH_FILES + hnn_fil;
               hnn_fil=TerminalInfoString(TERMINAL_DATA_PATH)+PATH_MQL5+PATH_FILES+hnn_fil;
              }
           }
         else hnn_fil=TerminalInfoString(TERMINAL_DATA_PATH)+PATH_MQL5+PATH_FILES+hnn_fil;
           } else {
         result=CON_OPENN+CON_FALSE;
         hnn_fil=TerminalInfoString(TERMINAL_DATA_PATH)+PATH_MQL5+PATH_FILES+hnn_fil;
        }
      source="unit InitHNN; Interface "+result+" var libr, term, exp, sym: TObject;"
             " Implementation function main: integer;\n\r" // Line #1
             " begin"
             " Result := 0;"
             " libr := Open('mt45.dll');\n\r" // Line #2
             " if (libr <> nil) then"
             " begin"
             " term := Open('"+hnn_path+"');\n\r" // Line #3
             " if (term <> nil) then"
             " begin"
             " exp := term.ObjectOfName('"+hnn_nam+"');"
             " if (exp = nil) then exp := term.AddObject('TMT45Expert');\n\r" // Line #5
             " if (exp <> nil) then"
             " begin"
             " if (exp.Name <> '"+hnn_nam+"') then exp.Name := '"+hnn_nam+"';\n\r" // Line #6
             " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');"
             " if (sym = nil) then sym := exp.AddObject('TMT45Symbol');"
             " if (sym <> nil) then"
             " begin"
             " sym.Log.Add('"+hnn_sym+hnn_per+"');\n\r"
             " if (sym.Name <> '"+hnn_sym+hnn_per+"') then sym.Name := '"+hnn_sym+hnn_per+"';"
             " if (sym.Period <> "+hnn_per+") then sym.Period := "+hnn_per+";"
             " if (openn = true) then"
             " begin"
             //                   " sym.Log.Add('" + hnn_fil + "');"
             " if (sym.Open('"+hnn_fil+"')) then Result := sym.TeachInput;\n\r" // ret input Line #8
             " end else"
             " begin"
             " sym.TeachInput := "+IntegerToString(hnn_in)+";"
             " sym.TeachOutput := "+IntegerToString(hnn_out)+";"
             " sym.TeachLayer := "+IntegerToString(hnn_layers)+";"
             " sym.TeachNeurons := "+IntegerToString(hnn_neurons)+";"
             " sym.TeachEpoch := "+IntegerToString(hnn_epoch)+";"
             " sym.FileName := '"+hnn_fil+"';"
             " Result := sym.TeachInput;\n\r" // ret input Line #9
             " end;"
             " end;"
             " end;"
             " end;"
             " end;"
             " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(res<=0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
        {
         Sleep(SLEEP_TIM);
         res=FileSize(m_hnn);
         num++;
        }
      if(res>0)
        {
         result=FileReadString(m_hnn,int(res/2));
         res=StringToInteger(result);
         if(res<=RES_OK)
            printf(__FUNCTION__+": Error! Initialization data(possible reason: FILE NOT EXIST OR CORRUPTED "+hnn_fil);
         else
           {
            printf(__FUNCTION__+": Initialization successful! NEURAL PATTERN "+string(res));
            ArrayResize(pattern,int(res+1));
            return(true);
           }
        }
      else
         printf(__FUNCTION__+": Error! pipe server not responding(possible elimination: RESTART HLAIMAN APPLICATION)");
     }
   else
      printf(__FUNCTION__+": Error! initializing pipe server (possible reason: HLAIMAN APPLICATION IS NOT RUNNING!)");
//--- ok
   return(false);
  }

Wie aus dem Code ersichtlich ist, deckt der erste Initialisierungschritt den Versuch ab, eine Named Pipe zu öffnen, um mit der Applikation Hlaiman in Kontakt zu treten Falls dieser Versuch fehlschlägt (Beispiel: die <hlaim.exe> wird nicht ausgeführt), endet das Ganze mit einem negativen Status. Im zweiten Schritt (nachdem der erste Schritt erfolgreich beendet wurde sowie der Indikatormodus erfolgreich operiert) werden lokale und gemeinsame Ordner des Terminals nach dem benötigten Dateinamen mit den Daten des neuronalen Netzwerks durchsucht . Der dritte Schritt dient der Vorbereitung des Codes in ObjectPascal (Delphi) zur direkten Initialisierung der Applikation Hlaiman.

Der Text des Codes wird daraufhin zum Ursprungsstring kopiert. Um eine komfortable Formatierung zu ermöglichen, wird dieser String via „\n\r“ in mehrere Unterstrings zerteilt, die Aufrufe der Methoden und Eigenschaften von Hlaiman-Objekten enthalten. Wie im Text definiert, repräsentiert die objektorientierte Umgebung des MetaTrader-5-Hlaiman-Plugins die Architektur eines Baums, wobei das Objekt des Plugins einen Teil der Wurzel darstellt.

Dem Objekt des MetaTrader-5-Terminals folgen im nächsten Level der Expert Advisor als auch Symbolobjekte. Im Falle einer erfolgreichen Übersetzung und Durchführung des via Named Pipes übermittelten Source Codes wird der zurückgegebene Ergebniswert die Zahl der Elemente der Input-Vektoren des neuronalen Netzwerks enthalten. Wie der Code bereits andeutet, wird dieser Wert dazu gebraucht, das Muster des Arrays zu initialisieren. Die Ausführung der Methode ist - mit einem positiven Status - komplett.

Die anderen elementaren Methoden der Klasse CSignalHNN sind CalculateHNN, AddPattern und TeachHNN. Die erste gibt die Resultate der neuronalen-Netzwerk-Kalkulationen im Indikatormodus aus. Die zweite und dritte kommen im Lehrmodus zum Einsatz, wenn es darum geht, Muster zu sammeln und den Lehrprozess des neuronalen Netzwerks einzuleiten.

Die Umsetzung dieser Methoden sieht in <SignalHNN.mqh> wie folgt aus:

//+------------------------------------------------------------------+
//| Calculate HNN signal                                             |
//+------------------------------------------------------------------+
double CSignalHNN::CalculateHNN(void)
  {
   if(m_hnn==0 || m_hnn==INVALID_HANDLE) return(0.0);
   int num = 0;
   ulong siz = 0;
   double res=0.0;
   string source,result="";
   if(FillPattern(0)==true)
     {
      result=CON_START;
      for(int i=1; i<(ArraySize(pattern)-1); i++)
         result= result+DoubleToString(pattern[i])+CON_ADD;
      result = result + DoubleToString(pattern[ArraySize(pattern) - 1]) + CON_END;
      source = "unit CalcHNN; Interface " + result + " var i: integer; libr, term, exp, sym, lst: TObject;"
              " Implementation function main: double;\n\r" // Line #1
              " begin"
              " Result := 0.0;"
              " libr := Open('mt45.dll');\n\r" // Line #2
              " if (libr <> nil) then"
              " begin"
              " term := Open('"+hnn_path+"');\n\r" // Line #3
              " if (term <> nil) then"
              " begin"
              " exp := term.ObjectOfName('"+hnn_nam+"');\n\r" // Line #4
              " if (exp <> nil) then"
              " begin"
              " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');\n\r" // Line #5
              " if (sym <> nil) then"
              " begin"
              " lst := TStringList.Create;"
              " if (lst <> nil) then"
              " begin"
              " lst.Text := cons;"
              " if (lst.Count >= sym.NetInputs.Count) then"
              " begin"
              " for i := 0 to sym.NetInputs.Count - 1 do"
              " begin"
              " sym.NetInputs.Objects[i].NetValue := StrToFloat(lst[i]);\n\r" // Line #6
              //                    " sym.Log.Add('Input ' + IntToStr(i) + ' = ' + lst[i]);"              
              " end;"
              " sym.Computed := true;"
              " Result := sym.NetOutputs.Objects[0].NetValue;\n\r" // ret input Line #7
              " end;"
              " lst.Free;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(siz<=0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
        {
         Sleep(SLEEP_TIM);
         siz=FileSize(m_hnn);
         num++;
        }
      if(siz>0)
        {
         result=FileReadString(m_hnn,int(siz/2));
         res=StringToDouble(result);
        }
     } //else Print("fill pattern error!");
   return(res);
  }
//+------------------------------------------------------------------+
//| AddPattern                                                       |
//+------------------------------------------------------------------+
bool CSignalHNN::AddPattern(string name,int ptype)
  {
   int num=0;
   long res=0;
   ulong siz=0;
   string result,source,nam=name;
   if(m_hnn!=0 || m_hnn!=INVALID_HANDLE)
     {
      pattern[0]=ptype;
      result=CON_START;
      for(int i=0; i<(ArraySize(pattern)-1); i++)
         result= result+DoubleToString(pattern[i])+CON_ADD;
      result = result + DoubleToString(pattern[ArraySize(pattern) - 1]) + CON_END;
      source = "unit AddPatternHNN; Interface " + result + " Implementation function main: integer;"
              " var i: integer; out: double; onam: string;"
              " libr, term, exp, sym, ord, tck, lst: TObject;\n\r" // Line #1
              " begin"
              " Result := 0;"
              " libr := Open('mt45.dll');\n\r" // Line #2
              " if (libr <> nil) then"
              " begin"
              " term := Open('"+hnn_path+"');\n\r" // Line #3
              " if (term <> nil) then"
              " begin"
              " exp := term.ObjectOfName('"+hnn_nam+"');\n\r" // Line #4
              " if (exp <> nil) then"
              " begin"
              " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');\n\r" // Line #5
              " if (sym <> nil) then"
              " begin"
              " lst := TStringList.Create;"
              " if (lst <> nil) then"
              " begin"
              " lst.Text := cons;"
              " if (lst.Count >= (sym.TeachInput + sym.TeachOutput)) then"
              " begin"
              " out := StrToFloat(lst[0]);"
              " if(out >= 0) then onam := 'BUY-"+nam+"'"
              " else onam := 'SELL-"+nam+"';"
              " ord := sym.ObjectOfName(onam);"
              " if (ord = nil) then ord := sym.AddObject('TMT45Order');\n\r" // Line #6                    
              " if (ord <> nil) then"
              " begin"
              " if (ord.Name <> onam) then ord.Name := onam;\n\r" // Line #7
              " if (out >= 0) then ord.OrderType := 0 else ord.OrderType := 1;"
              " if (ord.NetOutput <> out) then ord.NetOutput := out;\n\r" // Line #8
              " for i := 1 to sym.TeachInput do"
              " begin"
              " if(i <= ord.Count) then tck := ord.Items[i - 1] else"
              " tck := ord.AddObject('TMT45Tick');\n\r" // Line #10                    
              " if (tck <> nil) then"
              " begin"
              " tck.x := i;"
              " tck.y := StrToFloat(lst[i]);\n\r" // Line #11
              " end;"
              " end;"
              " end;"
              " Result := sym.Count;\n\r" // ret input Line #12
              " end;"
              " lst.Free;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end;"
              " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(siz<=0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
        {
         Sleep(SLEEP_TIM);
         siz=FileSize(m_hnn);
         num++;
        }
      if(siz>0)
        {
         result=FileReadString(m_hnn,int(siz/2));
         res=StringToInteger(result);
        }
     }
   return(res>0);
  }
//+------------------------------------------------------------------+
//| TeachHNN                                                         |
//+------------------------------------------------------------------+
bool CSignalHNN::TeachHNN(void)
  {
   int num=0;
   long res=0;
   ulong siz=0;
   string result,source;
   if(m_hnn!=0 || m_hnn!=INVALID_HANDLE)
     {
      source="unit TeachHNN; Interface const WAIT_TIM = 100; WAIT_CNT = 100;"
             "  var i: integer; libr, term, exp, sym: TObject;"
             " Implementation function main: integer;\n\r" // Line #1
             " begin"
             " Result := 0;"
             " libr := Open('mt45.dll');\n\r" // Line #2
             " if (libr <> nil) then"
             " begin"
             " term := Open('"+hnn_path+"');\n\r" // Line #3
             " if (term <> nil) then"
             " begin"
             " exp := term.ObjectOfName('"+hnn_nam+"');\n\r" // Line #4
             " if (exp <> nil) then"
             " begin"
             " sym := exp.ObjectOfName('"+hnn_sym+hnn_per+"');\n\r" // Line #5
             " if (sym <> nil) then"
             " begin"
             " if (sym.Teached) then sym.Teached := false;\n\r" // Line #6
             " sym.Teached := true;\n\r" // Line #7
             " Result := sym.Count;\n\r" // ret input Line #8
             " end;"
             " end;"
             " end;"
             " end;"
             " end; end.";
      FileWriteString(m_hnn,source,StringLen(source));
      FileFlush(m_hnn);
      while(siz<=0)
        {// && (MQL5InfoInteger(MQL5_TESTER) || num < WAIT_TIMES)) {
         Sleep(SLEEP_TIM);
         siz=FileSize(m_hnn);
         num++;
        }
      if(siz>0)
        {
         result=FileReadString(m_hnn,int(siz/2));
         res=StringToInteger(result);
        }
     }
   return(res>0);
  }

Man kann dem Code entnehmen, dass der Hauptkörper der Methode aus Source-Code-Zeilen besteht, deren Text dem der oben erwähnten InitHNN-Methodenbeschreibung gleicht. Der Unterschied besteht nur darin, dass die objektbasierte Hierarchie des Plugins zwei Levels zur Repräsentation von Mustern aufweist - „Order“ und „Tick“. Außerdem enthält der Code zusätzliche Objekteigenschaften und Methoden. Beispielsweise ist der Start der neuronalen-Netzwerk-Kalkulation durch die Computermarkierung des „Symbol“-Objekts markiert, wohingegen die Gelehrt-Markierung benutzt wird, wenn der Lehrprozess eingeleitet wird.

Außerdem unterschiedet sich die Methode CalculateHNN von anderen Methoden: Der Typ ihres „Haupt“-Werts, der durch die Funktion zurückgegeben wird, ist in diesem Fall „double“. Dieser Wert ist der Output eines neuronalen Netzwerks - das Signal, wobei das Kaufen-Level durch den Bereich 0 bist 1 und das Verkaufen-Level durch den Bereich 0 bis -1 repräsentiert wird. Dieses Signal wird seitens des EA dafür genutzt, Entscheidungen über die Eröffnung oder das Schließen von Handelspositionen zu treffen, und wird durch die Nachweismethode kontrolliert. Diese Methode führt Neuberechnungen im Falle des neuen Balkens durch und gibt diesen Wert als Prozentangabe aus.

//+------------------------------------------------------------------+
//| Check conditions for trading signals.                            |
//+------------------------------------------------------------------+
double CSignalHNN::Direction(void)
  {
   if( m_hnn == 0 || m_hnn == INVALID_HANDLE) return(EMPTY_VALUE);
//--- check new bar condition
   int cur_bar = Bars(hnn_sym, hnn_period);
   if (hnn_bar != cur_bar) {
//--- condition OK
      hnn_signal = CalculateHNN() * 100;
      hnn_bar = cur_bar;
   }
   return(hnn_signal);
  }

Um die Signalantwortschwelle des EAs hinsichtlich des Öffnens und Schließens von Handelspositionen einzustellen, können Sie die folgenden externen Variablen verwenden:

  • input int    Signal_ThresholdOpen =10;      // Signalschwellenwert zum Öffnen [0...100]
  • input int    Signal_ThresholdClose=10;      // Signalschwellenwert zum Schließen [0...100]

In der Praxis hängen die Signallevels von der Qualität und der Intensität des Lehrprozesses des neuronalen Netzwerks ab. Beides kann bewertet werden, indem man die verminderten Dynamiken von Rechenfehlern überwacht, die während des Lehrprozesses im Indikator angezeigt werden.


Fazit

Hlaiman EA Generator stellt Komponenten sowie eine transparente OOP-Umgebung zur Verfügung, mit deren Hilfe MQL5 integriert werden kann:

  1. Das Interface des MQL5-Assistenten erhält einen zusätzlichen Typ, der auf der Erkennung von Signalen und Mustern basiert, sowie die Möglichkeit, EAs zu generieren, die auf einem neuronalen Netzwerk basieren.
  2. Zusätzlich zu dieser Möglichkeit können Sie diese sehr leicht modifizieren und an ein sich änderndes Marktverhalten anpassen. Außerdem können Sie ihnen nachhaltig verschiedene Handelsinstrumente und Zeitrahmen beibringen.
  3. Da der MQL5-Assistent multiple Signalmodule aktivieren kann, können Sie komplexe Multiwährungs-Neuronale-Netzwerk-EAs kreieren und/oder indikatorbasierte, Neuronale-Netzwerk-EAs zusammenbauen. Sie können außerdem mit verschiedenen Filtern (zum Beispiel Zeitfiltern) kombiniert werden.
  4. Schließlich können die Module neuronaler Netzwerke als ein zusätzlicher Filter verwendet werden, um die Effektivität eines gebrauchsfertigen EAs zu erhöhen. Dies ist dadurch möglich, dass neuronale Netzwerke über die Fähigkeit verfügen, Wissen mithilfe der Visualisierungscharts der Testresultate des originalen EAs zu erlangen.

Die Verwendung eines Script Interpreters führt bei integrierten Computersystemen zu einer sinkenden Performance. Dies ist zweifellos ein Nachteil der oben beschriebenen Umsetzung. Andererseits darf nicht verschwiegen werden, dass die Interpretation des Skriptcodes / die Operation des Hlaiman-Plugins asynchron mit EX5 erfolg (z.B die Auseinandersetzung mit parallelen Aufträgen). Zweitens können MetaTrader 5 und Hlaiman auf verschiedenen Rechnern ausgeführt werden, die mit Named Pipes miteinander verbunden sind, um die Geschwindigkeit zeitintensiver Berechnungen zu erhöhen, wenn man mit großen neuronalen Netzwerken hantiert. Das Ausführen eines Handelsterminals auf einem separate Computers sorgt zwar nicht für mehr Performance, aber immerhin erhöht es ein wenig Ihre Sicherheit.

Ins rechte Licht gerückt: Wir können uns die Entwicklung eines selbstlernenden EAs ansehen, der fähig zum Traden ist. An dieser Stelle besteht der einfachste Weg, dies zu tun, darin, den Code des EAs mit dem Lehrprozesscode zu kombinieren, da beide auf der selben CSignalHNN-Klasse basieren, die die erforderliche Funktionalität besitzt. Ich hoffe, dass dieser Artikel entweder ihm folgende, thematisch verwandte Artikel gebiert, oder aber, dass er als Basis für gänzlich neue Artikel dienen wird.

Die Demoversion von Hlaiman EA Generator kann hier heruntergeladen werden.

Anhänge:

  • SignalHNN.mqh - Signalmodul, „MQL5\Include\Expert\Signal\".
  • TeachHNN.mq5 - Skript zur Wissensvermittlung, „MQL5\Scripts\".
  • SampleHNN.mq5 - Expert Advisor, der auf dem Handelssignalmodul „Signals of patterns Hlaiman Neural Network EA generator“ basiert und mittels MQL5-Assistent generiert wurde.

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

Beigefügte Dateien |
signalhnn.mqh (23.88 KB)
teachhnn.mq5 (9.67 KB)
samplehnn.mq5 (6.35 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (2)
Otto Pauser
Otto Pauser | 24 Nov. 2018 in 19:04
Metaquotes ist wohl an den Umsätzen des 

Hlaiman EA Generator 

beteiligt!?
Ivan Negreshniy
Ivan Negreshniy | 16 Jan. 2019 in 07:58
Otto Pauser:
Metaquotes ist wohl an den Umsätzen des 

Hlaiman EA Generator 

beteiligt!?

Sie sind nur daran interessiert, das Geld einer anderen Person zu zählen, oder möchten wissen, wie es funktioniert?

Zum Beispiel, wie die MetaQuotes ein System aufgebaut haben, in dem sich die Einnahmen des Unternehmens im Verhältnis zur Beteiligung an Unternehmen, Händlern und sehr kleinen Programmierern teilen können:)

Eine andere MQL5-OOP-Klasse Eine andere MQL5-OOP-Klasse
Dieser Artikel soll Sie damit vertraut machen, wie Sie von Grund auf einen objektorientierten Expert Advisor konstruieren: und zwar beginnend mit der theoretischen Konzeption bis hin zur praktischen Programmierung eines MQL5-EAs. Ich persönliche vertrete die Einstellung, dass nichts über die Learning-by-Doing-Methode geht. Ich werde Ihnen daher anhand eines praktischen Beispiels vorführen, wie Sie Ihre Ideen ordnen können, um Ihren Forex-Roboter mit einem Code zu versehen. Ich habe außerdem die Absicht, Ihnen einige OO-, also objektorientierte Prinzipien näherzubringen.
Einen automatisierten News-Trader kreieren Einen automatisierten News-Trader kreieren
Vorliegender Artikel stellt eine Fortsetzung des Artikels „Eine andere MQL5-OOP-Klasse“ dar, der Ihnen bereits gezeigt hat, wie Sie aus dem Nichts einen objektorientierten EA basteln, und der Ihnen Tipps zum objektorientierten Programmieren vermittelt hat. Heute werde ich Ihnen die technischen Grundlagen zeigen, mit deren Hilfe Sie einen EA erstellen können, der mit News tradet. Mein Ziel ist es dabei, Ihnen noch ein paar weitere Ideen betreffend objektorientierter Programmierung zu geben und Sie gleichzeitig mit einem neuen Thema zu konfrontieren - dem Arbeiten mit Dateisystemen.
Wie Sie OpenCl öffnen und für Kalkulationen verwenden. Wie Sie OpenCl öffnen und für Kalkulationen verwenden.
Es ist nun schon mehr als ein Jahr her, dass MQL5 OpenCL unterstützt. Allerdings haben noch nicht sehr viele Benutzer den wahren Wert von paralleler Datenverarbeitung (Parallel Computing) bezüglich Expert Advisors, Indikatoren oder Skripten erkannt. Dieser Artikel soll Ihnen dabei helfen, OpenCL auf Ihrem Computer zu installieren als auch einzurichten, so dass Sie diese Technologie in Ihrem MetaTrader-5-Handelsterminal verwenden können.
Der MQL5-Assistent: Wie man einem EA beibringt, einen bedingten Auftrag (Pending Order) eines beliebigen Preises zu platzieren Der MQL5-Assistent: Wie man einem EA beibringt, einen bedingten Auftrag (Pending Order) eines beliebigen Preises zu platzieren
Dieser Artikel beschreibt eine Methode, mit der man den Code eines Handelsignalmoduls so modifiziert, dass die Funktion zur Verfügung steht, einen bedingten Auftrag unabhängig des aktuellen Preises in Auftrag zu geben: Hierbei kann es sich um den Eröffnungs- oder Schlusskurs des vorherigen Balkens oder um den gleitenden Durchschnittswert handeln. Die Optionen sind grenzenlos. Entscheidend ist, dass Sie einen Eröffnungskurs für einen bedingten Auftrag einstellen können. Dieser Artikel richtet sich an all jene Trader, die sich mit bedingten Aufträgen (Pending Orders) auseinandersetzen.