English 日本語
preview
Wie man ein volumenbasiertes Handelssystem aufbaut und optimiert (Chaikin Money Flow - CMF)

Wie man ein volumenbasiertes Handelssystem aufbaut und optimiert (Chaikin Money Flow - CMF)

MetaTrader 5Handel | 23 April 2025, 11:45
29 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Einführung

Willkommen zu einem neuen Artikel, in dem wir neue Indikatoren im Hinblick auf ihre Erstellung, den Aufbau von Handelssystemen auf der Grundlage ihres Konzepts und die Optimierung dieser Systeme untersuchen, um bessere Erkenntnisse und Ergebnisse in Bezug auf Gewinne und Risiken zu erhalten. In diesem Artikel stellen wir einen neuen volumenbasierten technischen Indikator vor, den Indikator Chaikin Money Flow (CMF).

Es ist besser, hier etwas Wichtiges zu erwähnen. Das Hauptziel dieser Art von Artikel ist es, neue technische Werkzeuge zu teilen, die allein oder in Verbindung mit anderen Werkzeugen auf der Grundlage der Art dieser Werkzeuge zusätzlich zum Testen verwendet werden können, sie zu optimieren, um bessere Ergebnisse zu erhalten, um zu sehen, ob diese Werkzeuge nützlich sein können oder nicht.

Wir werden diesen neuen Indikator (CMF) entsprechend den unten aufgeführten Themen erstellen:

  1. Chaikin Money Flow: Verstehen Sie die Grundkenntnisse dieses technischen Instruments, indem beschrieben wird, wie er berechnet und verwendet werden kann.
  2. Nutzerdefinierter Chaikin Money Flow Indikator: Lernen Sie, wie Sie unseren nutzerdefinierten Indikator durch Modifikation oder Anwendung unserer Voreinstellungen kodieren können.
  3. Strategien mit dem Chaikin Money Flow: Wir werfen einen Blick auf einige einfache Handelsstrategien, die Teil unseres Handelssystems sind.
  4. Handelssystem mit dem Chaikin Money Flow: Erstellen, testen und optimieren dieses einfachen Handelssystems.
  5. Schlussfolgerung

Haftungsausschluss: Alle Informationen werden in der vorliegenden Form nur zu Informationszwecken bereitgestellt und sind nicht für Handelszwecke oder als Ratschläge gedacht. Die Informationen garantieren keinen Erfolg. Wenn Sie sich dafür entscheiden, diese Materialien auf einem Ihrer Handelskonten zu verwenden, tun Sie dies auf eigenes Risiko und Sie sind allein verantwortlich.



Chaikin Money Flow

Der Chaikin Money Flow (CMF) ist ein technischer Indikator, der auf dem Volumen unter Berücksichtigung der Kursentwicklung basiert. Es kann allein oder in Verbindung mit anderen Tools verwendet werden, um bessere Einblicke zu erhalten, wie wir noch sehen werden. Der CMF ist ein von Marc Chaikin entwickelter Indikator zur Überwachung der Akkumulation und Verteilung eines Instruments über einen bestimmten Zeitraum. Der Grundgedanke hinter dem CMF ist, dass es zu einer Akkumulation kommt, wenn sich der Schlusskurs dem Höchststand nähert. Nähert sich der Schlusskurs hingegen dem Tiefstand, ist dies ein Zeichen für eine Verteilung. Ein positives Ergebnis des Chaikin Money Flow liegt dann vor, wenn der Kurs bei steigendem Volumen durchgängig über dem Mittelpunkt des Balkens schließt. Ein negatives Ergebnis des Chaikin Money Flow liegt vor, wenn die Kursbewegung bei steigendem Volumen durchgehend unter dem Mittelpunkt des Balkens schließt.

Im Folgenden werden die Schritte zur Berechnung des CMF-Indikators beschrieben:

  • Berechnung des Money Flow Multiplier
Money Flow Multiplier = [(Schluss - Tief) - (Hoch - Schluss)] / (Hoch - Tief)
  • Berechnung des Money Flow Volume

Money Flow Volume = Money Flow Multiplier * Volumen der Periode

  • Berechnung des CMF

n-periodischer CMF = n-periodische Summe des Monet Flow Volume / n-periodische Summe des Volumens

Nach der Berechnung des Indikators wird er einen Bereich zwischen +1 und -1 anzeigen, der der folgenden Abbildung entspricht:

cmfInd

Da es sich bei dem Indikator um eine Linie handelt, die um den Nullpunkt oszilliert, können Veränderungen des CMF und des Kauf- oder Verkaufsmomentums an einem Über- oder Unterschreiten des Nullpunkts erkannt werden. Positive Werte über Null deuten auf eine Kaufkraft hin; andererseits sinkt der Indikator unter Null, wenn die Verkaufskraft die Kontrolle zu übernehmen beginnt. Wenn der CMF um die Nulllinie oszilliert, kann dies auf eine relativ gleiche Kauf- und Verkaufskraft oder einen fehlenden klaren Trend hinweisen. Der CMF wird als Instrument zur Erkennung und Bewertung von Trends in dem gehandelten Instrument verwendet.

Im nächsten Abschnitt können wir unseren Indikator nach Belieben anpassen, z. B. als Histogramm anstelle einer Linie zeichnen oder was auch immer wir für einen besseren Handel halten. Genau darum geht es, wenn wir einen Indikator durch Schreiben oder Bearbeiten seines Codes an unsere Vorlieben anpassen.


Nutzerdefinierter Chaikin Money Flow Indikator

In diesem Abschnitt zeigen wir Ihnen, wie Sie Schritt für Schritt einen nutzerdefinierten CMF-Indikator programmieren, den wir später in unserem einfachen Handelssystem verwenden können. Wie wir sehen werden, wird unsere Anpassung einfach sein, da das Hauptziel darin besteht, dem Leser die Augen für neue Einsichten und Ideen über den Indikator und Strategien zu öffnen, die in Abhängigkeit von diesem Volumenindikator verwendet werden können.

Nachfolgend sind die Schritte aufgeführt, die wir zur Programmierung dieses nutzerdefinierten Indikators durchführen werden:

Angabe zusätzlicher Parameter neben #property, um die folgenden Werte für Verhalten und Aussehen des Indikators zu identifizieren.

  • Die Beschreibung des Indikators durch Verwendung der Beschreibungskonstante und die Angabe des „Chaikin Money Flow“.
#property description "Chaikin Money Flow"
  • Platzierung des Indikators im separaten Fenster im Chart durch Verwendung der Konstante (indicator_separate_window).
#property indicator_separate_window
  • Anzahl der Puffer für die Berechnung der Indikatoren mit Hilfe der Konstante (indicator_buffers), wir setzen sie auf 4.
#property indicator_buffers 4
  • Anzahl der grafischen Reihen im Indikator durch Verwendung der Konstante (indicator_plots), wir setzen sie auf 1.
#property indicator_plots   1
  • Linienstärke in grafischen Reihen durch Verwendung der Konstante (indicator_width1), wobei 1 die Anzahl der grafischen Reihen ist, wir setzen sie auf 3.
#property indicator_width1  3
  • Horizontale Stufen von 1, 2 und 3 im separaten Indikatorfenster durch Verwendung der Konstanten (indicator_level1), (indicator_level2 ) und (indicator_level3) für die Stufen (0), (0,20) und (-0,20)
#property indicator_level1  0
#property indicator_level2  0.20
#property indicator_level3  -0.20
  • Der Stil der horizontalen Ebenen des Indikators mit Hilfe von (indicator_levelstyle), hier auf STYLE_DOT gesetzt.
#property indicator_levelstyle STYLE_DOT
  • Die Dicke der horizontalen Ebenen des Indikators mit Hilfe von (indicator_levelwidth), hier auf 0 gesetzt.
#property indicator_levelwidth 0
  • Die Farbe der horizontalen Ebenen des Indikators unter Verwendung von (indicator_levelcolor), gesetzt auf clrBlack.
#property indicator_levelcolor clrBlack
  • Die Art der grafischen Darstellung durch Verwendung von (indicator_type1), gesetzt auf DRAW_HISTOGRAM.
#property indicator_type1   DRAW_HISTOGRAM
  • Die Farbe für die Anzeige der Zeile N mit (indicator_color1)m, hier verwenden wir clrBlue.
#property indicator_color1  clrBlue
  • Angabe von Eingaben zur Festlegung von Nutzerpräferenzen in Bezug auf Periodenlänge und Volumentypen, die bei der Berechnung des Indikators verwendet werden, durch Verwendung der Eingabefunktion.
input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type
  • Array von cmfBuffer deklarieren.
double                    cmfBuffer[];

In der Funktion OnInit() richten wir den Indikator ein.

Verknüpfung eines eindimensionalen dynamischen Arrays vom Typ double mit dem CMF-Indikatorpuffer mit Hilfe von (SetIndexBuffer) und den folgenden Parametern:

  • index: die Angabe des Pufferindexes, der 0 sein wird.
  • buffer[]: die Angabe des Arrays, das der cmfBuffer sein wird. 
  • data_type: die Angabe des im Indikator-Array gespeicherten Datentyps.
SetIndexBuffer(0,cmfBuffer,INDICATOR_DATA);

Setzen Sie den Wert der entsprechenden Eigenschaft des Indikators mit Hilfe der Funktion (IndicatorSetInteger), deren Parameter sind:

  • prop_id: um den Identifikator zu definieren, der (INDICATOR_DIGITS) sein wird.
  • prop_value: zur Festlegung des einzustellenden Dezimalwerts, der (5) sein wird.
IndicatorSetInteger(INDICATOR_DIGITS,5);

Legen Sie fest, wie die Zeichnung gezeichnet werden soll, indem Sie die Funktion (PlotIndexSetInteger) mit den folgenden Parametern verwenden:

  • plot_index: zur Angabe des Plot-Stil-Index, der (0) sein wird.
  • prop_id: Angabe des Eigenschaftsbezeichners, der (PLOT_DRAW_BEGIN) eine der Enumeration ENUM_PLOT_PROPERTY_INTEGER sein wird.
  • prop_value: Angabe des Wertes, der als Eigenschaft festgelegt werden soll und der (0) sein wird.
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,0);

Geben Sie den Namen und die Periodenlänge des Indikators mit Hilfe der Funktion (IndicatorSetString) mit den Parametern an:

  • prop_id: zur Angabe des Bezeichners, der einer aus der Enumeration ENUM_CUSTOMIND_PROPERTY_STRING sein kann, und Angabe (INDICATOR_SHORTNAME).
  • prop_value: zur Angabe des Textwerts des Indikators, der "Chaikin Money Flow("+string(periods)+")" lautet.
IndicatorSetString(INDICATOR_SHORTNAME,"Chaikin Money Flow("+string(periods)+")");

Die Funktion OnCalculate zur Berechnung der CMF-Werte.

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])

Prüfen Sie, ob Daten zur Berechnung der CMF-Werte vorhanden sind oder nicht, indem Sie die if-Funktion verwenden

   if(rates_total<periods)
      return(0);

Wenn ich Daten habe und zuvor berechnet CMpreviouslyor nicht zu starten Berechnung des aktuellen Wertes

   int initPos = prev_calculated -1;
   if(initPos<0) initPos = 0;

