Schau, wie man Roboter kostenlos herunterladen kann
Finden Sie uns auf Twitter!
und werden Sie Mitglied unserer Fangruppe
Interessantes Skript?
Veröffentliche einen Link auf das Skript, damit die anderen ihn auch nutzen können
Hat Ihnen das Skript gefallen?
Bewerten Sie es im Terminal MetaTrader 5
Expert Advisors

MACD Beispiel - Experte für den MetaTrader 5

Veröffentlicht:
MetaQuotes
Ansichten:
4815
Rating:
(51)
Veröffentlicht:
2016.05.20 10:00
Aktualisiert:
2016.11.22 07:34
Benötigen Sie einen Roboter oder Indikator, der auf diesem Code basiert? Bestellen Sie ihn im Freelance-Bereich Zum Freelance

Der MACD Beispiel EA ist im Standardpaket des MetaTrader 5 Client Terminals enthalten und ist ein Beispiel für einen EA, der unter Verwendung des MACD Indikators tradet.

Die Datei des MACD Sample.mq5 Expert Advisors befindet sich in terminal_data_folder\MQL5\Experts\Examples\MACD\". Dieser Expert Advisor ist ein Beispiel für einen objektorientierten Ansatz in der EA Entwicklung.

Sehen wir uns die Struktur es Expert Advisors und wie er funktioniert an.


1 EA Eigenschaften

1.1. EA Eigenschaften

//+------------------------------------------------------------------------+
//|                                                 MACD Beispiel.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------------+
#property copyright   "Copyright 2009-2013, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version     "5.20"
#property description "Es ist wichtig sicherzustellen, dass der Expert in einem normalen"
#property description "Chart funktioniert und der Anwender hat keine Fehler bei den Eingaben gemacht"
#property description "Variablen (Lots, TakeProfit, TrailingStop) in unserem Fall,"
#property description "wir prüfen TakeProfit auf dem Chart für mehr als 2*trend_period bars"

Die ersten 5 Zeilen enthalten einen Kommentar, die folgenden sieben Zeilen stellen die Eigenschaften (copyright, link, version, description) für das MQL5-Programm mit Hilfe der Präprozessordirektive #property ein.

Wenn Sie den Expert Advisor ausführen, werden diese im "Allgemein" Tab angezeigt:

Der MACD Beispiel Expert Advisor

Abbildung 1 Allgemeine Parameter des MACD Beispiel EA

1.2. Include Files

Als nächstes weist die #include Direktive den Compiler an, die Dateien, die die trade Klassen der Standardbibliothek enthalten, einzubinden.

  • Trade.mqh (CTrade - eine Klasse für Trade Operationen);
  • SymbolInfo.mqh (CSymbolInfo - eine Klasse zum Arbeiten mit den Eigenschaften eines Handlesinstruments);
  • PositionInfo.mqh (CPositionInfo - eine Klasse für das Arbeiten mit den Eigenschaften offener Positionen);
  • AccountInfo.mqh (CAccountInfo - eine Klasse für das Arbeiten mit den Eigenschaften des Handelskontos).
//--- include Dateien 
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>

Instanzen der zuständigen Klassen werden dann als Membervariablen der CExpert Klasse verwendet (Abschnitt 3).

1.3. Eingaben

Dann kommt der Typ, Name, Standardwert und ein Kommentar. Ihre Rolle wird in Abb. 2 gezeigt.

//--- Expert Advisor Eingabeparameter
input double InpLots          =0.1; // Lotgröße
input int    InpTakeProfit    =50;  // Take Profit (in PIPS)
input int    InpTrailingStop  =30;  // Trailing Stop Level (in PIPS)
input int    InpMACDOpenLevel =3;   // MACD Eröffnungslevel (in PIPS)
input int    InpMACDCloseLevel=2;   // MACD Schließungslevel (in PIPS)
input int    InpMATrendPeriod =26;  // MA Trendperiode

Beachten Sie, dass die Namen der Eingabeparameter den Präfix "Inp" haben. Beachten Sie auch, dass globale Variablen den Präfix "Ext" haben. So ein Ansatz bei der Veriablenbenennung vereinfacht die Verwendung vieler verschiedener Variablen.

InpLots - trade volume, InpTakeProfit und InpTrailingStop legen die Take Profit und Trailing Stop Levels fest,

