Experimente mit neuronalen Netzen (Teil 7): Übergabe von Indikatoren

Roman Poshtar | 12 März, 2024

Einführung

In diesem Artikel werden wir näher auf die Bedeutung der Übergabe von aussagekräftigen Daten, den so genannten Zeitreihen, an ein neuronales Netz eingehen. Insbesondere werden wir unsere Lieblingsindikatoren weitergeben. Um dies zu erreichen, werde ich einige neue Konzepte vorstellen, die ich bei der Arbeit mit neuronalen Netzen verwende. Ich denke jedoch, dass dies noch nicht das Ende der Fahnenstange ist, und im Laufe der Zeit werde ich eine neue Vision davon haben, was und wie genau verabschiedet werden muss.


Hintergrund und Beobachtungen

Bei der Lektüre zahlreicher Artikel zu diesem Thema ergibt sich immer wieder ein trauriges Bild über die unmittelbaren Ergebnisse von Handelssystemen, die auf neuronalen Netzen basieren. Viele gute Ideen und Algorithmen bringen nicht die gewünschten Ergebnisse.

Bei der Übergabe von Eingabeparametern zeigt sich immer das gleiche Bild. Zum Beispiel die direkte Übergabe der Oszillatorwerte, die meiner Meinung nach nichts mit dem Preis eines Vermögenswertes zu tun hat. Oszillatoren haben ein bekanntes Problem – die so genannte Divergenz. Dies sind die Werte von Open, Close, High und Low, die, wenn sie direkt übergeben werden, keine Bedeutung haben, sondern unverständliches Rauschen in das System bringen. Diese Werte sind an nichts gebunden und weisen eine erhebliche Streuung über die Zeit auf. Öffnen Sie beispielsweise das Tageschart eines beliebigen Währungspaares und sehen Sie sich die Schwankungsbreite der Schlusskurse an.



Theorie und Konzepte

In diesem Abschnitt beschreibe ich einige der Konzepte, die ich für mich selbst klassifiziert habe und in meinen Experimenten verwende.

  1. Abstände – Der Abstand (distance) eines beliebigen Indikators zu einem anderen Indikator oder seinem Nullwert. Meiner Meinung nach besteht der wichtigste Grundsatz darin, die aktuelle Situation mit einem stabilen Wert in der Geschichte zu verknüpfen. Wenn man den direkten Wert des MA 1-Indikators zugrunde legt, erhält man eine unverständliche Stichprobenverteilung, da sich der Kurswert im Laufe der Zeit verändert, ohne dass es eine bestimmte Spanne gibt, die eine Klassifizierung oder den geringsten Hinweis auf ein statistisches Verhalten impliziert. Anders verhält es sich, wenn wir die Differenz zwischen zwei Indikatoren (z.B. MA 1 und MA 100 in Punkten oder den aktuellen Abstand auf der Nullkerze des MACD-Indikators mit seinem Wert vor 4 Kerzen) angeben. Anhand der Abstände können wir also feststellen, ob sich der Markt weit von seinem Durchschnitt entfernt hat und ob er im Vergleich zur historischen Stichprobe zum aktuellen Zeitpunkt deutlich überkauft oder überverkauft ist. Außerdem können wir anhand der Entfernung feststellen, wo sich der Markt nach oben oder unten bewegt. Der Wert kann entweder positiv oder negativ sein.

  2. Akkumulation – Die Berechnung des Gesamtwerts des Indikators oder der Indikatoren im Verhältnis zueinander oder ihres Nullpunkts oder ihrer Nullwertpunkte bei einigen Indikatoren, die nicht Null sind. Durch die Akkumulation lässt sich also feststellen, wie lange eine bestimmte Bewegung in eine bestimmte Richtung dauert. Wenn die Akkumulation gering ist, ist vielleicht gerade eine Konsolidierung im Gange. Ist die Akkumulation hingegen groß, so ist ein langwieriger Trend zu verzeichnen. Die Richtung hängt vom Vorzeichen (- oder +) ab. Mit anderen Worten, die Akkumulationswerte haben während der „Turbulenzen“ der Konsolidierung keine großen Werte, wohl aber bei Trends.

  3. Neigungswinkel – Der aktuelle Neigungswinkel des Indikators ist ein sehr gutes Mittel, um das neuronale Netz über die aktuelle Impulsbewegung oder deren Fehlen und die Abschwächung der Aktivität auf dem Instrument zu informieren. Die Möglichkeit, die Neigungswinkel der Indikatoren für eine bestimmte Zeitspanne, z. B. 10 Kerzen, zu bestimmen, hat sich bei der Analyse der aktuellen Situation im Vergleich zu den Ergebnissen der Stichproben auf der Grundlage der Vergangenheit bewährt. Ich messe Neigungswinkel im Bogenmaß. Dies ist die einzige Methode, die mir persönlich zusagt und nicht von der Skala des Charts abhängt. 



