MQL5 Assistent: Erstellen eines Moduls zum Verfolgen offener Positionen

MetaQuotes | 14 März, 2016

Einleitung

MetaTrader 5 verfügt über ein leistungsstarkes Werkzeug für die schnelle Überprüfung von Handelsideen. Dabei handelt es sich um MQL5 Wizard, den Erzeuger von Handelsstrategien. Die Verwendung des MQL5 Wizard für die automatische Erzeugung des Quellcodes von Expert Advisors wird im Beitrag "MQL5 Wizard: Erstellen von Expert Advisors ohne Programmierung" beschrieben. Die Offenheit des Systems zur Erzeugung von Codes ermöglicht die Ergänzung der Standardklassen durch benutzerdefinierte Klassen von Handelssignalen, Geldverwaltungssysteme und Verfolgungsmodule.

In diesem Beitrag werden die Prinzipien des Schreibens von Modulen zum Verfolgen offener Positionen für die weitere Verwendung im MQL5 Wizard beschrieben.

Ein mithilfe des MQL5 Wizards geschriebener Expert Advisor basiert auf vier Basisklassen:

Abbildung 1. Struktur der Basisklasse CExpert

Abbildung 1. Struktur der Basisklasse CExpert.


Die Klasse CExpert (oder ihre Unterklasse) ist der wichtigste "Antrieb" des Handelsroboters. Die Instanz der Klasse CExpert enthält Instanzen der Klassen CExpertSignal, CExpertMoney und CExpertTrailing (oder deren Unterklassen):

  1. CExpertSignal – Haupterzeuger der Handelssignale. Die in der Klasse CExpert beinhaltete Instanz der Unterklasse CExpertSignal liefert dem Expert Advisor Informationen über Möglichkeiten zum Markteintritt, Eintrittsniveaus und die Einrichtung von Schutzordern auf Basis interner Algorithmen. Die letztendliche Entscheidung über die Durchführung von Handelstätigkeiten wird durch den Expert Advisor getroffen. Sie können über das Schreiben eines Moduls von Handelssignalen im Beitrag "MQL5 Wizard: Erstellen eines Moduls von Handelssignalen" nachlesen.
  2. CExpertMoney ist das Hauptsystem zur Verwaltung von Geld und Risiken. Die Instanz der Unterklasse CExpertMoney berechnet Volumina zu öffnender Positionen und zu platzierender Pending Orders. Die letztendliche Entscheidung über Volumina wird durch den Expert Advisor getroffen. Die Prinzipien der Entwicklung von Modulen für Geld- und Risikomanagement werden im Beitrag "MQL5 Wizard: Erstellen eines Moduls für Geld- und Risikomanagement" beschrieben.
  3. CExpertTrailing ist das Hauptmodul zum Verfolgen offener Positionen. Die Instanz der Unterklasse CExpertTrailing signalisiert dem Expert Advisor, ob eine Anpassung der Schutzorder einer Position erforderlich ist. Die letztendliche Entscheidung über die Anpassung der Order wird durch den Expert Advisor getroffen.

Zusätzlich gehören die folgenden Klasseninstanzen zur Klasse CExpert:

Im weiteren Verlauf dieses Texts meinen wir mit "Expert Advisor" eine Instanz der Klasse CExpert oder ihrer Unterklasse.

Eine detailliertere Beschreibung der CExpert-Klasse und der Arbeit mit ihr finden Sie in einem gesonderten Beitrag.

1. Basisklasse CExpertTrailing

Die Klasse CExpertTrailing bildet die Basis des Moduls zum Verfolgen offener Positionen. Zur Interaktion mit der "Außenwelt" verfügt die Klasse CExpertTrailing über eine Reihe öffentlicher virtueller Methoden:

Initialisierung

 Beschreibung

virtuell Init

Die Initialisierung der Klasseninstanz sorgt für die Synchronisierung von Daten des Moduls mit Daten des EAs

virtuell ValidationSettings

Validierung der eingerichteten Parameter

virtuell InitIndicators

Erstellung und Initialisierung aller für die Arbeit des Erzeugers von Handelssignalen erforderlichen Indikatoren und Zeitreihen

Signale der Anpassung von Positionen

 

virtual CheckTrailingStopLong

Erzeugung eines Signals für die Anpassung einer langen Position mit Bestimmung eines neuen Preises für die Stop-Order

virtual CheckTrailingStopShort