Der Text im Kommentar der Eingabeparameterzeile wird gemeinsam mit Standardwerten im "Optionen"-Tab anstatt des Namens des Eingabeparameters angezeigt:

Abbildung 2. Eingabeparameter des MACD Beispiel EA

Abbildung 2. Eingabeparameter des MACD Beispiel EA


1.4. Globale Variablen

Dann wird die globale Variable ExtTimeOut deklariert. Sie wird für die Steuerung der Ausführungszeit der Tradeoperationen verwendet.

int ExtTimeOut=10; // Zeit (in Sekunden) zwischen Tradeoperationen

Nach der Deklaration der CSampleExpert Klasse wird in Zeile 76 ein andere globale Variable deklariert: ExtExpert - CSampleExpert Klassen Instanz:

//--- die globale Variable ExtExpert
CSampleExpert ExtExpert;

Das ExtExpert Objekt (CSampleExpert Klasse Beispiel) enthält die grundlegende Logik für die Handelsstrategie (Abschnitt 3).


2. Ereignishandling Funktionen

Ereignishandling Funktionen

2.1. Die OnInit() Initialisierungsfunktion

Die OnInit() Funktion wird einmal während des ersten Starts des Expert Advisors aufgerufen. Für gewöhnlich wird der EA im OnInit() Ereignishandler für die Benützung vorbereitet: Eingabeparameter werden geprüft, Indikatoren und Parameter werden initialisiert, etc. Im Falle von kritischen Fehlern bei denen eine weitere Verarbeitung keinen Sinn hat, wird die Funktion mmit dem Rückgabecode INIT_FAILED verlassen.

//+------------------------------------------------------------------------+
//| Experteninitialisierungfunktion                                  |
//+------------------------------------------------------------------------+
int OnInit(void)
  {
//--- Initialisierung und Erstellung aller benötigter Objekte
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- erfolgreiche Initialisierung
   return(INIT_SUCCEEDED);
  }

In diesem Fall wird die Init() Methode des ExtExpert Objektes aufgerufen, die true oder false abhängig von der Vorbereitung aller für die Ausführung benötigter Objekte zurück gibt (siehe Abschnitt 3.4). Im Falle eines Fehlers wird OnInit() mit dem Rückgabecode INIT_FAILED verlassen - das ist eine korrekte Art die Verarbeitung des EA/Indikators im Falle einer nicht erfolgreichen Initialisierung zu beenden.


2.2. Die OnTick() Funktion

Die OnTick() Funktion wird jedes Mal aufgerufen, wenn eine neue Quotierung für das Symbol am Chart für das der EA ausgeführt wird, erhalten wird.

