English Русский 中文 Español 日本語 Português 한국어 Français Italiano Türkçe
Entdecken der Trading-Strategieklassen der Standard Library - Anpassungsstrategien

Entdecken der Trading-Strategieklassen der Standard Library - Anpassungsstrategien

MetaTrader 5Handelssysteme | 5 Mai 2016, 13:33
1 258 0
Harvester Trading
Harvester Trading

Einleitung

Dieser Artikel richtet sich an Anfänger/Einsteiger, die eine teilweise funktionale Anpassung anstreben, ohne einen eigenen, völlig neuen EA schreiben zu wollen.

Mit MetaTrader 5 steht uns ein mächtiges Werkzeug zur Verfügung, das es uns erlaubt, ohne große (wenn überhaupt) Coding- oder Programmiersprachenkenntnisse professionell zu traden. All dies dank einem besonderen MetaTrader Editor-Feature: MQL5-Assistent. Der Assistent - auf dessen Inhalt/Funktionsweise wir nicht in vorliegendem Artikel eingehen werden - dient dazu, vollständige Programme (.mq5 & .ex5 Dateien), Algorithmen und Codes zu generieren. Er profitiert dabei von der Benutzung von MQL5 Standard Library sowie dessen Trading-Strategieklassen (die beide hervorragende Hilfsmittel darstellen).

Entdecken der Trading-Strategieklassen der Standard Library Anpassungsstrategien

Standard Library weist bereits eine ganze Menge an Trading-Strategiekassen auf: Einige davon erscheinen außerordentlich brauchbar und basieren auf mehr oder weniger berühmten Studien über die Finanzmärkte / Wirtschaftlichkeitsbetrachtungen. Es gibt mindestens eine Strategie für jeden einzelnen Indikator des standardisierten Indikatorsets von MetaTrader 5.

Um Handelssignale dieser Trading-Strategieklassen zu etablieren, bedient sich der MQL5 -Assistent eines Mechanismus, der auf einem Indikatorverhalten basiert, das einem logischen Code in Form von „Trading-Mustern“ entspringt. Jeder spezifisch erstellte Expert Adivsor greift auf diese Indikatoren (via #include-Instruktionen) und ihre Sets an Mustern und Trading-Entscheidungen zu, die dann zum Zwecke des Tradens in den Kern des EA importiert werden.



Der MQL5-Assistent

Im einem ersten Schritt geht es darum, mithilfe des MQL5-Assistenten einen Expert Advisor zu kreieren. Um den MQL5-Assistenten mittels MetaEditor zu öffnen, klicken Sie bitte auf „Neu“ unter „Datei“ oder wählen Sie den „Neu“-Button und daraufhin den „Expert Advisor (generieren)“-Button.

Abbildung 1. Neue Datei anlegen („generieren“ im Assistenten auswählen)

Lassen Sie uns den vom MQL5-Assistenten generierten Expert Advisor auf den Namen „MyExpert“ taufen.

Abbildung 2. Im MQL5-Assistenten erstellte/r EA-Name und -Parameter

Nun fügen wir zwei Indikatoren/Signale hinzu, um mit diesen zu arbeiten (Sie können aus der Liste verfügbarer Indikatoren so viele Bedingungen auswählen, wie sie wollen). In unserem Beispiel fügen wir zwei relativ bekannte Indikatoren hinzu: den Relative-Strength-Index (RSI) und den Moving Average (MA). Fügen Sie zunächst den RSI- und im Anschluss daran den MA-Indikator hinzu.

Abbildung 3. Wählen Sie zuerst RSI und dann MA an

Wir können nun einige Parameter nach eigenen Wünschen festsetzen, oder wir behalten die Voreinstellungen bei.

Abbildung 4. Signale der Parameter

Nun klicken wir auf OK und fahren mit unserem Assistenten fort, indem wir im nächsten Fenster (für den Moment) nicht Trailing-Stopp wählen. Gleichwohl können Sie dies natürlich tun, da es den Inhalt dieses Artikels nicht tangiert. Im nächsten Fenster wählen wir 5.0%-Trading sowie 0.1-Lot. Auch hier gilt, dass sie letztendlich beliebige Parameter auswählen können, da die Wahl keinen Einfluss auf die Botschaft vorliegenden Artikels hat.



Den generierten Code analysieren

Nach der Fertigstellung sollten Sie eine „MyExpert.mq5“-Datei erhalten. Sehen wir uns den Hauptteil des generierten Codes mal genauer an.

//+------------------------------------------------------------------+
//|                                                     MyExpert.mq5 |
//|                                                        Harvester |
//|                        https://www.mql5.com/en/users/Harvester |
//+------------------------------------------------------------------+
#property copyright "Harvester"
#property link      "https://www.mql5.com/en/users/Harvester"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\SignalRSI.mqh>
#include <Expert\Signal\SignalMA.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedLot.mqh>

Nehmen Sie bitte zunächst die #include-Dateien zur Kenntnis, die dem generierten Code via Assistent hinzugefügt wurden. Nun sehen wir Folgendes:

  • Expert.mqh
  • SignalRSI.mq
  • SignalMA.mqh

Betrachten wir uns nun folgendes Codesegment:

//--- Creating filter CSignalRSI
   CSignalRSI *filter0=new CSignalRSI;
   if(filter0==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter0");
      ExtExpert.Deinit();
      return(-3);
     }
   signal.AddFilter(filter0);

Wie der Titel bereits suggeriert, handelt es sich um eine Art von „Filter“, der auf die Marktkonditionen des generierten EA angewendet wird, der entweder einem Chart anzuhängen oder im Strategietester zu testen ist. Der Filter0 ist der erste Filter, der den „Index“ 0 aufweist. Genau für diesen ersten Filter haben wir in unserem Beispiel RSI ausgewählt.

CSignalRSI bedeutet hierbei Class Signal RSI. Diese Kategorie dient dazu, den RSI-Indikator zu bezeichnen und einige Bedingungen auf ihn anzuwenden, um Kauf- oder Verkaufssignale via Logikmuster des Assistenten zu erzeugen. RSI stellt somit unseren ersten Filter dar (mit der Filternummer 0).

Im folgenden Abschnitt des Codes gibt es einige Filterparameter, dann einen Trailing Stop-Abschnitt - wobei wir uns gegen Trailing entschieden haben - und später den Codeabschnitt, der sich mit Money Management beschäftigt.

Machen wir mit dem Folgenden weiter:

//--- Tuning of all necessary indicators
   if(!ExtExpert.InitIndicators())
     {
      //--- failed
      printf(__FUNCTION__+": error initializing indicators");
      ExtExpert.Deinit();
      return(-10);
     }
//--- ok
   return(0);
  }

Dieser Abschnitt ist ganz der Expert.mqh include-Datei gewidmet. Hier geht es um die Initialisierung der Indikatoren, die für die Expert-Operationen notwendig sind.

Der letzte Abschnitt des generierten EA-Codes befasst sich mit der Deinitialisierung und anderen Expert Advisor-Ereignissen:

//+------------------------------------------------------------------+
//| Deinitialization function of the expert                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ExtExpert.Deinit();
  }
//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
   ExtExpert.OnTick();
  }
//+------------------------------------------------------------------+
//| "Trade" event handler function                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
   ExtExpert.OnTrade();
  }
//+------------------------------------------------------------------+
//| "Timer" event handler function                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   ExtExpert.OnTimer();
  }
//+------------------------------------------------------------------+

Tatsächlich verwendet der vorliegende EA zwei Indikatoren (RSI und MA) für Handelsentscheidungen durch die Trading-Klassen-Standard Libary, die auf den beiden Logiken „Filter“ und „Gewichte“ basieren. Mehr Informationen hierzu finden Sie unter Module von Handelssignalen im MQL5-Verweisverzeichnis. Allerdings haben wir das Ziel, unsere eigene Trading-Strategie als neuen Filten zu verwenden.