Beispiele

Beispiele für die Verwendung von Abständen:

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;

   double a1 = ((ind_In1S1[0]-ind_In2S1[0])/Point());

   double a2 = ind_In3S1[0];

   double a3 = ind_In4S1[0];

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3);

  }

Log-Daten:

Beispiel für den Abstand 1

a1 – Differenz in Währungspaarpunkten zwischen MA 1 und MA 100 Indikator. Sie kann sowohl positive als auch negative Werte annehmen.

a2 – aktueller Wert des MACD-Indikators. Er kann sowohl positive als auch negative Werte annehmen.

a3 – aktueller Wert des CCI-Indikators. Er kann sowohl positive als auch negative Werte annehmen.

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    Candles= 10;

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;
input int    x4 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;
   double w4 = x4 - 10.0;

   double a1 = ((ind_In1S1[0]-ind_In1S1[Candles])/Point());

   double a2 = ((ind_In2S1[0]-ind_In2S1[Candles])/Point());

   double a3 = ind_In3S1[0]-ind_In3S1[Candles];
   
   double a4 = ind_In4S1[0]-ind_In4S1[Candles];

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("a3 = ", a4);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);

  }

Log-Daten:

Beispiel für den Abstand 2

a1 – Differenz der Punkte des Währungspaares des MA 1-Indikators bei Kerze 0 und Kerze 10. Sie kann sowohl positive als auch negative Werte annehmen.

a2 – Differenz der Währungspaarpunkte des MA 100 Indikators bei Kerze 0 und Kerze 10. Sie kann sowohl positive als auch negative Werte annehmen.

a3 – Differenz der Werte des MACD-Indikators bei Kerze 0 und Kerze 10. Sie kann sowohl positive als auch negative Werte annehmen.

a4 – Differenz der Werte des CCI-Indikators bei Kerze 0 und Kerze 10. Sie kann sowohl positive als auch negative Werte annehmen.

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    Candles= 10;

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;
input int    x4 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {
  
  int c1=0;
  int c2=0;
  int c3=0;

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;
   double w4 = x4 - 10.0;
   
   for(int i=0; i<=1000; i++){
   
    if(ind_In1S1[0]>ind_In2S1[0]){if (ind_In1S1[i]<ind_In2S1[i]){c1=i; break;}}
    
    if(ind_In1S1[0]<ind_In2S1[0]){if (ind_In1S1[i]>ind_In2S1[i]){c1=i; break;}}
   
   }   

   double a1 = ((ind_In1S1[0]-ind_In1S1[c1])/Point());
   
   double a2 = ((ind_In2S1[0]-ind_In2S1[c1])/Point());
   
   for(int i=0; i<=1000; i++){
   
    if(ind_In3S1[0]>0){if (ind_In3S1[i]<0){c2=i; break;}}
    
    if(ind_In3S1[0]<0){if (ind_In3S1[i]>0){c2=i; break;}}
   
   }      

   double a3 = ind_In3S1[0]-ind_In3S1[c2];
   
   for(int i=0; i<=1000; i++){
   
    if(ind_In4S1[0]>0){if (ind_In4S1[i]<0){c3=i; break;}}
    
    if(ind_In4S1[0]<0){if (ind_In4S1[i]>0){c3=i; break;}}
   
   }       
   
   double a4 = ind_In4S1[0]-ind_In4S1[c3];

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("a4 = ", a4);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);

  }