//+------------------------------------------------------------------------+
//| Expert new tick handling Funktion                                |
//+------------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // speichert Zeit des letzten Aufrufes und Timeout
//--- nicht ausführen, wenn die notwendige Zeit noch nicht vestrichen ist
   if(TimeCurrent()>=limit_time)
     {
      //--- Daten prüfen
      if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
        {
         //--- nach dem Aufruf der Processing() Methode den Wert von limit_time durch ExtTimeOut vergrößern
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

Im OnTick() Ereignishandler ist ein Mechanismus für periodische Aufrufe der ExtExpert.Processing() Methode enthalten, die für die Marktanalyse und Handelsoperation verwendet wird, wenn die Handelsbedingungen erfüllt sind.

Das Zeitintervall zwischen den Aufurfen wird durch den Wert vom Eingabeparameter ExtTimeOut gesetzt.


2.3. Die OnDeInit() Deinitialisierungsfunktion

OnDeInit() wird aufgerufen, wenn der EA vom Chart entfernt wird. Wenn ein Programm im Zuge seiner Arbeit graphische Objekte platziert, können diese vom Chart entfernt werden.

In diesem Beispiel wird keine Deinitialisierungsfunktion verwendet, keine Aktionen werden ausgeführt.


3. Die CSampleExpert Klasse

3.1. Die CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Das MACD Beispiel EA Klassen Beispiel                                  |
//+------------------------------------------------------------------------+
class CSampleExpert
  {
protected: 
   //--- geschützte Variablen - Klassenmember sind nur innerhalb der Klassenmethoden verfügbar 
   double            m_adjusted_point;             // ein Vervielfacher für 3/5-stellige Quotierungen
   CTrade            m_trade;                      // CTrade Klassen Beispiel
   CSymbolInfo       m_symbol;                     // CSymbolInfo Klassen Beispiel
   CPositionInfo     m_position;                   // CPositionInfo Klassen Beispiel
   CAccountInfo      m_account;                    // CAccountInfo Klassen Beispiel
   //--- indicator handles
   int               m_handle_macd;                // der MACD Indikator Handle
   int               m_handle_ema;                 // der Moving Average Indikator Handle
   //--- Indikator Buffers
   double            m_buff_MACD_main[];           // Buffer der Hauptlinie des MACD Indikator
   double            m_buff_MACD_signal[];         // Buffer der Signallinie des MACD Indikator
   double            m_buff_EMA[];                 // EMA Indikator Buffers
   //--- aktuelle Indikatorwerte
   double            m_macd_current;
   double            m_macd_previous;
   double            m_signal_current;
   double            m_signal_previous;
   double            m_ema_current;
   double            m_ema_previous;
   //--- Levels (in Standardpunkten)
   double            m_macd_open_level;
   double            m_macd_close_level;
   double            m_traling_stop;
   double            m_take_profit;

public: 
   //--- Konstruktor
                     CSampleExpert(void);
   //--- Destruktor
                     ~CSampleExpert(void);
   //--- öffentliche Methoden können von außerhalb der Klasse aus aufgerufen werden 
   //--- Initialisierungsmethode
   bool              Init(void);
   //--- Deinitialisierungsmethode
   void              Deinit(void);
   //--- Methode für Verarbeitung
   bool              Processing(void);
protected: 
   //--- geschützte Methoden können nur von innerhalb der Klassenmethoden aufgerufen werden 
   bool              InitCheckParameters(const int digits_adjust);
   bool              InitIndicators(void);
   bool              LongClosed(void);
   bool              ShortClosed(void);
   bool              LongModified(void);
   bool              ShortModified(void);
   bool              LongOpened(void);
   bool              ShortOpened(void);
  };

Die EA Klasse enthält Variablendeklarationen (Klassenmembers) und Funktionen (Klassenmethoden).

Zum bequemeren Arbeiten mit Variablen enthalten alle Klassenmembervariablen den Präfix "m_" (member), der anzeigt, dass eine Variable ein Klassenmember ist. Vor der Deklaration einer Variablen oder Methode wird ihr Type spezifiziert (oder Rückgabewert für Funktionen).

Sichbarkeit der Klassenmembervariablen und Methoden wird durch Verwendung von Zugriffsmodifikatoren definiert. In der Klasse CSampleExpert werden die Modifikatoren protected und public verwendet. Alle Variablen und Methoden die im Public-Abschnitt definiert wurden, sind öffentlich und auf sie kann von außerhalb zugegriffen werden. Die CSampleExpert Klasse hat fünf solcher Methoden:

  1. CSampleExpert(void) - ein Konstruktor  (wird automatisch aufgerufen, wenn eine Klasseninstanz erstellt wird);
  2. ~CSampleExpert(void) - ein Destruktor (wird automatisch aufgerufen, wenn eine Klasseninstanz gelöscht wird);
  3. bool Init(void) - Initialisierungsmethode, in der alle für die Verarbeitung benötigten Daten vorbereitet werden;
  4. void Deinit(void) - Deinitialisierungsmethode;
  5. bool Processing(void) - Methode für Verarbeitung.

CSampleExpert Klassenmembervariablen, die mit dem protected Zugriffsmodifikator deklariert wurden, sind nur innerhalb der CSampleExpert Klassenmethoden (und Kindklassen) verfügbar.

  1. double           m_adjusted_point - Vervielfacher Variabele für eine korrekte Verarbeitung von 3/5-stelligen Quotierungen;
  2. CTrade          m_trade - СTrade Klassenbeispiel;
  3. CSymbolInfo  m_symbol - CSymbolInfo Klassenbeispiel;
  4. CPositionInfo  m_position - СPositionInfo Klassen Beispiel;
  5. CAccountInfo  m_account - CAccountInfo Klassen Beispiel
  6. int                 m_handle_macd - eine Variable zur Speicherung des Wertes des MACD Indikator Handles.
  7. int                 m_handle_ema - eine Variable zur Speicherung des Wertes des EMA Indikator Handles;
  8. double           m_buff_MACD_main[] - ein dynamisches Array des Typs Double, das zur Abfrage der Werte der Haupt-MACD-Linie verwendet wird;
  9. double           m_buff_MACD_signal[] - ein dynamisches Array des Typs Double, das zur Abfrage der Werte der MACD Signallinie verwendet wird;
  10. double           m_buff_EMA[] - ein dynamisches Array des Typs Double, das zur Abfrage der Werte des EMA Indikators verwendet wird;
  11. double           m_macd_current - wird verwendet zur Speicherung des aktuellen Wertes der MACD Linie;
  12. double           m_macd_previous - wird verwendet zur Speicherung des vorherigen Wertes der Haupt-MACD-Linie;
  13. double           m_signal_current - iwird verwendet zur Speicherung des aktuellen Wertes der MACD Signallinie;
  14. double           m_signal_previous - wird verwendet zur Speicherung des vorherigen Wertes der MACD Signallinie;
  15. double           m_ema_current - wird verwendet zur Speicherung des aktuellen Wertes des EMA Indikators;
  16. double           m_ema_previous - wird verwendet zur Speicherung des vorherigen Wertes des EMA Indikator
  17. double           m_macd_open_level,
  18. double           m_macd_close_level,
  19. double           m_traling_stop,
  20. double           m_take_profit - werden verwendet zur Speicherung der Werte der Preislevels (gesetzt in Eingabeparametern) unter Berücksichtigung des m_adjusted_point Vervielfachers.

CSampleExpert Klassenmethoden, die mit dem protected Zugriffsmodifikator deklariert wurden:

  1. bool  InitCheckParameters(const int digits_adjust) - Prüfung der Richtigkeit der Eingabeparameter und Initialisierung der EA Parameter;
  2. bool  InitIndicators(void) - Initialisierung (Ersstellung ) der MACD und Moving Average Indikatoren;
  3. bool  LongClosed(void) - gibt true zurück (und schließt eine offene Long-Position) wenn die Bedingungen für das Schließen einer Longposition erfüllt sind;
  4. bool  ShortClosed(void) - gibt true zurück (und schließt eine offene Shortposition) enn die Bedingungen für das Schließen einer Shortposition erfüllt sind;
  5. bool  LongModified(void) - gibt true zurück (und verändert den StopLoss Preis) wenn die Bedingungen zum Ändern des Stop Loss levels einer offenen Long-Positon erfüllt sind;
  6. bool  ShortModified(void) - gibt true zurück (und verändert den StopLoss Preis) wenn die Bedingungen zum Ändern des Stop Loss levels einer offenen Short-Positon erfüllt sind;
  7. bool  LongOpened(void) - gibt true zurück (und öffnet eine Longposition) wenn die Bedingungen zum Öffnen einer Longpositon erfüllt sind;
  8. bool  ShortOpened(void) - gibt true zurück (und öffnet eine Shortposition) wenn die Bedingungen zum Öffnen einer Shortpositon erfüllt sind.


3.2. CSampleExpert Klassen Konstruktor

//+------------------------------------------------------------------------+
//| CSampleExpert Klassen Konstruktor                                |
//+------------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
                                     m_handle_macd(INVALID_HANDLE),
                                     m_handle_ema(INVALID_HANDLE),
                                     m_macd_current(0),
                                     m_macd_previous(0),
                                     m_signal_current(0),
                                     m_signal_previous(0),
                                     m_ema_current(0),
                                     m_ema_previous(0),
                                     m_macd_open_level(0),
                                     m_macd_close_level(0),
                                     m_traling_stop(0),
                                     m_take_profit(0)
  {
   ArraySetAsSeries(m_buff_MACD_main,true);
   ArraySetAsSeries(m_buff_MACD_signal,true);
   ArraySetAsSeries(m_buff_EMA,true);
  }

Der Klassenkonstruktor wird automatisch aufgerufen, wenn ein class sample Objekt erstellt wird. Wenn er aufgerufen wird, werden Standardwerte (in Klammern) für Klassenmembervariablen gesetzt und die Zeitreihen Indexierungs Richtung wird für m_buff_MACD_main[], m_buff_MACD_signal[], m_buff_EMA[] gesetzt.


3.3. CSampleExpert Klassen Destruktor

//+------------------------------------------------------------------------+
//| CSampleExpert Klassen Destruktor                                 |
//+------------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
  {
  }

Der CSampleExpert Klassen Destruktor enthält keinen Code.


3.4. Die Init Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Initialisierung und Verifikation der Eingabeparameter            |
//+------------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- Einstellen der allgemeinen Eigenschaften
   m_symbol.Name(Symbol());              // Symbol
   m_trade.SetExpertMagicNumber(12345);  // Magic
//--- Berücksichtigung von 3/5-stelligen Quotierungen
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- setzen des Wertes der Level unter Berücksichtigung des m_adjusted_point Modifizierers
   m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
   m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
   m_traling_stop    =InpTrailingStop*m_adjusted_point;
   m_take_profit     =InpTakeProfit*m_adjusted_point;
//--- setzen der Slippage auf 3 Punkte
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust))
      return(false);
   if(!InitIndicators())
      return(false);