Der erste Schritt hinsichtlich der Verwendung unserer eigenen Trading-Strategien besteht darin, die MyExpert.mq5-Datei leicht modifizieren. Lassen Sie uns zunächst einmal einen anderen Filter hinzufügen. Es handelt sich hierbei um den filter2, den wir direkt hinter den filter1-Code platzieren.

//--- Creating filter CSignalCCIxx
   CSignalCCIxx *filter2=new CSignalCCIxx;
   if(filter2==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter2");
      ExtExpert.Deinit();
      return(-4);
     }
   signal.AddFilter(filter2);
//--- Set filter parameters
   filter2.PeriodCCIxx(Signal_CCIxx_PeriodCCI);
   filter2.Applied(Signal_CCIxx_Applied);
   filter2.Weight(Signal_CCIxx_Weight);

Lassen Sie uns zu den #include-Dateien zurückkehren, die den Kern dieser Filter und der Marktentscheidungen darstellen. Bei der ersten handelt es sich um die Datei #include <Expert\Expert.mqh>. Diese include-Datei enthält ihrerseits einige Dateien.

  • #include "ExpertBase.mqh“
  • #include "ExpertTrade.mqh“
  • #nclude "ExpertSignal.mqh“
  • #include "ExpertMoney.mqh“
  • #include "ExpertTrailing.mqh“

Diese Dateien stellen die Grundstruktur des EA, also die Trading-Struktur, das Signal, Geld und die Trailing Stop-Bedienung dar. Wir werden diese Dateien an dieser Stelle nicht weiter untersuchen oder modifizieren. Wir konzentrieren uns vielmehr darauf, unsere eigenen Strategien hinzuzufügen, indem wir existierende Indikatoren des standardisierten MetaTrader 5-Indikatorsets benutzen und ihre include-Dateien hinzufügen.

Der MyExpert.mq5 Code beherbergt die #include-Dateien der RSI- und MA-Indikatoren, die uns in unserem Beispiel als Signale/Filter für die Trading-Marktentscheidungen dienten. Lassen Sie uns an dieser Stelle unsere eigenen modifizierten include-Dateien hinzufügen. Zu diesem Zwecke verwenden wir eine modifizierte - also eine „verbesserte“ - Version von Signalen, die zu dem CCI-Indikator gehören.

//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\SignalRSI.mqh>
#include <Expert\Signal\SignalMA.mqh>

#include <Expert\Signal\SignalCCIxx.mqh>   // This is our own 'custom' indicator for custom Signal management of the EA

Die SignalCClxx.mqh-Datei sollte in den \MQL5\Include\Expert\Signal\-Ordner kopiert werden und sollte gleichsam in den (durch den Assistenten generierten) EA integrierbar sein - genauso wie all die anderen Standard Library-#include Trade Classes-Signaldateien, die sich bereits in diesem Ordner befinden (SignalRSI.mqh und SignalMA.mqh).

Hierfür kopieren wir beispielsweise die ursprüngliche CCI-Datei, legen eine weitere an - die wir CCIxx nennen, die ein paar modifizierte Zeilen Code aufweist und die wir als #include-Datei verwenden. Wir werden nun der Einfachheit halber eine kopierte Version des CCI-Indikator der Standard Library verwenden.

Hierzu kopieren wir die Datei "\MQL5\Include\Expert\Signal\SignalCCI.mqh“ in die Datei "\MQL5\Include\Expert\Signal\SignalCCIxx.mqh". Der leichteste Weg, dies zu tun, ist das Anlegen einer Kopie, die daraufhin umbenannt wird.

Sehen wir uns diese Datei nun etwas genauer an. Eine Integration dieser „benutzerdefinierten“ Version in den Assistenten wurde bereits bewerkstelligt. Wir haben - wie oben erwähnt - den filter2-Code hinzugefügt und werden nun wie folgt fortfahren. Wir werden werden nicht länger die MyExpert.mq5-, sondern von nun an die SignalCCIxx.mqh-Datei fokussieren, die den tatsächlichen Kern des EAs aufgrund des filter2-Handelsignals des CCI-Indikators darstellt.



Anpassungsstrategien

Wir setzen nun das Hinzufügen des „halb-angepassten“ Strategiefilters, den wir CCIxx nennen (eine modifizierte Version von SignalCCI.mqh) fort. Ich wähle den Begriff halb-angepasst, da es sich eigentlich nicht um ein komplett neues Signal, sondern eher um eine modifizierte Version eines CCI-Indikators des Standardindikatorsets von MetaTrader 5 handelt. Auf diese Weise können selbst unerfahrene Benutzer und Programmierer Muster und Filter eines (durch einen MQL5-Assistenten erstellten) EAs leicht modifizieren, indem Sie auf die große Menge an bereits existierenden Indikatoren zurückgreifen. Mit anderen Worten können Sie Ihre eigenen Filter- und Muster-Versionen zum Generieren von Kauf- oder Verkaufsmarktsignalen erstellen. Dennoch handelt es sich um eine exzellente Basis für das Arbeiten mit Strategien.

Sehen wir uns das Beispiel an. Für all jene, die in an der Meisterschaft für Automatisiertes Trading 2011 teilnehmen wollen und die ein Feature suchen, mit dem sie existierenden Indikatoren benutzerdefinierte Muster hinzufügen können, bietet es sich an, schnell und sicher selbsterstellte, zulässige EAs durch den Assistenten generieren zu lassen.

Dies kann innerhalb einer einzigen Arbeitsstunde erreicht werden - die Generierung eines meisterschaftsgeeigneten EAs, der alle Funktionen aufweist, die für ein professionelles Trading (Money Management, Trailing Stop,...) notwendig sind. Auf den vom Assistenten generierten EA zurückkommend, bedeutet dies, dass der generierte Code frei von Fehlern sein muss, auf dass die Teilnehmer nichts korrigieren sowie keine Angst vor etwaigen Bugs haben müssen.

Der EA wird einfach so los-traden und wird perfekt fürs Traden geeignet sein, zumindest für all jene, die teilnehmen möchten, aber keine Ahnung vom Programmieren haben und keinen EA unter Job-Service (eine gute Alternative zur Teilnahme an einer Meisterschaft) ordern möchten. Es gibt eine große Palette an Input-Parametern, die zugewiesen werden können, um den Roboter an die Strategie, die Sie im Kopf haben, anzupassen.

Allerdings können Sie lediglich das Standardset von Indikatoren mit dem Standardset von Filtern und Mustern verwenden, das von MetaQuotes via Assistent und den Trading-Strategieklassen der Standard Library bereitgestellt wird. Dies ermöglicht eine große Anzahl an Kombinationsmöglichkeiten für ein erfolgreiches Traden, da Indikatoren viele Parameter (Zeitrahmen, Symbole) sowie die Parameter der Indikatoren selbst (wie beispielsweise Periode, Angewandter Preis, usw.) haben. Sie werden in diesem Artikel lernen, wie Sie MetaTrader 5-Standardindikator-Muster/Filter selbst modifizieren und hinzufügen können.

Kommen wir nun zur Datei SignalCCIxx.mqh, um deren Verhalten anzupassen, um somit letztendlich unser eigenes CCI-Signal-Trading-Modell (CCIxx) zu erstellen. Lassen Sie uns hierfür zunächst in der MyExpert.mq5-Datei neue Variablen für den Code im Input-Abschnitt ähnlich des folgenden Beispiels hinzufügen:

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string             Expert_Title         ="MyExpert";  // Document name
ulong                    Expert_MagicNumber   =26287;       // 
bool                     Expert_EveryTick     =false;       // 
//--- inputs for main signal
input int                Signal_ThresholdOpen =40;          // Signal threshold value to open [0...100]
input int                Signal_ThresholdClose=60;          // Signal threshold value to close [0...100]
input double             Signal_PriceLevel    =0.0;         // Price level to execute a deal
input double             Signal_StopLevel     =50.0;        // Stop Loss level (in points)
input double             Signal_TakeLevel     =50.0;        // Take Profit level (in points)
input int                Signal_Expiration    =4;           // Expiration of pending orders (in bars)
input int                Signal_RSI_PeriodRSI =8;           // Relative Strength Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_RSI_Applied   =PRICE_CLOSE; // Relative Strength Index(8,...) Prices series
input double             Signal_RSI_Weight    =0.7;         // Relative Strength Index(8,...) Weight [0...1.0]
input int                Signal_MA_PeriodMA   =90;          // Moving Average(12,0,...) Period of averaging
input int                Signal_MA_Shift      =0;           // Moving Average(12,0,...) Time shift
input ENUM_MA_METHOD     Signal_MA_Method     =MODE_SMA;    // Moving Average(12,0,...) Method of averaging
input ENUM_APPLIED_PRICE Signal_MA_Applied    =PRICE_CLOSE; // Moving Average(12,0,...) Prices series
input double             Signal_MA_Weight     =0.6;         // Moving Average(12,0,...) Weight [0...1.0]