Log-Daten:

Beispiel für den Abstand 3

a1 – Differenz des Punktes des Währungspaares des MA 1-Indikators bei Kerze 0 und der Kerze, die den letzten Schnittpunkt der Indikatoren MA1 und MA 100 aufwies. Sie kann sowohl positive als auch negative Werte annehmen.

a2 – Differenz der Währungspaarpunkte des MA 100-Indikators bei Kerze 0 und der Kerze, die den letzten Schnittpunkt der Indikatoren MA1 und MA 100 aufwies. Sie kann sowohl positive als auch negative Werte annehmen.

a3 – Differenz der Werte des MACD-Indikators bei Kerze 0 und der Kerze, die den letzten Schnittpunkt mit dem Wert 0 aufwies. Sie kann sowohl positive als auch negative Werte annehmen.

a4 – Differenz der Werte des CCI-Indikators bei Kerze 0 und der Kerze, die den letzten Schnittpunkt mit dem Wert 0 aufwies. Sie kann sowohl positive als auch negative Werte annehmen.

Die Suche nach dem Schnittwert wird zunächst in einer Schleife durchgeführt.


Beispiele für die Verwendung der Akkumulation zur Übergabe an ein Perzeptron:

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    Candles= 10;

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {
   double sum1 = 0;
   double sum2 = 0;
   double sum3 = 0;

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;

   for(int i=0; i<=Candles; i++)
     {

      sum1+=ind_In1S1[i]-ind_In2S1[i];

     }

   double a1 = sum1;

   for(int i=0; i<=Candles; i++)
     {

      sum2+=ind_In3S1[i];

     }

   double a2 = sum2;

   for(int i=0; i<=Candles; i++)
     {

      sum3+=ind_In4S1[i];

     }

   double a3 = sum3;

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3);

  }

Log-Daten:

Akkumulationsbeispiel 1

a1 – Akkumulation der Differenz zwischen den Indikatoren MA1 und MA 100 für die Anzahl der Kerzen des Parameters Candles. Sie kann sowohl positive als auch negative Werte annehmen.

a2 – Akkumulation des MACD-Indikators für die Anzahl der Kerzen des Parameters Candles. Sie kann sowohl positive als auch negative Werte annehmen.

a3 – Akkumulation des CCI-Indikators für die Anzahl der Kerzen des Parameters Candles. Sie kann sowohl positive als auch negative Werte annehmen.

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    Candles= 10;

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {
   double sum1 = 0;
   double sum2 = 0;
   double sum3 = 0;

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;

   for(int i=0; i<=1000; i++)
     {

      if(ind_In1S1[0]>ind_In2S1[0])
        {
         if(ind_In1S1[i]<ind_In2S1[i])
           {
            break;
           };
         sum1+=(ind_In1S1[i]-ind_In2S1[i]);
        }

      if(ind_In1S1[0]<ind_In2S1[0])
        {
         if(ind_In1S1[i]>ind_In2S1[i])
           {
            break;
           };
         sum1+=(ind_In1S1[i]-ind_In2S1[i]);
        }

     }

   double a1 = sum1;

   for(int i=0; i<=1000; i++)
     {

      if(ind_In3S1[0]>0)
        {
         if(ind_In3S1[i]<0)
           {
            break;
           };
         sum2+=ind_In3S1[i];
        }

      if(ind_In3S1[0]<0)
        {
         if(ind_In3S1[i]>0)
           {
            break;
           };
         sum2+=ind_In3S1[i];
        }

     }

   double a2 = sum2;

   for(int i=0; i<=1000; i++)
     {

      if(ind_In4S1[0]>0)
        {
         if(ind_In4S1[i]<0)
           {
            break;
           };
         sum3+=ind_In4S1[i];
        }

      if(ind_In4S1[0]<0)
        {
         if(ind_In4S1[i]>0)
           {
            break;
           };
         sum3+=ind_In4S1[i];
        }

     }

   double a3 = sum3;

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3);

  }