//--- erfolgreiche Beendigung
   return(true);
  }

In der Init() Methode werden Klassenmembervariablen initialisiert und die Eingabeparameter verifiziert.

Ein Aufruf der Name()Methode für das m_symbol Objekt (CSymbolInfo Klasseninstanz) setzt den Namen des Symbols, für den der Expert Advisor läuft, dann wird die Methode SetExpertMagicNumber() aufgerufen; sie etzt den Wert der Magicnummer für den EA für das m_trade Objekt (wird für Tradeoperationen verwendet). Danach wird die Digits() Methode verwendet, um die Anzahl der Stellen hinter dem Komma für das Symbol zu ermitteln und falls nötig werden die Werte der Levels angepasst.

Dann wird die SetDeviationInPoints() Methode des m_trade Objektes aufgerufen in der der Wert der erlaubten Slippage für Tradeoperationen gesetzt wird.


3.5. Die InitCheckParameters Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfung der Eingabeparameter                                     |
//+------------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
  {
//--- Prüfung der Richtigkeit des Take Profit Levels
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- Prüfung der Richtigkeit des Trailing Stop Levels
   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop muss größer sein als %d",m_symbol.StopsLevel());
      return(false);
     }
//--- Prüfung der Richtigkeit des Handelsvolumens
   if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
     {
      printf("Lotgröße muss liegen im Bereich von %f bis %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)
     {
      printf("Lotgröße korrespondiert nicht mit dem Volumenschritt %f",m_symbol.LotsStep());
      return(false);
     }
//--- Warung zeigen, wenn Take Profit<=Trailing Stop
   if(InpTakeProfit<=InpTrailingStop)
      printf("Warnung: Trailing Stop muss kleiner sein als Take Profit");
//--- erfolgreiche Beendigung
   return(true);
  }

Die Richtigkeit der EA Eingabeparameter wird in der InitCheckParameters() Methode geprüft. Wenn einer der Parameter ungültig ist, erscheint eine entsprechende Nachricht und die Funktion gibt false zurück.


3.6. Die InitIndicators() Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Indikatoren Initialisierungsmethode                              |
//+------------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
  {
//--- Erstellung des MACD Indikator
   if(m_handle_macd==INVALID_HANDLE)
      if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Fehler beim Erzeugen des MACD Indikator");
         return(false);
        }
//--- Erstellung des EMA Indikator
   if(m_handle_ema==INVALID_HANDLE)
      if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Fehler beim Erstellen des EMA Indikator");
         return(false);
        }