input int                Signal_CCIxx_PeriodCCI =8;            // Commodity Channel Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_CCIxx_Applied   =PRICE_CLOSE;  // Commodity Channel Index(8,...) Prices series
input double             Signal_CCIxx_Weight    =0.8;          // Commodity Channel Index(8,...) Weight [0...1.0]

Wir haben die Werte der Signal_RSI_Weight- und Signal_MAI_Weight-Variablen von 1.0 zu 0.7 und 0.6 geändert sowie zusätzlich die obigen, hervorgehobenen Zeilen hinzugefügt. Um mit den Input-Parametern der modifizierten CCIxx-Version des Musters, das zu dem CCI-Indikator der Trading Strategy-Klassen gehört, korrekt arbeiten zu können, haben wir diese drei Zeilen Code von der SignalCCI.mqh-Datei kopiert und einfach das Postfix „xx“ an „CCI“ angehangen.

In dem „geschützten“ Abschnitt der Klassendefinition gibt es viele verschiedene, interessante Elemente:

class CSignalCCI : public CExpertSignal
  {
protected:
   CiCCI             m_cci;            // object-oscillator
   //--- adjusted parameters
   int               m_periodCCI;      // the "period of calculation" parameter of the oscillator
   ENUM_APPLIED_PRICE m_applied;       // the "prices series" parameter of the oscillator
   //--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "reverse behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "divergence of the oscillator and price"
   int               m_pattern_3;      // model 3 "double divergence of the oscillator and price"
   //--- variables
   double            m_extr_osc[10];   // array of values of extremums of the oscillator
   double            m_extr_pr[10];    // array of values of the corresponding extremums of price
   int               m_extr_pos[10];   // array of shifts of extremums (in bars)
   uint              m_extr_map;       // resulting bit-map of ratio of extremums of the oscillator and the price

Sehen Sie sich die m_pattern genannten Int-Typen an. Diese Variablen sind progressiv von 0 bis 3 nummeriert, jede von ihnen entspricht einem „Muster“ oder, anders gesagt, einem Modell der Marktentscheidungsbedingungen betreffend den Kauf oder Verkauf eines Finanzinstruments.

Wir werden 2 angepasste Muster hinzufügen: m_pattern_4 und m_pattern_5. Hierfür müssen wir einfach nur zwei zusätzliche Zeilen Code hinzufügen: zwei Variablen des Typs Integer.

//--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "reverse behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "divergence of the oscillator and price"
   int               m_pattern_3;      // model 3 "double divergence of the oscillator and price"

   int               m_pattern_4;      // model 4 "our own first new pattern: values cross the zero"
   int               m_pattern_5;      // model 5 "our own second new pattern: values bounce around the zero"

Wenn Sie den Code im Auge behalten, werden Sie die Logik hinter Kaufen, Verkaufen, usw. verstehen. Aber wir werden uns an dieser Stelle nur auf den Abschnitt konzentrieren, wie Sie Muster hinzufügen, da wir nicht auf jede einzelne Zeile der include-Dateien eingehen werden (ein MQL-Verweis-Tool kann Ihnen beim Studium dieser Dateien, indem Sie sie selbst öffnen, gute Dienste leisten).

Wir möchten außerdem Folgendes tun: Suchen Sie in der CSignalCCIxx.mqh-Datei durch den Befehl CTRL+H nach „CCI" und ersetzen Sie den Eintrag durch „CCIxx". Gehen Sie nun auf „Alle ersetzen“, wodurch 41 Einträge geändert werden sollten. Gehen wir zum oberen Teil der Datei:

//+------------------------------------------------------------------+
//| Class CSignalCCIxx.                                              |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Commodity Channel Index' oscillator.               |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalCCIxx : public CExpertSignal
  {
protected:
   CiCCIxx             m_CCIxx;            // object-oscillator

und ändern Folgendes:

protected:
   CiCCIxx             m_CCIxx;            // object-oscillator

entsprechend der originalen SignalCCI.mqh-Datei:

protected:
   CiCCI             m_CCIxx;            // object-oscillator

Wir tun dies, da CiCCI von einer anderen include-Datei aufgerufen wird; und, falls wir den Namen ändern, wir augenscheinlich mehrere Fehlermeldungen erhalten. Nun können wir die SignalCCIxx.mqh-Datei kompilieren, ohne dass wir auch nur eine einzige Warnung oder einen einzigen Fehler erhalten. Falls dennoch Fehler/Warnungen auftreten sollten, haben Sie einen Fehler gemacht. Bitte wiederholen Sie die Prozedur in diesem Fall.

Kommen wir nun zum Kern des Hinzufügens von Mustern. Aus purer Lust an der Freude fügen wir 2 Market Trading-Verhaltensmuster hinzu. Insgesamt erhalten wir somit 4 neue Signale (Muster), 2 derselben Art für Kaufen und 2 derselben Art für Verkaufen. Der nun zu ändernde Teil ist der Folgende:

//+------------------------------------------------------------------+
//| Constructor CSignalCCIxx.                                        |
//| INPUT:  no.                                                      |
//| OUTPUT: no.                                                      |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
void CSignalCCIxx::CSignalCCIxx()
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
//--- setting default values for the oscillator parameters
   m_periodCCIxx  =14;
//--- setting default "weights" of the market models
   m_pattern_0  =90;         // model 0 "the oscillator has required direction"
   m_pattern_1  =60;         // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =100;        // model 2 "divergence of the oscillator and price"
   m_pattern_3  =50;         // model 3 "double divergence of the oscillator and price"
   m_pattern_4  =90;         // model 4 "our own first new pattern: "
   m_pattern_5  =90;         // model 5 "our own second new pattern: 
}

Wir haben den Mustern m_pattern_4 und m_pattern_5 den Wert 90 zugewiesen, allerdings sollten oder vielmehr müssen Sie diese mit Ihren eigenen Werten versehen: Es handelt sich dabei um die Gewichte, die Sie Ihren Marktmodellen zuweisen wollen, da sie das Trading-Verhalten Ihres Roboters regeln.

Lassen Sie uns aus Spaß zwei neue Marktmodelle hinzufügen. Zwei ganz simple, die uns lediglich zu Forschungszwecken dienen sollen und bei denen es sich nicht um realexistierende Handelssignale handelt (also versuchen Sie bitte nicht, mit ihnen zu traden). Das Fadenkreuz wird uns dabei helfen, die Werte des CCI-Indikators für die entsprechenden Balken in den unteren Figuren zu identifizieren.



Erstes Muster

Durchquerung der Null-Linie von unten nach oben

Hier haben wir unser erstes Muster für: „Votum, dass der Preis steigen wird“.

  • Abb. 5 zeigt den CCI-Wert, der mit Balken 1 korrespondiert (ein Balken vor dem aktuellen). Dessen Wert beträgt 45.16, also > 0.
  • Abb. 6 zeigt den CCI-Wert, der mit Balken 2 korrespondiert (zwei Balken vor dem aktuellen). Dessen Wert betrug -53.92, also < 0.
  • Die Null-Linie (Wert 0.00) des CCI-Indikators wurde von unten nach oben innerhalb von 2 Balken durchquert.

Abbildung 5. Unser erstes Muster: Preisanstieg - CCI in Balken 1   Abbildung 6. Unser erstes Muster: Preisanstieg - CCI in Balken 2

Die Null-Linie von oben nach unten durchqueren

Hier haben wir unser erstes Muster für: „Votum, dass der Preis fallen wird“.

  • Abb. 7 zeigt den CCI-Werte, der mit Balken 1 korrespondiert (ein Balken vor dem aktuellen). Dessen Wert beträgt -28.49, also < 0.
  • Abb. 8 zeigt den CCI-Wert, der mit Balken 2 korrespondiert (zwei Balken vor dem aktuellen). Dessen Wert betrug 2.41, also > 0.
  • Die Null-Linie (Wert 0.00) des CCI-Indikators wurde von oben nach unten innerhalb von 2 Balken durchquert.

Abbildung 7. Unser erstes Muster: Preisrückgang - CCI in Balken 1   Abbildung 8. Unser erstes Muster: Preisrückgang - CCI in Balken 2



Zweites Muster

Durchquerung der Null-Linie von oben nach unten und wieder zurück nach oben

Hier nun unser zweites Muster für: „Votum, dass der Preis steigen wird“.

  • Abb. 9 zeigt den CCI-Wert, der mit Balken 1 korrespondiert (ein Balken vor dem aktuellen). Dessen Wert beträgt 119.06, also > 0.
  • Abb. 10 zeigt den CCI-Wert, der mit Balken 2 korrespondiert (zwei Balken vor dem aktuellen). Dessen Wert betrug -20.38, also < 0.
  • Abb. 11 zeigt den CCI-Wert, der mit Balken 3 korrespondiert (drei Balken vor dem aktuellen). Dessen Wert betrug 116.85, also wieder > 0.
  • Die Null-Linie (Wert 0.00) des CCI-Indikators wurde von oben nach unten durchquert. Dann kehrte die CC-Indikatorlinie wieder zurück nach oben und springt an der Null-Linie innerhalb von drei Balken wild umher.

Abbildung 9. Unser zweites Muster: Preisanstieg - CCI in Balken 1   Abbildung 10. Unser zweites Muster: Preisanstieg - CCI in Balken 2   Abbildung 10. Unser zweites Muster: Preisanstieg - CCI in Balken 3

Durchquerung der Null-Linie von unten nach oben und wieder zurück nach unten

Hier nun unser zweites Muster für: „Votum, dass der Preis fallen wird“.

  • Abb. 12 zeigt den CCI-Wert, der mit Balken 1 korrespondiert (ein Balken vor dem aktuellen). Dessen Wert beträgt -58.72, also < 0.
  • Abb. 13 zeigt den CCI-Wert, der mit Balken 2 korrespondiert (zwei Balken vor dem aktuellen). Der Wert betrug 57.65 , also > 0.
  • Abb. 14 zeigt den CCI-Wert, der mit Balken 3 korrespondiert (drei Balken vor dem aktuellen). Der Wert betrug -85.54, also wieder < 0.
  • Die Null-Linie (Wert 0.00) des CCI-Indikators wurde von unten nach oben durchquert. Dann kehrte die CC-Indikatorlinie wieder zurück nach unten und springt an der Null-Linie innerhalb von drei Balken wild umher.

Abbildung 12. Unser zweites Muster: Preisrückgang - CCI in Balken 1   Abbildung 13. Unser zweites Muster: Preisrückgang - CCI in Balken 2   Abbildung 14. Unser zweites Muster: Preisrückgang - CCI in Balken 3



Muster Implementieren

Um diese 4 Bedingungen zu implementieren (2 pro Muster), müssen wir den folgenden Codeabschnitt wie folgt modifizieren. Unten haben wir die hervorgehobenen Codezeilen für die Kauf-Bedingung hinzugefügt (siehe obiger Kommentar: „Votum, dass der Preis steigen wird“).

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//| INPUT:  no.                                                      |
//| OUTPUT: number of "votes" that price will grow.                  |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
int CSignalCCIxx::LongCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(Diff(idx)>0.0)
     {
      //--- the oscillator is directed upwards confirming the possibility of price growth
      if(IS_PATTERN_USAGE(0)) result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
      if(IS_PATTERN_USAGE(1) && Diff(idx+1)<0.0 && CCIxx(idx+1)<-100.0)
         result=m_pattern_1;      // signal number 1
      //--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
      if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
        {
         ExtState(idx);
         //--- if the model 2 is used, search for the "divergence" signal
         if(IS_PATTERN_USAGE(2) && CompareMaps(1,1))      // 00000001b
            result=m_pattern_2;   // signal number 2
         //--- if the model 3 is used, search for the "double divergence" signal
         if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2))   // 00010001b
            return(m_pattern_3);  // signal number 3
        }
      // if the model 4 is used, look for crossing of the zero line
      if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0)
         result=m_pattern_4;      // signal number 4 
      // if the model 5 is used, look for the bouncing around the zero line
      if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0 && CCIxx(idx+3)>0.0)
         result=m_pattern_5;      // signal number 5
     }