Berechnen Sie den CMF in folgenden Schritten

  • Wählen Sie den Datenträgertyp aus.
  • Schleife zur Berechnung des CMF-Wertes für jeden Balken.
  • Deklaration von sumAccDis, sumVol.
  • Schleife zur Berechnung der deklarierten Variablen (sumAccDis, sumVol) nach Deklaration und Definition der Variablen (thisTickVolume).
  • Ergebnis in den Puffer von cmfBuffer speichern.
  • Rückgabe der berechneten Werte.
   if(volumeTypeInp==VOLUME_TICK)
   {
      for(int pos = initPos;pos<=rates_total-periods;pos++)
      {
         double sumAccDis = 0;
         long sumVol = 0;
         
         for(int i = 0; i < periods && !IsStopped(); ++i)
         {
            long thisTickVolume = tick_volume[pos+i];
            sumVol += thisTickVolume;
            sumAccDis += AccDis(high[pos+i], low[pos+i], close[pos+i], thisTickVolume);
         }
         
         cmfBuffer[pos+periods-1] = sumAccDis/sumVol;
      }
   }
   else
   {
      for(int pos = initPos;pos<=rates_total-periods;pos++)
      {
         double sumAccDis = 0;
         long sumVol = 0;
         
         for(int i = 0; i < periods && !IsStopped(); ++i)
         {
            long thisTickVolume = volume[pos+i];
            sumVol += thisTickVolume;
            sumAccDis += AccDis(high[pos+i], low[pos+i], close[pos+i], thisTickVolume);
         }
         
         cmfBuffer[pos+periods-1] = sumAccDis/sumVol;
      }
   }
   
   return (rates_total-periods-10);

Deklaration der Funktion (AccDis), die im Code verwendet wurde, um 4 Variablen (Hoch, Tief, Schlusskurs und Volumen) zu haben, die uns helfen, den Geldflussmultiplikator und das Geldflussvolumen für den Balken zu berechnen, die zur Berechnung des CMF verwendet werden.

double AccDis(double high,double low,double close,long volume)
{
   double res=0;
   
   if(high!=low)
      res=(2*close-high-low)/(high-low)*volume;
   
   return(res);
}

Nun haben wir unseren Code zur Erstellung unseres nutzerdefinierten CMF-Indikators fertiggestellt. Den vollständigen Code in einem Block finden Sie unten:

#property description "Chaikin Money Flow"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   1
#property indicator_width1  3
#property indicator_level1  0
#property indicator_level2  0.20
#property indicator_level3  -0.20
#property indicator_levelstyle STYLE_DOT
#property indicator_levelwidth 0
#property indicator_levelcolor clrBlack
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrBlue
input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type
double                    cmfBuffer[];
void OnInit()
{
   SetIndexBuffer(0,cmfBuffer,INDICATOR_DATA);
   IndicatorSetInteger(INDICATOR_DIGITS,5);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,0);
   IndicatorSetString(INDICATOR_SHORTNAME,"Chaikin Money Flow("+string(periods)+")");
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   if(rates_total<periods)
      return(0);
   int initPos = prev_calculated -1;
   if(initPos<0) initPos = 0;
   if(volumeTypeInp==VOLUME_TICK)
   {
      for(int pos = initPos;pos<=rates_total-periods;pos++)
      {
         double sumAccDis = 0;
         long sumVol = 0;
         
         for(int i = 0; i < periods && !IsStopped(); ++i)
         {
            long thisTickVolume = tick_volume[pos+i];
            sumVol += thisTickVolume;
            sumAccDis += AccDis(high[pos+i], low[pos+i], close[pos+i], thisTickVolume);
         }
         cmfBuffer[pos+periods-1] = sumAccDis/sumVol;
      }
   }
   else
   {
      for(int pos = initPos;pos<=rates_total-periods;pos++)
      {
         double sumAccDis = 0;
         long sumVol = 0;
         
         for(int i = 0; i < periods && !IsStopped(); ++i)
         {
            long thisTickVolume = volume[pos+i];
            sumVol += thisTickVolume;
            sumAccDis += AccDis(high[pos+i], low[pos+i], close[pos+i], thisTickVolume);
         }
         
         cmfBuffer[pos+periods-1] = sumAccDis/sumVol;
      }
   }
   return (rates_total-periods-10);
}
double AccDis(double high,double low,double close,long volume)
{
   double res=0;
   
   if(high!=low)
      res=(2*close-high-low)/(high-low)*volume;
   
   return(res);
}

Sobald Sie diesen Code zusammengestellt und kompiliert haben, finden Sie die Datei in Ihrem Indikatorordner. Wenn Sie es zum Chart hinzufügen, sehen Sie es dort, wie in der folgenden Abbildung

CMFInd

Wie Sie sehen, sieht dieser Indikator genauso aus und funktioniert genauso wie der Indikator in unserem nutzerdefinierten Code. Sie können sie nach Ihren Bedürfnissen ändern, je nachdem, was Ihnen in Ihrem System hilft. Bis jetzt haben wir einen nutzerdefinierten CMF-Indikator, der in unserem Handelssystem verwendet werden kann, abhängig von unseren einfachen Strategien, über die wir im nächsten Abschnitt sprechen werden.


Strategien des Chaikin Money Flow

In diesem Abschnitt möchte ich Ihnen einige einfache Strategien vorstellen, die Sie mit dem CMF-Indikator anwenden können. Diese Strategien folgen verschiedenen Konzepten und Regeln, um unsere Tests in Bezug auf Leistung und Optimierung auf gute, methodische Weise durchzuführen. Diese Strategien sind vom Konzept her einfach, aber Sie können sie nach Ihren Vorlieben entwickeln, um sie zu testen und zu sehen, wie nützlich sie sein können.

Wir werden die folgenden drei einfachen Strategien anwenden:

  • Strategie des Kreuzens der Nulllinie des CMF
  • Strategie der überkauften und überverkauften Märkte des CMF
  • Strategie der Trendvalidierung durch den CMF

Strategie des Kreuzens der Nulllinie des CMF:

Diese Strategie ist ziemlich einfach. Er verwendet den Wert des CMF-Indikators, um zu bestimmen, wann er kaufen oder verkaufen soll. Wenn der vorherige CMF-Wert negativ und der aktuelle oder letzte Wert positiv ist, handelt es sich um ein Kaufsignal. Das Gegenteil ist der Fall, wenn der vorherige CMF-Wert positiv und der aktuelle oder letzte Wert negativ ist.

Einfach:

Vorheriger CMF < 0 und aktueller CMF > 0 --> Kaufen

Vorheriger CMF > 0 und aktueller CMF < 0 --> Verkaufen 

Die CMF-Strategie für überkaufte und überverkaufte Märkte:

Diese Strategie unterscheidet sich ein wenig von der letzten. Er prüft andere Werte, um zu sehen, ob er sich in einem überkauften oder überverkauften Bereich befindet. Diese Bereiche können sich von Zeit zu Zeit oder über verschiedene Instrumente hinweg ändern, und Sie können dies durch visuelle Inspektion der Indikatorbewegung feststellen, bevor Sie sich für sie entscheiden. Wenn der CMF-Wert unter oder gleich -0,20 ist, wird das Kaufsignal ausgelöst, und umgekehrt. Wenn der CMF-Wert über oder gleich 0,20 ist, wird das Verkaufssignal ausgelöst.

Einfach:

CMF <= -0,20 --> Kaufen

CMF >= 0,20 --> Verkaufen

Die CMF-Trendvalidierungsstrategie:

Diese Strategie hat auch einen anderen Ansatz, wenn es darum geht, ihre Signale zu erhalten, werden wir einen anderen Indikator, der den Trend oder zumindest die Bewegung der Preise bestätigen kann, ob nach oben oder unten mit dem Erhalten des Signals des Kreuzens der Nulllinie kombinieren. Wir werden die Verwendung des gleitenden Durchschnitts mit dem CMF-Indikator kombinieren. Wenn der vorherige Schlusskurs unter dem vorherigen Wert des gleitenden Durchschnitts liegt und gleichzeitig der aktuelle Briefkurs über dem gleitenden Durchschnitt liegt und der aktuelle CMF-Wert über Null liegt, wird ein Kaufsignal ausgelöst und umgekehrt. Wenn der vorherige Schlusskurs über dem vorherigen Wert des gleitenden Durchschnitts liegt und gleichzeitig der aktuelle Geldkurs unter dem gleitenden Durchschnitt liegt und der aktuelle CMF-Wert unter Null liegt, wird das Verkaufssignal ausgelöst.

Einfach:

prevClose < prevMA, ask > MA, und CMF > 0 --> Kaufen

prevClose > prevMA, bid < MA, und CMF < 0 --> Verkaufen

Wir werden jede dieser Strategien testen und optimieren, indem wir verschiedene Konzepte ausprobieren, um so viele bessere Ergebnisse wie möglich zu erzielen. Wie das funktioniert, werden wir im nächsten Abschnitt sehen.


Das Handelssystem mit dem Chaikin Money Flow

In diesem Abschnitt zeige ich Ihnen, wie Sie die einzelnen Strategien Schritt für Schritt programmieren können. Dann werde ich sie testen und Ihnen zeigen, wie wir sie optimieren können, um bessere Ergebnisse zu erzielen. Bleiben Sie also dran und lesen Sie diesen wirklich interessanten Teil des Artikels. Bevor wir uns mit der Programmierung von Strategien befassen, werde ich einen kleinen EA programmieren, der uns die CMF-Werte auf dem Chart anzeigt. Dies wird unsere Basis für alle EAs sein. Dadurch wird auch sichergestellt, dass wir in unseren EAs für jede Strategie einen genauen Indikator mit genauen Werten verwenden.

Als Nächstes werden wir mit diesem einfachen EA arbeiten:

Eingaben des EA einstellen, um die gewünschten Perioden und die Art des Volumens festzulegen, die in der Funktion des Aufrufs des Indikators verwendet werden sollen

input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type

Deklaration der Integer-Variablen cmf:

int cmf;

In OnInit() werden wir unseren nutzerdefinierten CMF-Indikator initialisieren, indem wir ihn mit der Funktion iCustom aufrufen, deren Parameter sind:

  • Symbol: Hier geben Sie den Symbolnamen als Zeichenkette ein. Es wird für das aktuelle Symbol „_Symbol“ sein.
  • Period: Hier geben Sie für den Zeitrahmen einen Wert aus ENUM_TIMEFRAMES an. Es wird PERIOD_CURRENT sein, um den aktuellen Zeitrahmen anzuwenden.
  • Name: Hier geben Sie den Namen des nutzerdefinierten Indikators ein, den Sie mit dem korrekten Pfad auf Ihrem lokalen Rechner aufrufen, d. h. Sie müssen den Ordner/custom_indicator_name eingeben. Wir nennen ihn „Chaikin_Money_Flow“.
  • ...: Hier geben Sie die Liste der Indikator-Eingabeparameter ein, falls vorhanden. Es handelt sich um die Eingaben wie Periodenlänge und VolumeTypeInp.

Dann verwenden wir die Rückgabewert „INIT_SUCCEEDED“, wenn die Initialisierung erfolgreich war, um zum nächsten Teil des Codes überzugehen.

int OnInit()
  {
   cmf = iCustom(_Symbol,PERIOD_CURRENT,"Chaikin_Money_Flow",periods,volumeTypeInp);
   return(INIT_SUCCEEDED);
  }

In OnDeinit() tragen wir die Nachricht ein, dass EA entfernt wird, wenn das Ereignis der Deinitialisierung eintritt.

void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }

In OnTick() wird ein Array für cmfInd[] als Double-Datentyp deklariert.

double cmfInd[];

Abrufen von Daten eines bestimmten Puffers des cmf-Indikators mit Hilfe der Funktion CopyBuffer. Die Parameter:

  • indicator_handle: das Handle für den Werteabruf in das zuvor deklarierte Array „cmf“. 
  • buffer_num: die Angabe der cmf-Puffernummer (0). 
  • start_pos: die Angabe der Startposition (0).
  • count: die Angabe der zu kopierenden Anzahl (3).
  • buffer[]: die Angabe des zu füllenden Arrays cmfInd[].
CopyBuffer(cmf,0,0,3,cmfInd);

Wir setzen das Flag AS_SERIES-Flag auf cmfInd[], um das Array als Zeitreihe zu indizieren. Als Parameter können Sie das Array[] und das Flag, das bei Erfolg wahr sein soll, verwenden.

ArraySetAsSeries(cmfInd,true);

Definieren der Variablen vom Typ double für den CMF-Stromwert, die auf 5 Dezimalen normalisiert wird, aber das können Sie selbst festlegen.

double cmfVal = NormalizeDouble(cmfInd[0], 5);

Im Chart schreiben wir den aktuellen cmf-Wert, der zuvor mit der Kommentarfunktion definiert wurde.