//--- erfolgreiche Beendigung
   return(true);
  }

In der InitIndicators() Methode wird die Richtigkeit der initialen Werte der Variablen m_handle_macd und m_handle_ema variables geprüft(sie müssen gleich INVALID_HANDLE sein, da sie vom Konstruktor initialisiert wurden), und die technischen Indikatoren MACD und Moving Average werden erzeugt (Verwendung der iMACD und iMA Funktionen). Bei Erfolg gibt die Funktion true zurück und die Indikatorenhandles werden in den Klassenmembers m_handle_macd und m_handle_ema gespeichert.

Die Handles der erstellten Indikatoren werden dann für die Prüfung der Menge der berechneten Daten verwendet (BarsCalculated) und es werden numerische Werte (CopyBuffer) der Indikatoren in der Processing() Methode ermittelt.


3.7. Die LongClosed() Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfung der Bedingungen für das Schließen einer Longposition     |
//+------------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
  {
   bool res=false;
//--- Soll die Position geschlossen werden?
   if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
         if(m_macd_current>m_macd_close_level)
           {
            //--- Schließen der Position
            if(m_trade.PositionClose(Symbol()))
               printf("Longposition von %s wird geschlossen",Symbol());
            else
               printf("Fehler beim Schließen der Postion von %s : '%s'",Symbol(),m_trade.ResultComment());
            res=true;
           }
//--- Rückgabe des Ergebnisses
   return(res);
  }