//--- return the result
   return(result);
  }

Lassen Sie uns nun den entsprechenden Codeabschnitt für die Verkauf-Bedingung modifizieren. Unten haben wir die hervorgehobenen Codezeilen für die Verkauf-Bedingung hinzugefügt (siehe obiger Kommentar: „Votum, dass der Preis fallen wird“).

//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//| INPUT:  no.                                                      |
//| OUTPUT: number of "votes" that price will fall.                  |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
int CSignalCCIxx::ShortCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(Diff(idx)<0.0)
     {
      //--- the oscillator is directed downwards confirming the possibility of falling of price
      if(IS_PATTERN_USAGE(0)) result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
      if(IS_PATTERN_USAGE(1) && Diff(idx+1)>0.0 && CCIxx(idx+1)>100.0)
         result=m_pattern_1;      // signal number 1
      //--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
      if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
        {
         ExtState(idx);
         //--- if the model 2 is used, search for the "divergence" signal
         if(IS_PATTERN_USAGE(2) && CompareMaps(1,1))      // 00000001b
            result=m_pattern_2;   // signal number 2
         //--- if the model 3 is used, search for the "double divergence" signal
         if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2))   // 00010001b
            return(m_pattern_3);  // signal number 3
        }
      if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)<0.0 && CCIxx(idx+2)>0.0)
         result=m_pattern_4;      // signal number 4 
      if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)<0.0 && CCIxx(idx+2)>0.0 && CCIxx(idx+3)<0.0)
         result=m_pattern_5;      // signal number 5  
     }
//--- return the result
   return(result);
  }

Die (idx+1) oder (idx+2) ... (Idx+n) der letzten, hinzugefügten Zeilen erscheint recht simpel, ist allerdings ein wichtiger Punkt: +1, +2, +3, usw. stellt einfach nur die Anzahl der Balken vor dem aktuellen dar (der aktuelle ist die brennende "Kerze", der nullte Balken).

Abbildung 15. Balken (Kerzen) korrespondieren mit der (idx) Variable im Code.

Ergo: je mehr idx+N, umso mehr Balken gehen wir zurück. Jeder Balken (idx+n) korrespondiert mit dem Indikatorwert der selben „vertikalen“ Position im selben Zeitfenster.

Abbildung 16. Jeder Balken (idx+n) korrespondiert mit dem relativen CCI-Wert

In der Abb. 16 hat der nullte Balken (die Kerze, die sich am weitesten rechts befindet und im Code mit idx oder [idx+0] korrespondiert) den korrespondierenden CCI-Wert unter 0.00. Ferner hat der zweite (idx+1) als auch der dritte Balken (idx+2) einen Wert, der jeweils unter der Null-Linie liegt. Wir haben nun andere Balken mit einem vertikalen Pfeil markiert, aber wenn Sie Ihre Maus über den vierten Balken (idx+3) drüber halten, dann Sehen Sie, dass dessen korrespondierender CCI-Wert über 0.00 liegt.