Comment("CMF value = ",cmfVal);

Den vollständigen Code finden Sie in dem unten stehenden Codeblock.

//+------------------------------------------------------------------+
//|                                                      CMF_Val.mq5 |
//+------------------------------------------------------------------+
input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type
int cmf;
int OnInit()
  {
   cmf = iCustom(_Symbol,PERIOD_CURRENT,"Chaikin_Money_Flow",periods,volumeTypeInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
    double cmfInd[];
    CopyBuffer(cmf,0,0,3,cmfInd);
    ArraySetAsSeries(cmfInd,true);
    double cmfVal = NormalizeDouble(cmfInd[0], 5);
    Comment("CMF value = ",cmfVal);
  }

Nach dem Kompilieren dieses Codes und dem Einfügen in den Chart als EA können wir das gleiche Ergebnis wie unten finden:

CMF_Val

Wie Sie sehen können, ist der CMF-Wert auf dem Chart derselbe wie der des eingefügten Indikators (0,15904). Wir können dies als Ausgangspunkt für andere EAs und Strategien verwenden.

Strategie des Kreuzens der Nulllinie des CMF:

Wie gesagt, müssen wir die Strategie des Kreuzens über Null so kodieren, dass die Trades automatisch auf der Grundlage dieses Kreuzens generiert werden. Das Programm muss ständig jeden neuen Balken überprüfen. Wenn der Indikator über Null kreuzt, ist das ein Anlass, einen Kaufauftrag zu erteilen. Wenn der Indikator unter Null kreuzt, ist das ein Anlass, einen Verkaufsauftrag zu erteilen.

Hier ist der vollständige Code, der diese Aufgabe erfüllen wird:
//+------------------------------------------------------------------+
//|                                           CMF_Zero_Crossover.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type
input double cmfPosLvls = 0.20; // CMF OB Level
input double cmfNegLvls = -0.20; // CMF OS Level
input int maPeriodInp=20; //MA Period
input double      lotSize=1;
input double      slLvl=300;
input double      tpLvl=900;
int cmf;
CTrade trade;
int barsTotal;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   cmf = iCustom(_Symbol,PERIOD_CURRENT,"Chaikin_Money_Flow",maPeriodInp,volumeTypeInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double cmfInd[];
      CopyBuffer(cmf,0,0,3,cmfInd);
      ArraySetAsSeries(cmfInd,true);
      double cmfVal = NormalizeDouble(cmfInd[0], 5);
      double cmfPreVal = NormalizeDouble(cmfInd[1], 5);
      double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
      if(cmfPreVal<0 && cmfVal>0)
        {
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }
      if(cmfPreVal>0 && cmfVal<0)
        {
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
	}
     }
  }
//+------------------------------------------------------------------+

Nur damit Sie es wissen, es gibt Unterschiede in diesem Code:

Einbinden der Datei Trade für den Aufruf von Handelsfunktionen.

#include <trade/trade.mqh>

Wir fügen weitere vom Nutzer zu bestimmende Eingaben hinzu, cmfPosLvls für überverkaufte Level, cmfNegLvls für überkaufte Level, Lotgröße, Stop-Loss, Take-Profit.

input double cmfPosLvls = 0.20; // CMF OB Level
input double cmfNegLvls = -0.20; // CMF OS Level
input double      lotSize=1;
input double      slLvl=300;
input double      tpLvl=900;

Deklaration der Handelsobjekte, barTotal Ganzzahlvariable.

CTrade trade;
int barsTotal;

In OnTick() müssen wir nur prüfen, ob es einen neuen Balken gibt, damit der Code ausgeführt wird. Wir können dies tun, indem wir eine if-Bedingung verwenden, nachdem wir eine Integer-Variable namens bars definiert haben.

int bars=iBars(_Symbol,PERIOD_CURRENT);
if(barsTotal != bars)

Wenn es einen neuen Balken gibt, müssen wir den restlichen Code mit den folgenden Unterschieden ausführen:

Aktualisieren von barsTotal, damit es gleich bars ist:

barsTotal=bars;

Deklaration des vorherigen cmf-Wertes.

double cmfPreVal = NormalizeDouble(cmfInd[1], 5);

Deklaration der Variablen ask und bid:

double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);

Bedingung für den Kauf festlegen: Wenn (cmfPreVal<0 und cmfVal>0), können wir SL, TP deklarieren und einen Kaufauftrag erteilen.

      if(cmfPreVal<0 && cmfVal>0)
        {
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }

Bedingung für den Verkauf festlegen,: Wenn (cmfPreVal>0 und cmfVal<0), können wir SL, TP deklarieren und eine Verkaufsauftrag erteilen.

      if(cmfPreVal>0 && cmfVal<0)
        {
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }

Nachdem wir diesen Code zusammengestellt und an das Chart angehängt haben, können wir sehen, dass die Positionen genauso platziert sind wie im Beispiel unten, das aus der Testphase stammt.

Kaufposition:

kaufen

Verkaufsposition:

verkaufen

Nun müssen wir alle Strategien für EURUSD ein Jahr lang testen, vom 1.1.2023 bis zum 31.12.2023. Wir werden 300 Punkte für SL und 900 für TP verwenden. Unser Hauptansatz zur Optimierung besteht darin, ein anderes Konzept zu testen oder ein weiteres Instrument, wie den gleitenden Durchschnitt, hinzuzufügen. Sie können auch andere Zeitrahmen testen, um herauszufinden, welcher von ihnen besser funktioniert. Auch diese Art der Optimierung ist einen Versuch wert.

Was die Ergebnisse der Strategietests zum Vergleich zwischen den beiden anbelangt, so werden wir uns auf die folgenden Schlüsselmessungen konzentrieren:

  • Net profit: Dieser wird berechnet, indem der Bruttoverlust vom Bruttogewinn abgezogen wird. Der höchste Wert ist der beste.
  • Balance DD relative: Dies ist der maximale Verlust, den das Konto während des Handels erleidet. Je niedriger, desto besser.
  • Profit factor: Dies ist das Verhältnis von Bruttogewinn zu Bruttoverlust. Je höher, desto besser.
  • Expected Payoff: Dies ist der durchschnittliche Gewinn oder Verlust eines Handelsgeschäfts. Der höchste Wert ist der beste.
  • Recovery factor: Er misst, wie gut sich die getestete Strategie nach Verlusten erholt. Je höher, desto besser.
  • Sharpe Ratio: Sie bestimmt das Risiko und die Stabilität des getesteten Handelssystems, indem sie die Rendite mit der risikofreien Rendite vergleicht. Die höchste Sharpe Ratio ist die beste.