Die LongClosed() Methode gibt true zurück (und schließt die offene Longposition) wenn die Bedingungen für das Schließen der Position erfüllt sind:

  1. m_macd_current>0 - der aktuell Wert der Hauptlinie dies MACD Indikator ist positiv (MACD Histogramm ist über der Nulllinie);
  2. m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal nach unten gekreuzt.
  3. m_macd_current>m_macd_close_level - der aktuell Wert der Hauptlinie des MACD Indikator ist größer als der m_macd_close_level.


3.8. Die ShortClosed() Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfung Bedingungen für das Schließen einer Shortposition        |
//+------------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
  {
   bool res=false;
//--- Soll die Position geschlossen werden?
   if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
         if(MathAbs(m_macd_current)>m_macd_close_level)
           {
            //--- Schließen der Position
            if(m_trade.PositionClose(Symbol()))
               printf("Schließe Shortposition von %s",Symbol());
            else
               printf("Fehler beim Schließen der Postion von %s : '%s'",Symbol(),m_trade.ResultComment());
            res=true;
           }
//--- Rückgabe des Ergebnisses
   return(res);
  }

Die ShortClosed() Methode gibt true zurück (und schließt eine offene Shortposition) wenn Bedingungen für das Schließen einer Shortposition erfüllt sind:

  1. m_macd_current<0 - der aktuelle Wert der Hauptlinie des MACD Indikator ist negativ (MACD-Histogramm ist unter der Nulllinie).
  2. m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal aufwärts gekreuzt.
  3. MathAbs(m_macd_current)>m_macd_close_level - der aktuelle Wert der Hauptlinie des MACD Indikator ist größer als m_macd_close_level.


3.9. Die LongModified() Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfe Bedingungen für Modifikation von Longposition              |
//+------------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
  {
   bool res=false;
//--- Prüfung ob Trailing Stop benötigt wird
   if(InpTrailingStop>0)
     {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
        {
         double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
           {
            //--- Stop Loss und Take Profit der Position modifizieren
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Modifiziere Longposition von %s",Symbol());
            else
              {
               printf("Fehler beim Modifizieren der Position für %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Parametermodifikation : SL=%f,TP=%f",sl,tp);
              }
            res=true;
           }
        }
     }
//--- Rückgabe des Ergebnisses
   return(res);
  }

Die LongModified() Methode gibt true zurück (und modifiziert den Stop Loss Wert der Position) wenn die Bedingungen für die Modifikation einer Longposition erfüllt sind: Wenn der Wert der Eingabe InpTrailingStop>0, dann ist die Bedingung erfüllt, dass der Preis InpTrailingStop Punkte vom Einsteigspreis in Richtung der Position zurückgelegt hat. Dann wird der neue Stop Loss Level berechnet und der Stop Loss Parameter der offenen Position wird modifiziert.


3.10. Die ShortModified Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfe Bedingungen für Modifikation von Longposition              |
//+------------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
  {
   bool   res=false;
//--- Prüfung ob Trailing Stop benötigt wird
   if(InpTrailingStop>0)
     {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
        {
         double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
           {
            //--- Stop Loss und Take Profit der Position modifizieren
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Modifiziere Shortposition von %s",Symbol());
            else
              {
               printf("Fehler beim Modifizieren der Position für %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Parametermodifikation : SL=%f,TP=%f",sl,tp);
              }
            res=true;
           }
        }
     }
//--- Rückgabe des Ergebnisses
   return(res);
  }

Die ShortModified() Methode gibt true zurück (und modifiziert den Stop Loss Wert der Position) wenn die Bedingungen für die Modifikation einer Shortposition erfüllt sind: Wenn der Wert der Eingabe InpTrailingStop>0, dann ist die Bedingung erfüllt, dass der Preis InpTrailingStop Punkte vom Eröffnungspreis in Richtung der Position zurückgelegt hat. Dann wird der neue Stop Loss Level berechnet und der Stop Loss Parameter der offenen Position wird modifiziert.


