und werden Sie Mitglied unserer Fangruppe
Veröffentliche einen Link auf das Skript, damit die anderen ihn auch nutzen können
Bewerten Sie es im Terminal MetaTrader 5
- Veröffentlicht:
- MetaQuotes
- Ansichten:
- 5302
- Rating:
- 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:
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
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:
- CSampleExpert(void) - ein Konstruktor (wird automatisch aufgerufen, wenn eine Klasseninstanz erstellt wird);
- ~CSampleExpert(void) - ein Destruktor (wird automatisch aufgerufen, wenn eine Klasseninstanz gelöscht wird);
- bool Init(void) - Initialisierungsmethode, in der alle für die Verarbeitung benötigten Daten vorbereitet werden;
- void Deinit(void) - Deinitialisierungsmethode;
- 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.
- double m_adjusted_point - Vervielfacher Variabele für eine korrekte Verarbeitung von 3/5-stelligen Quotierungen;
- CTrade m_trade - СTrade Klassenbeispiel;
- CSymbolInfo m_symbol - CSymbolInfo Klassenbeispiel;
- CPositionInfo m_position - СPositionInfo Klassen Beispiel;
- CAccountInfo m_account - CAccountInfo Klassen Beispiel
- int m_handle_macd - eine Variable zur Speicherung des Wertes des MACD Indikator Handles.
- int m_handle_ema - eine Variable zur Speicherung des Wertes des EMA Indikator Handles;
- double m_buff_MACD_main[] - ein dynamisches Array des Typs Double, das zur Abfrage der Werte der Haupt-MACD-Linie verwendet wird;
- double m_buff_MACD_signal[] - ein dynamisches Array des Typs Double, das zur Abfrage der Werte der MACD Signallinie verwendet wird;
- double m_buff_EMA[] - ein dynamisches Array des Typs Double, das zur Abfrage der Werte des EMA Indikators verwendet wird;
- double m_macd_current - wird verwendet zur Speicherung des aktuellen Wertes der MACD Linie;
- double m_macd_previous - wird verwendet zur Speicherung des vorherigen Wertes der Haupt-MACD-Linie;
- double m_signal_current - iwird verwendet zur Speicherung des aktuellen Wertes der MACD Signallinie;
- double m_signal_previous - wird verwendet zur Speicherung des vorherigen Wertes der MACD Signallinie;
- double m_ema_current - wird verwendet zur Speicherung des aktuellen Wertes des EMA Indikators;
- double m_ema_previous - wird verwendet zur Speicherung des vorherigen Wertes des EMA Indikator
- double m_macd_open_level,
- double m_macd_close_level,
- double m_traling_stop,
- 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:
- bool InitCheckParameters(const int digits_adjust) - Prüfung der Richtigkeit der Eingabeparameter und Initialisierung der EA Parameter;
- bool InitIndicators(void) - Initialisierung (Ersstellung ) der MACD und Moving Average Indikatoren;
- 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;
- 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;
- 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;
- 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;
- bool LongOpened(void) - gibt true zurück (und öffnet eine Longposition) wenn die Bedingungen zum Öffnen einer Longpositon erfüllt sind;
- 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:
- m_macd_current>0 - der aktuell Wert der Hauptlinie dies MACD Indikator ist positiv (MACD Histogramm ist über der Nulllinie);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal nach unten gekreuzt.
- 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:
- m_macd_current<0 - der aktuelle Wert der Hauptlinie des MACD Indikator ist negativ (MACD-Histogramm ist unter der Nulllinie).
- m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal aufwärts gekreuzt.
- 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:
- m_macd_current<0 - der aktuelle Wert der Hauptlinie des MACD Indikator ist negativ (MACD-Histogramm ist unter der Nulllinie);
- m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal aufwärts gekreuzt;
- 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;
- 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:
- m_macd_current>0 - der aktuell Wert der Hauptlinie dies MACD Indikator ist positiv (MACD Histogramm ist über der Nulllinie);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - die Hauptlinie des MACD Indikator hat das Signal nach unten gekreuzt;
- m_macd_current>m_macd_open_level - der aktuelle Wert der Hauptlinie des MACD Indikator Modulo ist größer als m_macd_open_level;
- 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
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

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

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.

Ein Handelssystem das den T3_TRIX Indikator verwendet.

Handelssystem das den RSIOMA_V2 Indikator verwendet.