Erzeugung eines Signals für die Anpassung einer kurzen Position mit Bestimmung eines neuen Preises für die Stop-Order


Beschreibung der Methoden

1.1 Initialisierungsmethoden

1.1.1 Init

Die Init()-Methode wird automatisch nach dem Hinzufügen der Klasseninstanz zum Expert Advisor aufgerufen. Ein Überschreiben der Methode ist nicht erforderlich.

virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);

1.1.2 ValidationSettings

Die ValidationSettings()-Methode wird vom Expert Advisor nach der Festlegung aller Parameter aufgerufen. Die Methode muss überschrieben werden, wenn es Einrichtungseinstellungen gibt.

virtual bool ValidationSettings();

Die überschriebene Methode muss true ausgeben, wenn alle Parameter korrekt (für die Verwendung geeignet) sind. Wenn irgendein Parameter ungültig ist, muss der Parameter false ausgeben (weitere Verwendung ist unmöglich).

Die Basisklasse CExpertTrailing verfügt über keine einzustellenden Parameter, deshalb gibt die Methode immer true aus, ohne Prüfungen durchzuführen.

1.1.3 InitIndicators

Die InitIndicators()-Methode erstellt und initialisiert alle erforderlichen Indikatoren und Zeitreihen. Sie wird vom Expert Advisor nach der Festlegung und Validierung aller Parameter aufgerufen. Die Methode sollte überschrieben werden, falls der Erzeuger von Handelssignalen mindestens einen Indikator oder eine Zeitreihe nutzt.

virtual bool InitIndicators(CIndicators* indicators);

Indikatoren und/oder Zeitreihen müssen über die entsprechenden Klassen der Standardbibliothek genutzt werden. Pointer aller Indikatoren und/oder Zeitreihen müssen zur Indikatorsammlung des Expert Advisors hinzugefügt werden (zu der der Pointer als Parameter übergeben wird).

Die überschriebene Methode muss true ausgeben, wenn alle Anpassungen der Indikatoren und/oder Zeitreihen erfolgreich waren (für die Verwendung geeignet). Wenn mindestens eine Operation mit den Indikatoren und/oder Zeitreihen fehlgeschlagen ist, muss die Methode false ausgeben (weitere Verwendung ist unmöglich).

Die Basisklasse CExpertTrailing nutzt keine Indikatoren und Zeitreihen, deshalb gibt die Methode der Basisklasse immer true aus, ohne Prüfungen durchzuführen.


1,2. Methoden zur Prüfung des Signals zur Positionsanpassung

1.2.1 CheckTrailingStopLong

Die Methode CheckTrailingStopLong() erzeugt ein Signal zur Anpassung einer langen Position und definiert einen neuen Preis der Stop-Loss-Order (sowie der Take-Profit-Order, falls erforderlich). Sie wird vom Expert Advisor aufgerufen, um zu bestimmen, ob eine lange Position angepasst werden muss. Sie muss überschrieben werden, wenn Sie ein Signal zur Anpassung einer langen Position generieren möchten.

virtual bool CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)

Die Methode muss den Algorithmus der Prüfung der Bedingung für die Anpassung der langen Position umsetzen. Wenn die Bedingung erfüllt ist, muss der Variable sl (sowie tp, falls erforderlich) der entsprechende Wert zugewiesen werden und die Methode muss true ausgeben. Verweise auf die Variablen sl und tp müssen als Parameter übergeben werden. Wenn die Bedingung nicht erfüllt ist, muss die Methode false ausgeben.

Die Basisklasse CExpertTrailing verfügt über keinen eingebetteten Algorithmus zur Erzeugung eines Signals zur Anpassung einer langen Position, deshalb gibt die Methode der Basisklasse immer false aus.

1.2.2 CheckTrailingStopShort

Die Methode CheckTrailingStopShort() erzeugt ein Signal zur Anpassung einer kurzen Position und definiert einen neuen Preis der Stop-Loss-Order (sowie der Take-Profit-Order, falls erforderlich). Sie wird vom Expert Advisor aufgerufen, um zu bestimmen, ob eine kurze Position angepasst werden muss. Die Methode muss überschrieben werden, wenn Sie ein Signal zur Anpassung einer kurzen Position generieren möchten.

virtual bool CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)