3.11. Die LongOpened() Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfe auf Eröffnung einer Longposition                           |
//+------------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- Prüfe Bedingungen für das Öffnen einer Longposition
   if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
         if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous)
           {
            double price=m_symbol.Ask();
            double tp   =m_symbol.Bid()+m_take_profit;
            //--- Prüfung der freien Margin
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
               printf("Wir haben kein Geld. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- Eröffnung einer Longpositon
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
                  printf("Öffne Position für %s",Symbol());
               else
                 {
                  printf("Fehler beim Öffnen einer BUY Position für %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Eröffnungsparameters : Preis=%f,TP=%f",price,tp);
                 }
              }
            res=true;
           }
//--- Rückgabe des Ergebnisses
   return(res);
  }

Die LongOpened() Methode gibt true zurück (und öffnet eine Longposition) wenn die Bedingungen für das Öffnen einer BUY-Positon erfüllt sind:

  1. m_macd_current<0 - der aktuelle Wert der Hauptlinie des MACD Indikator ist negativ (MACD-Histogramm ist unter der Nulllinie);
  2. m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal aufwärts gekreuzt;
  3. MathAbs(m_macd_current)>m_macd_open_level - der aktuelle Wert der Hauptlinie des MACD Indikator Modulo ist größer als m_macd_open_level;
  4. m_ema_current>m_ema_previous - ema wächst.

Wenn alle Bedingungen erfüllt sind, wird die freie Margin geprüft(FreeMarginCheck() Methode der CAccountInfo Standard Bibliotheksklasse) und eine Longposition wird unter Verwendung der PositionOpen() Method der CTrade Klasse eröffnet.


3.12. Die ShortOpened Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Prüfe auf Eröffnung einer Shortposition                          |
//+------------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
  {
   bool res=false;
//--- Prüfe Bedingungen für das Öffnen einer Shortposition
   if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
         if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous)
           {
            double price=m_symbol.Bid();
            double tp   =m_symbol.Ask()-m_take_profit;
            //--- Prüfung der freien Margin
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
               printf("Wir haben kein Geld. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- Öffnen einer Shortposition
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
                  printf("Öffne Position für %s",Symbol());
               else
                 {
                  printf("Fehler beim Öffnen einer SELL-Position für %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Eröffnungsparameters : Preis=%f,TP=%f",price,tp);
                 }
              }
            res=true;
           }
//--- Rückgabe des Ergebnisses
   return(res);
  }

Die ShortOpened() Methode gibt true zurück (und öffnet eine Shortpositon) wenn die Bedingungen zum Öffnen einer Verkaufspositon erfüllt sind:

  1. m_macd_current>0 - der aktuell Wert der Hauptlinie dies MACD Indikator ist positiv (MACD Histogramm ist über der Nulllinie);
  2. m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal nach unten gekreuzt;
  3. m_macd_current>m_macd_open_level - der aktuelle Wert der Hauptlinie des MACD Indikator Modulo ist größer als m_macd_open_level;
  4. m_ema_current<m_ema_previous - ema fällt.

Wenn alle Bedingungen erfüllt sind, wird die freie Margin geprüft(FreeMarginCheck() Method der CAccountInfo Standard Bibliotheksklasse) und eine Shortposition wird unter Verwendung der PositionOpen() Method der CTrade Klasse eröffnet.


3.13 Die Processing() Methode der CSampleExpert Klasse

//+------------------------------------------------------------------------+
//| Hauptfunktion gibt true zurück, wenn eine Position verarbeitet wurde   |
//+------------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
  {
//--- Quotierungen aktualisieren
   if(!m_symbol.RefreshRates())
      return(false);
//--- Aktualisierung des Indikatorwertes
   if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2)
      return(false);
   if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main)  !=2 ||
      CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 ||
      CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA)         !=2)
      return(false);
//--- Um die Arbeit mit den Indikatoren zu vereinfachen und für schnelleren Zugriff
//--- werden die aktuellen Werte derIndikatoren in internen Variablen gespeichert (Klassenmembers)
   m_macd_current   =m_buff_MACD_main[0];
   m_macd_previous  =m_buff_MACD_main[1];
   m_signal_current =m_buff_MACD_signal[0];
   m_signal_previous=m_buff_MACD_signal[1];
   m_ema_current    =m_buff_EMA[0];
   m_ema_previous   =m_buff_EMA[1];