Log-Daten:

Akkumulationsbeispiel 2

a1 – Akkumulation der Differenz zwischen den Indikatoren MA1 und MA 100 ab dem letzten Schnittpunkt. Sie kann sowohl positive als auch negative Werte annehmen.

a2 – Akkumulation des MACD-Indikators ab dem Punkt des letzten Schnittpunkts mit dem Wert 0. Sie kann sowohl positive als auch negative Werte annehmen.

a3 – Akkumulation des CCI-Indikators ab dem Punkt des letzten Schnittpunkts mit dem Wert 0. Sie kann sowohl positive als auch negative Werte annehmen.


Beispiele für die Verwendung von Neigungswinkeln von Indikatoren:

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    Candles= 10;

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;
input int    x4 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;
   double w4 = x4 - 10.0;

   double a1 = (((ind_In1S1[0]-ind_In1S1[Candles])/Point())/Candles);

   double a2 = (((ind_In2S1[0]-ind_In2S1[Candles])/Point())/Candles);

   double a3 = ((ind_In3S1[0]-ind_In3S1[Candles])/Candles);

   double a4 = ((ind_In4S1[0]-ind_In4S1[Candles])/Candles);

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("a4 = ", a4);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);

  }

Log-Daten:

Beispiel für Winkel 1

a1 – Neigungswinkel des MA1-Indikators für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

a2 – Neigungswinkel des MA100-Indikators für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

a3 – Neigungswinkel des MACD-Indikators für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

a4 – Neigungswinkel des CCI-Indikators für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;
input int    x4 = 1;

int handle_In1S1;
int handle_In2S1;
int handle_In3S1;
int handle_In4S1;

double ind_In1S1[];
double ind_In2S1[];
double ind_In3S1[];
double ind_In4S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In3S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In4S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In3S1,true);
   if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In4S1,true);
   if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {

   int c1=0;
   int c2=0;
   int c3=0;

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;
   double w4 = x4 - 10.0;

   for(int i=0; i<=1000; i++)
     {

      if(ind_In1S1[0]>ind_In2S1[0])
        {
         if(ind_In1S1[i]<ind_In2S1[i])
           {
            c1=i;
            break;
           }
        }

      if(ind_In1S1[0]<ind_In2S1[0])
        {
         if(ind_In1S1[i]>ind_In2S1[i])
           {
            c1=i;
            break;
           }
        }

     }

   double a1 = (((ind_In1S1[0]-ind_In1S1[c1])/Point())/c1);

   double a2 = (((ind_In2S1[0]-ind_In2S1[c1])/Point())/c1);

   for(int i=0; i<=1000; i++)
     {

      if(ind_In3S1[0]>0)
        {
         if(ind_In3S1[i]<0)
           {
            c2=i;
            break;
           }
        }

      if(ind_In3S1[0]<0)
        {
         if(ind_In3S1[i]>0)
           {
            c2=i;
            break;
           }
        }

     }

   double a3 = ((ind_In3S1[0]-ind_In3S1[c2])/c2);

   for(int i=0; i<=1000; i++)
     {

      if(ind_In4S1[0]>0)
        {
         if(ind_In4S1[i]<0)
           {
            c3=i;
            break;
           }
        }

      if(ind_In4S1[0]<0)
        {
         if(ind_In4S1[i]>0)
           {
            c3=i;
            break;
           }
        }

     }

   double a4 = ((ind_In4S1[0]-ind_In4S1[c3])/c3);

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("a4 = ", a4);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);

  }

Log-Daten:

Beispiel für Winkel 2