Für die meisten Benutzer ist dieser Fakt offensichtlich. Als Neuling hingegen ist es gut zu wissen, auf welche Weise grafische Balken/Kerzen des Preis-Charts, die grafische Ansicht von CCI-Indikatoren, ihre entsprechenden (idx) Variablen sowie die Werte des CCIxx-Indikators miteinander korrespondieren.

Dies ist wichtig, um Ihre ausgewählten Indikatoren auf einem Chart zu erkennen und zu versuchen, die Korrelation zwischen Preisbalken/Kerzen und dem Verhalten der ausgewählten Indikatoren zu „visualisieren“, um auf diese Weise eine Strategie zu konzipieren, deren Code Sie leicht mithilfe des Balkenindex (idx) und dem Wert der Indikatorvariable schreiben können.

Der folgende Code der SignalCCIxx.mqh-Datei:

CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0

meint in Worten das Folgende:

CCI Indicator value (one bar before, named idx+1) is above the zero line of CCI indicator
AND
CCI Indicator value (two bars before, named idx+2) is below the zero line of CCI indicator

Es handelt sich hierbei um das kleinste Beispiel dafür, wie simpel es ist, zwei benutzerdefinierte Muster - die auf dem von uns gewählten Indikatorwert (ICC) basieren - hinzuzufügen.

Die Bedingung „Preis wird ansteigen“ oder „Preis wird sinken“ muss niedergeschrieben werden und in den Mustern auf diese Weise hinzugefügt werden; gleichwohl verbietet niemand, eine noch komplexere Bedingung zu kreieren. Lassen Sie uns vor dem finalen Test noch einen Blick auf die Mechanismen zum Öffnen und Schließen von Positionen werfen.

Im Abschnitt Trading-Strategieklassen der Standard Library des MQL5-Handbuchs haben wir diesen Mechanismus samt Logik bereits sehr gut erklärt.

Die Datei MyExpert.mq5 besitzt kurz gesagt zwei Input-Parameter (zwei Integer-Variablen):

//--- inputs for main signal
input int                Signal_ThresholdOpen =40;          // Signal threshold value to open [0...100]
input int                Signal_ThresholdClose=60;          // Signal threshold value to close [0...100]

Die Schwellenwerte zum Öffnen und Schließen sind Werte, die zum Berechnen verwendet werden, falls ein Trade (entsprechend unseren Trading-Modellen) „long“ oder „short“ geöffnet und dann geschlossen wird. Der Schwellenwert nimmt einen Integer zwischen 0 und 100 an. Was bedeuten diese Parameter?

Signal_ThresholdOpen ist der Wert, um eine Long Postion oder Short Position zu öffnen; Signal_ThresholdClose ist der Wert, um eine vormals geöffnete Postion zu schließen. Diese Werte werden infolge eines einfachen, aber zugleich brillanten Mechanismus kalkuliert, der tief in die Logik der vom Assistenten generierten EAs eingewebt ist.

Jedes einzelne Signal in den Signal__.mqh-Dateien (__ steht stellvertretend für den Namen eines benutzten Indikators [in unserem Fall: MA, RSI und CCIxx]) besteht aus Mustern, so wie wir sie zuvor bereits detailliert betrachtet haben. Lassen Sie sie uns erneut im Sinne unseres Beispiels betrachten. Unsere SignalMA.mqh-Datei liefert uns 4 Muster samt ihren relativen „Gewichten“ für jedes Muster:

//--- setting default "weights" of the market models
   m_pattern_0 =80;          // model 0 "price is on the necessary side from the indicator"
   m_pattern_1 =10;          // model 1 "price crossed the indicator with opposite direction"
   m_pattern_2 =60;          // model 2 "price crossed the indicator with the same direction"
   m_pattern_3 =60;          // model 3 "piercing"

und für RSI derselben SignalRSI.mqh-Datei in der gleichen Weise:

//--- setting default "weights" of the market models
   m_pattern_0  =70;         // model 0 "the oscillator has required direction"
   m_pattern_1  =100;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =90;         // model 2 "failed swing"
   m_pattern_3  =80;         // model 3 "divergence of the oscillator and price"
   m_pattern_4  =100;        // model 4 "double divergence of the oscillator and price"
   m_pattern_5  =20;         // model 5 "head/shoulders"

In „unserer eigenen" SignalCCIxx.mqh-Datei (beinahe eine Kopie von SignalCCI.mqh) haben wir die folgenden Werte:

//--- setting default "weights" of the market models
   m_pattern_0  =90;         // model 0 "the oscillator has required direction"
   m_pattern_1  =60;         // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =100;        // model 3 "divergence of the oscillator and price"
   m_pattern_3  =50;         // model 4 "double divergence of the oscillator and price"
   m_pattern_4  =80;         // model 4 "our own first new pattern: "
   m_pattern_5  =90;         // model 5 "our own second new pattern: "

Die üblichen 0-, 1-, 2-, 3- sowie unsere eigenen, 4- und 5-Muster, wobei die beiden letzteren die Werte 80 und 90 aufweisen. Wenn wir nun MyExpert.ex5 mit dem Chart verknüpfen oder mit dem Strategietester testen, werden die Muster all der von uns gewählten Signale (RSI, MA und CCIxx) kontinuierlich berechnet.

Falls die Bedingungen eines oder mehrerer Muster erfüllt sind, so wird das Signal dieses Musters für die nächste Berechnung aktiviert. Wenn also beispielsweise die Bedingungen des Muster m_pattern_4 der SignalCCIxx.mqh-Datei erfüllt sind:

// if the model 4 is used, look for crossing of the zero line
       if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0)
          result=m_pattern_4;      // signal number 4 

so wird es potentiellen Handelssignal entstehen. Anders gesagt, falls der CCI-Wert von Balken 1 > 0.0 und gleichzeitig der CCI-Wert von Balken 2 < 0.0 (wie in Abb. 5 und 6), so ist die Bedingung erfüllt und m_pattern_4 (Signalnummer 4) wird aktiviert.

Der Gewichtswert, den wir für das Signal unserer CCIxx-Strategie eingestellt haben, entspricht dem absoluten Wert von 80. Er wird allerdings für den Fall „Votum, dass der Preis fallen wird“ -80 und für den Fall „Votum, dass der Preis steigen wird“ 80 annehmen. Das „Votum, dass der Preis fallen wird“ hat also ein negatives Vorzeichen vor de Original-Gewichtswert des Musters gesetzt.

Angenommen die Bedingung für m_pattern_4 wird erfüllt, so wird ein Trade nur unter folgenden Voraussetzungen geöffnet:

  • Das Signal Nummer 4 (m_pattern_4) ist das einzige Signal, dessen Bedingung erfüllt ist (Signal aktiviert) UND es erreichte das Ziel von Signal_ThresholdOpen (dessen Wert mit dem Koeffizienten multipliziert, hat den Signal_ThresholdOpen-Wert erreicht oder übertroffen).

  • Das Signal Nummer 4 hat das Ziel von Signal_ThresholdOpen erreicht, während es mit anderen Signalen seines CCIxx-Strategie-Pendants (dem „Votum, dass der Preis fallen wird“-Signal/Muster der CCIxx-Strategie) konkurriert, und mit all den anderen Signalen anderer Indikatoren (RSI- und MA-Signale) entgegengesetzter Richtungen konkurriert (in diesem Fall ist die entgegengesetzte Richtung die Short-Richtung, da wir das m_pattern_4-Muster betreffend „Votum, dass der Preis steigen wird“ analysieren).

Wir ordnen also jedes Muster einer der zwei folgenden, konkurrierenden Fraktionen zu: Bull- und Bear-Signale. Wenn diese Muster/Signale derselben Richtung („Votum, dass der Preis steigen wird“) erfolgreich sind (aktiviert), werden sie aufsummiert und diese Summe wird dann mit dem Signal_ThresholdOpen-Wert verglichen. Falls keine Positionen geöffnet wurden oder die Summe im Falle einer vorher geöffneten Position mit dem Signal_ThresholdClose-Wert verglichen wird (im vorliegenden Fall: Short Position), so hat m_pattern_4 von SignalCCIxx.mqh den Wert:

  • 80 für die Bedingung „Preisanstieg“
  • und -80 für die Bedingung „Preisabfall“

