English
preview
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 24): Gleitende Durchschnitte

MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 24): Gleitende Durchschnitte

MetaTrader 5Handelssysteme | 2 August 2024, 10:33
34 0
Stephen Njuki
Stephen Njuki

Einführung

Wir setzen diese Serie über die MQL5-Assistenten fort, indem wir uns den Indikator des gleitenden Durchschnitts ansehen und überlegen, wie er der Bibliothek der bereits verfügbaren Tools auf eine Weise hinzugefügt werden könnte, die für einige Händler neu sein könnte. Die Gleitender Durchschnitt hat sehr viele Varianten als einzelne Zeitreihe, die an ein Diagramm angehängt werden kann, aber auch andere Varianten als Oszillator und sogar andere als Hüllkurvenindikator.

Wir werden diese verschiedenen Anwendungen oder Varianten innerhalb einer speziellen Kategorie von 3 gleitenden Durchschnitten (MA) untersuchen, die Pythagoräische Durchschnitte. Die 3 MAs unter diesem Namen sind Arithmetischer Durchschnitt (AM), Geometrischer Durchschnitt (GM) und Harmonischer Durchschnitt (HM). Das erste, das arithmetische Mittel, ist das, woran jeder zuerst denkt, wenn von MA die Rede ist. Er ist einfach der Durchschnitt einer beliebigen Anzahl von Werten in einer Menge. Wikipedia hat eine sehr interessante Zusammenfassung all dieser 3 Mittel in einem Diagramm. Sie wird unten geteilt:


Die obige Darstellung ist ein Halbkreis, dessen Durchmesser ungleichmäßig in zwei Werte a und b aufgeteilt ist. Das arithmetische Mittel dieser beiden Werte ist im Diagramm als A in rot markiert, was erwartungsgemäß dem Radius des Halbkreises entspricht. Der Vollständigkeit halber wird die Formel für das arithmetische Mittel im Folgenden wie folgt wiedergegeben:

wobei

  • AM ist das arithmetische Mittel
  • x sind die Werte, deren Durchschnitt berechnet wird
  • n ist die Anzahl der Menge

Das geometrische Mittel ergibt sich aus der Formel:

wobei

  • GM ist das geometrische Mittel
  • x und n sind die gleichen wie bei AM oben

Der GM-Wert auf dem obigen Halbkreis entspricht in seiner Länge dem mit G gekennzeichneten blauen Strecke, wodurch der kleinere b-Wert stärker gewichtet wird als das größere a. Bemerkenswert ist auch, dass die GM immer positiv sein wird, selbst wenn alle Werte negativ sind! Diesem Szenario könnte man begegnen, indem man der berechneten GM einen negativen Wert zuweist, wenn die Menge ausschließlich negative Zahlen enthält, aber wenn es sich um eine Mischung aus negativen und positiven Werten handelt, wird die Ermittlung der tatsächlichen GM problematisch.

Für das harmonische Mittel ist die Halbkreisdarstellung die mit H bezeichnete Linie, deren Länge dem Durchschnitt von a und b entspricht. Seine Formel ist wie folgt:

wobei

  • HM das harmonische Mittel ist,
  • x und n stehen für dasselbe wie oben.

