English Русский 中文 Español 日本語 Português
preview
Experimente mit neuronalen Netzen (Teil 7): Übergabe von Indikatoren

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

MetaTrader 5Handelssysteme | 12 März 2024, 16:34
322 0
Roman Poshtar
Roman Poshtar

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:

  • Übergabe der Abstände zur aktuellen Nullkerze. MA 1 Indikator im Verhältnis zum MA 100. MACD-Indikator im Verhältnis zu seinen aktuellen und Nullwerten. Der CCI-Indikator im Verhältnis zu seinem aktuellen Wert und seinem Nullwert.
#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.

  • Übergene Abstände N-Kerzen zurück. MA 1 Indikator. MA 100 Indikator. MACD-Indikator. Der Indikator CCI:
#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.

  • Übergeben der Abstände des Schnittpunkts der Indikatoren MA1 und MA 100 relativ zu ihrem Nullwert in der Vergangenheit. Der MACD-Indikator relativ zu seinem Nullwert in der Vergangenheit. Der CCI-Indikator relativ zu seinem Nullwert in der Vergangenheit.
#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:

  • Übergeben der Akkumulation für N Indikatorkerzen.
#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.

  • Durchlaufende Akkumulation ab dem Nullpunkt des Indikators in der Vergangenheit oder dem letzten Schnittpunkt von Indikatoren in der Vergangenheit.
#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:

  • Neigungswinkel für N-Indikatorenkerzen.
#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.

  • Der Neigungswinkel vom Nullpunkt des Indikators in der Vergangenheit oder dem letzten Schnittpunkt von Indikatoren in der Vergangenheit.
#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:

  • Kombinierte Übergabe der Werte der Indikatoren MA1 und MA100.
#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:

  • Devisenmarkt;
  • EURUSD;
  • Zeitrahmen: H1;
  • Indikatoren: MA 1 SMA CLOSE, MA 200 SMA CLOSE, CCI 42, StdDev 60.
  • Stop Loss und Take Profit, 400 und 830;
  • Optimierungs- und Testmodus „1 Minute OHLC“ und „Maximum Profit“. Unser EA arbeitet zunächst mit M1-Eröffnungskursen. Hier werden wir den Modus „Maximaler Gewinn“ als Experiment verwenden;
  • Optimierungsbereich 1 Jahr. Vom 2021.10.10 bis 2022.10.10. 1 Jahr ist keine Art von Kriterium. Sie können es mehr oder weniger auf eigene Faust versuchen;
  • Der Zeitraum für die Vorwärtsprüfung beträgt 1 Jahr. Von 2022.10.10 bis 2023.10.10;
  • Bei der Vorwärtsprüfung wurden die ersten 50 besten Optimierungsergebnisse gleichzeitig verwendet;
  • Ersteinlage 10000;
  • Hebel 1:500.

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.

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

Beigefügte Dateien |
EA.zip (23.32 KB)
Entwicklung eines Replay System (Teil 28): Expert Advisor Projekt — Die Klasse C_Mouse (II) Entwicklung eines Replay System (Teil 28): Expert Advisor Projekt — Die Klasse C_Mouse (II)
Als man begann, die ersten rechenfähigen Systeme zu entwickeln, war für alles die Mitwirkung von Ingenieuren erforderlich, die das Projekt sehr gut kennen mussten. Wir sprechen von den Anfängen der Computertechnologie, einer Zeit, in der es noch nicht einmal Terminals zum Programmieren gab. Im Laufe der Entwicklung, als immer mehr Menschen daran interessiert waren, etwas zu erschaffen, entstanden neue Ideen und Wege der Programmierung, die das frühere Wechseln der Steckverbindungen ersetzten. Zu diesem Zeitpunkt erschienen die ersten Terminals.
Entwicklung eines Replay System (Teil 27): Expert Advisor Projekt — Die Klasse C_Mouse (II) Entwicklung eines Replay System (Teil 27): Expert Advisor Projekt — Die Klasse C_Mouse (II)
In diesem Artikel werden wir die Klasse C_Mouse implementieren. Es bietet die Möglichkeit, auf höchstem Niveau zu programmieren. Wenn man über High-Level- oder Low-Level-Programmiersprachen spricht, geht es jedoch nicht darum, obszöne Wörter oder Jargon in den Code aufzunehmen. Es ist genau andersherum. Wenn wir von High-Level- oder Low-Level-Programmierung sprechen, meinen wir, wie leicht oder schwer der Code für andere Programmierer zu verstehen ist.
Erstellen von Multi-Symbol- und Multi-Perioden-Indikatoren Erstellen von Multi-Symbol- und Multi-Perioden-Indikatoren
In diesem Artikel werden wir uns mit den Grundsätzen der Erstellung von Multi-Symbol- und Multi-Perioden-Indikatoren befassen. Wir werden auch sehen, wie man auf die Daten solcher Indikatoren von Expert Advisors und anderen Indikatoren zugreifen kann. Wir werden die Hauptmerkmale der Verwendung von Multi-Indikatoren in Expert Advisors und Indikatoren besprechen und sehen, wie man sie durch nutzerdefinierte Indikatorpuffer darstellen kann.
Von der Saisonalität des Devisenmarktes profitieren Von der Saisonalität des Devisenmarktes profitieren
Wir sind alle mit dem Konzept der Saisonalität vertraut, z. B. sind wir alle an steigende Preise für frisches Gemüse im Winter oder an steigende Kraftstoffpreise bei strengem Frost gewöhnt, aber nur wenige Menschen wissen, dass es auf dem Devisenmarkt ähnliche Muster gibt.