Verbinden von neuronalen Netzwerken von NeuroSolutions

ds2 | 14 März, 2016

Einleitung

Ich schätze, dass alle Händler, die neuronale Netzwerke zum ersten Mal sehen, überlegen, wie großartig es wäre, sie für die Marktanalyse zu nutzen. Es gibt viele Programme, mit denen Sie Ihre eigenen Netzwerke in jeder beliebigen Konfiguration bequem visuell erstellen, einlernen und testen können. Sie können erforderliche Informationen aus dem Client Terminal in ein neuronales Netzwerkprogramm exportieren und dort analysieren.

Doch was, wenn Sie das erstellte neuronale Netzwerk im automatischen Handel nutzen möchten? Ist es möglich, einen Expert Advisor so einzustellen, dass es sich mit einem neuronalen Netzwerk verbindet und in Echtzeit handelt?

Ja. Einige neuronale Netzwerkprogramme verfügen über die nötigen Programmschnittstellen. Eins davon heißt NeuroSolutions. Die aktuellste Version ist Version 6, allerdings hat nicht jeder diese Version und die beliebteste Version ist derzeit die fünfte. [Anm. d. Übers.: Dies galt zum Verfassungszeitpunkt des Beitrags im Januar 2011. Zum Zeitpunkt dieser Übersetzung ist die 7. Version bereits verfügbar.] Deshalb beschreibt dieser Beitrag die Interaktion mit der 5. Version. Sie brauchen die vollständige Distribution des Programms. Sie beinhaltet den Custom Solution Wizard, den wir benötigen.


Ersinnen einer Strategie

Die Strategie für unser Testbeispiel ist einfach. Nennen wir sie WeekPattern. Sie prognostiziert den Schließungspreis eines Balkens bei seiner Eröffnung auf dem Timeframe D1 mithilfe eines neuronalen Netzwerks. Abhängig von den erhaltenen Informationen tätigt sie einen Buy- oder Sell-Abschluss und hält diesen über den ganzen Tag. Die Preisprognose basiert auf den OHLC-Werten der vorhergehenden 5 Balken. Zur Erhöhung der Genauigkeit der Arbeit des neuronalen Netzwerks senden wir ihm anstatt der Preise selbst nur die Preisänderungen in Bezug auf den Eröffnungspreis des aktuellen (Null-)Balkens.

Vorbereiten der Einlerndaten

Bevor wir mit der Erstellung eines Netzwerks beginnen, schreiben wir ein MQL5-Script, das alle Gebote in der erforderlichen Form aus dem Client Terminal exportiert. Diese Informationen werden benötigt, um das neuronale Netzwerk einzulernen. Die Daten werden als Textdatei exportiert. Listen Sie in der ersten Zeile der Datei die Feldnamen durch Komma getrennt auf. Die nächsten Zeilen werden für kommagetrennte Daten genutzt. Jede Zeile ist eine Kombination von Ein- und Ausgängen des neuronalen Netzwerks. In unserem Fall geht das Script in jeder Zeile um einen Balken in der Preishistorie zurück und schreibt die OHLC-Werte von 6 Balken in die Zeile (5 Balken aus der Vergangenheit sind Eingänge und ein aktueller Balken ist der Ausgang).

Das Script WeekPattern-Export.mq5 muss auf dem erforderlichen Timeframe des erforderlichen Symbols gestartet werden (in unserem Fall D1 EURUSD). In den Einstellungen müssen ein Dateiname und die erforderliche Menge an Zeilen festgelegt werden (260 Zeilen für D1 entsprechen ungefähr der Historie für 1 Jahr). Der vollständige Code des Scripts:

#property script_show_inputs
//+------------------------------------------------------------------+
input string    Export_FileName = "NeuroSolutions\\data.csv"; // File for exporting (in the folder "MQL5\Files")
input int       Export_Bars     = 260; // Number of lines to be exported
//+------------------------------------------------------------------+
void OnStart() 
  {
  
   // Create the file
   int file = FileOpen(Export_FileName, FILE_WRITE|FILE_CSV|FILE_ANSI, ',');
   
   if (file != INVALID_HANDLE)
     {
      // Write the heading of data
      
      string row="";
      for (int i=0; i<=5; i++)
        {
         if (StringLen(row)) row += ",";
         row += "Open"+i+",High"+i+",Low"+i+",Close"+i;
        }
      FileWrite(file, row);
      
      // Copy all required information from the history
      
      MqlRates rates[], rate;
      int count = Export_Bars + 5;
      if (CopyRates(Symbol(), Period(), 1, count, rates) < count)
        {
         Print("Error! Not enough history for exporting of data.");
         return;
        }
      ArraySetAsSeries(rates, true);
      
      // Write data      
      
      for (int bar=0; bar<Export_Bars; bar++)
        {
         row="";
         double zlevel=0;
         for (int i=0; i<=5; i++)
           {
            if (StringLen(row)) row += ",";
            rate = rates[bar+i];
            if (i==0) zlevel = rate.open; // level for counting of prices
            row += NormalizeDouble(rate.open -zlevel, Digits()) + ","
                 + NormalizeDouble(rate.high -zlevel, Digits()) + ","
                 + NormalizeDouble(rate.low  -zlevel, Digits()) + ","
                 + NormalizeDouble(rate.close-zlevel, Digits());
           }
         FileWrite(file, row);
        }

      FileClose(file);
      Print("Export of data finished successfully.");
     }
   else Print("Error! Failed to create the file for data export. ", GetLastError());
  }
//+------------------------------------------------------------------+

Nach dem Export der Daten erhalten wir die Datei data.csv. Ihre ersten Zeilen sehen (zum Beispiel) so aus:

Open0,High0,Low0,Close0,Open1,High1,Low1,Close1,Open2,High2,Low2,Close2,Open3,High3,Low3,Close3,Open4,High4,Low4,Close4,Open5,High5,Low5,Close5
0,0.00463,-0.0041,0.00274,-0.00518,0.00182,-0.00721,-6e-005,0.00561,0.00749,-0.00413,-0.00402,0.02038,0.02242,0.00377,0.00565,0.03642,0.0379,0.01798,0.02028,0.0405,0.04873,0.03462,0.03647
0,0.007,-0.00203,0.00512,0.01079,0.01267,0.00105,0.00116,0.02556,0.0276,0.00895,0.01083,0.0416,0.04308,0.02316,0.02546,0.04568,0.05391,0.0398,0.04165,0.04504,0.05006,0.03562,0.0456
0,0.00188,-0.00974,-0.00963,0.01477,0.01681,-0.00184,4e-005,0.03081,0.03229,0.01237,0.01467,0.03489,0.04312,0.02901,0.03086,0.03425,0.03927,0.02483,0.03481,0.02883,0.04205,0.02845,0.03809

Das ist das Format, das von NeuroSolutions verstanden wird. Nun können wir mit der Erstellung und dem Einlernen eines Netzwerks beginnen.

Erstellen des neuronalen Netzwerks

In NeuroSolutions können Sie schnell ein neuronales Netzwerk erstellen, selbst wenn Sie das Programm zum ersten Mal sehen und wenig über neuronale Netzwerke wissen. Wählen Sie hierzu beim Programmstart den Assistenten für Anfänger NeuralExpert (Beginner):

Darin müssen Sie einen Aufgabentyp festlegen, der durch das neuronale Netzwerk gelöst werden soll:

Geben Sie dann die Datei mit Einlerninformationen an, die wir im vorherigen Kapitel erstellt haben:

Wählen Sie als Eingänge des Netzwerks alle Felder der Datei mit Ausnahme der Felder des Nullbalkens:

Da wir keine Textfelder haben, wählen Sie nichts aus:

Geben Sie unsere Datei mit Informationen erneut an:

Wählen Sie nur einen Ausgang für unser Netzwerk:

Der Assistent schlägt standardmäßig die Erstellung des einfachsten Netzwerks vor. Das tun wir auch:

Der Assistent hat seine Arbeit abgeschlossen und ein neuronales Netzwerk für uns erstellt (kein eingelerntes Netzwerk, nur eine einfache Struktur):

Nun können wir damit arbeiten. Wir können es einlernen, testen und für die Datenanalyse verwenden.

Wenn Sie auf die Schaltfläche Test klicken, sehen Sie, wie das nicht eingelernte Netzwerk unsere Aufgabe lösen wird. Beantworten Sie die Fragen des Testassistenten:

Führen Sie den Test auf Basis der Informationen aus derselben Datei aus:

Der Test ist vorbei. Im Fenster "Output vs. Desired Plot" (Ausgabe vs. erwünschte Darstellung) sehen Sie ein Diagramm, das die erhaltenen Werte aus dem Netzwerk (rot) auf unserer Historie und die realen Werte (blau) anzeigt. Sie sehen, dass sie sich ziemlich stark unterscheiden:

Lernen wir das Netzwerk nun ein. Klicken Sie dazu auf die grüne Schaltfläche Start in der Werkzeugleiste unterhalb des Menüs. Das Einlernen wird nach einigen Sekunden abgeschlossen und das Diagramm verändert sich:

Nun sehen Sie im Diagramm, dass das Netzwerk Ergebnisse anzeigt, die korrekt zu sein scheinen. Somit können Sie es für den Handel nutzen. Speichern Sie das Netzwerk unter dem Namen WeekPattern.

Exportieren des neuronalen Netzwerks in eine DLL

Ohne NeuroSolutions zu beenden, klicken Sie auf die Schaltfläche CSW, mit der der Custom Solution Wizard gestartet wird. Wir müssen eine DLL aus dem vorliegenden neuronalen Netzwerk erzeugen.

Der Wizard kann DLLs für verschiedene Programme erzeugen. Soweit ich es verstanden habe, brauchen Sie zum Kompilieren der DLL Visual C++ in einer der folgenden Versionen: 5.0/6.0/7.0 (.NET 2002)/7.1 (.NET 2003)/8.0 (.NET 2005). Aus irgendeinem Grund nimmt er keine Express-Versionen (ich habe es geprüft).

MetaTrader ist in der Liste der Zielanwendungen nicht zu finden. Wählen Sie deshalb Visual C++.

Pfad zum Speichern des Ergebnisses:

Wenn alles erfolgreich abgeschlossen ist, werden Sie vom Wizard benachrichtigt:

In dem im Wizard festgelegten Ordner erscheinen viele Dateien. Die wichtigsten davon sind: WeekPattern.dll, die unser neuronales Netzwerk mit der Programmschnittstelle dazu enthält, und WeekPattern.nsw, die die Balance-Einstellungen des neuronalen Netzwerks nach seinem Einlernprozess enthält. Unter den restlichen Dateien finden Sie eine, die ein Beispiel der Arbeit mit diesem neuronalen DLL-Netzwerk beinhaltet. In diesem Fall ist es das Projekt in Visual C++ 6.

Verbinden des neuronalen DLL-Netzwerks mit MetaTrader

Das im vorherigen Kapitel erstellte neuronale DLL-Netzwerk ist für die Nutzung in Visual-C++-Projekten vorgesehen. Es arbeitet mit Objekten mit einer so komplexen Struktur, dass es in MQL5 schwer oder gar unmöglich zu beschreiben wäre. Deshalb werden wir diese DLL nicht direkt mit MetaTrader verbinden. Stattdessen erstellen wir einen kleinen DLL-Adapter. Dieser Adapter wird eine einfache Funktion für die Arbeit mit dem neuronalen Netzwerk enthalten. Diese Funktion erstellt das Netzwerk, übergibt die Eingangsinformationen an das Netzwerk und gibt die Ausgangsdaten aus.

Dieser Adapter lässt sich einfach aus MetaTrader 5 aufrufen. Und der Adapter verbindet sich mit dem in NeuroSolutions erstellten neuronalen DLL-Netzwerk. Da der Adapter in Visual C++ geschrieben sein wird, wird er keine Probleme mit den Objekten dieser DLL haben.

Sie müssen den DLL-Adapter nicht selbst erstellen. Die fertige DLL ist an diesen Beitrag angehängt. Der Adapter funktioniert mit allen in NeuroSolutions erstellten neuronalen DLL-Netzwerken. Sie können den Rest dieses Kapitels überspringen.

Wenn Sie aber Erfahrung mit der Programmierung in C++ haben und daran interessiert sind, wie ein solcher Adapter erstellt wird, lesen Sie dieses Kapitel bis zum Schluss. Sie werden ihn wahrscheinlich verbessern wollen, weil noch einige weitere Funktionen aus einem neuronalen DLL-Netzwerk exportiert werden können. Zum Beispiel die Einlernfunktion (damit sich ein Expert Advisor an einen sich verändernden Markt anpassen und das Netzwerk dabei automatisch neu einlernen kann). Die volle Liste von Funktionen erhalten Sie durch die Analyse des durch den Custom Solution Wizard erzeugten Beispiels, das im vorherigen Kapitel gezeigt wird.

Wir brauchen nur bestimmte Dateien aus diesem Beispiel.

