
Cross-Plattform Expert Advisor: Stopps
Inhaltsverzeichnis
- Einführung
- COrder
- CStop
- CStops
- COrderStop
- COrderStops
- Darstellung der Stopps auf dem Chart
- Prüfen der Stopps einer Position
- Beispiele
- Schlussfolgerung
- Die Programme dieses Artikels
- Die Dateien der Klassen dieses Artikels
Einführung
Wie in einem vorherigen Artikel besprochen, haben wir für einen plattformübergreifenden Experten Advisor eine Positionsverwaltung (COrderManager) erstellt, der die meisten Unterschiede zwischen MQL4 und MQL5 in Bezug auf den Ein- und Ausstieg von Positionen berücksichtigt. In beiden Versionen speichert der Expert Advisor die Informationen der Positionen im Speicher, indem er Instanzen von COrder erstellt. Die Container mit den dynamischen Pointern auf die Instanzen dieses Klassenobjekts stehen auch als Mitglieder der Klasse COrderManager (für aktuelle und historische Positionen) zur Verfügung.
Es ist möglich, dass die Positionsverwaltung die Stopps einer jeden Position direkt kontrolliert. Dies würde allerdings gewisse Einschränkungen mit sich bringen:
- Wahrscheinlich müsste COrderManager erweitert werden, um die Handhabung der Stopps für jeden Position anzupassen.
- Die existierenden Methoden des COrderManager befassen sich nur mit der Eröffnung der Hauptpositionen.
Der COrderManager könnte erweitert werden, so dass er die Stopps für jede Position einzeln handhabt. Dies beschränkt sich jedoch nicht nur auf die Platzierung der tatsächlichen Stopps, sondern auch andere Aufgaben im Zusammenhang mit der Kontrolle dieser Stopps, wie z. B. die Modifizierung und Überprüfung, ob der Markt bereits ein bestimmtes Preisniveau erreicht hat. Diese Funktionen würden COrderManager wesentlich komplexer machen, als er es derzeit ist, ganz zu schweigen von der zweifachen Implementierung.
Der Order-Manager beschäftigt sich nur mit der Eröffnung der Hauptpositionen, während einige Stopps den EA dazu verpflichten würden, andere Handelsoperationen durchzuführen, wie z. B. die Platzierung von Pending-Orders und das Schließen offener Positionen. Es wäre zwar möglich, dass der Order-Manager die Hauptpositionen selbstständig abwickeln kann, aber am besten sollte er sich aber auf die Eröffnung von Hauptpositionen konzentrieren und einem anderen Klassenobjekt die Stopps überlassen.
In diesem Artikel werden wir die Implementierung besprechen, bei der COrderManager (wie es derzeit der Fall ist) ausschließlich den Ein- und Ausstieg von Hauptpositionen handhabt, und die Stopps separat durch ein anderes Klassenobjekt (CStop) bearbeitet werden.
COrder
Wie wir aus einem früheren Artikel (siehe Cross-Plattform Expert Advisor: Orders) lesen konnten, wird nach erfolgreicher Positionseröffnung (entry) eine Instanz von COrder angelegt. Sowohl für MetaTrader 4 als auch für MetaTrader 5 können die Informationen über Stoploss und Takeprofit auf Seiten des Brokers gespeichert werden. Sollten die Stopps jedoch vor dem Broker verborgen bleiben oder mehrere Stopps involviert sein, sollten die Informationen über die meisten Stopps lokal gespeichert werden. Im letzteren Fall sollte also nach erfolgreicher Eröffnung einer Position zunächst die Instanz von COrder angelegt werden, gefolgt von einer neuen Instanz des Objektes mit deren verschiedenen Stoploss und Takeprofits. In einem früheren Artikel haben wir gezeigt, wie die Instanz von COrder beim Anlegen dem Order-Manager hinzugefügt werden, wie es auch die folgenden Abbildung zeigt:
Die Stopps werden in gleicher Weise hinzugefügt. Dafür müssen wir nur eine neue Methode nach dem Erstellen der Instanz von COrder einfügen, und bevor sie in die Liste der offenen Positionen (COrders) eingetragen wird. Deshalb müssen wir die obige Abbildung nur geringfügig ändern, wie die folgende Abbildung zeigt:
Der allgemeine Vorgang des Erstellen eines Stopps zeigt das folgende Bild:
Wie oben, in den beiden vorherigen Flussdiagrammen zu sehen ist, wird, sobald eine Position erfolgreich eröffnet wurde, eine neue Instanz von COrder angelegt, die diese repräsentiert. Danach werden die Instanzen COrderStop für jeden angegebenen Stoploss und jeden Takeprofit. Falls während der Initialisierung des Expert Advisors keine Instanz CStop deklariert wurde, wird dieser besondere Vorgang übersprungen. Wurden hingegen Instanzen von COrderStop erstellt, werden die Pointer auf diese Instanzen von dem vorher erstellten Objekt COrder gespeichert. Wir finden diesen Vorgang in der Methode Init() von COrder:
bool COrderBase::Init(COrders *orders,CStops *stops) { if(CheckPointer(orders)) SetContainer(GetPointer(orders)); if(CheckPointer(stops)) CreateStops(GetPointer(stops)); m_order_stops.SetContainer(GetPointer(this)); return true; }
Beim Erstellen der Stopps für die Instanz COrder können wir sehen, dass die Methode CreateStops() aufgerufen wird, wie man unten sieht:
void COrderBase::CreateStops(CStops *stops) { if(!CheckPointer(stops)) return; if(stops.Total()>0) { for(int i=0;i<stops.Total();i++) { CStop *stop=stops.At(i); if(CheckPointer(stop)==POINTER_INVALID) continue; m_order_stops.NewOrderStop(GetPointer(this),stop); } } }Die Methode iteriert über alle verfügbaren Instanzen von CStop, jeweils mit einem Paar von Stoploss und Takeprofit. Jede dieser Instanzen von CStop wird an eine Instanz von COrderStops übergeben, die einfach ein Container für alle Stopps einer Position ist. Damit können wir die Hierarchie der Klassenobjekte wie folgt aufbauen:
Für jede Instanz von COrder gibt es ein Mitglied des Typs COrderStops. Diese Instanz von COrderStops ist der Container (eine Erweiterung von CArrayObj), die die Pointer auf die Instanzen von COrderStop enthält. Jede Instanz von COrderStop steht für einen Stopp (CStop) für ausschließlich dieser spezifischen Position (Instanz von COrder).
CStop
Wie bereits erwähnt, möchten wir eine bestimmte Stufe der Freiheit in der Art haben, wie die Stopps von jeder Position behandelt werden, ohne den Quellcode des Order-Managers ändern zu müssen. Dies wird größtenteils durch die Klasse CStop erreicht. Folgendes sollte die Klasse leisten:
- Definieren der Stoploss und Takeprofits
- Durchführen der benötigten Berechnungen für die Stopps
- Implementieren der Stoploss und Takeprofits der Hauptposition
- Prüfen, ob die Stopps erreicht wurden
- Ausgleichen der Unterschiede zwischen MQL4 und MQL5 bei der Implementierung der Stoploss und Takeprofits
- Definieren, wie die Stopps im Laufe der Zeit behandelt werden sollen (z. B. Breakeven, Trailing etc.)
Die Punkte 1-5 werden in diesem Artikel besprochen, während dem Punkt 6 ein eigener Artikel gewidmet sein wird.
Typen
In diesem Artikel werden drei Arten von Stopps behandelt:
- Brokerseitige Stopps – Stopps, die dem Broker zusammen mit dem Handelsauftrag übergeben werden
- Stopps als Pending-Orders – Stopps mittels Pending-Orders, die entweder teilweise oder ganz die jeweilige Position schließen (Metatrader 4, Metatrader 5 "hedging mode"), oder die Größe der Position vermindern (Metatrader 5 "netting mode").
- Virtuelle Stopps (Stealth Stop) – Stopps, die der Broker nicht kennt und die lokal durch den Expert Advisor verwaltet werden.
Im MetaTrader 4 sind die brokerseitigen Stopps, die Stoploss und Takeprofits, mit denen der Händler am meisten vertraut ist. Die sind die Preise oder Stopps, die zusammen mit der Handelsauftrag dem Broker geschickt werden. Der Metatrader 5 im "hedging mode" verwendet dieselbe Mechanik wie der Metatrader 4. Im "netting mode" andererseits wird eine Pending-Order als Stopp von CStop verwendet, da Stoploss und Takeprofit sich unterscheiden(angewendet auf die ganze Position des Symbols oder des Handelsinstrumentes).
Ein Stopp durch eine Pending-Order verwendet eben eine Pending-Order, um irgendwie einen brokerseitigen Stopp zu imitieren. Sobald eine Pending-Order ausgelöst wurde, wird der EA eine Handelsoperation ausführen (OrderCloseBy), um die bestehende Position durch das Volumen der gerade ausgelösten Pending-Order zu schließen. Dies gilt für die Metatrader 4 und Metatrader 5 im "hedging mode". Der Metatrader 5 im "netting mode" schließt einen Teil oder das ganze Volumen der offenen Position automatisch, da es je Symbol immer nur eine offene Position geben kann.
Hauptstopp
Der Hauptstopp ist der Stopp, der die ganze Position komplett schließt. Normalerweise ist dies der brokerseitige Stopp. Wenn brokerseitig entweder der Stoploss oder der Takeprofit ausgelöst werden, verschwindet die gesamte Position vom Markt, egal, ob der EA mit ihr weiterarbeiten wollte oder nicht. Wenn es jedoch mehrere Stopps gibt und keine brokerseitigen Stopps, wäre es womöglich eine schlechte Idee, wenn der EA entscheiden soll, welcher der Stopps der Hauptstopp ist. In diesem Falls muss der Programmierer entscheiden, welche Instanz von CStop der Hauptstopp sein soll. Das erweist sich für für manche Funktionen und Eigenschaften als besonders nützlich, die auf einem solchen Hauptstopp basieren, wie zum Beispiel das Geldmanagement. Da der Stoploss des Hauptstopps die gesamte Position schließt, repräsentiert er das maximale Risiko der Position. Und die Kenntnis über diese Situation erlaubt dem EA auf dieser Basis die Lotgröße zu berechnen.
Es ist erwähnenswert, dass, wenn ein Stopp als Hauptstopp ausgewählt wird, sein Volumen immer gleich dem anfänglichen Volumen der Hauptposition ist. Dies funktioniert gut mit den brokerseitigen und den virtuellen Stopps, aber nicht mit Stopps, die auf Pending-Orders basieren. Es gibt zwei Probleme, die zu dieser Lösung führen.
Der erste Grund ist, dass im MetaTrader 4 der Eröffnungspreis einer Pending-Order modifiziert werden kann, solange die Pending-Order noch nicht ausgelöst wird. Das ist im Metatrader 5 unmöglich, da eine klare Struktur der Handelsoperationen aufrechterhalten werden muss. Eine neue Pending-Order muss erteilt werden, und, wenn sie erfolgreich ist, sollte die alte gelöscht werden, und von da an sollte der Expert Advisor die neue Pending-Order als neuen Stopp verwenden.
Das zweite Problem ist die Möglichkeit, dass die alte Pending-Order ausgelöst wird, während die zweite, neue Pending-Order gerade an den Broker geschickt wird. Da der EA keine Kontrolle über das Auslösen der Pending-Orders hat (die hat der Broker), kann dies zu Problemen wie z. B. zu verwaisten Hauptpositionen oder einem Stopp führen, der ein höheres Volumen als das der eigentlichen Position schließen würde.
Um diese Probleme zu vermeiden, wäre der einfachere Ansatz, das Volumen der Pending-Orders bei der Eröffnung der Hauptposition zu verteilen, anstatt das Volumen der Pending-Orders während der gesamten Laufzeit des offenen Position dynamisch anzupassen. Dies setzt jedoch voraus, dass keine weiterer Pending-Order als Stopp existieren darf, wenn der Hauptstopp vom Typ Pending-Order ist.
Volumen
Für den Hauptstopp ist es nicht erforderlich, eine Lotgröße anzugeben, die das Volumen der Hauptposition vermindert, denn sobald sie ausgelöst wird, sollte die gesamte Position geschlossen werden. Bei den anderen Stopps muss jedoch das Volumen berücksichtigt werden, da sie in der Regel nur Anteile der Hauptposition schießen sollen. Es können vier verschiedene Typen unterschieden werden:
- Fix – feste Lotgröße
- Verbleibender Prozentsatz – offen bleibender Prozentsatz der Hauptposition
- Gesamter Prozentsatz – Prozentsatz der gesamten Lotgröße (Anfangsvolumen) der Hauptposition
- Verbleibend – das verbleibende Volumen der Hauptposition.
Eine feste Lotgröße ist die einfachste Form der Bestimmung des Volumens. Das würde jedoch nicht optimal funktionieren, wenn der Expert Advisor für jede Position dynamisch das Volumen berechnet, d.h. mit einem Geldmanagement. Dies ist nur dann ideal, wenn die Lotgröße über die ganze Zeit, die der Expert Advisor arbeitet, konstant bleibt.
"Verbleibender Prozentsatz" und "Verbleibend" werden am besten als virtuelle Hauptstopps verwendet. "Verbleibend" würde einen EA daran hindern verwaiste Positionen mit noch noch offenen Positionen zu erstellen oder eine Position mit einem Volumen größer als das des noch existierenden Volumens der Hauptposition zu schließen. "Verbleibende Prozentsatz" andererseits wird verwendet, wenn der Expert Advisor die Position nicht mit dem Anfangsvolumen sondern dem noch existierenden Volumen der Hauptposition schließen soll.
Der gesamte Prozentanteil kann für Stopps brokerseitig, virtuell oder mit Pending-Orders verwendet werden. Die Berechnungen für diese Vorgehensweise basiert auf dem Anfangsvolumen der Hauptposition.
One-Cancels-the-Other (OCO)
CStop verfügt immer über zwei Werte, von denen einer der Stoploss, der andere Takeprofit ist. Es ist jedoch auch nur ein einziger Stopp möglich (nur Takeprofit und ohne Stoploss oder umgekehrt), wenn dem anderen der Wert Null zugewiesen wird. Standardmäßig wird bei nur einen Stopp, wenn dieser ausgelöst wird, der andere geschlossen. Die einzige Ausnahme davon ist, wenn CStop der Hauptstopp ist.
Basisklasse
Der Code der Basisklasse CStop (CStopBase) ist unten angeführt:
class CStopBase : public CObject { protected: //--- Stopps, Parameter bool m_active; bool m_main; string m_name; bool m_oco; double m_stoploss; string m_stoploss_name; ENUM_STOP_TYPE m_stop_type; double m_takeprofit; string m_takeprofit_name; int m_delay; //--- Stopps, Parameter der Position ENUM_VOLUME_TYPE m_volume_type; double m_volume; int m_magic; int m_deviation; string m_comment; //--- Stopps Parameter des Objektes bool m_entry_visible; bool m_stoploss_visible; bool m_takeprofit_visible; color m_entry_color; color m_stoploss_color; color m_takeprofit_color; ENUM_LINE_STYLE m_entry_style; ENUM_LINE_STYLE m_stoploss_style; ENUM_LINE_STYLE m_takeprofit_style; //--- Objekte CSymbolManager *m_symbol_man; CSymbolInfo *m_symbol; CAccountInfo *m_account; CTradeManager m_trade_man; CExpertTradeX *m_trade; CTrails *m_trails; CEventAggregator *m_event_man; CStops *m_stops; public: CStopBase(void); ~CStopBase(void); virtual int Type(void) const {return CLASS_TYPE_STOP;} //--- Initialisierung virtual bool Init(CSymbolManager*,CAccountInfo*,CEventAggregator*); virtual bool InitAccount(CAccountInfo*); virtual bool InitEvent(CEventAggregator*); virtual bool InitSymbol(CSymbolManager*); virtual bool InitTrade(void); virtual CStops *GetContainer(void); virtual void SetContainer(CStops*); virtual bool Validate(void) const; //--- Abfragen und Ändern bool Active(void); void Active(const bool); bool Broker(void) const; void Comment(const string); string Comment(void) const; void Delay(int delay); int Delay(void) const; void SetDeviation(const int); int SetDeviation(void) const; void EntryColor(const color clr); void EntryStyle(const ENUM_LINE_STYLE); void EntryVisible(const bool); bool EntryVisible(void) const; void Magic(const int); int Magic(void) const; void Main(const bool); bool Main(void) const; void Name(const string); string Name(void) const; void OCO(const bool oco); bool OCO(void) const; bool Pending(void) const; void StopLoss(const double); double StopLoss(void) const; void StopLossColor(const color); bool StopLossCustom(void); void StopLossName(const string); string StopLossName(void) const; void StopLossVisible(const bool); bool StopLossVisible(void) const; void StopLossStyle(const ENUM_LINE_STYLE); void StopType(const ENUM_STOP_TYPE); ENUM_STOP_TYPE StopType(void) const; string SymbolName(void); void TakeProfit(const double); double TakeProfit(void) const; void TakeProfitColor(const color); bool TakeProfitCustom(void); void TakeProfitName(const string); string TakeProfitName(void) const; void TakeProfitStyle(const ENUM_LINE_STYLE); void TakeProfitVisible(const bool); bool TakeProfitVisible(void) const; bool Virtual(void) const; void Volume(double); double Volume(void) const; void VolumeType(const ENUM_VOLUME_TYPE); ENUM_VOLUME_TYPE VolumeType(void) const; //--- Stopps, Prüfung virtual bool CheckStopLoss(COrder*,COrderStop*); virtual bool CheckTakeProfit(COrder*,COrderStop*); virtual bool CheckStopOrder(ENUM_STOP_MODE,COrder*,COrderStop*)=0; virtual bool DeleteStopOrder(const ulong)=0; virtual bool DeleteMarketStop(const ulong)=0; virtual bool OrderModify(const ulong,const double); //--- Stopps, Erstellen des Objektes virtual CStopLine *CreateEntryObject(const long,const string,const int,const double); virtual CStopLine *CreateStopLossObject(const long,const string,const int,const double); virtual CStopLine *CreateTakeProfitObject(const long,const string,const int,const double); //--- Stopps, Preisberechnung virtual bool Refresh(const string); virtual double StopLossCalculate(const string,const ENUM_ORDER_TYPE,const double); virtual double StopLossCustom(const string,const ENUM_ORDER_TYPE,const double); virtual double StopLossPrice(COrder*,COrderStop*); virtual double StopLossTicks(const ENUM_ORDER_TYPE,const double); virtual double TakeProfitCalculate(const string,const ENUM_ORDER_TYPE,const double); virtual double TakeProfitCustom(const string,const ENUM_ORDER_TYPE,const double); virtual double TakeProfitPrice(COrder*,COrderStop*); virtual double TakeProfitTicks(const ENUM_ORDER_TYPE,const double); //--- Stopps, Trailing virtual bool Add(CTrails*); virtual double CheckTrailing(const string,const ENUM_ORDER_TYPE,const double,const double,const ENUM_TRAIL_TARGET); protected: //--- Objekt erstellen virtual CStopLine *CreateObject(const long,const string,const int,const double); //--- Stopps, Preisberechnung virtual double LotSizeCalculate(COrder*,COrderStop*); //--- Stopps, Positionseröffnung virtual bool GetClosePrice(const string,const ENUM_ORDER_TYPE,double&); //--- Stopps, Position schließen virtual bool CloseStop(COrder*,COrderStop*,const double)=0; //--- Deinitialisierung virtual void Deinit(void); virtual void DeinitSymbol(void); virtual void DeinitTrade(void); virtual void DeinitTrails(void); };
Für Stoploss und Takeprofits auf der Basis von Pips oder Points müssen wir uns zumindest an vier Methoden der Klasse erinnern:
- Der Typ Stopp (brokerseitig, per Pending-Order oder virtuell), mittels der Methode StopType()
- Der Typ Volumen verwendet zur Berechnung die Methode VolumeType()
- Stoploss in Points (wenn nötig) mittels der Methode Stoploss()
- Takeprofit in Points (wenn nötig) mittels der Methode Takeprofit()
Sie weisen den Mitgliedern der Klasse Werte zu, so dass wir sie nicht im einzelnen ausarbeiten müssen. Die meisten anderen Methoden werden von der Klasse nur für interne Berechnungen benötigt. Zu den wichtigsten dieser geschützten Methoden gehören die Methoden StoplossCalculate() und TakeprofitCalculate(), deren Code im Folgenden dargestellt ist:
double CStopBase::StopLossCalculate(const string symbol,const ENUM_ORDER_TYPE type,const double price) { if(!Refresh(symbol)) return 0; if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_LIMIT) return price-m_stoploss*m_symbol.Point(); else if(type==ORDER_TYPE_SELL || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_LIMIT) return price+m_stoploss*m_symbol.Point(); return 0; } double CStopBase::TakeProfitCalculate(const string symbol,const ENUM_ORDER_TYPE type,const double price) { if(!Refresh(symbol)) return 0; if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_LIMIT) return price+m_takeprofit*m_symbol.Point(); else if(type==ORDER_TYPE_SELL || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_LIMIT) return price-m_takeprofit*m_symbol.Point(); return 0; }
Beide Methoden haben drei Argumente, die sich alle auf die Hauptposition beziehen. Die Methoden aktualisieren zunächst mit der Methode Refresh() das Symbol, das einfach die Verwaltung der Symbole aktuell auf das übergebene Symbol konzentriert. Nach der Aktualisierung wird der Werte entweder des Stoploss oder des Takeprofits zurückgegeben, auf Basis des "point values", den die Instanz bei ihrer Initialisierung gespeichert hat.
CStops
Die Klasse CStops dient als Container für die Instanzen von CStop. Eine Instanz dieser Klasse muss dynamisch einem ihrer Mitglieder zum Order-Manager hinzugefügt werden, der folgende Code zeigt CStopsBase, die Basisklasse von CStops:
class CStopsBase : public CArrayObj { protected: bool m_active; CEventAggregator *m_event_man; CObject *m_container; public: CStopsBase(void); ~CStopsBase(void); virtual int Type(void) const {return CLASS_TYPE_STOPS;} //--- Initialisierung virtual bool Init(CSymbolManager*,CAccountInfo*,CEventAggregator*); virtual CObject *GetContainer(void); virtual void SetContainer(CObject*); virtual bool Validate(void) const; //--- Ändern und Abfragen virtual bool Active(void) const; virtual void Active(const bool); virtual CStop *Main(void); //--- Wiederherstellung virtual bool CreateElement(const int); };
Diese Klasse ist sehr ähnlich den anderen, in diesem Artikel beschrieben Containern.
COrderStop
COrderStop ist die Implementierung von CStop für eine spezielle Position. Für eine gegebene Position kann CStop maximal einen COrderStop erzeugen. Eine beliebige Anzahl von Instanzen von COrderStop kann sich jedoch dieselbe Instanz von CStop teilen. Wenn ein Expert Advisor also 3 verschiedene Instanzen von CStop hat, erwarten wir in der Regel, dass jede Instanz von COrder die gleiche Anzahl von Instanzen von COrderStop hat. Wenn der Expert Advisor 1000 Mal gehandelt hat, dann würde die Anzahl der angelegten Instanzen von COrderStop 1000 * 3 = 3000 betragen, während die Anzahl der angelegten Instanzen von CStop immer noch 3 betragen würde.
Die Definition von COrderStopBase, von der aus COrderStop gestartet wird, ist im folgenden Code dargestellt:
class COrderStopBase : public CObject { protected: bool m_active; //--- Stopp Parameter double m_volume; CArrayDouble m_stoploss; CArrayDouble m_takeprofit; ulong m_stoploss_ticket; ulong m_takeprofit_ticket; bool m_stoploss_closed; bool m_takeprofit_closed; bool m_closed; ENUM_STOP_TYPE m_stop_type; string m_stop_name; //--- Objekt der Hauptposition COrder *m_order; //--- Stopp Objekt CStop *m_stop; CStopLine *m_objentry; CStopLine *m_objsl; CStopLine *m_objtp; COrderStops *m_order_stops; public: COrderStopBase(void); ~COrderStopBase(void); virtual int Type(void) const {return CLASS_TYPE_ORDERSTOP;} //--- Initialisierung virtual void Init(COrder*,CStop*,COrderStops*); virtual COrderStops *GetContainer(void); virtual void SetContainer(COrderStops*); virtual void Show(bool); //--- Abfragen und Ändern bool Active(void) const; void Active(bool active); string EntryName(void) const; ulong MainMagic(void) const; ulong MainTicket(void) const; double MainTicketPrice(void) const; ENUM_ORDER_TYPE MainTicketType(void) const; COrder *Order(void); void Order(COrder*); CStop *Stop(void); void Stop(CStop*); bool StopLoss(const double); double StopLoss(void) const; double StopLoss(const int); void StopLossClosed(const bool); bool StopLossClosed(void); double StopLossLast(void) const; string StopLossName(void) const; void StopLossTicket(const ulong); ulong StopLossTicket(void) const; void StopName(const string); string StopName(void) const; bool TakeProfit(const double); double TakeProfit(void) const; double TakeProfit(const int); void TakeProfitClosed(const bool); bool TakeProfitClosed(void); double TakeProfitLast(void) const; string TakeProfitName(void) const; void TakeProfitTicket(const ulong); ulong TakeProfitTicket(void) const; void Volume(const double); double Volume(void) const; //--- Prüfen virtual void Check(double&)=0; virtual bool Close(void); virtual bool CheckTrailing(void); virtual bool DeleteChartObject(const string); virtual bool DeleteEntry(void); virtual bool DeleteStopLines(void); virtual bool DeleteStopLoss(void); virtual bool DeleteTakeProfit(void); virtual bool IsClosed(void); virtual bool Update(void) {return true;} virtual void UpdateVolume(double) {} //--- Deinitialisierung virtual void Deinit(void); //--- Wiederherstellung virtual bool Save(const int); virtual bool Load(const int); virtual void Recreate(void); protected: virtual bool IsStopLossValid(const double) const; virtual bool IsTakeProfitValid(const double) const; virtual bool Modify(const double,const double); virtual bool ModifyStops(const double,const double); virtual bool ModifyStopLoss(const double) {return true;} virtual bool ModifyTakeProfit(const double){return true;} virtual bool UpdateOrderStop(const double,const double){return true;} virtual bool MoveStopLoss(const double); virtual bool MoveTakeProfit(const double); };
COrderStop befindet sich in COrderStops (siehe nächster Abschnitt), die sich wiederum in COrder enthalten ist. Bei der eigentlichen Entwicklung eines EA ist es nicht mehr notwendig, eine Instanz von COrderStop zu deklarieren. Diese wird von COrder automatisch auf Basis einer bestimmten Instanz von CStop angelegt.
COrderStops
class COrderStopsBase : public CArrayObj { protected: bool m_active; CArrayInt m_types; COrder *m_order; public: COrderStopsBase(void); ~COrderStopsBase(void); virtual int Type(void) const {return CLASS_TYPE_ORDERSTOPS;} void Active(bool); bool Active(void) const; //--- Initialisierung virtual CObject *GetContainer(void); virtual void SetContainer(COrder*); virtual bool NewOrderStop(COrder*,CStop*)=0; //--- Prüfen virtual void Check(double &volume); virtual bool CheckNewTicket(COrderStop*); virtual bool Close(void); virtual void UpdateVolume(const double) {} //--- Ausblenden und Zeigen der Linien der Stopps virtual void Show(const bool); //--- Wiederherstellung virtual bool CreateElement(const int); virtual bool Save(const int); virtual bool Load(const int); };
So wie CStop schaut auch dies wie ein typischer Container aus. Er enthält jedoch einige Methoden, die die Methoden der Objekte spiegeln, deren Pointer er speichern soll (COrderStop).
Darstellung der Stopps auf dem Chart
CStopLine ist ein Mitglied der Klasse CStop, dessen primäre Aufgabe die grafische Darstellung der Stopps auf dem Chart ist. Es hat drei wichtige Funktionen für einem Expert Advisor:
- Anzeigen der Stopps bei der Initialisierung einer Instanz von COrder
- Aktualisieren der Stopps, falls einer oder beide Stopps geändert worden sind
- Entfernen der Stopps, sobald die Position vom Markt gelöscht worden ist
All diese Funktionen werde mittels der Klasse CStop implementiert.
Die Definition von CStopLineBase, von der sich CStopLine abgeleitet, ist unten angeführt:
class CStopLineBase : public CChartObjectHLine { protected: bool m_active; CStop *m_stop; public: CStopLineBase(void); ~CStopLineBase(void); virtual int Type(void) const {return CLASS_TYPE_STOPLINE;} virtual void SetContainer(CStop*); virtual CStop *GetContainer(void); bool Active(void) const; void Active(const bool); virtual bool ChartObjectExists(void) const; virtual double GetPrice(const int); virtual bool Move(const double); virtual bool SetStyle(const ENUM_LINE_STYLE); virtual bool SetColor(const color); };
In älteren Versionen des MetaTrader 4 sind Stoploss und Takeprofit nicht durch Ziehen veränderbar. Die Stopps mussten entweder über das Auftragsfenster oder mit Hilfe von Expert Advisorn und Skripten angepasst werden. Die grafische Darstellung der Stopps kann jedoch nützlich sein, besonders wenn es sich um virtuelle handelt.
Prüfen der Stopps einer Position
Nachdem die Stopps erfolgreich für eine bestimmte Position erstellt wurden, wäre der nächste Schritt zu überprüfen, ob der Markt den Wert einer der Stopps erreicht hat. Bei brokerseitigen Stopps ist die Prüfung nicht notwendig, da vom Server die Position dann geschlossen wird. Bei virtuellen Stopps und Stopps, die auf Pending-Orders basieren, muss jedoch der Expert Advisor in den meisten Fällen das Schließen der Position selbst durchführen.
Bei virtuellen Stopps ist der Expert Advisor für die Überwachung der Marktbewegungen und die Überprüfung, ob der Markt einen bestimmten Stopp erreicht hat, allein verantwortlich. Die folgende Abbildung zeigt allgemein das Vorgehen. Sobald der Markt ein Stopp erreicht, führt der Expert Advisor die entsprechende Art des Schließens der Position durch.
Für Stopps und Pending-Orders ist der Vorgang etwas komplizierter. Ein ausgelöster Stopp würde zu einer Pending-Order führen, die ausgelöst wurde, d. h. zu einer Position wird. Das passiert automatisch auf Seiten des Brokers. So läge es in der Verantwortung des Expert Advisors zu erkennen, ob die gegebene Pending-Order noch schwebend ist oder bereits als reale Position im Markt existiert. Wurde die Pending-Order bereits ausgelöst, so ist der Expert Advisor für das Schließen der Hauptposition mit dem gerade ausgelösten Volumen der Pending-Order verantwortlich - ein Auftrag der Form "close-by".
In allen Fällen wird, sobald die Pending-Order als Stopp ausgelöst wurde, der Stopp als geschlossen gekennzeichnet. Das soll verhindern, dass ein Stopp mehrmals ausgeführt wird.
Beispiele
Example #1: Ein EA, der Heiken Ashi und Moving Average verwendet, mit einem einzigen Stopp (Hauptstopp)
Den meisten Expert Advisor reicht ein Stoploss und ein Takeprofit. Wir werden nun das Beispiel aus dem vorherigen Artikel (siehe Cross-Plattform Expert Advisor: Zeitfilter) erweitern, um dem Quellcode einen Stoploss und Takeprofit hinzuzufügen. Dazu erstellen wir zunächst eine neue Instanz des Containers (CStops). Dann erstellen wir eine Instanz von CStop, und übergeben dann dessen Pointer dem Container. Der Pointer auf den Container wird dann schließlich dem Order-Manager hinzugefügt. Der Code wird unten gezeigt:
int OnInit() { //--- zusätzlicher Code CStops *stops=new CStops(); CStop *main=new CStop("main"); main.StopType(stop_type_main); main.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); main.Main(true); main.StopLoss(stop_loss); main.TakeProfit(take_profit); stops.Add(GetPointer(main)); order_manager.AddStops(GetPointer(stops)); //--- zusätzlicher Code }
Die Testergebnisse der brokerseitigen Stopps im Metatrader 4 sind in der folgenden Tabelle aufgelistet. Es ist das, was Händler normalerweise erwarten, wenn ein Expert Advisor seinen Handel auf dieser Plattform ausführt.
# | Zeit | Typ | Auftrag | Größe | Preis | S / L | T / P | Gewinn | Kontostand |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 1.05097 | 1.04097 | ||
2 | 2017.01.03 11:34 | t/p | 1 | 0.30 | 1.04097 | 1.05097 | 1.04097 | 150.00 | 3150.00 |
3 | 2017.01.05 11:00 | sell | 2 | 0.30 | 1.05149 | 1.05649 | 1.04649 | ||
4 | 2017.01.05 17:28 | s/l | 2 | 0.30 | 1.05649 | 1.05649 | 1.04649 | -150.00 | 3000.00 |
Stopps, die auf Pending-Orders basieren, werden wie bei standardmäßigen SL/TP im Voraus platziert, jedoch in Form von Pending-Orders. Sobald die Pending-Order ausgelöst wird, führt der Expert Advisor einen "close-by" durch und schließt den Hauptposition mit dem Volumen des ausgelösten Pending-Order. Anders als bei standardmäßigen sl/tp führt der Expert Advisor dies jedoch auf Seiten des Händlers durch. Dies wird nicht ausgeführt, es sei denn, die Handelsplattform ist online und der EA läuft auf einem Chart.
# | Zeit | Typ | Auftrag | Größe | Preis | S / L | T / P | Gewinn | Kontostand |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 0.00000 | 0.00000 | ||
2 | 2017.01.03 10:00 | buy stop | 2 | 0.30 | 1.05097 | 0.00000 | 0.00000 | ||
3 | 2017.01.03 10:00 | buy limit | 3 | 0.30 | 1.04097 | 0.00000 | 0.00000 | ||
4 | 2017.01.03 11:34 | buy | 3 | 0.30 | 1.04097 | 0.00000 | 0.00000 | ||
5 | 2017.01.03 11:34 | close by | 1 | 0.30 | 1.04097 | 0.00000 | 0.00000 | 150.00 | 3150.00 |
6 | 2017.01.03 11:34 | close by | 3 | 0.00 | 1.04097 | 0.00000 | 0.00000 | 0.00 | 3150.00 |
7 | 2017.01.03 11:34 | delete | 2 | 0.30 | 1.05097 | 0.00000 | 0.00000 | ||
8 | 2017.01.05 11:00 | sell | 4 | 0.30 | 1.05149 | 0.00000 | 0.00000 | ||
9 | 2017.01.05 11:00 | buy stop | 5 | 0.30 | 1.05649 | 0.00000 | 0.00000 | ||
10 | 2017.01.05 11:00 | buy limit | 6 | 0.30 | 1.04649 | 0.00000 | 0.00000 | ||
11 | 2017.01.05 17:28 | buy | 5 | 0.30 | 1.05649 | 0.00000 | 0.00000 | ||
12 | 2017.01.05 17:28 | close by | 4 | 0.30 | 1.05649 | 0.00000 | 0.00000 | -150.00 | 3000.00 |
13 | 2017.01.05 17:28 | close by | 5 | 0.00 | 1.05649 | 0.00000 | 0.00000 | 0.00 | 3000.00 |
14 | 2017.01.05 17:28 | delete | 6 | 0.30 | 1.04649 | 0.00000 | 0.00000 |
Virtuelle Stopps senden nichts über die Stopps der Hauptposition. Der Broker wird erst informiert, wenn der EA einen Auftrag zum Schließen sendet. Die folgende Tabelle zeigt das Verhalten des EA bei virtuellen Stopps. Sobald hier der Preis eines Stopps erreicht wird, sendet der EA eine Auftrag an den Server, die Hauptposition zu schließen.
# | Zeit | Typ | Auftrag | Größe | Preis | S / L | T / P | Gewinn | Kontostand |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 0.00000 | 0.00000 | ||
2 | 2017.01.03 11:34 | close | 1 | 0.30 | 1.04097 | 0.00000 | 0.00000 | 150.00 | 3150.00 |
3 | 2017.01.05 11:00 | sell | 2 | 0.30 | 1.05149 | 0.00000 | 0.00000 | ||
4 | 2017.01.05 17:28 | close | 2 | 0.30 | 1.05649 | 0.00000 | 0.00000 | -150.00 | 3000.00 |
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 17:28:37 | 5 | EURUSD | buy | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | sl 1.05649 | ||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 5 | 0.00 | 0.00 | -150.00 | 3 000.00 | sl 1.05649 |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
Im "hedging mode" arbeiten die Pending-Orders wie im Metatrader 4, so dass der EA ein Schließen der Form "close-by" durchführt, wenn die Pending-Order ausgelöste worden ist.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.03 11:34:38 | 5 | EURUSD | close by | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | close #2 by #4 | ||||
2017.01.05 11:00:00 | 6 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | buy stop | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
2017.01.05 11:00:00 | 8 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 17:28:37 | canceled | |||||
2017.01.05 17:28:37 | 9 | EURUSD | close by | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | close #6 by #7 | ||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | in | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 4 | EURUSD | buy | out by | 0.30 | 1.04097 | 5 | 0.00 | 0.00 | 150.00 | 3 150.00 | close #2 by #4 |
2017.01.03 11:34:38 | 5 | EURUSD | sell | out by | 0.30 | 1.04597 | 5 | 0.00 | 0.00 | 0.00 | 3 150.00 | close #2 by #4 |
2017.01.05 11:00:00 | 6 | EURUSD | sell | in | 0.30 | 1.05149 | 6 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 7 | EURUSD | buy | in | 0.30 | 1.05649 | 7 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 9 | EURUSD | sell | out by | 0.30 | 1.05149 | 9 | 0.00 | 0.00 | 0.00 | 3 150.00 | close #6 by #7 |
2017.01.05 17:28:37 | 8 | EURUSD | buy | out by | 0.30 | 1.05649 | 9 | 0.00 | 0.00 | -150.00 | 3 000.00 | close #6 by #7 |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
Mit virtuellen Stopps sehen wir normalerweise kein Zeichen für "Close", wie es MetaTrader 4 anzeigt. Der Vorgang des Schießens wird durch eine Position in der Gegenrichtung der Hauptposition erreicht. In der Liste historischer Deals können wir aber erkennen, ob ein Kauf oder Verkauf, ein Ein- oder Ausstieg getätigt wurde.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 17:28:37 | 5 | EURUSD | buy | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 5 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 5 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 6 | EURUSD | buy stop | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 17:28:37 | canceled | |||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 5 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 6 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 5 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 6 | EURUSD | buy stop | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 17:28:37 | canceled | |||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 5 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 6 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
Die folgende Tabelle zeigt die Verwendung virtueller Stopps im MetaTrader 5 im "netting mode". Die virtuellen Stopps im "netting mode" sehen zwar genauso aus wie im "hedging mode", aber die internen Abläufe sind unterschiedlich.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 17:28:37 | 5 | EURUSD | buy | 0.30 / 0.30 | 1.05649 | 2017.01.05 17:28:37 | filled | |||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.30 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 17:28:37 | 5 | EURUSD | buy | out | 0.30 | 1.05649 | 5 | 0.00 | 0.00 | -150.00 | 3 000.00 | |
0.00 | 0.00 | 0.00 | 3 000.00 | |||||||||
Example #2: Ein EA, der Heiken Ashi und Moving Average mit drei Stopps verwendet
Komplexere Expert Advisor benötigen oft mehr als einen Stoploss und einen Takeprofit. Wir verwenden die gleiche Methode wie im vorherigen Beispiel, wenn wir zusätzliche Stopps hinzufügen, nämlich die Stopps mit den Namen "stop1" und "stop2":
int OnInit() { //--- zusätzlicher Code CStops *stops=new CStops(); CStop *main=new CStop("main"); main.StopType(stop_type_main); main.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); main.Main(true); main.StopLoss(stop_loss); main.TakeProfit(take_profit); stops.Add(GetPointer(main)); CStop *stop1=new CStop("stop1"); stop1.StopType(stop_type1); stop1.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); stop1.Volume(0.35); stop1.StopLoss(stop_loss1); stop1.TakeProfit(take_profit1); stops.Add(GetPointer(stop1)); CStop *stop2=new CStop("stop2"); stop2.StopType(stop_type2); stop2.VolumeType(VOLUME_TYPE_PERCENT_TOTAL); stop2.Volume(0.35); stop2.StopLoss(stop_loss2); stop2.TakeProfit(take_profit2); stops.Add(GetPointer(stop2)); order_manager.AddStops(GetPointer(stops)); //--- zusätzlicher Code }
Die folgende Tabelle zeigt die Ergebnisse eines Tests mit dem Metatrader 4:
# | Zeit | Typ | Auftrag | Größe | Preis | S / L | T / P | Gewinn | Kontostand |
1 | 2017.01.03 10:00 | sell | 1 | 0.30 | 1.04597 | 1.05097 | 1.04097 | ||
2 | 2017.01.03 10:00 | buy stop | 2 | 0.11 | 1.04847 | 0.00000 | 0.00000 | ||
3 | 2017.01.03 10:00 | buy limit | 3 | 0.11 | 1.04347 | 0.00000 | 0.00000 | ||
4 | 2017.01.03 10:21 | buy | 3 | 0.11 | 1.04347 | 0.00000 | 0.00000 | ||
5 | 2017.01.03 10:21 | close by | 1 | 0.11 | 1.04347 | 1.05097 | 1.04097 | 27.50 | 3027.50 |
6 | 2017.01.03 10:21 | sell | 4 | 0.19 | 1.04597 | 1.05097 | 1.04097 | ||
7 | 2017.01.03 10:21 | close by | 3 | 0.00 | 1.04347 | 0.00000 | 0.00000 | 0.00 | 3027.50 |
8 | 2017.01.03 10:21 | delete | 2 | 0.11 | 1.04847 | 0.00000 | 0.00000 | ||
9 | 2017.01.03 10:34 | close | 4 | 0.11 | 1.04247 | 1.05097 | 1.04097 | 38.50 | 3066.00 |
10 | 2017.01.03 10:34 | sell | 5 | 0.08 | 1.04597 | 1.05097 | 1.04097 | ||
11 | 2017.01.03 11:34 | t/p | 5 | 0.08 | 1.04097 | 1.05097 | 1.04097 | 40.00 | 3106.00 |
12 | 2017.01.05 11:00 | sell | 6 | 0.30 | 1.05149 | 1.05649 | 1.04649 | ||
13 | 2017.01.05 11:00 | buy stop | 7 | 0.11 | 1.05399 | 0.00000 | 0.00000 | ||
14 | 2017.01.05 11:00 | buy limit | 8 | 0.11 | 1.04899 | 0.00000 | 0.00000 | ||
15 | 2017.01.05 12:58 | buy | 8 | 0.11 | 1.04899 | 0.00000 | 0.00000 | ||
16 | 2017.01.05 12:58 | close by | 6 | 0.11 | 1.04899 | 1.05649 | 1.04649 | 27.50 | 3133.50 |
17 | 2017.01.05 12:58 | sell | 9 | 0.19 | 1.05149 | 1.05649 | 1.04649 | ||
18 | 2017.01.05 12:58 | close by | 8 | 0.00 | 1.04899 | 0.00000 | 0.00000 | 0.00 | 3133.50 |
19 | 2017.01.05 12:58 | delete | 7 | 0.11 | 1.05399 | 0.00000 | 0.00000 | ||
20 | 2017.01.05 16:00 | close | 9 | 0.19 | 1.05314 | 1.05649 | 1.04649 | -31.35 | 3102.15 |
21 | 2017.01.05 16:00 | buy | 10 | 0.30 | 1.05314 | 1.04814 | 1.05814 | ||
22 | 2017.01.05 16:00 | sell stop | 11 | 0.11 | 1.05064 | 0.00000 | 0.00000 | ||
23 | 2017.01.05 16:00 | sell limit | 12 | 0.11 | 1.05564 | 0.00000 | 0.00000 | ||
24 | 2017.01.05 17:09 | sell | 12 | 0.11 | 1.05564 | 0.00000 | 0.00000 | ||
25 | 2017.01.05 17:09 | close by | 10 | 0.11 | 1.05564 | 1.04814 | 1.05814 | 27.50 | 3129.65 |
26 | 2017.01.05 17:09 | buy | 13 | 0.19 | 1.05314 | 1.04814 | 1.05814 | ||
27 | 2017.01.05 17:09 | close by | 12 | 0.00 | 1.05564 | 0.00000 | 0.00000 | 0.00 | 3129.65 |
28 | 2017.01.05 17:09 | delete | 11 | 0.11 | 1.05064 | 0.00000 | 0.00000 | ||
29 | 2017.01.05 17:28 | close | 13 | 0.11 | 1.05664 | 1.04814 | 1.05814 | 38.50 | 3168.15 |
30 | 2017.01.05 17:28 | buy | 14 | 0.08 | 1.05314 | 1.04814 | 1.05814 | ||
31 | 2017.01.05 17:40 | t/p | 14 | 0.08 | 1.05814 | 1.04814 | 1.05814 | 40.00 | 3208.15 |
Wie aus der obigen Tabelle ersichtlich, wurden für die erste Positionen alle drei Stopps ausgelöst. Für den virtuellen Stopp schloss die EA erwartungsgemäß einen Teil der Hauptposition. Für den Stopp mittels Pending-Order führte der EA unmittelbar nach Ausführung der Pending-Order ein Schließen der Form "close-by" durch und reduzierte mit seinem Volumen das der Hauptposition. Schließlich, durch den Hauptstopp, den brokerseitigen Stopp, wurde die Hauptposition mit dem verbliebenen Volumen von 0,08 Lot geschlossen.
Die folgende Tabelle zeigt die Ergebnisse eines Tests mit dem Metatrader 5 "hedging mode":
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.11 / 0.00 | 1.04847 | 2017.01.03 10:21:32 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | |||||
2017.01.03 10:21:32 | 5 | EURUSD | close by | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | close #2 by #4 | ||||
2017.01.03 10:33:40 | 6 | EURUSD | buy | 0.11 / 0.11 | 1.04247 | 2017.01.03 10:33:40 | filled | |||||
2017.01.03 11:34:38 | 7 | EURUSD | buy | 0.08 / 0.08 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 8 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 11:00:00 | 9 | EURUSD | buy stop | 0.11 / 0.00 | 1.05399 | 2017.01.05 12:58:27 | canceled | |||||
2017.01.05 11:00:00 | 10 | EURUSD | buy limit | 0.11 / 0.11 | 1.04899 | 2017.01.05 12:58:27 | filled | |||||
2017.01.05 12:58:27 | 11 | EURUSD | close by | 0.11 / 0.11 | 1.04896 | 2017.01.05 12:58:27 | filled | close #8 by #10 | ||||
2017.01.05 16:00:00 | 12 | EURUSD | buy | 0.19 / 0.19 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 13 | EURUSD | buy | 0.30 / 0.30 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 16:00:00 | 14 | EURUSD | sell stop | 0.11 / 0.00 | 1.05057 | 2017.01.05 17:09:40 | canceled | |||||
2017.01.05 16:00:00 | 15 | EURUSD | sell limit | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | |||||
2017.01.05 17:09:40 | 16 | EURUSD | close by | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | close #13 by #15 | ||||
2017.01.05 17:28:47 | 17 | EURUSD | sell | 0.11 / 0.11 | 1.05660 | 2017.01.05 17:28:47 | filled | |||||
2017.01.05 17:29:15 | 18 | EURUSD | sell | 0.08 / 0.08 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 10:21:32 | 3 | EURUSD | buy | in | 0.11 | 1.04347 | 4 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 10:21:32 | 4 | EURUSD | buy | out by | 0.11 | 1.04347 | 5 | 0.00 | 0.00 | 27.50 | 3 027.50 | close #2 by #4 |
2017.01.03 10:21:32 | 5 | EURUSD | sell | out by | 0.11 | 1.04597 | 5 | 0.00 | 0.00 | 0.00 | 3 027.50 | close #2 by #4 |
2017.01.03 10:33:40 | 6 | EURUSD | buy | out | 0.11 | 1.04247 | 6 | 0.00 | 0.00 | 38.50 | 3 066.00 | |
2017.01.03 11:34:38 | 7 | EURUSD | buy | out | 0.08 | 1.04097 | 7 | 0.00 | 0.00 | 40.00 | 3 106.00 | tp 1.04097 |
2017.01.05 11:00:00 | 8 | EURUSD | sell | in | 0.30 | 1.05149 | 8 | 0.00 | 0.00 | 0.00 | 3 106.00 | |
2017.01.05 12:58:27 | 9 | EURUSD | buy | in | 0.11 | 1.04896 | 10 | 0.00 | 0.00 | 0.00 | 3 106.00 | |
2017.01.05 12:58:27 | 10 | EURUSD | buy | out by | 0.11 | 1.04896 | 11 | 0.00 | 0.00 | 27.83 | 3 133.83 | close #8 by #10 |
2017.01.05 12:58:27 | 11 | EURUSD | sell | out by | 0.11 | 1.05149 | 11 | 0.00 | 0.00 | 0.00 | 3 133.83 | close #8 by #10 |
2017.01.05 16:00:00 | 12 | EURUSD | buy | out | 0.19 | 1.05307 | 12 | 0.00 | 0.00 | -30.02 | 3 103.81 | |
2017.01.05 16:00:00 | 13 | EURUSD | buy | in | 0.30 | 1.05307 | 13 | 0.00 | 0.00 | 0.00 | 3 103.81 | |
2017.01.05 17:09:40 | 14 | EURUSD | sell | in | 0.11 | 1.05557 | 15 | 0.00 | 0.00 | 0.00 | 3 103.81 | |
2017.01.05 17:09:40 | 16 | EURUSD | buy | out by | 0.11 | 1.05307 | 16 | 0.00 | 0.00 | 0.00 | 3 103.81 | close #13 by #15 |
2017.01.05 17:09:40 | 15 | EURUSD | sell | out by | 0.11 | 1.05557 | 16 | 0.00 | 0.00 | 27.50 | 3 131.31 | close #13 by #15 |
2017.01.05 17:28:47 | 17 | EURUSD | sell | out | 0.11 | 1.05660 | 17 | 0.00 | 0.00 | 38.83 | 3 170.14 | |
2017.01.05 17:29:15 | 18 | EURUSD | sell | out | 0.08 | 1.05807 | 18 | 0.00 | 0.00 | 40.00 | 3 210.14 | tp 1.05807 |
0.00 | 0.00 | 210.14 | 3 210.14 | |||||||||
Wie aus der obigen Tabelle zeigt, arbeitet der EA irgendwie ähnlich wie der Metatrader 5 im "hedging mode". Die Vorgänge sind die gleichen wie im Metatrader 4 für alle drei Typen der Stopps.
Die folgende Tabelle zeigt die Ergebnisse eines Tests auf Metatrader 5 im "netting mode":
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.30 / 0.00 | 1.05097 | 2017.01.03 11:34:38 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.03 10:00:00 | 5 | EURUSD | buy stop | 0.11 / 0.00 | 1.04847 | 2017.01.03 10:21:32 | canceled | |||||
2017.01.03 10:00:00 | 6 | EURUSD | buy limit | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | |||||
2017.01.03 10:33:40 | 7 | EURUSD | buy | 0.11 / 0.11 | 1.04247 | 2017.01.03 10:33:40 | filled | |||||
2017.01.05 11:00:00 | 8 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 9 | EURUSD | buy stop | 0.30 / 0.00 | 1.05649 | 2017.01.05 16:00:00 | canceled | |||||
2017.01.05 11:00:00 | 10 | EURUSD | buy limit | 0.30 / 0.00 | 1.04649 | 2017.01.05 16:00:00 | canceled | |||||
2017.01.05 11:00:00 | 11 | EURUSD | buy stop | 0.11 / 0.00 | 1.05399 | 2017.01.05 12:58:27 | canceled | |||||
2017.01.05 11:00:00 | 12 | EURUSD | buy limit | 0.11 / 0.11 | 1.04899 | 2017.01.05 12:58:27 | filled | |||||
2017.01.05 16:00:00 | 13 | EURUSD | buy | 0.19 / 0.19 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 14 | EURUSD | buy | 0.30 / 0.30 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 15 | EURUSD | sell stop | 0.30 / 0.00 | 1.04807 | 2017.01.05 17:29:15 | canceled | |||||
2017.01.05 16:00:00 | 16 | EURUSD | sell limit | 0.30 / 0.30 | 1.05807 | 2017.01.05 17:29:15 | filled | |||||
2017.01.05 16:00:00 | 17 | EURUSD | sell stop | 0.11 / 0.00 | 1.05057 | 2017.01.05 17:09:40 | canceled | |||||
2017.01.05 16:00:00 | 18 | EURUSD | sell limit | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | |||||
2017.01.05 17:28:47 | 19 | EURUSD | sell | 0.11 / 0.11 | 1.05660 | 2017.01.05 17:28:47 | filled | |||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 5 | EURUSD | buy | in/out | 0.30 | 1.04097 | 4 | 0.00 | 0.00 | 40.00 | 3 040.00 | |
2017.01.03 10:21:32 | 3 | EURUSD | buy | out | 0.11 | 1.04347 | 6 | 0.00 | 0.00 | 27.50 | 3 067.50 | |
2017.01.03 10:33:40 | 4 | EURUSD | buy | out | 0.11 | 1.04247 | 7 | 0.00 | 0.00 | 38.50 | 3 106.00 | |
2017.01.05 11:00:00 | 6 | EURUSD | sell | in/out | 0.30 | 1.05149 | 8 | 0.00 | -0.61 | 231.44 | 3 336.83 | |
2017.01.05 12:58:27 | 7 | EURUSD | buy | in/out | 0.11 | 1.04896 | 12 | 0.00 | 0.00 | 20.24 | 3 357.07 | |
2017.01.05 16:00:00 | 8 | EURUSD | buy | in | 0.19 | 1.05307 | 13 | 0.00 | 0.00 | 0.00 | 3 357.07 | |
2017.01.05 16:00:00 | 9 | EURUSD | buy | in | 0.30 | 1.05307 | 14 | 0.00 | 0.00 | 0.00 | 3 357.07 | |
2017.01.05 17:29:15 | 12 | EURUSD | sell | out | 0.30 | 1.05807 | 16 | 0.00 | 0.00 | 157.11 | 3 514.18 | |
2017.01.05 17:09:40 | 10 | EURUSD | sell | out | 0.11 | 1.05557 | 18 | 0.00 | 0.00 | 30.11 | 3 544.29 | |
2017.01.05 17:28:47 | 11 | EURUSD | sell | out | 0.11 | 1.05660 | 19 | 0.00 | 0.00 | 41.44 | 3 585.73 | |
0.00 | -0.61 | 586.34 | 3 585.73 | |||||||||
Hier zeigt sich ein Problem. Der Stopp am Ende schloss mit 0,30 Lot statt mit 0,08 Lot, wie in den beiden vorangegangenen Tests festgestellt wurde.
Wie bereits erwähnt, unterscheiden sich die standardmäßigen Stoploss und Takeprofits im MetaTrader 5, "netting mode", von denen der beiden vorherigen Versionen. So würde der EA den brokerseitigen Stopp in eine Pending-Order umwandeln. Mit dieser Einstellung verfügt der EA jedoch bereits über zwei Stopps auf der Basis von Pending-Orders und einer davon ist ein Hauptstopp. Wie bereits erwähnt, würde dies zu verwaisten Positionen führen. Der End- oder der Hauptstopp würde immer ein Volumen haben, das dem anfänglichen Volumen des Hauptposition entspricht. Da es auch noch andere Stopps gibt, kann es dazu führen, dass der Hauptstopp die Position mit einem Volumen größer als das noch existierende schließen will.
Um dies Problem zu lösen, könnte man den Hauptstopp virtuell setzen, anstatt einen brokerseitigen oder einen Stopp als Pending-Order zu erstellen. Mit dieser neuen Einstellung verfügt der EA nun über zwei virtuelle Stopps und einen Stopp, der auf einer Pending-Order basiert. Das Ergebnis eines Tests mit dieser neuen Einstellung wird unten angezeigt.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 3 | EURUSD | buy stop | 0.11 / 0.00 | 1.04847 | 2017.01.03 10:21:32 | canceled | |||||
2017.01.03 10:00:00 | 4 | EURUSD | buy limit | 0.11 / 0.11 | 1.04347 | 2017.01.03 10:21:32 | filled | |||||
2017.01.03 10:33:40 | 5 | EURUSD | buy | 0.11 / 0.11 | 1.04247 | 2017.01.03 10:33:40 | filled | |||||
2017.01.03 11:34:38 | 6 | EURUSD | buy | 0.08 / 0.08 | 1.04097 | 2017.01.03 11:34:38 | filled | |||||
2017.01.05 11:00:00 | 7 | EURUSD | sell | 0.30 / 0.30 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 8 | EURUSD | buy stop | 0.11 / 0.00 | 1.05399 | 2017.01.05 12:58:27 | canceled | |||||
2017.01.05 11:00:00 | 9 | EURUSD | buy limit | 0.11 / 0.11 | 1.04899 | 2017.01.05 12:58:27 | filled | |||||
2017.01.05 16:00:00 | 10 | EURUSD | buy | 0.19 / 0.19 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 11 | EURUSD | buy | 0.30 / 0.30 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 12 | EURUSD | sell stop | 0.11 / 0.00 | 1.05057 | 2017.01.05 17:09:40 | canceled | |||||
2017.01.05 16:00:00 | 13 | EURUSD | sell limit | 0.11 / 0.11 | 1.05557 | 2017.01.05 17:09:40 | filled | |||||
2017.01.05 17:28:47 | 14 | EURUSD | sell | 0.11 / 0.11 | 1.05660 | 2017.01.05 17:28:47 | filled | |||||
2017.01.05 17:29:15 | 15 | EURUSD | sell | 0.08 / 0.08 | 1.05807 | 2017.01.05 17:29:15 | filled | |||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 10:21:32 | 3 | EURUSD | buy | out | 0.11 | 1.04347 | 4 | 0.00 | 0.00 | 27.50 | 3 027.50 | |
2017.01.03 10:33:40 | 4 | EURUSD | buy | out | 0.11 | 1.04247 | 5 | 0.00 | 0.00 | 38.50 | 3 066.00 | |
2017.01.03 11:34:38 | 5 | EURUSD | buy | out | 0.08 | 1.04097 | 6 | 0.00 | 0.00 | 40.00 | 3 106.00 | |
2017.01.05 11:00:00 | 6 | EURUSD | sell | in | 0.30 | 1.05149 | 7 | 0.00 | 0.00 | 0.00 | 3 106.00 | |
2017.01.05 12:58:27 | 7 | EURUSD | buy | out | 0.11 | 1.04896 | 9 | 0.00 | 0.00 | 27.83 | 3 133.83 | |
2017.01.05 16:00:00 | 8 | EURUSD | buy | out | 0.19 | 1.05307 | 10 | 0.00 | 0.00 | -30.02 | 3 103.81 | |
2017.01.05 16:00:00 | 9 | EURUSD | buy | in | 0.30 | 1.05307 | 11 | 0.00 | 0.00 | 0.00 | 3 103.81 | |
2017.01.05 17:09:40 | 10 | EURUSD | sell | out | 0.11 | 1.05557 | 13 | 0.00 | 0.00 | 27.50 | 3 131.31 | |
2017.01.05 17:28:47 | 11 | EURUSD | sell | out | 0.11 | 1.05660 | 14 | 0.00 | 0.00 | 38.83 | 3 170.14 | |
2017.01.05 17:29:15 | 12 | EURUSD | sell | out | 0.08 | 1.05807 | 15 | 0.00 | 0.00 | 40.00 | 3 210.14 | |
0.00 | 0.00 | 210.14 | 3 210.14 | |||||||||
Das Gesamtvolumen der Stopps gleicht nun dem Anfangsvolumen der Hauptposition.
Beispiel #3: Stopps mit Geldmanagement
In einem früheren Artikel (siehe Cross-Plattform Expert Advisor: Geldmanagement) wurde diskutiert, dass einige Methoden des Geldmanagements von Stopps abhängen (Takeprofit ist möglich, aber normalerweise wird Stoploss verwendet). Geldmanagementmethoden wie fixe Anteile, fixes Risiko, fixes Risiko je Point/Pip erfordern oft einen begrenzenden Stoploss. Wenn man diesen Wert nicht festlegt, bedeutet dies ein sehr großes oder gar unendliches Risiko, und so wäre auch das berechnete Volumen sehr groß. Um einen Expert Advisor zu zeigen, der die in diesem Artikel erwähnten Klassenobjekte mit Geldmanagement verwenden kann, werden wir die im ersten Beispiel noch kommentierten Codezeilen jetzt in die Kompilierung mit einbeziehen.
Zuerst entfernen wir die Kommentarzeichen der Codezeilen für die Geldmanagementmethoden, wie im Code unten gezeigt, innerhalb der Funktion OnInit():
int OnInit() { //--- zusätzlicher Code order_manager=new COrderManager(); money_manager= new CMoneys(); CMoney *money_fixed=new CMoneyFixedLot(0.05); CMoney *money_ff=new CMoneyFixedFractional(5); CMoney *money_ratio=new CMoneyFixedRatio(0,0.1,1000); CMoney *money_riskperpoint=new CMoneyFixedRiskPerPoint(0.1); CMoney *money_risk=new CMoneyFixedRisk(100); money_manager.Add(money_fixed); money_manager.Add(money_ff); money_manager.Add(money_ratio); money_manager.Add(money_riskperpoint); money_manager.Add(money_risk); order_manager.AddMoneys(money_manager); //--- zusätzlicher Code }
Am Anfang des Quellcodes deklarieren wir dann eine benutzerdefinierte Enumeration, so dass wir einen externen Parameter erstellen können, der es uns erlaubt, die Geldmanagementmethode auszuwählen, wie unten aufgeführt:
enum ENUM_MM_TYPE { MM_FIXED=0, MM_FIXED_FRACTIONAL, MM_FIXED_RATIO, MM_FIXED_RISK_PER_POINT, MM_FIXED_RISK };
Wir deklarieren eine neue Eingabeparameter für diese Enumeration:
input ENUM_MM_TYPE mm_type=MM_FIXED_FRACTIONAL;
Schließlich müssen wir diesen Parameter mit der tatsächliche Auswahl der Geldmanagementmethode in der Funktion OnTick() verknüpfen:
void OnTick() { //--- manage_trades(); if(symbol_info.RefreshRates()) { signals.Check(); if(signals.CheckOpenLong()) { close_last(); if(time_filters.Evaluate(TimeCurrent())) { Print("Entering buy trade.."); money_manager.Selected((int)mm_type); //use mm_type, cast to 'int' type order_manager.TradeOpen(Symbol(),ORDER_TYPE_BUY,symbol_info.Ask()); } } else if(signals.CheckOpenShort()) { close_last(); if(time_filters.Evaluate(TimeCurrent())) { Print("Entering sell trade.."); money_manager.Selected((int)mm_type); //use mm_type, cast to 'int' type order_manager.TradeOpen(Symbol(),ORDER_TYPE_SELL,symbol_info.Bid()); } } } }
Da die Geldmanagementmethoden nur rechnen, gibt es keine Kompatibilitätsprobleme zwischen MQL4 und MQL5. Die beiden vorangegangenen Beispiele haben bereits gezeigt, wie die Stopps auf den beiden Plattformen funktionieren. Die folgenden Tabellen zeigen die Ergebnisse der Tests mit MetaTrader 5 "hedging mode".
Die folgende Tabelle zeigt ein Testergebnis unter Verwendung des Geldmanagements des fixen Anteils. Die codierte Einstellung riskiert 5% des Kontostandes. Mit einem Anfangssaldo von $3000 erwarten wir einen Verlust von ca. $150, wenn die erste Position durch den Stoploss geschlossen wird. Da Stoploss und Takeprofit den gleichen Wert haben (500 Punkte), erwarten wir, dass die Position $150 gewinnt, wenn Takeprofit erreicht wird.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.30 / 0.30 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.30 / 0.30 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.32 / 0.32 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 16:00:00 | 5 | EURUSD | buy | 0.32 / 0.32 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 6 | EURUSD | buy | 0.31 / 0.31 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 17:29:15 | 7 | EURUSD | sell | 0.31 / 0.31 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.30 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.30 | 1.04097 | 3 | 0.00 | 0.00 | 150.00 | 3 150.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.32 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 150.00 | |
2017.01.05 16:00:00 | 5 | EURUSD | buy | out | 0.32 | 1.05307 | 5 | 0.00 | 0.00 | -50.56 | 3 099.44 | |
2017.01.05 16:00:00 | 6 | EURUSD | buy | in | 0.31 | 1.05307 | 6 | 0.00 | 0.00 | 0.00 | 3 099.44 | |
2017.01.05 17:29:15 | 7 | EURUSD | sell | out | 0.31 | 1.05807 | 7 | 0.00 | 0.00 | 155.00 | 3 254.44 | tp 1.05807 |
0.00 | 0.00 | 254.44 | 3 254.44 | |||||||||
Beachten Sie, dass das berechnete Volumen auch von der Genauigkeit des Brokers abhängt, die durch die Parameter minimales Lot und minimale Lotstep bestimmt werden. Wir können vom Expert Advisor nicht erwarten, dass er immer ganz genau den errechneten Wert verwenden kann. Unter den Randbedingungen kann es für den Expert Advisor notwendig sein, den Wert abzurunden. Dasselbe gilt auch für die anderen Methoden des Geldmanagements.
Bei einem Geldmanagement des fixen Risikos pro Point ist die kodierte Einstellung des Risikos $0,1 pro Point. Bei einer Einstellung von 500 Points für Stoploss und Takeprofit erwarten wir, dass der Gewinn/Verlust auf jeden Fall $50 beträgt.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.10 / 0.10 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.10 / 0.10 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.10 / 0.10 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 16:00:00 | 5 | EURUSD | buy | 0.10 / 0.10 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 6 | EURUSD | buy | 0.10 / 0.10 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 17:29:15 | 7 | EURUSD | sell | 0.10 / 0.10 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.10 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.10 | 1.04097 | 3 | 0.00 | 0.00 | 50.00 | 3 050.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.10 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 050.00 | |
2017.01.05 16:00:00 | 5 | EURUSD | buy | out | 0.10 | 1.05307 | 5 | 0.00 | 0.00 | -15.80 | 3 034.20 | |
2017.01.05 16:00:00 | 6 | EURUSD | buy | in | 0.10 | 1.05307 | 6 | 0.00 | 0.00 | 0.00 | 3 034.20 | |
2017.01.05 17:29:15 | 7 | EURUSD | sell | out | 0.10 | 1.05807 | 7 | 0.00 | 0.00 | 50.00 | 3 084.20 | tp 1.05807 |
0.00 | 0.00 | 84.20 | 3 084.20 | |||||||||
Für ein Geldmanagement des fixen Risikos wurde ein Risiko von $100 codiert. Die EA wiederum würde ein Volumen berechnen, dass zu dem festgelegten Risiko passt. Das Ergebnis ist unten dargestellt.
Aufträge |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Auftrag | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.03 10:00:00 | 2 | EURUSD | sell | 0.20 / 0.20 | 1.04597 | 1.05097 | 1.04097 | 2017.01.03 10:00:00 | filled | |||
2017.01.03 11:34:38 | 3 | EURUSD | buy | 0.20 / 0.20 | 1.04097 | 2017.01.03 11:34:38 | filled | tp 1.04097 | ||||
2017.01.05 11:00:00 | 4 | EURUSD | sell | 0.20 / 0.20 | 1.05149 | 1.05649 | 1.04649 | 2017.01.05 11:00:00 | filled | |||
2017.01.05 16:00:00 | 5 | EURUSD | buy | 0.20 / 0.20 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 6 | EURUSD | buy | 0.20 / 0.20 | 1.05307 | 1.04807 | 1.05807 | 2017.01.05 16:00:00 | filled | |||
2017.01.05 17:29:15 | 7 | EURUSD | sell | 0.20 / 0.20 | 1.05807 | 2017.01.05 17:29:15 | filled | tp 1.05807 | ||||
Deals |
||||||||||||
Zeit | Deal | Symbol | Typ | Direction | Volumen | Preis | Auftrag | Commission | Swap | Gewinn | Kontostand | Kommentar |
2017.01.01 00:00:00 | 1 | balance | 0.00 | 0.00 | 3 000.00 | 3 000.00 | ||||||
2017.01.03 10:00:00 | 2 | EURUSD | sell | in | 0.20 | 1.04597 | 2 | 0.00 | 0.00 | 0.00 | 3 000.00 | |
2017.01.03 11:34:38 | 3 | EURUSD | buy | out | 0.20 | 1.04097 | 3 | 0.00 | 0.00 | 100.00 | 3 100.00 | tp 1.04097 |
2017.01.05 11:00:00 | 4 | EURUSD | sell | in | 0.20 | 1.05149 | 4 | 0.00 | 0.00 | 0.00 | 3 100.00 | |
2017.01.05 16:00:00 | 5 | EURUSD | buy | out | 0.20 | 1.05307 | 5 | 0.00 | 0.00 | -31.60 | 3 068.40 | |
2017.01.05 16:00:00 | 6 | EURUSD | buy | in | 0.20 | 1.05307 | 6 | 0.00 | 0.00 | 0.00 | 3 068.40 | |
2017.01.05 17:29:15 | 7 | EURUSD | sell | out | 0.20 | 1.05807 | 7 | 0.00 | 0.00 | 100.00 | 3 168.40 | tp 1.05807 |
0.00 | 0.00 | 168.40 | 3 168.40 | |||||||||
Schlussfolgerung
In diesem Artikel haben wir das Hinzufügen von Stopps in einem plattformübergreifenden Expert Advisor diskutiert. Beiden Handelsplattformen, obwohl sie viele parallele Funktionen haben, unterscheiden sich erheblich in der Art und Weise, wie Stopps implementiert werden. Dieser Artikel enthält eine Methode, mit der diese Unterschiede ausgeglichen werden können, damit ein Expert Advisor mit beiden Plattformen kompatibel ist.
Programme, die im diesem Artikel verwendet werden
# |
Name |
Typ |
Beschreibung |
---|---|---|---|
1. |
stops_ha_ma1.mqh |
Header-Datei |
Header-Datei, die der Expert Advisor im ersten Beispiel verwendet |
2. |
stops_ha_ma1.mq4 | Expert Advisor |
Quellcode, verwendet von MQL4-Expert Advisor im ersten Beispiel |
3. |
stops_ha_ma1.mq5 | Expert Advisor | Quellcode, verwendet von MQL5-Expert Advisor im ersten Beispiel |
4. | stops_ha_ma2.mqh | Header-Datei | Header-Datei, die der Expert Advisor im zweiten Beispiel verwendet |
5. | stops_ha_ma2.mq4 | Expert Advisor |
Quellcode, verwendet von MQL4-Expert Advisor im zweiten Beispiel |
6. | stops_ha_ma2.mq5 | Expert Advisor |
Quellcode, verwendet von MQL5-Expert Advisor im zweiten Beispiel |
7. | stops_ha_ma3.mqh | Header-Datei | Header-Datei, die der Expert Advisor im dritten Beispiel verwendet |
8. | stops_ha_ma3.mq4 | Expert Advisor |
Quellcode, verwendet von MQL4-Expert Advisor im dritten Beispiel |
9. | stops_ha_ma3.mq5 | Expert Advisor |
Quellcode, verwendet von MQL5-Expert Advisor im dritten Beispiel |
Die Dateien der Klassen dieses Artikels
# |
Name |
Typ |
Beschreibung |
---|---|---|---|
1. |
MQLx\Base\Stop\StopBase.mqh |
Header-Datei |
CStop (base class) |
2. |
MQLx\MQL4\Stop\Stop.mqh | Header-Datei | CStop (MQL4 version) |
3. |
MQLx\MQL5\Stop\Stop.mqh | Header-Datei | CStop (MQL5 version) |
4. | MQLx\Base\Stop\StopsBase.mqh | Header-Datei | CStops (CStop container, base class) |
5. | MQLx\MQL4\Stop\Stops.mqh | Header-Datei | CStops (MQL4 version) |
6. | MQLx\MQL5\Stop\Stops.mqh | Header-Datei | CStops (MQL5 version) |
7. | MQLx\Base\Stop\StopLineBase.mqh | Header-Datei | CStopLine (graphical representation, base class) |
8. | MQLx\MQL4\Stop\StopLine.mqh | Header-Datei | CStopLine (MQL4 version) |
9. | MQLx\MQL5\Stop\StopLine.mqh | Header-Datei | CStopLine (MQL5 version) |
10. | MQLx\Base\Order\OrderStopBase.mqh | Header-Datei | COrderStop (base class) |
11. | MQLx\MQL4\Order\OrderStop.mqh | Header-Datei | COrderStop (MQL4 version) |
12. | MQLx\MQL5\Order\OrderStop.mqh | Header-Datei | COrderStop (MQL5 version) |
13. |
MQLx\Base\Order\OrderStopVirtualBase.mqh | Header-Datei |
COrderStopVirtual (virtual stop level, base class) |
14. | MQLx\Base\Order\OrderStopVirtual.mqh | Header-Datei |
COrderStopVirtual (MQL4 version) |
15. |
MQLx\Base\Order\OrderStopVirtual.mqh | Header-Datei |
COrderStopVirtual (MQL5 version) |
16. | MQLx\Base\Order\OrderStopPendingBase.mqh | Header-Datei |
COrderStopPending (pending order stop level, base class) |
17. | MQLx\Base\Order\OrderStopPending.mqh | Header-Datei |
COrderStopPending (MQL4 version) |
18. |
MQLx\Base\Order\OrderStopPending.mqh | Header-Datei |
COrderStopPending (MQL5 version) |
19. |
MQLx\Base\Order\OrderStopBroker.mqh | Header-Datei |
COrderStopBroker (broker-based stop level, base class) |
20. | MQLx\Base\Order\OrderStopBroker.mqh | Header-Datei |
COrderStopBroker (MQL4 version) |
21. | MQLx\Base\Order\OrderStopBroker.mqh | Header-Datei |
COrderStopBroker (MQL5 version) |
22. | MQLx\Base\Order\OrderStopsBase.mqh | Header-Datei |
COrderStops (COrderStop container, base class) |
23. | MQLx\Base\Order\OrderStops.mqh | Header-Datei |
COrderStops (MQL4 version) |
24. | MQLx\Base\Order\OrderStops.mqh | Header-Datei |
COrderStops (MQL5 version) |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/3620





- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.