a1 – Neigungswinkel des MA1-Indikators ab dem letzten Schnittpunkt der Indikatoren MA1 und MA100. Er kann sowohl positive als auch negative Werte annehmen.

a2 – Neigungswinkel des MA100-Indikators ab dem letzten Schnittpunkt der Indikatoren MA1 und MA100. Er kann sowohl positive als auch negative Werte annehmen.

a3 – Neigungswinkel des MACD-Indikators ab dem Punkt des letzten Schnittpunktes des Wertes 0 durch den Indikator. Er kann sowohl positive als auch negative Werte annehmen.

a4 – Neigungswinkel des CCI-Indikators ab dem Punkt des letzten Schnittpunkts des Wertes 0 mit dem Indikator. Er kann sowohl positive als auch negative Werte annehmen.


Beispiel für die Verwendung kombinierter Werte zur Übergabe an das Perzeptron:

#property copyright   "2023, Roman Poshtar"
#property link        "https://www.mql5.com/ru/users/romanuch"
#property strict
#property version   "1.0"

input int    Candles= 10;

input int    x1 = 1;
input int    x2 = 1;
input int    x3 = 1;
input int    x4 = 1;
input int    x5 = 1;
input int    x6 = 1;
input int    x7 = 1;

int handle_In1S1;
int handle_In2S1;

double ind_In1S1[];
double ind_In2S1[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {

   handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In1S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_In2S1==INVALID_HANDLE)
     {
      return(INIT_FAILED);
     }
//---

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In1S1,true);
   if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1))
     {
      return;
     }
//---

//--- get data from the three buffers of the i-Regr indicator
   ArraySetAsSeries(ind_In2S1,true);
   if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1))
     {
      return;
     }
//---

   perceptron1();

  }

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {

   int c1=0;
   double sum1 = 0;
   double sum2 = 0;

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;
   double w4 = x4 - 10.0;
   double w5 = x5 - 10.0;
   double w6 = x6 - 10.0;
   double w7 = x7 - 10.0;

   double a1 = ((ind_In1S1[0]-ind_In2S1[0])/Point());

   for(int i=0; i<=Candles; i++)
     {

      sum1+=ind_In1S1[i]-ind_In2S1[i];

     }

   double a2 = sum1;

   for(int i=0; i<=1000; i++)
     {

      if(ind_In1S1[0]>ind_In2S1[0])
        {
         if(ind_In1S1[i]<ind_In2S1[i])
           {
            break;
           };
         sum2+=(ind_In1S1[i]-ind_In2S1[i]);
        }

      if(ind_In1S1[0]<ind_In2S1[0])
        {
         if(ind_In1S1[i]>ind_In2S1[i])
           {
            break;
           };
         sum2+=(ind_In1S1[i]-ind_In2S1[i]);
        }

     }

   double a3 = sum2;

   double a4 = (((ind_In1S1[0]-ind_In1S1[Candles])/Point())/Candles);

   double a5 = (((ind_In2S1[0]-ind_In2S1[Candles])/Point())/Candles);

   for(int i=0; i<=1000; i++)
     {

      if(ind_In1S1[0]>ind_In2S1[0])
        {
         if(ind_In1S1[i]<ind_In2S1[i])
           {
            c1=i;
            break;
           }
        }

      if(ind_In1S1[0]<ind_In2S1[0])
        {
         if(ind_In1S1[i]>ind_In2S1[i])
           {
            c1=i;
            break;
           }
        }

     }

   double a6 = (((ind_In1S1[0]-ind_In1S1[c1])/Point())/c1);

   double a7 = (((ind_In2S1[0]-ind_In2S1[c1])/Point())/c1);

   Print("a1 = ", a1);
   Print("a2 = ", a2);
   Print("a3 = ", a3);
   Print("a4 = ", a4);
   Print("a5 = ", a5);
   Print("a6 = ", a6);
   Print("a7 = ", a7);
   Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4 + w5 * a5 + w6 * a6 + w7 * a7));
   Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4 + w5 * a5 + w6 * a6 + w7 * a7);

  }