Wäre der Wert b, aus irgendeinem Grund Null, wie aus dem Halbkreisdiagramm ersichtlich, wären sowohl das geometrische als auch das harmonische Mittel Null. (Und das, obwohl bei der Berechnung des harmonischen Mittels eine „Division durch Null" existiert). Interessanterweise gilt dies unabhängig von der Anzahl (d. h. wenn es mehr als 2 sind) der Zahlen, deren Durchschnitte berechnet werden; solange eine dieser Zahlen eine Null ist, sind das geometrische Mittel und das harmonische Mittel aller Werte Null.

Diese Eigenschaft misst im Wesentlichen das Ausmaß, in dem der kleinste Wert in einer Menge nahe bei Null liegt. Was bedeutet das nun für die Händler? Je nachdem, um welche Daten des gleitenden Durchschnitts es sich handelt, kann dies eine Reihe von Bedeutungen haben.

Wenn es sich nur um den Preis von Wertpapieren handelt, könnte der gleitende Durchschnitt ein guter Indikator für die Unterstützung sein. Warum? Sie (die GM & HM) verleiht den niedrigen Preisen mehr Gewicht. Dies könnte zum Beispiel bedeuten, dass ein Kursdurchbruch unter diesen Durchschnitten eine größere Bedeutung hat als ein Durchbruch unter einem regulären gleitenden Durchschnitt.GM und HM könnten also auf der Unterstützungsseite der meisten Kursbewegungen einfallsreich sein. Wie sieht es auf der Seite des Widerstands aus? Mit den folgenden Formeln können wir ein Spiegeläquivalent von GM und HM erhalten:

HM' = AM + (AM - HM)

GM' = AM + (AM - GM)

wobei:

  • HM' ist der reflektierte harmonische Durchschnitt
  • GM’ ist das geometrische Mittel der Reflexion
  • AM, GM und HM sind die gleichen wie oben.

Durch die Einführung von spiegelbildlichen Äquivalenten oder Spiegelungen von GM und HM wird in gewisser Weise ein Gleichgewicht zu den Durchschnittswerten hergestellt, da die Gewichtung dieser Spiegelungen zwangsläufig zu den größeren Werten in jeder Wertegruppe tendiert, deren Durchschnitt berechnet wird. Das bedeutet auch, dass wir zur Beantwortung der Frage nach dem Widerstand nun entweder GM' oder HM' als höhere preisgewichtete Durchschnitte verwenden können, die als effektivere Näherungswerte zur Definition des Widerstandsniveaus dienen.

Die Bedeutung von GM gegenüber HM für unsere Zwecke ist nur eine Frage des Grades. Dies liegt daran, dass beide zu den kleineren Werten hin gewichtet sind, wobei der Hauptunterschied darin besteht, dass HM eine höhere Gewichtung zu Null hat als GM.


Nutzerspezifische Implementierungen

Wir sehen uns nun an, wie diese einfachen Durchschnittswerte in MQL5 eingesetzt werden können, um ihre einzigartigen Eigenschaften zu nutzen. Der erste Punkt ist das arithmetische Mittel. Von diesen 3 ist dies der gewöhnlichste, da er die Grundlagen der Durchschnittswerte ohne jegliche Modifikationen übernimmt, und die einfachste Art, diesen Durchschnitt zu verwenden, dürfte die Beobachtung von Preisüberkreuzungen sein. Es gibt viele Anwendungen von gleitenden Durchschnitten bei der Verfolgung der Preisstruktur, und dies dürfte wohl die einfachste und gängigste sein. Daher wird diese Anwendung hier in erster Linie zu Vergleichszwecken mit den anderen, nicht so gebräuchlichen GM- und HM-Mitteln, die bereits oben vorgestellt wurden, vorgestellt.

Benchmarking und Vergleich sind inhärente MQL5-Assistent versammelten Experten, vor allem für die Signalklassen, da jede gewählte Signalklasse in den Assistenten kann eine Gewichtung zugewiesen werden, oder ein Mitspracherecht, bei der Bestimmung der Kauf- und Verkaufs-Bedingungen eines gehandelten Wertpapiers. Dank der Vektordatentypen können wir den AM-Puffer leicht von dieser Funktion abrufen:

//+------------------------------------------------------------------+
//| Arithmetic Mean                                                  |
//+------------------------------------------------------------------+
double CSignalAM::AM(int Index, int Mask = 8)
{  vector _am;
   _am.CopyRates(m_symbol.Name(), m_period, Mask, Index, m_fast);
   return(_am.Mean());
}

Außerdem können wir mit dieser Funktion die aktuelle Kurslücke messen, die für die Verfolgung der Überkreuzung des gleitenden Durchschnitts entscheidend ist:

   double            CrossOver(int Index)
   {                 m_close.Refresh(-1);
      return(AM(Index) - m_close.GetData(Index));
   }

In Fällen, in denen manuell gehandelt wird, wäre es in der Regel sinnvoller, diesen Indikator sowie den GM- und HM-Indikator als nutzerdefinierten Indikator zu codieren. Wir handeln nicht manuell, da es sich um einen Expert Advisor handelt, und daher ist eine Funktion, die auf die eingebauten Preispuffer der Klasse zugreift, genau richtig.

Der HM-Durchschnitt ist wie der GM-Durchschnitt zu den kleineren Werten hin gewichtet, und wie wir oben gesehen haben, kann dies gespiegelt werden, um einen anderen Durchschnitt, HM', zu bilden, der zu den höheren Werten hin gewichtet ist. HM & HM' sind also Mittel, die zu den Extremen hin gewichtet sind, und eignen sich daher gut, um Abweichungen zu erkennen. Wenn man nun an Divergenzen denkt, könnte das erste, was einem in den Sinn kommt, ein Unterschied im Trend zwischen einem Oszillator und seinem Wertpapierkurs sein. Diese Anfälle treten in sehr kurzen Zeiträumen auf, und man muss auf der Hut sein, um sie zu erwischen. Es kann sich aber auch um eine Divergenz bei den Kursen ein und desselben Wertpapiers auf unterschiedlichen Zeitrahmen handeln, z. B. ein Kursrückgang auf dem einstündigen Zeitrahmen, während auf dem wöchentlichen Zeitrahmen ein starker Aufwärtstrend besteht.

Um jedoch die „Verzerrungen" des harmonischen Mittels auszunutzen, werden wir auf Divergenzen zwischen hohen und niedrigen Preisen achten. Insbesondere werden wir nur dann Positionen eröffnen, wenn die Veränderung der hohen Preise in eine andere Richtung geht als die Veränderung der niedrigen Preise. Dies könnte jedoch noch auf zwei Arten untersucht werden. Entweder eröffnen wir eine Position bei fallenden Hochs und steigenden Tiefs oder wir eröffnen sie bei steigenden Hochs und fallenden Tiefs. In diesem Artikel befassen wir uns mit letzterem, aber da alle Quellen am Ende dieses Artikels angehängt sind, kann der Leser diese anpassen und versuchen, die populärere „Engulf-Divergenz“ zu nutzen, die wir nicht berücksichtigt haben.

Wir suchen also nach einem Anstieg des harmonischen Durchschnitts der Höchststände, der mit einem Rückgang des harmonischen Durchschnitts der Tiefststände einhergeht, um Positionen zu eröffnen. Ein Follow-up-Indikator, der bei der Eröffnung einer Kauf- oder Verkaufs-Position hilft, kann hier angepasst werden, aber was wir als Follow-up verwenden, ist einfach die Veränderung des Schlusskurses. Bei einem Anstieg des Schlusskurses nach einer Divergenz des vorhergehenden Balkens kaufen wir und umgekehrt.

Der Code für die Umsetzung ist, wie wir bei AM gesehen haben, ebenfalls zweigeteilt. Zunächst haben wir die HM-Funktion und ihre Spiegelung, die im Folgenden vorgestellt wird:

//+------------------------------------------------------------------+
//| Harmonic Mean                                                    |
//+------------------------------------------------------------------+
double CSignalHM::HM(int Index, int Mask = 8)
{  vector _hm, _hm_i;
   _hm_i.CopyRates(m_symbol.Name(), m_period, Mask, Index, m_slow);
   _hm = (1.0 / _hm_i);
   return(m_slow / _hm.Sum());
}
//+------------------------------------------------------------------+
//| Inverse Harmonic Mean                                            |
//+------------------------------------------------------------------+
double CSignalHM::HM_(int Index, int Mask = 8)
{  double _am = AM(Index, Mask);
   double _hm = HM(Index, Mask);
   return(_am + (_am - _hm));
}

Dann haben wir die Divergenzfunktion, und die lautet wie folgt:

   double            Divergence(int Index)
   {                 return((HM_(Index, 2) - HM_(Index + 1, 2)) - (HM(Index, 4) - HM(Index + 1, 4)));
   }

Bei der Verwendung von Vektoren zum Kopieren und Laden von Daten ist der Index „Kursmaske" unverzichtbar, da er ein schnelles Umschalten zwischen verschiedenen Kursen (OHLC) ermöglicht und gleichzeitig die Verwendung der in den Vektordatentyp eingebauten Statistikfunktionen eine Menge Code erspart. Darüber hinaus verwenden unsere Testfunktionen für diese pythagoreischen Durchschnitte zwei gleitende Durchschnittsperioden, eine schnelle und eine langsame Periodenlänge. Dies ist eine gängige Praxis, insbesondere bei der Verwendung der Kreuzungs-Strategie zur Bestimmung von Einstiegs- und Ausstiegspunkten. Sowohl für den harmonischen Durchschnitt als auch für den geometrischen Durchschnittpuffer stützen wir uns bei der Berechnung unserer Werte auf die langsame Periode. Die schnellen Perioden werden nur für den arithmetischen Durchschnittpuffer verwendet.

Dies kann natürlich geändert oder angepasst werden, um der eigenen Strategie und dem eigenen Ansatz besser zu entsprechen, aber wir halten uns hier nur zu Testzwecken daran.

Schließlich wird der geometrische Durchschnitt, der wie der harmonische Durchschnitt in ähnlicher Weise wie die Bollinger-Bänder angewandt wird. Es ist, als ob die Harmonische mehr zu kleinen Werten und in einem etwas größeren Ausmaß gewichtet wird. Diese Gewichtung ist ideal für die Ableitung eines Bollinger-Band-ähnlichen Indikators, da die Bollinger-Bänder bekanntlich ein gleitender Durchschnitt plus 2 Standardabweichungen sind. Bevor wir uns jedoch mit der Implementierung befassen, sollte der Code für die Ermittlung des geometrischen Mittels und seines Spiegelbildes (hochwertiges gewichtetes Äquivalent) wie folgt lauten:

//+------------------------------------------------------------------+
//| Geometric Mean                                                   |
//+------------------------------------------------------------------+
double CSignalGM::GM(int Index, int Mask = 8)
{  vector _gm;
   _gm.CopyRates(m_symbol.Name(), m_period, Mask, Index, m_slow);
   return(pow(_gm.Prod(), 1.0 / m_slow));
}
//+------------------------------------------------------------------+
//| Inverse Geometric Mean                                           |
//+------------------------------------------------------------------+
double CSignalGM::GM_(int Index, int Mask = 8)
{  double _am = AM(Index, Mask);
   double _gm = GM(Index, Mask);
   return(_am + (_am - _gm));
}

Auch hier verwenden wir wieder die Vektordatentypen und ihre eingebauten Funktionen, um unseren Kodierungsprozess zu beschleunigen. Es gibt zwei Puffer der Bänder, ein oberes Band und ein unteres Band. Auch diese werden über die beiden unten aufgeführten Funktionen abgerufen:

   double            BandsUp(int Index)
   {  vector _bu;
      _bu.CopyRates(m_symbol.Name(), m_period, 2, Index, m_slow);
      return(GM_(Index, 2) + (2.0 * _bu.Std()));
   }

   double            BandsDn(int Index)
   {  vector _bd;
      _bd.CopyRates(m_symbol.Name(), m_period, 4, Index, m_slow);
      return(GM(Index, 4) - (2.0 * _bd.Std()));
   }

Die beiden Funktionen geben einfach den oberen Bandpreis und den unteren Bandpreis für die Funktionen „BandsUp" bzw. „BandsDn" zurück. Diese zurückgegebenen Werte können leicht in parallele Puffer für die Analyse in einer Reihe von Formen rekonstituiert werden. Wir verwenden sie einfach als Crossover, um festzustellen, ob wir möglicherweise Kauf- oder Verkaufs-Position eröffnen können. Um zu prüfen, ob eine Kauf-Position vorliegt, benötigen wir die Bestätigung, dass der Kurs das untere Band von unten durchquert hat, d. h. er lag unter dem unteren Band, liegt aber jetzt darüber. In ähnlicher Weise müssten wir zur Überprüfung von Verkaufs-Positionen eine Überschreitung des oberen Bandes von oben bestätigen, wenn der Kurs oberhalb des oberen Bandes lag, aber in einem nachfolgenden Kursbalken nun darunter liegt.


Nutzerdefinierte Signalklassen

Jede dieser 3 Pythagoras-MAs kann in einer einzigen Klasse mit einem zusätzlichen Parameter kombiniert werden, der die Auswahl einer dieser MAs zur Verwendung in einem Expert Advisor ermöglicht. Wir implementieren diese jedoch als separate Signalklassen, da wir die Gewichtungseinstellung der Signalklassen untersuchen werden, indem wir eine Optimierung für die ideale Gewichtung jedes Durchschnitts durchführen, um ein Gefühl dafür zu bekommen, welches dieser Signale und damit welcher der Durchschnitte für die Prognose und die Platzierung von Aufträgen mit unserem Expert Advisor nützlicher ist.

Bevor wir uns jedoch ein Bild von der relativen Bedeutung machen, kann es sinnvoll sein, zunächst unabhängige Tests für jede Signalklasse durchzuführen, sodass die relativen Gewichte, die wir am Ende erhalten, als Validierung (oder Widerlegung) dieser ersten Testläufe dienen können, die wir durchgeführt haben. Wir beginnen also mit der Entwicklung eines Expert Advisors für jeden der 3 Durchschnittswerte und testen sie unabhängig voneinander, um ihre eigene Leistung zu bewerten. Sobald wir diese Ergebnisse haben, führen wir Tests mit einem Expert Advisor durch, der alle drei Durchschnitte kombiniert, um die relative Gewichtung der einzelnen Durchschnitte zu optimieren.

Um eine Kauf- oder Verkaufs-Bedingung für die Signalklasse des arithmetischen Mittels zu entwickeln, prüfen wir einfach, ob sich der Kreuzungs-Wert ändert, wie er von der Funktion „Crossover" zurückgegeben wird, deren Code oben gemeinsam genutzt wird. Unsere langen und kurzen Bedingungscodes sind recht kurz, und beide werden im Folgenden erläutert:

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CSignalAM::LongCondition(void)
{  int result = 0;
   if(CrossOver(StartIndex()) > 0.0 && CrossOver(StartIndex()+1) < 0.0)
   {  result = int(round(100.0 * ((CrossOver(StartIndex()) - CrossOver(StartIndex()+1))/fmax(fabs(CrossOver(StartIndex()))+fabs(CrossOver(StartIndex()+1)),fabs(CrossOver(StartIndex()+1))+fabs(CrossOver(StartIndex()+2))))));
   }
   return(result);
}
//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CSignalAM::ShortCondition(void)
{  int result = 0;
   if(CrossOver(StartIndex()) < 0.0 && CrossOver(StartIndex()+1) > 0.0)
   {  result = int(round(100.0 * ((CrossOver(StartIndex()+1) - CrossOver(StartIndex()))/fmax(fabs(CrossOver(StartIndex()))+fabs(CrossOver(StartIndex()+1)),fabs(CrossOver(StartIndex()+1))+fabs(CrossOver(StartIndex()+2))))));
   }
   return(result);
}

Wie immer scheint es darauf anzukommen, den Ergebniswert zu normalisieren, falls ein potenzielles Signal vorliegt. Für die AM verwenden wir die aktuelle Veränderung der Kreuzungs-Werte geteilt durch den größten Wert der vorherigen Crossover-Werte. Natürlich ist dies ein Bereich, der sehr stark angepasst werden kann, und der Leser kann seine eigene Implementierung wählen, aber die hier gewählte nutzt das arithmetische Mittel und wird daher verwendet.

Der harmonische Durchschnitt der Kauf- und Verkaufs-Bedingungen verwendet wiederum die Divergenzfunktionen, um potenzielle Eröffnungen von Long- und Short-Positionen herauszufiltern. Wir haben die unten angegebenen Kauf- und Verkaufs-Bedingungen:

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CSignalHM::LongCondition(void)
{  int result = 0;
   m_close.Refresh(-1);
   if(Divergence(StartIndex()+1) > 0.0 && m_close.GetData(StartIndex()) > m_close.GetData(StartIndex()+1))
   {  result = int(round(100.0 * (Divergence(StartIndex()+1)/(fabs(Divergence(StartIndex()))+fabs(Divergence(StartIndex()+1))))));
   }
   return(result);
}
//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CSignalHM::ShortCondition(void)
{  int result = 0;
   m_close.Refresh(-1);
   if(Divergence(StartIndex()+1) > 0.0 && m_close.GetData(StartIndex()) < m_close.GetData(StartIndex()+1))
   {  result = int(round(100.0 * (Divergence(StartIndex()+1)/(fabs(Divergence(StartIndex()))+fabs(Divergence(StartIndex()+1))))));
   }
   return(result);
}

Mit dem harmonischen Durchschnitt suchen wir nach einer positiven Divergenz, bei der die Höchstwerte steigen und die Tiefstwerte fallen, gefolgt von einem Kursanstieg des Schlusskurses für einen Kauf oder einem Kursrückgang des Schlusskurses für einen Verkauf. Diese beiden Ereignisse finden nacheinander und nicht auf demselben Balken statt. Diese Divergenz ist in vielerlei Hinsicht das Gegenteil des beliebteren Engulf-Musters, das in der Regel fallende Hochs und steigende Tiefs aufweist.

Sobald wir eine Öffnung haben, entweder für Kauf oder Verlauf, ist die nächste Frage, den ganzzahligen Wert des Ergebnisses zu bestimmen, der immer der Ausgang für die langen und kurzen Bedingungen dieser Signalklassenfunktionen ist. Auch hier gibt es mehrere Ansätze, die zur Quantifizierung des Ergebnisses herangezogen werden können, und mehrere dieser Ansätze könnten sich auf andere Indikatoren als das harmonische Mittel beziehen. Für unsere Zwecke wollen wir uns jedoch noch mehr auf das harmonische Mittel stützen, um den Ergebnisbetrag zu ermitteln. Deshalb verwenden wir ein Verhältnis zwischen der aktuellen Abweichung und der Größe der vorherigen Werte, um einen ganzzahligen Wert im Bereich von 0 bis 100 zu erhalten.

Dieses Ergebnis bedeutet also einfach, dass wir umso optimistischer oder pessimistischer sind, je größer die aktuelle Divergenz ist. Im Nenner dieses Ergebnisverhältnisses (das wir prozentual auf den Bereich 0 - 100 normieren) stehen der aktuelle und der vorherige Divergenzwert. Dies führt uns zur Anwendung des geometrischen Mittels.

Das GM wird durch die Berechnung von oberen und unteren Bollinger-Bändern implementiert, die auf den GM-Puffern basieren, wie oben beschrieben. Um dies als ein umsetzbares Signal zu verwenden, prüfen wir, wie oben erwähnt, ob sich das untere Kursband nach oben und das obere Band nach unten kreuzt, um einen Aufwärtstrend bzw. einen Abwärtstrend zu erkennen. Dies wird in den langen und kurzen Bedingungen wie folgt kodiert:

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CSignalGM::LongCondition(void)
{  int result = 0;
   m_close.Refresh(-1);
   if(m_close.GetData(StartIndex()) > m_close.GetData(StartIndex() + 1) && m_close.GetData(StartIndex()) > BandsDn(StartIndex()) && m_close.GetData(StartIndex() + 1) < BandsDn(StartIndex() + 1))
   {  result = int(round(100.0 * ((m_close.GetData(StartIndex()) - m_close.GetData(StartIndex()+1))/(fabs(m_close.GetData(StartIndex()) - m_close.GetData(StartIndex()+1)) + fabs(BandsUp(StartIndex()) - BandsDn(StartIndex()))))));
   }
   return(result);
}
//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CSignalGM::ShortCondition(void)
{  int result = 0;
   m_close.Refresh(-1);
   if(m_close.GetData(StartIndex()) < m_close.GetData(StartIndex() + 1) && m_close.GetData(StartIndex()) < BandsUp(StartIndex()) && m_close.GetData(StartIndex() + 1) > BandsUp(StartIndex() + 1))
   {  result = int(round(100.0 * ((m_close.GetData(StartIndex()+1) - m_close.GetData(StartIndex()))/(fabs(m_close.GetData(StartIndex()) - m_close.GetData(StartIndex()+1)) + fabs(BandsUp(StartIndex()) - BandsDn(StartIndex()))))));
   }
   return(result);
}

Die Größe des Ergebnisses, wie wir sie mit dem arithmetischen Mittel und dem harmonischen Mittel verfolgt haben, wird sich auch eher an das geometrische Mittel anlehnen und keinen anderen Indikator verwenden. Daher ist das Ergebnis bei GM ein Verhältnis zwischen der Veränderung des Schlusskurses und dem Abstand zwischen dem oberen und dem unteren Band unserer abgeleiteten Bollinger-Bänder. Auch hier bedeutet dieses Ergebnis, dass eine größere Kursbewegung im Verhältnis zur Kompression der Bandlücke ein größeres Einstiegs- oder Schließungssignal anzeigen sollte. Schließ-Signal, weil die Kauf- und Verkaufs-Bedingung nicht nur die Eröffnungsschwellen festlegt, sondern auch die Schwelle bestimmt, bei der ihre umgekehrten Positionen geschlossen werden. In den Eingabeeinstellungen gibt es also immer einen Schwellenwert zum Eröffnen und zum Schließen. Letzterer sollten geringer sein als erstere, da Sie Kauf-Positionen schließen wollen, bevor Sie Verkaufs-Positionen eingehen und umgekehrt.

Darüber hinaus könnten mögliche alternative Implementierungen der von GM abgeleiteten Bollinger-Bänder bei der Festlegung eines Signals Optionen in Betracht ziehen, die die Größe der Lücke zwischen dem oberen und dem unteren Band mit der Neigung des Basislinien-Durchschnitts und einigen anderen Iterationen verfolgen. Unsere Anwendung hier ist nicht die einzige Art und Weise, wie wir die Bollinger-Bänder verwenden oder betrachten können.


Strategieprüfung und Leistungsbewertung

Wir werden also zunächst unabhängige Testläufe mit jedem gleitenden Pythagoras-Durchschnitt allein in einem Expert Advisor durchführen. Sobald wir die unabhängigen Ergebnisse jedes einzelnen haben, führen wir einen Testlauf eines Expert Advisors durch, der mit allen drei Signalen des gleitenden Pythagoras-Durchschnitts zusammengestellt ist, und optimieren diesen Expert Advisor, um die relative Gewichtung jedes unserer Durchschnitte zu ermitteln.

Aus Gründen der Einheitlichkeit werden wir Tests mit einem Symbol EURJPY auf dem 20-Minuten-Zeitrahmen für das Jahr 2023 durchführen. Für das arithmetische Mittel erhalten wir folgende Ergebnisse:

r1

c1

Für das harmonische Mittel ergibt sich folgendes:

r2

c2

Und für das geometrische Mittel gilt schließlich Folgendes:

r3

c3

Aus der unabhängigen Performance geht hervor, dass der geometrische Durchschnitt am stärksten ist, gefolgt vom einfachen arithmetischen Mittel und dem Schlusslicht, der harmonischen Durchschnittdivergenz. Unsere Ergebnisse werden natürlich durch die Tatsache beeinflusst, dass wir über ein sehr kleines Zeitfenster testen und spezifische Anpassungen bei der Interpretation und Implementierung der Einstiegssignale für jedes der Mittel vorgenommen haben. Es sind eindeutig weitere Tests erforderlich, um Schlussfolgerungen zur relativen Leistung zu ziehen, aber dies deutet auf eine relativ große Leistungsvariabilität hin, was ein vielversprechendes Signal für erste Tests sein kann.

Wenn wir nun Tests mit allen drei Durchschnittswerten durchführen und versuchen, sie für die relative Gewichtung zu optimieren, erhalten wir als eines der besseren Ergebnisse folgendes:

r4

c4

Es ist klar, dass die unabhängigen Ergebnisse des geometrischen Mittels immer noch das Glockenspiel sind, natürlich vorbehaltlich der Prüfung über längere Zeiträume. Interessanterweise - oder ironischerweise - muss dem besten unabhängigen Signal die geringste Gewichtung von 0,4 gegeben werden, damit alle 3 Signale zusammen funktionieren. Die unabhängigen Nachzügler des harmonischen Mittels und des arithmetischen Mittels werden mit 1,0 und 0,9 stärker gewichtet, was erklären könnte, warum die Gesamtleistung aller drei Durchschnittswerte zusammen nicht nur geringer ist als die unabhängige Leistung des geometrischen Mittels, sondern die Leistung des GM auch dann noch besser ist, wenn man die unabhängigen Leistungen des arithmetischen und des harmonischen Mittels addiert. Die Einstellungen für den kombinierten Expert Advisor werden im Folgenden erläutert:

s_alle


Schlussfolgerung

Wie bereits erwähnt, sind ausführliche Tests, vorzugsweise über längere Zeiträume, immer gerechtfertigt und sicherer als ein Versuch mit wenigen Tests, wie z. B. dem hier vorliegenden von einem Jahr. Wie immer stellen wir den beigefügten Code für diese Signale nach den Richtlinien zusammen, die Sie in den Artikeln hier und hier finden können. Der geometrische Durchschnitt, der von den drei in diesem Artikel betrachteten Durchschnitten am stärksten auf kleinere Werte ausgerichtet ist, ist in der Bollinger-Band-Umgebung vielversprechend, wir haben jedoch den harmonischen Durchschnitt in einer ähnlichen Band-Umgebung nicht untersucht, um definitivere Schlussfolgerungen zu dieser relativen Leistung ziehen zu können. Außerdem gibt es neben den Bollinger-Bändern, dem AM-Crossover oder der HM-Divergenz noch andere gleitende Durchschnitte in Form von Oszillatoren wie den OSMA oder TRIX die wir nicht untersucht haben. Diese und andere Methoden können bei der Abwägung des relativen Potenzials der pythagoreischen Durchschnitte berücksichtigt werden.


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

Beigefügte Dateien |
SignalWZ_24_AM.mqh (8.42 KB)
SignalWZ_24_HM.mqh (8.35 KB)
SignalWZ_24_GM.mqh (8.72 KB)
pyth_all.mq5 (7.72 KB)
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Automatisierte Parameter-Optimierung für Handelsstrategien mit Python und MQL5 Automatisierte Parameter-Optimierung für Handelsstrategien mit Python und MQL5
Es gibt mehrere Arten von Algorithmen zur Selbstoptimierung von Handelsstrategien und Parametern. Diese Algorithmen werden zur automatischen Verbesserung von Handelsstrategien auf der Grundlage historischer und aktueller Marktdaten eingesetzt. In diesem Artikel werden wir uns eine davon mit Python und MQL5-Beispielen ansehen.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Beherrschung der Marktdynamik: Erstellen eines Expert Advisors (EA) mit Unterstützungs- und Widerstandsstrategie Beherrschung der Marktdynamik: Erstellen eines Expert Advisors (EA) mit Unterstützungs- und Widerstandsstrategie
Ein umfassender Leitfaden zur Entwicklung eines automatisierten Handelsalgorithmus auf der Grundlage einer Unterstützungs- und Widerstandsstrategie. Detaillierte Informationen zu allen Aspekten der Erstellung eines Expert Advisors in MQL5 und dem Testen in MetaTrader 5 - von der Analyse des Preisbereichsverhaltens bis zum Risikomanagement.