Die Methode muss den Algorithmus zur Prüfung der Bedingung für die Anpassung einer kurzen Position umsetzen. Wenn die Bedingung erfüllt ist, muss der Variable sl (sowie tp, falls erforderlich) der entsprechende Wert zugewiesen werden und die Methode muss true ausgeben. Verweise auf die Variablen sl und tp müssen als Parameter übergeben werden. Wenn die Bedingung nicht erfüllt ist, muss die Methode false ausgeben.

Die Basisklasse CExpertTrailing verfügt über keinen eingebetteten Algorithmus zur Erzeugung eines Signals zur Anpassung einer kurzen Position, deshalb gibt die Methode der Basisklasse immer false aus.

2. Schreiben Ihres eigenen Moduls zur Verfolgung offener Positionen

Nachdem wir die Struktur der Basisklasse CExpertTrailing betrachtet haben, können Sie mit der Erstellung Ihres eigenen Moduls zur Verfügung offener Positionen fortfahren.

Wie bereits erwähnt, bildet die Klasse CExpertTrailing einen Satz öffentlicher virtueller "Schnüre", Methoden also, anhand derer Nutzung der Expert Advisor die Meinung des Moduls zur Verfolgung offener Positionen zur Notwendigkeit der Anpassung von Schutzordern erfahren kann.

Deshalb ist es unser vorrangiges Ziel, unsere eigene Klasse zur Verfolgung offener Positionen zu erstellen, die wir von der CExpertTrailing-Klasse ableiten und die jeweiligen virtuellen Methoden überschreiben und die nötigen Algorithmen umsetzen.

Unser zweites Ziel (das nicht weniger wichtig ist) ist es, unsere Klasse für den MQL5 Wizard "sichtbar" zu machen. Doch das Wichtigste zuerst.

2.1 Erstellen der Klasse des Erzeugers von Handelssignalen

Fangen wir an.

Als Erstes erstellen wir (zum Beispiel mithilfe des MQL5 Wizards) eine Include-Datei mit der Erweiterung mqh.

Im Dateimenü wählen wir dazu "Erzeugen" aus (oder drücken Ctrl+N) und geben die Erzeugung einer eingeschlossenen Datei an

Abb. 2 Erzeugung einer einzuschließenden Datei mit Hilfe des MQL5 Assistenten.

Abb. 2 Erzeugung einer einzuschließenden Datei mit Hilfe des MQL5 Assistenten.

Beachten Sie, dass die Datei im Ordner Include\Expert\ erstellt werden sollte, damit sie vom MQL5 Wizard als Modul zur Verfolgung offener Positionen "entdeckt" werden kann.

Um die Standardbibliothek nicht zu vermüllen, erstellen Sie Ihren eigenen Ordner Include\Expert\Trailing\MyTrailing, in dem wir die Datei SampleTrailing.mqh erstellen, und geben Sie diese Parameter im MQL5 Wizard an:

Abbildung 3. Festlegen des Ablageorts der Include-Datei.

Abb. 3 Festlegen des Ablageorts der Include-Datei.

Als Ergebnis der Arbeit des MQL5 Wizard erhalten wir das folgende Muster:

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2010
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+

Was nun folgt ist nur "manuelle" Arbeit. Entfernen Sie alles Unnötige und fügen Sie hinzu, was nötig ist (Include-Datei ExpertTrailing.mqh der Standardbibliothek und eine noch leere Klassenbeschreibung).

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing.                                           |
//| Purpose: Class for trailing of open positions.                   |
//|             Is derived from the CExpertTrailing class.           |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
  };
//+------------------------------------------------------------------+

Nun müssen die Algorithmen ausgewählt werden.

Nehmen wir den folgenden Algorithmus als Basis unseres Moduls zur Verfolgung offener Positionen: Verschieben Sie die Stop-Order in einen verlustfreien Bereich, wenn sich der Preis um eine festgelegte Distanz in die benötigte Richtung bewegt. Bilden Sie dies in unserer Datei ab.

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing.                                           |
//| Purpose: Class for trailing of open positions by                 |
//|             moving the Stop order "to the loseless level".       |
//|             Is derived from the CExpertTrailingclass.            |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
  };
//+------------------------------------------------------------------+

Definieren wir nun, welche Daten zum Treffen von Entscheidungen über die Anpassung von Schutzordern erforderlich sind. In unserem Fall ist es der Gewinn einer angepassten Position in Punkten.