Die Testergebnisse für den 15-Minuten-Zeitrahmen sind unten dargestellt:

15min-Backtest1

 15min-Backtest2

15min-Backtest3

Aus den Ergebnissen der 15-Minuten-Tests lassen sich folgende wichtige Werte für die Testnummern ableiten:

  • Net Profit: 29019.10 USD.
  • Balance DD relative: 23%.
  • Profit factor: 1.09.
  • Expected payoff: 19.21.
  • Recovery factor: 0.88.
  • Sharpe Ratio: 0.80.

Es sieht so aus, als könne die Strategie mit dem 15-Minuten-Zeitrahmen profitabel sein, aber der Drawdown ist hoch, was das Risiko erhöhen würde. Wir werden also eine andere Strategie mit einem anderen Konzept ausprobieren: den überkauften und überverkauften CMF.

Die CMF-Strategie für überkaufte und überverkaufte Märkte:

Wie bereits erwähnt, müssen wir diese Strategie so programmieren, dass sie Kauf- und Verkaufsaufträge auf der Grundlage der sich überkauften und überverkauften Bereiche automatisch durch den EA platziert. Die Bereiche, die wir betrachten, sind 0,20 für überverkauft und -0,20 für überverkauft. Der EA muss also jeden CMF-Wert im Auge behalten und ihn mit diesen Bereichen vergleichen. Wenn der CMF gleich oder unter -0,20 ist, sollte der EA einen Kaufauftrag erteilen. Wenn der CMF-Wert gleich oder größer als 0,20 ist, sollte der EA einen Verkaufsauftrag erteilen.

Sie können die Schritte der Erstellung dieser Strategie oder EA im folgenden vollständigen Code sehen:

//+------------------------------------------------------------------+
//|                                                 CMF_MA_OB&OS.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type
input double cmfPosLvls = 0.20; // CMF OB Level
input double cmfNegLvls = -0.20; // CMF OS Level
input double      lotSize=1;
input double      slLvl=300;
input double      tpLvl=900;
int cmf;
CTrade trade;
int barsTotal;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   cmf = iCustom(_Symbol,PERIOD_CURRENT,"Chaikin_Money_Flow",periods,volumeTypeInp);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double cmfInd[];
      CopyBuffer(cmf,0,0,3,cmfInd);
      ArraySetAsSeries(cmfInd,true);
      double cmfVal = NormalizeDouble(cmfInd[0], 5);
      double cmfPreVal = NormalizeDouble(cmfInd[1], 5);
      double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
      if(cmfVal<=cmfNegLvls)
        {
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }
      if(cmfVal>=cmfPosLvls)
        {
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }
     }
  }
//+------------------------------------------------------------------+

Die Unterschiede in diesem Code sind unten:

Legen Sie zwei Eingaben für die überkauften und überverkauften Bereiche fest, je nachdem, was der Nutzer wünscht. Verwenden Sie vorerst die Standardwerte (0,20 und -0,20).

input double cmfPosLvls = 0.20; // CMF OB Level
input double cmfNegLvls = -0.20; // CMF OS Level

Bedingungen der Strategie

Platzieren Sie eine Kaufposition, wenn der CMF-Wert kleiner als oder gleich dem cmfNegLvls ist

      if(cmfVal<=cmfNegLvls)
        {
         double slVal=ask - slLvl*_Point;
         double tpVal=ask + tpLvl*_Point;
         trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
        }

Platzieren Sie eine Verkaufsposition, wenn der CMF-Wert größer als oder gleich dem cmfPosLvls ist

      if(cmfVal>=cmfPosLvls)
        {
         double slVal=bid + slLvl*_Point;
         double tpVal=bid - tpLvl*_Point;
         trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
        }

Wenn wir diesen Code zusammengestellt haben und ihn im Chart durchlaufen lassen, können wir sehen, wo die Positionen mit den Bedingungen der Strategie übereinstimmen, genau wie in den Beispielen aus der Testphase.

Kaufposition:

kaufen

Position verkaufen:

verkaufen

Wir werden diese Strategie mit demselben Ansatz testen, den wir bei der vorherigen Prüfung des Kreuzens der Null des CMF verwendet haben. Wir werden EURUSD vom 1.1.2023 bis zum 31.12.2023 auf dem 15-Minuten-Zeitrahmen mit 300 Punkten für SL und 900 für TP testen. Die folgenden Abbildungen zeigen die Ergebnisse dieser Prüfung:

15min-Backtest1

 15min-Backtest2

15min-Backtest3

Aus den Ergebnissen der 15-Minuten-Tests lassen sich folgende wichtige Werte für die Testnummern ableiten:

  • Net Profit: 58029.90 USD.
  • Balance DD relative: 55.60%.
  • Profit factor: 1.06.
  • Expected payoff: 14.15.
  • Recovery factor: 0.62.
  • Sharpe Ratio: 0.69.

Jetzt, da wir mehr Gewinne mit einem höheren Drawdown sehen, werden wir versuchen, es zu optimieren, indem wir einen anderen technischen Indikator mit dem Kreuzen der Null des CMF zur Trendvalidierung hinzufügen oder kombinieren; wir werden sehen, was in der nächsten Strategie passiert.

Strategie der Trendvalidierung durch den CMF:

Wie gesagt, müssen wir einen weiteren technischen Indikator, den gleitenden Durchschnitt, mit dem Nulldurchgang des CMF kombinieren, um die Bewegung in beide Richtungen (aufwärts und abwärts) zu bestätigen. Der EA muss jeden Schlusskurs, die Nachfrage und den CMF überprüfen. Der Wert wird verwendet, um die Position der einzelnen Elemente im Verhältnis zu den anderen zu bestimmen. Wenn der letzte Schlusskurs unter dem letzten gleitenden Durchschnittswert liegt, der aktuelle Briefkurs über dem aktuellen gleitenden Durchschnitt liegt und der CMF-Wert über Null liegt, müssen wir einen Kaufauftrag erteilen. Wenn hingegen der letzte Schlusskurs über dem letzten gleitenden Durchschnittswert liegt, der aktuelle Geldkurs unter dem aktuellen gleitenden Durchschnitt liegt und der CMF-Wert unter Null liegt, müssen wir einen Verkaufsauftrag erteilen.

Hier ist der vollständige Code für diesen EA:

//+------------------------------------------------------------------+
//|                                          CMF_trendValidation.mq5 |
//+------------------------------------------------------------------+
#include <trade/trade.mqh>
input int                 periods=20; // Periods
input ENUM_APPLIED_VOLUME volumeTypeInp=VOLUME_TICK;  // Volume Type
input int maPeriodInp=20; //MA Period
input double      lotSize=1;
input double      slLvl=300;
input double      tpLvl=900;
int cmf;
int ma;
CTrade trade;
int barsTotal;
int OnInit()
  {
   barsTotal=iBars(_Symbol,PERIOD_CURRENT);
   cmf = iCustom(_Symbol,PERIOD_CURRENT,"Chaikin_Money_Flow",periods,volumeTypeInp);
   ma = iMA(_Symbol,PERIOD_CURRENT,maPeriodInp,0,MODE_SMA,PRICE_CLOSE);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("EA is removed");
  }
void OnTick()
  {
   int bars=iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      double cmfInd[];
      double maInd[];
      CopyBuffer(cmf,0,0,3,cmfInd);
      CopyBuffer(ma,0,0,3,maInd);
      ArraySetAsSeries(cmfInd,true);
      ArraySetAsSeries(maInd,true);
      double cmfVal = NormalizeDouble(cmfInd[0], 5);
      double maVal= NormalizeDouble(maInd[0],5);
      double cmfPreVal = NormalizeDouble(cmfInd[1], 5);
      double maPreVal = NormalizeDouble(maInd[1],5);;
      double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
      double prevClose = iClose(_Symbol,PERIOD_CURRENT,1);
      if(prevClose<maPreVal && ask>maVal)
        {
         if(cmfVal>0)
           {
            double slVal=ask - slLvl*_Point;
            double tpVal=ask + tpLvl*_Point;
            trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
           }
        }
      if(prevClose>maPreVal && bid<maVal)
        {
         if(cmfVal<0)
           {
            double slVal=bid + slLvl*_Point;
            double tpVal=bid - tpLvl*_Point;
            trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
           }
        }
     }
  }
//+------------------------------------------------------------------+

Die wichtigsten Unterschiede in diesem Code wie folgt:

Hinzufügen einer weiteren Eingabe für den Nutzer, um die Periodenlänge des verwendeten gleitenden Durchschnitts zu bestimmen.

input int maPeriodInp=20; //MA Period

Deklaration einer Integer-Variablen für den gleitenden Durchschnitt.

int ma;

Definieren der von ma erstellte Variable mit Hilfe der Funktion iMA, deren Parameter sind:

  • symbol: um den Namen des Symbols festzulegen, „_Symbol“ verwendet das aktuelle Symbol des Charts. 
  • Periode: um den Zeitrahmen des gleitenden Durchschnitts festzulegen, und sie wird (PERIOD_CURRENT) auf den aktuell verwendeten Zeitrahmen angewendet werden.
  • ma_period: zur Festlegung des Mittelungszeitraums, es handelt sich um die Nutzereingabe von (maPeriodInp).
  • ma_shift: zur Einstellung der horizontalen Verschiebung, falls erforderlich.
  • ma_method: um die Art der Glättung oder den Typ des gleitenden Durchschnitts anzugeben, wird (MODE_SMA) der einfache MA verwendet.
  • applied_price: um die Art des Preises anzugeben, wir verwenden „PRICE_CLOSE“.
ma = iMA(_Symbol,PERIOD_CURRENT,maPeriodInp,0,MODE_SMA,PRICE_CLOSE);

Deklarieren des Arrays maInd[].

double maInd[];

Abrufen der Daten eines bestimmten Puffers des MA-Indikators mit Hilfe der Funktion CopyBuffer.

CopyBuffer(ma,0,0,3,maInd);

Wir setzen AS_SERIES-Flag für das Array maInd[], um es als Zeitreihe zu indizieren.

ArraySetAsSeries(maInd,true);

Definieren der aktuellen und vorherigen MA-Werte.

double maVal= NormalizeDouble(maInd[0],5);
double prevClose = iClose(_Symbol,PERIOD_CURRENT,1);

Bedingungen der Kaufposition, prevClose<maPreVal, ask>maVal, und cmfVal>0.

      if(prevClose<maPreVal && ask>maVal)
        {
         if(cmfVal>0)
           {
            double slVal=ask - slLvl*_Point;
            double tpVal=ask + tpLvl*_Point;
            trade.Buy(lotSize,_Symbol,ask,slVal,tpVal);
           }
        }

Bedingungen der Verkaufsposition, prevClose>maPreVal, bid<maVal, und cmfVal<0.

      if(prevClose>maPreVal && bid<maVal)
        {
         if(cmfVal<0)
           {
            double slVal=bid + slLvl*_Point;
            double tpVal=bid - tpLvl*_Point;
            trade.Sell(lotSize,_Symbol,bid,slVal,tpVal);
           }
        }

Nach der Ausführung dieses EA können wir den erteilten Auftrag wie in den unten stehenden Abbildungen sehen:

Die Kaufposition:

kaufen

Die Verkaufsposition:

verkaufen

Wir testen diese Strategie mit dem gleichen Ansatz wie die vorherigen Tests für den „CMF_Zero_Crossover“ und die OB- und OS-Strategien. Wir testen EURUSD vom 1.1.2023 - 31.12.2023 auf dem 15-Minuten-Zeitrahmen mit 300 Punkten für SL und 900 für TP. Die folgenden Zahlen beziehen sich auf das Ergebnis dieses Tests:

15min-Backtest1

15min-Backtest2

15min-Backtest3

Aus den Ergebnissen der 15-Minuten-Tests lassen sich folgende wichtige Werte für die Testnummern ableiten:

  • Net Profit: 40723.80 USD.
  • Balance DD relative: 6.30%.
  • Profit factor: 1.91.
  • Expected payoff: 167.59.
  • Recovery factor: 3.59.
  • Sharpe Ratio: 3.90.

Betrachtet man die Ergebnisse der einzelnen Strategien, so wird deutlich, dass die CMF-Trendvalidierung in Bezug auf die wichtigsten Messungen am besten abschneidet.


Schlussfolgerung

Wie wir in diesem Artikel gesehen haben, ist das Volumen ein sehr wichtiges Konzept im Handel, vor allem, wenn es mit anderen wichtigen Instrumenten kombiniert wird. Darüber hinaus haben wir erkannt, dass die Optimierung eine sehr wichtige Aufgabe beim Testen jeder Strategie ist, da sie durch kleine Änderungen beeinflusst werden kann. Ich rate Ihnen, Ihre Tests zu machen, indem Sie verschiedene Aspekte wie Zeitrahmen, SL und TP ändern und andere Werkzeuge hinzufügen, bis Sie vernünftige Ergebnisse finden.

Es wird vorausgesetzt, dass Sie wissen, wie man den Chaikin Money Flow Volumenindikator verwendet, wie man ihn anpasst und codiert und wie man EAs basierend auf verschiedenen einfachen Strategien erstellt, optimiert und testet:

  • Strategie des Kreuzens der Nulllinie des CMF.
  • Die CMF-OB- und OS-Strategie.
  • Strategie der Trendvalidierung durch den CMF.

Darüber hinaus haben Sie lernen können, welche Lösung aufgrund von Optimierungs- und Testergebnissen besser ist. Ich hoffe, Sie haben diesen Artikel als nützlich empfunden, und wenn Sie weitere Artikel von mir lesen möchten, z. B. über den Aufbau von Handelssystemen auf der Grundlage der beliebtesten technischen Indikatoren und andere, können Sie sie über meine Seite mit meinen Publikationen gelangen.

Die angehängten Quellcodedateien sind dieselben wie unten:

Datei Name Beschreibung
Chaikin_Money_Flow Er ist für unseren selbst erstellten CMF-Indikator.
CMF_Zero_Crossover Es ist für den EA von CMF mit der Handelsstrategie des Kreuzens der Null.
CMF_OBOS Es ist für den EA von CMF mit überkauften und überverkauften Handelsstrategie.
CMF_trendValidation Es ist für den EA von CMF mit Bewegungs-, Trend-Validierung Handelsstrategie.


Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/16469

Beigefügte Dateien |
CMF_OBeOS.mq5 (1.72 KB)
Nachrichtenhandel leicht gemacht (Teil 6): Ausführen des Handels (III) Nachrichtenhandel leicht gemacht (Teil 6): Ausführen des Handels (III)
In diesem Artikel wird die Nachrichtenfilterung für einzelne Nachrichtenereignisse auf der Grundlage ihrer IDs implementiert. Darüber hinaus werden frühere SQL-Abfragen verbessert, um zusätzliche Informationen zu liefern oder die Laufzeit der Abfrage zu verkürzen. Außerdem wird der in den vorangegangenen Artikeln erstellte Code funktionsfähig gemacht.
Erstellen von selbstoptimierenden Expert Advisors in MQL5 (Teil 3): Dynamische Trendfolge- und Mean-Reversion-Strategien Erstellen von selbstoptimierenden Expert Advisors in MQL5 (Teil 3): Dynamische Trendfolge- und Mean-Reversion-Strategien
Die Finanzmärkte werden in der Regel entweder in eine Handelsspanne oder in einen Trendmodus eingeteilt. Diese statische Sichtweise des Marktes kann es uns leichter machen, kurzfristig zu handeln. Sie ist jedoch von der Realität des Marktes abgekoppelt. In diesem Artikel geht es darum, besser zu verstehen, wie genau sich die Finanzmärkte zwischen diesen beiden möglichen Modi bewegen und wie wir unser neues Verständnis des Marktverhaltens nutzen können, um Vertrauen in unsere algorithmischen Handelsstrategien zu gewinnen.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 51): Verstärkungslernen mit SAC MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 51): Verstärkungslernen mit SAC
Soft Actor Critic ist ein Reinforcement Learning Algorithmus, der 3 neuronale Netze verwendet. Ein Netzwerk für den Actor und 2 Critic-Netze. Diese maschinellen Lernmodelle werden in einer Master-Slave-Partnerschaft gepaart, in der die Kritiker modelliert werden, um die Prognosegenauigkeit des Akteursnetzwerks zu verbessern. Während wir in dieser Serie auch ONNX vorstellen, untersuchen wir, wie diese Ideen als nutzerdefiniertes Signal eines von einem Assistenten zusammengestellten Expert Advisors getestet werden können.
Einführung in MQL5 (Teil 10): Eine Anleitung für Anfänger zur Arbeit mit den integrierten Indikatoren in MQL5 Einführung in MQL5 (Teil 10): Eine Anleitung für Anfänger zur Arbeit mit den integrierten Indikatoren in MQL5
Dieser Artikel führt in die Arbeit mit integrierten Indikatoren in MQL5 ein und konzentriert sich auf die Erstellung eines RSI-basierten Expert Advisors (EA) mit einem projektbasierten Ansatz. Sie werden lernen, RSI-Werte abzurufen und zu nutzen, Liquiditätsdurchbrüche zu handhaben und die Handelsvisualisierung mit Chart-Objekten zu verbessern. Darüber hinaus wird in dem Artikel ein wirksames Risikomanagement hervorgehoben, einschließlich der Festlegung eines prozentualen Risikos, der Umsetzung von Risiko-Ertrags-Verhältnissen und der Anwendung von Risikomodifikationen zur Sicherung von Gewinnen.