Protokolldaten:

Kombinierte Übergabe Beispiel 1

a1 – Abstand zwischen MA1 und MA100 auf der aktuellen Kerze. Er kann sowohl positive als auch negative Werte annehmen.

a2 – Akkumulation zwischen den Indikatoren MA1 und MA100 für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

a3 – Akkumulation zwischen den Indikatoren MA1 und MA100 ab dem Punkt des letzten Schnittpunkts der Indikatoren. Er kann sowohl positive als auch negative Werte annehmen.

a4 – Neigungswinkel des MA1-Indikators für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

a5 – Neigungswinkel des MA100-Indikators für die Anzahl der Kerzen des Parameters Candles. Er kann sowohl positive als auch negative Werte annehmen.

a6 – Neigungswinkel des MA1-Indikators ab dem letzten Schnittpunkt der Indikatoren. Er kann sowohl positive als auch negative Werte annehmen.

a7 – Neigungswinkel des MA100-Indikators ab dem letzten Schnittpunkt der Indikatoren. Er kann sowohl positive als auch negative Werte annehmen.


Expert Advisors

 Hier werden wir zwei EAs entwickeln. Als Beispiel werden wir die Werte der Abstände zwischen den Indikatoren verwenden. Die erste wird für die Optimierung und Auswahl der Parameter eingesetzt. Der zweite ist für den Handel mit den Ergebnissen des ersten gedacht. Ich habe diesen Ansatz bereits in meinen früheren Artikeln berücksichtigt. Diese Methode hilft, alle verfügbaren Optimierungsergebnisse zu sortieren und für den Handel zu nutzen. Zum Beispiel haben wir bei der Optimierung 50 gute Ergebnisse erzielt. Wie Sie sich vielleicht vorstellen können, ist die Installation eines EA auf 50 Charts nicht sehr praktisch. Daher werden wir alle Ergebnisse gleichzeitig mit Hilfe des zweiten EA verwenden.

Mehr über die Methode erfahren Sie in meinem Artikel „Experimente mit neuronalen Netzen (Teil 3)“: Praktische Anwendung

Ich werde im Folgenden den Hauptcode des ersten EA zur Optimierung bereitstellen und beschreiben, was wir dem Perzeptron übergeben haben:

Der Hauptcode für die Eröffnung von Positionen.

      //SELL++++++++++++++++++++++++++++++++++++++++++++++++
      if((perceptron1()<-Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (SpreadS1<=MaxSpread))
        {
         OpenSell(symbolS1.Name(), LotsXSell, TP, SL, EAComment);
        }

      //BUY++++++++++++++++++++++++++++++++++++++++++++++++
      if((perceptron1()>Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (SpreadS1<=MaxSpread))
        {
         OpenBuy(symbolS1.Name(), LotsXBuy, TP, SL, EAComment);
        }

Perceptron-Code.  

  1. a1 ist der Abstand zwischen dem MA1-Indikator auf der aktuellen Kerze und der Kerze vom Parameter Candles.  
  2. a2 ist der Abstand zwischen dem MA100-Indikator auf der aktuellen Kerze und der Kerze vom Parameter Candles.  
  3. a3 ist der Abstand zwischen dem CCI-Indikator der aktuellen Kerze und der Kerze vom Parameter Candles.  
  4. a4 ist der Abstand zwischen dem StdDev-Indikator der aktuellen Kerze und der Kerze vom Parameter Candles. 

Der Parameter Candles war in diesem Fall nicht optimiert und hatte einen Wert von 8.

//+------------------------------------------------------------------+
//|  The PERCEPRRON - a perceiving and recognizing function          |
//+------------------------------------------------------------------+
double perceptron1()
  {

   double w1 = x1 - 10.0;
   double w2 = x2 - 10.0;
   double w3 = x3 - 10.0;
   double w4 = x4 - 10.0;

   double a1 = ((ind_In1S1[0]-ind_In1S1[Candles])/PointS1);

   double a2 = ((ind_In2S1[0]-ind_In2S1[Candles])/PointS1);

   double a3 = (ind_In3S1[0]-ind_In3S1[Candles]);

   double a4 = (ind_In4S1[0]-ind_In4S1[Candles]);

   return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }


Ich werde hier alle Parameter für die Optimierung und Prüfung angeben, um sie im Text nicht weiter zu wiederholen:

Die Optimierungseinstellungen sind in der folgenden Abbildung dargestellt:

Optimierungseinstellungen

Die Ergebnisse der Optimierung sind in den folgenden Screenshots dargestellt:

Optimierungsergebnis 1


Optimierungsergebnis 2

Nachdem die Optimierung abgeschlossen ist, erstellen wir eine Datei im CSV-Format für Excel. Ich möchte Sie daran erinnern, dass wir die ersten 50 besten Ergebnisse nehmen. Wir fügen die resultierende Datei zum Testen in den Code des zweiten EA ein. Im Code sieht es dann wie folgt aus.

string EURUSD[][8]=
  {
   {"Profit","Trades","x1","x2","x3","x4","Param"},
   {"266.45","239","2","1","9","8","5000"},
   {"266.45","239","2","1","9","13","5000"},
   {"266.45","239","2","1","9","11","5000"},
   {"266.45","239","2","1","9","10","5000"},
   {"266.45","239","2","1","9","8","5000"},
   {"266.45","239","2","1","9","12","5000"},
   {"266.45","239","2","1","9","20","5000"},
   {"266.45","239","2","1","9","14","5000"},
   {"266.45","239","2","1","9","2","5000"},
   {"266.45","239","2","1","9","3","5000"},
   {"259.69","239","0","0","12","17","5500"},
   {"259.69","239","0","0","12","8","5500"},
   {"259.69","239","0","0","12","1","5500"},
   {"259.69","239","0","0","12","9","5500"},
   {"259.69","239","0","0","12","16","5500"},
   {"259.69","239","0","0","12","18","5500"},
   {"259.69","239","0","0","12","11","5500"},
   {"259.69","239","0","0","12","7","5500"},
   {"259.69","239","0","0","12","15","5500"},
   {"259.69","239","0","0","12","8","5500"},
   {"259.69","239","0","0","12","9","5500"},
   {"259.69","239","0","0","12","17","5500"},
   {"259.69","239","0","0","12","6","5500"},
   {"259.69","239","0","0","12","15","5500"},
   {"259.69","239","0","0","12","4","5500"},
   {"259.69","239","0","0","12","7","5500"},
   {"259.69","239","0","0","12","11","5500"},
   {"259.69","239","0","0","12","14","5500"},
   {"259.69","239","0","0","12","1","5500"},
   {"259.69","239","0","0","12","5","5500"},
   {"259.69","239","0","0","12","3","5500"},
   {"259.69","239","0","0","12","0","5500"},
   {"259.69","239","0","0","12","12","5500"},
   {"259.69","239","0","0","12","16","5500"},
   {"259.69","239","0","0","12","8","5500"},
   {"259.69","239","0","0","12","10","5500"},
   {"259.69","239","0","0","12","16","5500"},
   {"259.69","239","0","0","12","18","5500"},
   {"259.69","239","0","0","12","13","5500"},
   {"259.69","239","0","0","12","9","5500"},
   {"259.69","239","0","0","12","12","5500"},
   {"259.69","239","0","0","12","11","5500"},
   {"259.69","239","0","0","12","7","5500"},
   {"259.69","239","0","0","12","15","5500"},
   {"259.69","239","0","0","12","14","5500"},
   {"259.69","239","0","0","12","3","5500"},
   {"259.69","239","0","0","12","19","5500"},
   {"259.69","239","0","0","12","0","5500"},
   {"259.69","239","0","0","12","17","5500"},
   {"259.69","239","0","0","12","2","5500"}
  };

Ich werde auch den Code für den zweiten Handels-EA zur Verfügung stellen. Wie Sie sehen, gehen wir in der Schleife alle Werte durch, die wir während der Optimierung erhalten haben, und vergleichen sie mit den aktuellen Ergebnissen der Perceptron-Ausführung. Wenn die Werte übereinstimmen, wird eine entsprechende Kauf- oder Verkaufsposition eröffnet. Die Begrenzung der Anzahl der gleichzeitig geöffneten Positionen wird durch den Parameter MaxSeries und die Funktion CalculateSeries gesteuert, die die Positionen anhand von Kommentaren berechnet.

      for(int i=1; i<=(ArraySize(EURUSD)/8)-1; i++)
        {

         comm=(EURUSD[i][0]+EURUSD[i][1]);

         x1=(int)StringToInteger(EURUSD[i][2]);
         x2=(int)StringToInteger(EURUSD[i][3]);
         x3=(int)StringToInteger(EURUSD[i][4]);
         x4=(int)StringToInteger(EURUSD[i][5]);

         Param=(int)StringToInteger(EURUSD[i][6]);

         //SELL++++++++++++++++++++++++++++++++++++++++++++++++
         if((NewOpen==true) && (CalculateSeries(Magic)<MaxSeries) && (perceptron1()<-Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment+" En_"+comm)==0) && (SpreadS1<=MaxSpread))
           {
            OpenSell(symbolS1.Name(), LotsXSell, TP, SL, EAComment+" En_"+comm);
           }

         //BUY++++++++++++++++++++++++++++++++++++++++++++++++
         if((NewOpen==true) && (CalculateSeries(Magic)<MaxSeries) && (perceptron1()>Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment+" En_"+comm)==0) && (SpreadS1<=MaxSpread))
           {
            OpenBuy(symbolS1.Name(), LotsXBuy, TP, SL, EAComment+" En_"+comm);
           }

        }