Lassen Sie uns annehmen, dass ALLE anderen Muster ALLER anderen Signale (SignalRSI.mqh, SignalMA.mqh und die Muster 0,1,2,3 & 5 von SignalCCIxx.mqh) den Wert 0 haben. Dann liegt der Fall vor, dass „Signal-Kontrahenten“ „aus dem Spiel sind“. Somit verbleiben nur noch zwei m_pattern_4: einmal Kaufen und einmal Verkaufen. Wir haben also nur noch das m_pattern_4 aktiv, da es einen Wert besitzt, der ungleich 0, also beispielsweise 80 beträgt.

//--- setting default "weights" of the market models
   m_pattern_0 =0;          // model 0 "price is on the necessary side from the indicator"
   m_pattern_1 =0;          // model 1 "price crossed the indicator with opposite direction"
   m_pattern_2 =0;          // model 2 "price crossed the indicator with the same direction"
   m_pattern_3 =0;          // model 3 "piercing"

und für RSI derselben SignalRSI.mqh-Datei in der gleichen Weise:

//--- setting default "weights" of the market models
   m_pattern_0  =0;         // model 0 "the oscillator has required direction"
   m_pattern_1  =0;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =0;        // model 2 "failed swing"
   m_pattern_3  =0;        // model 3 "divergence of the oscillator and price"
   m_pattern_4  =0;        // model 4 "double divergence of the oscillator and price"
   m_pattern_5  =0;        // model 5 "head/shoulders"

In „unserer eigenen" SignalCCIxx.mqh-Datei (beinahe eine Kopie von SignalCCI.mqh) haben wir die folgenden Werte:

//--- setting default "weights" of the market models
   m_pattern_0  =0;        // model 0 "the oscillator has required direction"
   m_pattern_1  =0;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =0;        // model 3 "divergence of the oscillator and price"
   m_pattern_3  =0;        // model 4 "double divergence of the oscillator and price"
   m_pattern_4  =80;       // model 4 "our own first new pattern: "
   m_pattern_5  =0;        // model 5 "our own second new pattern: "

Zum Beginn dieses Artikels haben wir diese Zeilen hinzugefügt:

input int                Signal_CCIxx_PeriodCCI =8;            // Commodity Channel Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_CCIxx_Applied   =PRICE_CLOSE;  // Commodity Channel Index(8,...) Prices series
input double             Signal_CCIxx_Weight    =0.8;          // Commodity Channel Index(8,...) Weight [0...1.0]

Wir haben uns dabei auf die Variable Signal_CCIxx_Weight (mit dem Wert 0.8) konzentriert. Signal_ThresholdOpen wird dann erreicht, also ausgelöst, falls der Schwellenwert erreicht wird. Der Wert wird wie folgt berechnet:

0.8 (Signal_CCIxx_Weight input parameter)
*
80 (m_pattern_4's weight value)
= 64 is the signal strength for the "voting that price will grow"

Es handelt sich um „Votum, dass der Preis steigen wird“, da der Algorithmus ein „Preisanstieg“-Signal (m_pattern_4 of SignalCCIxx) erhielt, und der Wert 80 ist.

Falls hypothetisch gesehen ein „Votum, dass der Preis fallen wird“ (m_pattern_4 von SignalCCIxx) vorläge, dann wäre der Wert -80. Für „Preisabfall“ wird dem Algorithmus einfach nur ein Minuszeichen zum Musterwert hinzufügen. Für den Fall „Votum, dass der Preis fallen wird“ sehen die Berechnungen folgendermaßen aus:

0.8 (Signal_CCIxx_Weight input parameter)
*
-80 (m_pattern_4's weight value)
= -64 = the negative value is considered for short positions

-64 --> 64 (in absoluten Werten) ist die Signalstärke für „Votum, dass der Preis fallen wird“. Die Signalstärke wird immer in absoluten Werten ausgedrückt, wohingegen Short Position-Werte von einem Minus und Long Position-Werte von einem Plus begleitet werden.

Lassen Sie uns zu einem der obigen Long Position-Beispiele zurückkehren, das den Wert 64 und die Signalstärke 64 erreicht hat. Falls keine anderen konkurrierenden, gegensätzlichen (mit negativem Vorzeichen) Signale (m_pattern_N of Signal__) vorliegen, so wird Signal_ThresholdOpen mit dem Wert 40 erreicht, da die Stärke des Long-Signals 64 beträgt und Signal_ThresholdOpen das Level 40 erreicht und es um 24 übertrifft (40+24=64). Das das Signal_ThresholdOpen-Signal erreicht wurde, wird eine Long Position geöffnet.

Würden wir beispielsweise Signal_CCIxx_Weight den Wert 0.4 zuweisen, so würden kein Long Positions mehr geöffnet werden, da:

0.4 (the Signal_CCIxx_Weight)
*
80(m_pattern_4)
= 32 (strength of "long signal")

und das Level 40 (Signal_ThresholdOpen) wird nicht erreicht, da 32 < 40. Folglich werden keine Long Positions geöffnet.

Das obige Beispielset an Werten (alle Werte 0, Ausnahme: m_pattern_4 von SignalCCIxx.mqh = 80) ist natürlich Quatsch, hilft uns aber dabei, die Logik des Assistenten sowie des Gewicht- und Schwellenwertsystems zu verstehen. Normalerweise würden Sie jedem m_pattern_N eines jeden Signal__ ein bevorzugtes Gewicht zuweisen. Wenn Sie einem Muster die Null zuweisen, so bedeutet dies nur, dass dieses Muster nicht genutzt werden wird.

Wenn wir einen anderen Wert obigen Beispiels (mit allen Parametern außer m_pattern_4 von SignalCCIxx.mqh = 0) beispielsweise m_pattern_1 von SignalRSI.mqh auf 100 ändern, so ändern sich die Berechnungen, so dass wir es nun mit 4 Kontrahenten zu tun bekommen:

  • m_pattern_4 (Bull) und m_pattern_4 (Bear) der Datei SignalCCIxx.mqh mit den Werten 80 beziehungsweise -80.
  • M_pattern_1 (Bull) und m_pattern_1 (Bear) der Datei SignalRSI.mqh mit den Werten 100 beziehungsweise -100.
m_pattern_4 Bullish --> 0.8 * 80 = 64
m_pattern_2 Bullish --> 0.7 * 100 = 70
m_pattern_4 Bearish --> 0.8 * (-80) = -64
m_pattern_2 Bearish --> 0.7 * (-100) = -70

Wir erhalten also 4 mögliche Kombinationen:

A) m_pattern_4 Bullish + m_pattern_2 Bullish = {[0.8 * (80)] + [0.7 * (100)]}/2 = [64 + (70)]/2 = 134/2 = 67
B) m_pattern_4 Bullish + m_pattern_2 Bearish = {[0.8 * (80)] + [0.7 * (-100)]}/2 = [64 + (-70)]/2 = -6/2 = -3
C) m_pattern_4 Bearish + m_pattern_2 Bullish = {[0.8 * (-80)] + [0.7 * (100)]}/2 = [(-64) + 70]/2 = 6/2 = 3
D) m_pattern_4 Bearish + m_pattern_2 Bearish = {[0.8 * (-80)] + [0.7 * (-100)]}/2 = [(-64) + (-70)]/2 = -134/2 = -67

Fall A
Der positive Wert 67. Eine Long Position wird geöffnet, da Signal_ThresholdOpen mit dem Wert 40 erreicht und sogar übertroffen wird. Die Long Position wird später geschlossen, wenn der Signal_ThresholdClose-Wert 60 erreicht und von dem absoluten Wert des Beispiels D = -67 = |67| (absoluter Wert) übertroffen wird, da für die Stärke von Beispiel D in absoluten Werten gilt: 67 > 60 (das ist der Schwellenwert von Signal_ThresholdClose).