//--- korrekter Markteinstieg ist wichtig, aber ein korrekter Ausstieg ist noch wichtiger
//--- Zuerst prüfen, ob es eine offene Position gibt
   if(m_position.Select(Symbol()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- wenn nötig versuchen wir eine Longposition zu schließen oder modifizieren
         if(LongClosed())
            return(true);
         if(LongModified())
            return(true);
        }
      else
        {
         //--- wenn nötig versuchen wir eine Shortposition zu schließen oder modifizieren
         if(ShortClosed())
            return(true);
         if(ShortModified())
            return(true);
        }
     }
//--- keine offenen Positionen
   else
     {
      //--- Prüfe Bedingungen und öffne eine Longposition falls notwendig
      if(LongOpened())
         return(true);
      //--- Prüfe Bedingungen und öffne eine Shortposition falls notwendig
      if(ShortOpened())
         return(true);
     }
//--- Ausstieg ohne Verarbeitung von Positionen
    return(false);
  }

Die Processing() Methode der CSampleExpert Klasse ist die Methode des Expert Advisor. Die Processing() Methode wird im OnTick() Ereignishandler aufgerufen und das Zeitintervall zwischen erfolgreichen Aufrufen dieser Methode wird protokolliert (nicht weniger als ExtTimeOut Sekunden) (Abschnitt 2.2).

Durch den Aufruf der RefreshRates() Methode der CSymbolInfo Klasse werden die Quotierungen aktualisiert. Die BarsCalculated() Funktion wird verwendet, um die Anzahl von Balken abzufragen für die die IndikatorenMACD und Moving Average berechnet werden (Abschnitt 3.6.); wenn die Anzahl der Balken weniger als 2 ist, verlasse die Funktion und gib false zurück.

Dann fordert der Aufruf der CopyBuffer Funktion die letzten zwei Werte der technischen Indikatorem an (die Haupt- und Signallinie des MACD und Moving Average Werte); und wenn die Menge der kopierten Daten kleiner als zwei ist, verlasse die Funktion. Danach werden die Werte der Indikatoren von den Arrays m_buff_MACD_main[], m_buff_MACD_signal[] und m_buff_EMA[] in die Variablen m_macd_current, m_macd_previous, m_signal_current, m_signal_previous, m_ema_current und m_ema_previous kopiert.

Der nächste Schritt ist die Arbeit mit einer Position mit den Mitteln der Klasse CPositionInfo der Standardbibliothek. Wenn der Aufruf der Select() Methode true zurück gibt, bedeutet das, dass es derzeit eine offene Position gibt, ihr Typ wird durch die PositionType() Methode bestimmt. Weitere Arbeit wird in Überinstimmung mit dem Typ der offenen Position ausgeführt.


4. Backtesting

Die besten Werte für die Parameter können durch Verwendung des Strategie Testers des MetaTrader 5 Terminals gefunden werden.

Abbildung 3 zeigt die Ergebnisse des Test des Expert Advisor für 2013 mit Standardeinstellungen.

Abbildung 3. Backtesterebnisse für MACD Beispiel Expert Advisor

Abbildung 3. Backtesterebnisse für MACD Beispiel Expert Advisor

Schlussfolgerungen

Der MACD Beispiel Expert Advisor, der im Standardpaket des MetaTrader 5 Terminals enthalten ist, ist ein Beispiel für einen objektorientierten Ansatz in der EA Entwicklung.


Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalpublikation: https://www.mql5.com/ru/code/2154

MultiT3_TRIXx7Signal MultiT3_TRIXx7Signal

Der MultiT3_TRIXx7Signal Indikator zeigt Informationen des aktuellen Trends unter Verwendung der Werte von sieben T3_TRIX Indikatoren von verschiedenen TimeFrames.

BackgroundCandle_T3_TRIX_HTF BackgroundCandle_T3_TRIX_HTF

Der Indikator zeichnet Kerzen größerer TimeFrames als farbig gefüllte Rechtecke. Rechtecke werden farbig gefüllt in Übereinstimmung mit der Richtung des T3_TRIX Histogramms.

Exp_T3_TRIX Exp_T3_TRIX

Ein Handelssystem das den T3_TRIX Indikator verwendet.

Exp_RSIOMA_V2 Exp_RSIOMA_V2

Handelssystem das den RSIOMA_V2 Indikator verwendet.