Erstellen Sie in Visual C++ (dieselbe Version wie im Custom Solution Wizard) ein leeres DLL-Projekt mit dem Namen NeuroSolutionsAdapter und kopieren Sie aus dem Beispiel die Dateien NSNetwork.h, NSNetwork.cpp und StdAfx.h hinein. Erstellen Sie ebenso die leere Datei main.cpp:

Schreiben Sie in die Datei main.cpp den folgenden Code:

#include "stdafx.h"
#include "NSNetwork.h"

extern "C" __declspec(dllexport) int __stdcall CalcNeuralNet(
                LPCWSTR dllPath_u, LPCWSTR weightsPath_u,
                double* inputs, double* outputs)
{       
    // Transform the lines from Unicode to normal ones
    CString dllPath     (dllPath_u);
    CString weightsPath (weightsPath_u);

    // Create neuronet
    NSRecallNetwork nn(dllPath);
    if (!nn.IsLoaded()) return (1);

    // Load balances
    if (nn.LoadWeights(weightsPath) != 0) return (2);
        
    // Pass input data and calculate the output
    if (nn.GetResponse(1, inputs, outputs) != 0) return (3);

    return 0;
}

Build. Der DLL-Adapter ist fertig!

Verwenden des neuronalen Netzwerks im Expert Advisor

Wir haben bereits mehrere Dateien erstellt. Lassen Sie mich die Dateien auflisten, die für die Arbeit des Expert Advisors benötigt werden, und die Ordner, in die Sie sie legen sollten. Alle diese Dateien sind an den Beitrag angehängt.

Datei Beschreibung Ablageort (im Terminal-Ordner)
WeekPattern.dll unser in NeuroSolutions erstelltes neuronales DLL-Netzwerk MQL5\Files\NeuroSolutions\
WeekPattern.nsw Balance-Einstellungen unseres neuronalen Netzwerks MQL5\Files\NeuroSolutions\
NeuroSolutionsAdapter.dll universeller DLL-Adapter für jedes beliebige neuronale DLL-Netzwerk MQL5\Libraries\

Hier sehen Sie den vollständigen Code des Expert Advisors WeekPattern.mq5. Um die Suche und anschließende Anpassung zu erleichtern, befindet sich alles, was mit dem neuronalen Netzwerk im Zusammenhang steht, in der separaten Klasse CNeuroSolutionsNeuralNet.

input double    Lots = 0.1;
//+------------------------------------------------------------------+
// Connect the DLL adapter, using which we are going to use the DLL neuronet created in NeuroSolutions
#import "NeuroSolutionsAdapter.dll"
int CalcNeuralNet(string dllPath, string weightsPath, double& inputs[], double& outputs[]);
#import 
//+------------------------------------------------------------------+
class CNeuroSolutionsNeuralNet
{
private:
   string dllPath;     // Path to a DLL neuronet created in NeuroSolutions
   string weightsPath; // Path to a file of the neuronet balances
public:
   double in[20]; // Neuronet inputs - OHLC of 5 bars
   double out[1]; // Neuronet outputs - Close of a current bar

   CNeuroSolutionsNeuralNet();
   bool Calc();
};
//+------------------------------------------------------------------+
void CNeuroSolutionsNeuralNet::CNeuroSolutionsNeuralNet()
{
   string terminal = TerminalInfoString(TERMINAL_PATH);
   dllPath     = terminal + "\\MQL5\\Files\\NeuroSolutions\\WeekPattern.dll";
   weightsPath = terminal + "\\MQL5\\Files\\NeuroSolutions\\WeekPattern.nsw";
}
//+------------------------------------------------------------------+
bool CNeuroSolutionsNeuralNet::Calc()
  {
   // Get current quotes for the neuronet
   MqlRates rates[], rate;
   CopyRates(Symbol(), Period(), 0, 6, rates);
   ArraySetAsSeries(rates, true);
      
   // Fill the array of input data of the neuronet
   double zlevel=0;   
   for (int bar=0; bar<=5; bar++)
     {
      rate = rates[bar];
      // 0 bar is not taken for input
      if (bar==0) zlevel=rate.open; // level of price calculation
      // 1-5 bars are inputed
      else
        {
         int i=(bar-1)*4; // input number
         in[i  ] = rate.open -zlevel;
         in[i+1] = rate.high -zlevel;
         in[i+2] = rate.low  -zlevel;
         in[i+3] = rate.close-zlevel;
        }
     }
 
   // Calculate the neuronet in the NeuroSolutions DLL (though the DLL adapter)
   int res = CalcNeuralNet(dllPath, weightsPath, in, out);
   switch (res)
     {
      case 1: Print("Error of creating neuronet from DLL \"", dllPath, "\""); return (false);
      case 2: Print("Error of loading balances to neuronet from the file \"", weightsPath, "\""); return (false);
      case 3: Print("Error of calculation of neuronet");  return (false);
     }
     
   // Output of the neuronet has appeared in the array out, you shouldn't do anything with it

   return (true);
  }