Fall B
Der negative Wert -3. Es werde keine Short Positions geöffnet, da Signal_ThresholdOpen mit dem Wert 40 nicht erreicht und von dem absoluten Wert des Beispiels B übertroffen wird: -3 wurde zu 3, wenn wir die absoluten Werte, um die „Signalstärke“ zu berechnen, und 3 < 40 (Wert eines Signals, um eine Position zu öffnen) betrachten. Es gibt keine offenen Short Positions und augenscheinlich auch keine Berechnungen zum Schließen von Short Positions.

Fall C
Der positive Wert 3. Es werde keine Long Positions geöffnet, da Signal_ThresholdOpen mit dem Wert 40 nicht erreicht und von dem absoluten Wert des Beispiels C übertroffen wird, da 3 < 40 (Wert eines Signals, um eine Position zu öffnen). Es gibt keine offenen Long Positions und augenscheinlich auch keine Berechnungen zum Schließen von Long Positions.

Fall D
Der negative Wert -67. Eine Long Position wird geöffnet, da Signal_ThresholdOpen mit dem Wert 40 erreicht und von der Signalstärke - die mithilfe des absoluten Werts von -67, also 67 berechnet wird (67 > 40) - übertroffen wird. Die Long Position wird später geschlossen, wenn der Signal_ThresholdClose-Wert 60 erreicht und von dem absoluten Wert des Beispiels A = 67 übertroffen wird, da 67 (die Stärke von Fall A) > 60 (das ist der Schwellenwert von Signal_ThresholdClose).

Mit anderen Worten, zum Öffnen von Short Positions, müssen wir zuerst die Richtung aufgrund der negativen Signalwerte identifizieren, und dann wird der negative Wert in seinen absoluten Wert umgewandelt, um die Signalstärke zu berechnen, die dann mit Signal_ThresholdOpen verglichen wird, um zu sehen, ob gilt: ersteres >= letzteres.

Das Schließen von Long Positions geht auf ähnliche Weise: Zunächst ziehen wir einen negativen Werte in Betracht, um Long Positions zu schließen (im Gegenteil, der Wert zum Schließen von Short Positions ist positiv), dann wird dieser negative Wert in seinen absoluten Wert umgewandelt, um zu überprüfen, ob dieser Wert >= Signal_ThresholdClose ist.

Für das Öffnen von Long Positions und das Schließen von Short Positions werden die Berechnungen mit positiven Zahlen durchgeführt (es gibt keine Signale mit Minuszeichen). Es gibt also keinen Grund, die absoluten Werte zu berechnen. Das Öffnen von Long Positions wird ebenso wie das Schließen von Short Positions durch positive Signalstärkewerte ausgelöst.

Zunächst haben wir das Plus- und das Minuszeichen zum Öffnen von Long- oder zum Öffnen von Short- sowie zum Schließen einer Short- oder zum Schließen einer Long Position betrachtet. Dann haben wir die absoluten Werte berechnet, um diese mit den Schwellenwerten von Signal_ThresholdOpen und Signal_ThresholdClose zu vergleichen, die ihrerseits mit positiven Vorzeichen berechnet werden (Signal_ThresholdOpen und Signal_ThresholdClose können keine negativen Vorzeichen aufweisen).

Positionendetails

Lassen Sie uns zu den Details einer Position kommen

  • Normales Trading. Die Position wird geöffnet und dann geschlossen. Danach wird die Position nicht erneut geöffnet.
  • Umkehrungen von Positionen. Die Position wird geöffnet, geschlossen und dann erneut in die entgegengesetzte Richtung geöffnet

Eine Long-Position wird geöffnet, falls:

Open_long >= Signal_ThresholdOpen
FALLS Signal_ThresholdClose <= Signal_ThresholdOpen
Wir erhalten ein Signal zum Verkaufen, also wird die Long-Position umgekehrt,falls:
Open_short > Signal_ThresholdClose AND Open_short > Signal_ThresholdOpen
Wir erhalten ein Signal zum Verkaufen, also wird die Long-Position geschlossen,falls:
Open_short > Signal_ThresholdClose AND Open_short < Signal_ThresholdOpen

FALLS Signal_ThresholdClose >= Signal_ThresholdOpen
Wir erhalten ein Signal zum Verkaufen, also wird die Long-Position umgekehrt,falls:
Open_short > Signal_ThresholdClose OR Open_short > Signal_ThresholdOpen
Wir erhalten ein Signal zum Verkaufen, also wird die Long-Position geschlossen, falls:
Open_short > Signal_ThresholdClose OR Open_short < Signal_ThresholdOpen

Für den Fall dass gilt, Signal_ThresholdClose >= Signal_ThresholdOpen, handelt es sich um das Boolean „ODER“, da Signal_ThresholdClose >= Signal_ThresholdOpen bereits die Werte von Signal_ThresholdOpen enthält. Die Position wird daher geschlossen, oder durch den Wert Signal_ThresholdClose >= Signal_ThresholdOpen überschrieben werden. In jedem Fall liegt ein Short-Reversal vor.

Eine Short-Position wird geöffnet, falls:

Open_short >= Signal_ThresholdOpen.
Signal_ThresholdClose <= Signal_ThresholdOpen
Wir erhalten ein Signal zum Kaufen, also wird die Short-Position umgekehrt,falls:
Open_long > Signal_ThresholdClose AND Open_long > Signal_ThresholdOpen
Wir erhalten ein Signal zum Kaufen, also wird die Short-Position geschlossen, falls:
Open_long > Signal_ThresholdClose AND Open_long < Signal_ThresholdOpen

FALLS Signal_ThresholdClose >= Signal_ThresholdOpen
Wir erhalten ein Signal zum Kaufen, also wird die Short-Position umgekehrt,falls:
Open_long > Signal_ThresholdClose OR Open_long > Signal_ThresholdOpen
Wir erhalten ein Signal zum Kaufen, also wird die Short-Position geschlossen, falls:
Open_long > Signal_ThresholdClose OR Open_long < Signal_ThresholdOpen

Für den Fall dass gilt, Signal_ThresholdClose >= Signal_ThresholdOpen, handelt es sich um das Boolean „ODER“, da Signal_ThresholdClose >= Signal_ThresholdOpen bereits die Werte von Signal_ThresholdOpen enthält. Die Position wird daher geschlossen oder durch den Wert Signal_ThresholdClose >= Signal_ThresholdOpen überschrieben werden. In jedem Fall liegt ein Long-Reversal vor.

Der Mechanismus zum Öffnen und Schließen von Positionen von den vom Assistenten generierten EAs ist äußerst intelligent, da er auf einem System von Gewichten, Werten und Schwellenwerten basiert. Mithilfe dieses Mechanismus werden Positionen „methodisch“ und ohne logische Fehler verarbeitet.



Preislevel und Auslaufen von Signalen

Es gibt noch eine andere wichtige Variable:

input double             Signal_PriceLevel    =0.0;         // Price level to execute a deal

Diese Variable ist für das Verständnis des Mechanismus der vom Assistenten kreierten EAs äußerst bedeutend und kann folgendermaßen simplifiziert werden.

  • Signal_PriceLevel entscheidet darüber, ob ein Long-Signal als ein Buy-Stop- oder als ein Buy-Limit-Befehl sowie ein Short-Signal als ein Sell-Stop- oder als ein Sell-Limit-Befehl verarbeitet werden soll. Mehr Details betreffend die Stop- und Limit-Aufträge finden Sie auf der MetaTrader 5-Hilfeseite.

  • Werden der Input-Variable Signal_PriceLevel negative Werte zugewiesen, so ergibt dies immer Stop-Aufträge (Kaufen oder Verkaufen).

  • Werden der Input-Variable Signal_PriceLevel positive Werte zugewiesen, so ergibt dies immer Limit-Aufträge (Kaufen oder Verkaufen).

Abbildung 17. Auf Signal_PriceLevel basierende Stop- und Limit-Aufträge

Zum Beispiel:

EURUSD - Long-Positions