Definieren Sie die Liste der Parameter für die Einrichtung unseres Moduls zur Verfolgung offener Positionen. Wir brauchen zwei Parameter:

  1. Menge der Punkte des Gewinns der Position, anhand derer wir vorschlagen, die Stop-Order in einen verlustfreien Bereich zu verschieben.
  2. Verlustfreier Bereich, d. h. wie viele Gewinnpunkte wir durch die verschobene Stop-Order festlegen.

Die Einstellungen des Moduls werden in geschützten Datenteilen der Klasse gespeichert. Der Zugriff auf die Einstellungen erfolgt durch die entsprechenden öffentlichen Methoden.

Wir ergänzen unsere Datei mit diesen Veränderungen:

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing.                                           |
//| Purpose: Class for trailing of open positions                    |
//|             by moving Stop order to a lossless level.            |
//|             Is derived from the CExpertTrailing class.           |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             //threshold level of profit
   int                m_stop_level;         // lossless level

public:
   //--- methods of setting adjustable parameters
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
  };
//+------------------------------------------------------------------+

Um die einstellbaren Parameter mit Standardwerten zu initialisieren, müssen wir den Klassenkonstruktor hinzufügen.

Überschreiben Sie zur Validierung der Einstellungen die virtuelle Methode ValidationSettings (gemäß der Beschreibung der Basisklasse).

Beschreibung der Klasse:

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing.                                           |
//| Purpose: Class for trailing of open positions                    |
//|             by moving Stop order to a lossless level.            |
//|             Is derived from the CExpertTrailing class.           |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // threshold level of profit
   int                m_stop_level;         // lossless level

public:
                      CSampleTrailing();
   //--- methods of setting adjustable parameters
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
   //--- method of validating the adjustable parameters
   virtual bool        ValidationSettings();
  };
//+------------------------------------------------------------------+

Umsetzung der Methode ValidationSettings():

//+------------------------------------------------------------------+
//| Validation of adjustable parameters.                             |
//| INPUT:  no.                                                      |
//| OUTPUT: true if parameter are correct, false - if not.           |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleTrailing::ValidationSettings()
  {
   if(!CExpertTrailing::ValidationSettings())
      return(false);
//--- check wheter the Init method is called
   if(m_symbol==NULL) return(false);
//--- check parameters
   if((m_profit-m_stop_level)*m_adjusted_point<=m_symbol.StopsLevel()*m_symbol.Point() && m_profit!=0.0)
     {
      printf(__FUNCTION__+": threshold level of profit must be greater than the level of  setting of orders");
      return(false);
     }
//--- ok
   return(true);
  }

Alle vorbereitenden Schritte sind abgeschlossen.

Betrachten wir unsere Algorithmen nun detaillierter.

1. Ein Signal für die Anpassung einer langen Position erscheint, wenn die folgenden Bedingungen erfüllt sind:

Schlagen Sie in diesem Fall vor, die Stop-Order gemäß den Einstellungen anzupassen. Überschreiben Sie zu diesem Zweck die virtuelle Methode CheckTrailingStopLong und füllen Sie sie mit den entsprechenden Funktionen.

2 Ein Signal für die Anpassung einer kurzen Position erscheint, wenn die folgenden Bedingungen erfüllt sind:

Schlagen Sie in diesem Fall vor, die Stop-Order gemäß den Einstellungen anzupassen. Überschreiben Sie zu diesem Zweck die virtuelle Methode CheckTrailingStopShort und füllen Sie sie mit den entsprechenden Funktionen.

Beschreibung der Klasse

class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // threshold level of profit
   int                m_stop_level;         // lossless level

public:
                      CSampleTrailing();
   //--- methods of setting adjustable parameters
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
   //--- method of validation of adjustable parameters
   virtual bool       ValidationSettings();
   //--- methods of generation of position modification signals
   virtual bool       CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp);
   virtual bool       CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp);
  };

Umsetzung der Methoden CheckTrailingStopLong und CheckTrailingStopShort:

//+------------------------------------------------------------------+
//| Check for modification of stop orders of a long position.        |
//| INPUT:  position - pointer to a position object,                 |
//|         sl       - link for a new price of stop loss order,      |
//|         tp       - link for a new price of take profit order.    |
//| OUTPUT: true if condition is satisfied, false - if not.          |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)
  {
//--- check of pointer
   if(position==NULL) return(false);
//--- check of parameter
   if(m_profit==0.0)  return(false);
//--- already in a lossless zone?
   double open=position.PriceOpen();
   if(position.StopLoss()>=open) return(false);
//--- check of profit
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(m_symbol.Bid()-open>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open+m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a short position.       |
//| INPUT:  position - pointer to a position object,                 |
//|         sl       - link to a new price of stop loss order,       |
//|         tp       - link to a new price of take profit order.     |
//| OUTPUT: true if condition is satisfied, false - if not.          |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)
  {
//--- check of pointer
   if(position==NULL) return(false);
//--- check of parameter
   if(m_profit==0.0)  return(false);
//--- already in a lossless zone?
   double open=position.PriceOpen();
   if(position.StopLoss()<=open) return(false);
//--- check of profit
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(open-m_symbol.Ask()>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open-m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }

2,2 Schreiben einer Beschreibung der erstellten Klasse von Handelssignalen für den MQL5 Wizard

Wir widmen uns nur der Lösung des zweiten Problems. Unser Modul zur Verfolgung offener Positionen sollte durch den MQL5 Wizard "erkannt" werden.

Die erste Voraussetzung haben wir bereits erfüllt: Wir haben die Datei an einem Ort platziert, an dem sie vom MQL5 Wizard "gefunden" wird. Doch das genügt noch nicht. Der MQL5 Assistent muss die Datei nicht nur "finden", er muss sie auch als solche "erkennen". Dafür müssen wir den Klassendeskriptor für den MQL5 Wizard zum Originaltext hinzufügen.

Einen Klassen-Descriptor ist ein Block an Kommentaren, der gemäß bestimmter Regeln zusammengesetzt ist.

Und die sehen wir uns jetzt mal an.

1. Der Kommentarblock sollte mit den folgenden Zeilen beginnen:

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |

2. Die nächste Zeile ist ein Testdeskriptor (was wir bei der Auswahl des Signals im MQL5 Wizard sehen werden) im Format "//| Title=<Text> |". Ist der Text zu lang für einen Zeile, dann fügen Sie noch eine Zeile (aber nicht mehr!) hinzu. </p>

In unserem Fall erhalten wir:

//| Title=Signal on the crossing of a price and the MA               |
//| entering on its back movement                                    |

3. Es folgt eine Zeile mit dem Klassentypen im Format "//| Type=<Type> |". Das <Typ> Feld muss den Signalwert besitzen (zusätzlich zu Signalen kennt der MQL5 Assistent auch noch andere Typen an Klassen).

Man schreibt:

//| Type=Trailing                                                    |

4. Die folgende Zeile im Format "//| Name=<Name> |" ist der Kurzname des Signals (wird vom MQL5 Wizard zum Erzeugen der Namen der globalen Variablen des Experten verwendet).

Wir erhalten folgendes:

//| Name=BreakEven                                                   |

5. Der Name einer Klasse ist ein wichtiger Bestandteil der Beschreibung. In der Zeile im Format "//| Class=<ClassNameа> |", muss der <ClassName> Parameter mit dem Namen unserer Klasse übereinstimmen:

//| Class=CSampleTrailing                                            |

6. Wir füllen diese Zeile nicht aus, aber sie muss vorhanden sein (es handelt sich um einen Link zum Nachschlagewerk):

//| Page=                                                            |

7. Es folgen Beschreibungen der Parameter der Moduleinstellungen.

Dies ist ein Satz von Zeilen (die Menge der Zeilen entspricht der Menge der Parameter).

Das Format jeder Zeile lautet: "//| Parameter=<NameOfMethode>,<TypeOfParameter>,<DefaultValue> |".

Hier ist unser Parametersatz:

//| Parameter=Profit,int,20                                          |
//| Parameter=StopLevel,int,0                                        |

8. Der Kommentarblock sollte mit den folgenden Zeilen enden:

//+------------------------------------------------------------------+
// wizard description end

Fügen wir den Deskriptor zum Quellcode hinzu.

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Moving a position to a lossless level                      |
//| Type=Trailing                                                    |
//| Name=BreakEven                                                   |
//| Class=CSampleTrailing                                            |
//| Page=                                                            |
//| Parameter=Profit,int,20                                          |
//| Parameter=StopLevel,int,0                                        |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSampleTrailing.                                           |
//| Purpose: Class for trailing of open positions                    |
//|             by moving Stop order to a lossless level.            |
//|             Is derived from the CExpertTrailing class.           |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // threshold level of profit
   int                m_stop_level;         // lossless level

public:
                      CSampleTrailing();
   //--- method of setting adjustable parameters
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
   //--- method of validation of adjustable settings
   virtual bool       ValidationSettings();
   //--- methods of generation of position modification signals
   virtual bool       CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp);
   virtual bool       CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp);
  };