//+------------------------------------------------------------------+
//| Calculate Positions                                              |
//+------------------------------------------------------------------+
int CalculateSeries(ulong mag)
  {
   int total=0;
   string com="";

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      if(position.SelectByIndex(i))
        {
         if(position.Magic()==mag)
           {
            if(com!=position.Comment())
              {
               com=position.Comment();
               total++;
              }
           }
        }
     }
//---
   return(total);
  }

Ergebnis des Backtests:

Ergebnis des Backtests

Ergebnis des Vorwärtstests:

Ergebnis des Vorwärtstests


Vorwärtstests des Testergebnisses 2


Schlussfolgerung

Liste der Dateien im Anhang:

  1. Distance 1, Distance 2, Distance 3 – EAs mit Beispielen für die Übergabe der Abstände an das Perzeptron;
  2. Accumulation 1, Akkumulation 2 – EAs mit Beispielen für die Übergabe der Akkumulation an das Perceptron;
  3. Angle 1, Angle 2 – EAs mit Beispielen für die Übergabe von Indikatorneigungswinkeln an das Perzeptron;
  4. Combo 1 – EA mit einem Beispiel für die Übergabe kombinierter Indikatordaten an das Perzeptron;
  5. Perceptron – opt – Optimierung EA;
  6. Perceptron – trade – EA für den Handel mit optimierten Parametern.

 Wie aus den Ergebnissen des Vorwärtstests ersichtlich ist, funktioniert unser Ansatz zur Übermittlung von Indikatoren gut. In den ersten sechs Monaten schiebt der EA die Bilanz recht zuversichtlich nach oben. Oben habe ich alle möglichen Beispiele für Überholindikatoren angeführt. Vielleicht sind Sie daran interessiert, sie zu testen. Dieses Mal wurde viel Arbeit geleistet, aber es gibt immer etwas, das man anstreben kann.

Wenn Sie Fragen haben, können Sie mich gerne über das Forum oder per privater Nachricht kontaktieren. Ich werde Ihnen immer gerne helfen.