Signal_PriceLevel = -70 (Minus 70)
also, falls Signal Open aktiviert wird (beispielsweise mit dem aktuellen Preis = 1.2500),
wird der EA eine Buy Stop-Order platzieren, die aus 1.2500 + 70 = 1.2570 besteht
(schlechter als der aktuelle Preis, falls auf steigende Tendenz spekuliert wird)


Signal_PriceLevel = 60 (Plus 60)
also, falls Signal Open aktiviert wird (beispielsweise mit dem aktuellen Preis = 1.2500),
wird der EA eine Buy Limit-Order platzieren, die aus 1.2500 - 60 = 1.2440 besteht
(besser als der aktuelle Preis, falls auf steigende Tendenz spekuliert wird)

EURUSD - Short-Positions

Signal_PriceLevel = -70 (Minus 70)
also, falls Signal Open aktiviert wird (beispielsweise mit dem aktuellen Preis = 1.2500),
wird der EA eine Sell Stop-Order platzieren, die aus 1.2500 - 70 = 1.2430 besteht
(besser als der aktuelle Preis, falls auf steigende Tendenz spekuliert wird)


Signal_PriceLevel = 60 (Minus 60)
also, falls Signal Open aktiviert wird (beispielsweise mit dem aktuellen Preis = 1.2500),
wird der EA eine Sell Limit-Order platzieren, die aus 1.2500 + 60 = 1.2560 besteht
(schlechter als der aktuelle Preis, falls auf steigende Tendenz spekuliert wird)

Schließlich definiert die Input-Variable,

input int                Signal_Expiration    =4;           // Expiration of pending orders (in bars)

wie viele Male (in Balken ausgedrückt) die Stop-/Limit-Aufträge erneuert werden sollen.

Flussdiagramm

Dieses vereinfachte Flussdiagramm wird Ihnen dabei helfen, die dynamischen Mechanismen der vom Assistenten erstellten EAs zu verstehen.

Abbildung 18. Vereinfachtes Flussdiagramm von aktiven Aufträgen und Positionen

Strategietester

Lassen Sie uns nun zum Kontext unserer selbstdefinierten Strategie zurückkommen und eine SignalCCIxx.mqh-Datei kompilieren. Falls keine Fehler auftreten, sollte alles in Ordnung sein. Tatsächlich haben wir nun 2 neue Trading-Entscheidungsmodellmuster hinzugefügt. Jedes dieser Muster weist eine Kauf- und Verkauf- sowie eine Bedingung zum Öffnen und Schließen auf.

Lassen Sie uns nun eine MyExpert.mq5-Date kompilieren - falls alles in Ordnung ist, sollte es 0 Fehler und 0 Warnungen geben. Bemühen wir nun unseren Strategietester. Ich habe einige Parameter im Strategietester für das EUR/USD-Symbol zusammen mit einer Periode ähnlich der letzten Meisterschaft für Automatisiertes Trading 2011 (ATC2011 benutzt.

Abbildung 19. Einige simple Parameter, um die ATC2011 mit MyExpert.mq5 zu emulieren.

Obgleich „gute“ Resultate angezeigt werden und die ursprüngliche Einzahlung in weniger als 3 Monaten mit einem fixen Lot-Betrag mehr als verdoppelt wird, empfehle ich nicht, diesen EA für das reale Trading zu verwenden. Vielmehr lege ich Ihnen nahe, Ihre eigenen Muster/Modelle hinzuzufügen und mit diesen zu experimentieren und sie zu optimieren, bis Sie die entsprechenden Ergebnisse erhalten, die Ihnen zusagen.

Wie dem auch sei, ich wollte Ihnen an dieser Stelle lediglich vorführen, dass es eine gute Idee sein kann, existierende Trading-Strategieklassen zu verbessern.

Abbildung 20. Resultate der Pseudo-ATC2011 mit MyExpert.mq5

Sie können Muster und Modelle kreieren und diese via MQL5.community anderen Mitgliedern zur Verfügung stellen. Mithilfe des MQL5-Assistenten und der simplen Methode, die in diesem Artikel diskutiert worden ist, wird es ein Leichtes sein, diese zu testen. Dieser Artikel stellt nur ein Beispiel dar, wie Sie die Trading-Strategieklassen der Standard Library erkunden können und wie leicht es eigentlich ist, diese Bibliotheken zu modifizieren, um eigene Trading-Systeme zu erstellen.

Fazit

Wir haben dem CCI-Signal kinderleicht 2 neue Filter/Muster hinzugefügt. Sie können dies für alle anderen Indikatoren wiederholen und sich somit Ihr ganz eigenes Repertoire an Signalen zusammenstellen. Falls Sie diese Aufgabe strukturiert und gewissenhaft erledigen, wird Ihnen am Ende ein äußerst mächtiges Trading-Werkzeug zur Verfügung stehen.

Auf diese Weise können Sie effektiv Ihre eigenen Strategien hinzufügen, indem Sie sich lediglich auf den Kern der Strategien - die Arbeit mit Indikatoren - konzentrieren. Lassen Sie den MQL5-Assistenten all die Arbeit (Trading-Funktionen und -Operationen des EAs) erledigen - dies spart Ihnen wertvolle Zeit und garantiert Ihnen die Korrektheit Ihres EAs.

Sie können kinderleicht via MetaTrader 5-Standardindikatoren Ihre eigenen Strategien konzipieren und in folgenden EA packen: ATC-fertig.

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

Beigefügte Dateien |
myexpert.mq5 (8.57 KB)
signalccixx.mqh (21.02 KB)
Statistische Carry Trade-Strategie Statistische Carry Trade-Strategie
Ein statistischer Algorithmus zum Schutz von offenen, positiven Swap-Positionen vor ungewollten Kursbewegungen. Dieser Artikel widmet sich einer Variante der Carry Trade Protection-Strategie, die die potentiellen Risiken einer Kursbewegung in die entgegengesetzte Richtung einer offenen Position kompensiert.
MetaQuotes-ID im MetaTrader Mobil-Terminal MetaQuotes-ID im MetaTrader Mobil-Terminal
Auf Android und iOS basierende Geräte bieten uns viele verschiedene Features, die vielen von uns weitgehend unbekannt sind. Eines davon stellen die sogenannten Push Notifications dar, die dazu genutzt werden können, private Nachrichten zu empfangen - und zwar unabhängig von unserer Telefonnummer beziehungsweise unserem Mobilfunkbetreiber. MetaTrader Mobil-Terminal kann bereits heute schon derartige Nachrichten direkt seitens Ihres Trading Roboters empfangen. Sie müssen lediglich die MetaQuotes-ID Ihres Geräts kennen. Zum heutigen Zeitpunkt haben bereits mehr als 9 000 000 Mobil-Terminals eine derartige ID erhalten.
Neuronale Netzwerke: Von der Theorie zur Praxis Neuronale Netzwerke: Von der Theorie zur Praxis
Heutzutage hat sicherlich jeder Trader schon einmal etwas von einem neuronalen Netzwerk gehört - und weiß, wie cool es ist, diese zu benutzen. Die Mehrheit scheint zu glauben, dass es sich bei all jenen, die mit neuronalen Netzwerken operieren, um irgendwelche Übermenschen handeln würde. Mithilfe des vorliegenden Artikels verbinde ich die Absicht, Ihnen die Architektur eines neuronalen Netzwerks samt seiner Applikationen und praktischen Nutzanwendungen näherzubringen.
Kopieren des Handels aus MetaTrader 5 nach MetaTrader 4 Kopieren des Handels aus MetaTrader 5 nach MetaTrader 4
Ist es möglich, heute auf einem echten MetaTrader-5-Konto zu handeln? Wie organisiert man solchen Handel? Dieser Beitrag behandelt die Theorie hinter diesen Fragen und die Arbeitscodes zum Kopieren von Abschlüssen aus dem MetaTrader 5 Terminal nach MetaTrader 4. Dieser Beitrag wird sowohl für Entwickler von Expert Advisors als auch für praktizierende Händler hilfreich sein.