//+------------------------------------------------------------------+
//| Constructor CSampleTrailing.                                     |
//| INPUT:  no.                                                      |
//| OUTPUT: no.                                                      |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
void CSampleTrailing::CSampleTrailing()
  {
//--- setting default values
   m_profit    =20;
   m_stop_level=0;
  }
//+------------------------------------------------------------------+
//| Check of adjustable parameters.                                  |
//| INPUT:  no.                                                      |
//| OUTPUT: true if the parameters are correct, false if not.        |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleTrailing::ValidationSettings()
  {
//--- what if the Init has not been called?
   if(m_symbol==NULL) return(false);
//--- check of parameters
   if((m_profit-m_stop_level)*m_adjusted_point<=m_symbol.StopsLevel()*m_symbol.Point() && m_profit!=0.0)
     {
      printf(__FUNCTION__+": threshold level of profit must be greater than the level of setting stop orders");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a long position.        |
//| INPUT:  position - pointer to a position object,                 |
//|         sl       - link for a new price of stop loss order,      |
//|         tp       - link for a new price of take profit order.    |
//| OUTPUT: true if condition is satisfied, false if not.            |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)
  {
//--- check of pointer
   if(position==NULL) return(false);
//--- check of parameters
   if(m_profit==0.0)  return(false);
//--- already in a lossless zone?
   double open=position.PriceOpen();
   if(position.StopLoss()>=open) return(false);
//--- check of profit
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(m_symbol.Bid()-open>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open+m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a short position.       |
//| INPUT:  position - pointer to a position object,                 |
//|         sl       - link for a new price of stop loss order,      |
//|         tp       - link for a new take profit order.             |
//| OUTPUT: true if condition is satisfied, false if not.            |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)
  {
//--- check of pointer
   if(position==NULL) return(false);
//--- check of parameters
   if(m_profit==0.0)  return(false);
//--- already in a lossless zone?
   double open=position.PriceOpen();
   if(position.StopLoss()<=open) return(false);
//--- check of profit
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(open-m_symbol.Ask()>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open-m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }
//+------------------------------------------------------------------+

Und das ist alles. Das Verfolgungsmodul ist einsatzbereit.

Damit der Erzeuger von Handelsstrategien MQL5 Wizard unser Modul nutzen kann, müssen wir MetaEditor neu starten (MQL5 Wizard durchsucht den Ordner Include\Expert nur beim Start).

Nach dem Neustart von MetaEditor kann das erstellte Modul zur Verwaltung offener Positionen im MQL5 Wizard genutzt werden:

Abbildung 5. Das erstellte Modul zur Verwaltung offener Positionen im MQL5 Wizard.

Abbildung 5. Das erstellte Modul zur Verwaltung offener Positionen im MQL5 Wizard.

Die im Abschnitt der Beschreibung der Parameter des Moduls zur Verwaltung offener Positionen festgelegten Eingabeparameter sind nun verfügbar:

Abbildung 6 Die Eingabeparameter des erstellen Moduls zur Verwaltung offener Positionen im MQL5 Wizard.

Abbildung 6. Die Eingabeparameter des erstellen Moduls zur Verwaltung offener Positionen im MQL5 Wizard.

Die besten Werte der Eingabeparameter der umgesetzten Handelsstrategie knnen mithilfe des Strategietesters des MetaTrader-5-Terminals gefunden werden.

Fazit

Als Erzeuger von Handelsstrategien vereinfacht der MQL5 Wizard das Testen von Handelsideen enorm. Der Code des erzeugten Experten basiert auf den Klassen von Handelsstrategien aus der Standardbibliothek, die für die Erstellung bestimmter Implementierungen von Handelssignalklassen, Klassen für die Geld- und Risikoverwaltung und Klassen für die Positionsunterstützung genutzt werden. 

In diesem Beitrag wird besprochen, wie Ihre eigene Klasse zum Verwalten offener Positionen durch die Verschiebung des Stop-Loss-Niveaus in einen verlustfreien Bereich, wenn sich der Preis in Richtung der Position bewegt, geschrieben und mit dem MQL5 Wizard verbunden werden kann, um Drawdowns beim Handel zu verringern. Es wird auch auf die Struktur und das Format der Beschreibung der erstellten Klasse für den MQL5 Wizard eingegangen.