//+------------------------------------------------------------------+

CNeuroSolutionsNeuralNet NN;
double Prognoze;

//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
void OnTick() 
  {
   // Get the price prediction from the neuronet
   if (NN.Calc()) Prognoze = NN.out[0];
   else           Prognoze = 0;

   // Perform necessary trade actions
   Trade();
  }
//+------------------------------------------------------------------+
void Trade() 
  {

   // Close an open position if it is opposite to the prediction

   if(PositionSelect(_Symbol)) 
     {
      long type=PositionGetInteger(POSITION_TYPE);
      bool close=false;
      if((type == POSITION_TYPE_BUY)  && (Prognoze <= 0)) close = true;
      if((type == POSITION_TYPE_SELL) && (Prognoze >= 0)) close = true;
      if(close) 
        {
         CTrade trade;
         trade.PositionClose(_Symbol);
        }
     }

   // If there is no positions, open one according to the prediction

   if((Prognoze!=0) && (!PositionSelect(_Symbol))) 
     {
      CTrade trade;
      if(Prognoze > 0) trade.Buy (Lots);
      if(Prognoze < 0) trade.Sell(Lots);
     }
  }
//+------------------------------------------------------------------+

Eine gute Möglichkeit zu überprüfen, ob wir das neuronale Netzwerk korrekt verbunden haben, ist die Ausführung des Expert Advisors im Strategietester auf dem gleichen Zeitraum, der für das Einlernen des neuronalen Netzwerks verwendet wurde.

Denn das neuronale Netzwerk ist an diesen Zeitraum angepasst. Also ist es darauf eingelernt, Gewinnsignale für Datenmuster zu erkennen und weiterzugeben, die in diesem spezifischen Zeitraum überwiegen. Ein Wirtschaftlichkeitsdiagramm eines Expert Advisors, das für einen solchen Zeitraum gezeichnet wird, sollte absteigend sein.

Überprüfen wir das. In unserem Fall erhalten wir das folgende schöne Diagramm:

Das bedeutet, dass alles korrekt verbunden wurde.

Für die Statistik sehen Sie hier die weiteren Testberichte des Expert Advisors:

Für alle Fälle führe ich noch Erklärungen für Neueinsteiger in die Entwicklung von Handelsstrategien und neuronalen Netzwerken auf.

Die Wirtschaftlichkeit eines Expert Advisors auf einem Zeitraum, der für seine Optimierung genutzt wurde (Handel seines neuronalen Netzwerks) sagt nichts über die Gesamtwirtschaftlichkeit des EAs aus. In anderen Worten: Sie garantiert nicht seine Wirtschaftlichkeit in anderen Zeiträumen. Es kann andere vorherrschende Muster geben.

Die Erstellung von Handelsstrategien, die ihre Wirtschaftlichkeit über die Grenzen des Einlernens hinaus beibehalten, ist eine komplexe und schwierige Aufgabe. Sie sollten sich nicht auf NeuroSolutions oder sonstige Anwendungen für neuronale Netzwerke verlassen, um dieses Problem für Sie zu lösen. Die Anwendung erstellt nur ein neuronales Netzwerk für Ihre Daten.

Aus diesen Gründen führe ich das Ergebnis des Forward-Testings des erhaltenen Expert Advisors an dieser Stelle nicht auf. Die Erstellung einer wirtschaftlichen Handelsstrategie ist nicht das Ziel dieses Beitrags. Das Ziel ist zu erklären, wie ein neuronales Netzwerk mit einem Expert Advisor verbunden wird.

Fazit

Händler sollten nun über ein weiteres leistungsstarkes und benutzerfreundliches Werkzeug für die automatische Handelsanalyse und den Handel verfügen. Zusammen mit einem tiefgreifenden Verständnis der Prinzipien und Möglichkeiten von neuronalen Netzwerken sowie den Regeln für ihr Einlernen ermöglicht es Ihnen die Erstellung gewinnbringender Expert Advisors.