English Русский 中文 Español 日本語 Português
Cross-Plattform Expert Advisor: Orders

Cross-Plattform Expert Advisor: Orders

MetaTrader 5Integration | 29 September 2016, 10:16
817 0
Enrico Lambino
Enrico Lambino

Inhaltsverzeichnis


Einführung

MetaTrader 4 und MetaTrader 5 verwenden unterschiedliche Konventionen, um den Handel durchzuführen. Dieser Artikel diskutiert die Möglichkeit, mit einem Klassenobjekt die Aufgaben des Handels mit den Server durchzuführen, unabhängig davon, auf welcher Handelsplattform oder in welchem Modus ein Cross-Plattform Expert Advisor arbeitet.

Konventionen

Es gibt sehr viele Unterschiede, wie MetaTrader 4 und MetaTrader 5 den Handel durchführen. Um alle Details der Möglichkeiten der Handelsdurchführung zu betrachten, müssen wir drei verschiedene Versionen/Modi beider Plattformen berücksichtigen: (1) MetaTrader 4, (2) MetaTrader 5 im "Netting" Modus und (3) MetaTrader 5 im "Hedging" Modus.

MetaTrader 4

In MetaTrader 4, wenn ein Expert Advisor erfolgreich eine Bestellung absendet, erhält er eine Ticketnummer, sie ist eine Identifikationsnummer dieses Auftrages. Bei Änderungen und dem Schließen dieser Position, wird diese Ticketnummer verwendet, bis die Position geschlossen wird.

Diese Situation wird etwas komplizierter, wenn eine Position nur teilweise geschlossen wird. Dazu wird die Funktion OrderClose mit der Angabe der Anzahl der zuschließenden Lots aufgerufen, die kleiner ist als die Gesamtzahl der Lots dieser offenen Position. Wenn ein solcher Auftrag erteilt wurde, wird die Position (oder das Ticket der Position) mit der angebenden Lotgröße geschlossen. Die restliche Lotgröße verbleibt im Markt, aber als eine neue Position desselben Typs wie die teilweise geschlossenen Position. Da aber die Funktion OrderClose nur einen logische Wert zurückgibt, gibt es keine schnelle Lösung, die neue Ticketnummer der verbliebenen Position zu erhalten, außer die Liste aller offenen Positionen des Kontos durchzugehen. Bedenke Sie, dass unmöglich ist, alleine über die Funktion OrderClose die Ticketnummer zu erhalten. Diese Funktion liefert nur eine logische Variable, während OrderSend, in MQL4, die gültige Ticketnummer nach einer erfolgreichen Positionseröffnung zurückliefert.

MetaTrader 5 (Netting)

Die Abwicklung der Handelsoperationen durch MetaTrader 5 schaut auf den ersten Blick ziemlich kompliziert aus, aber sie ist einfacher zu handhaben als im MetaTrader 4. Dies gilt zumindest für die Händler (die Nicht-Programmierer).

Der Standard des MetaTrader 5 ist der "Netting" Modus. In diesem Modus werden die Ergebnisse der Positionen in einer konsolidiert. Die Volumen einer konsolidierten Positionen eines Typs kann sich im Laufe der Zeit durch neue Positionen desselben Typs ändern. Aus der Sicht eines Programmierers es ist ein wenig komplizierter. Anders als in MQL4, wo es nur ein Konzept für Aufträge gibt, muss der Programmierer jetzt mit drei verschiedene Arten des Handelns auseinander setzen. Die folgende Tabelle vergleicht den "Netting"-Modus in MQL5 mit ihre groben Entsprechung in MQL4:

 Art
 MQL5 (Netting)
MQL4 (grobe Entsprechung)
OrderEröffnungsanfrage (Pending oder Marktorder)Eröffnungsanfrage (Pending oder Marktorder)
 Deal Deal(s) auf Basis eines einzelnen Auftrages (Marktorder oder ausgelöste Pendingorder) Einzelne Marktorder wie auf dem Terminal
 Position Positionen (konsolidiert) Summe aller Positionen des Handelsterminal (Positionstypen gelten)

In MQL5 sind einmal gesendete Aufträge unveränderbar, während in MQL4 einige Eigenschaften der Position noch geändert werden können, obwohl sie schon im Markt ist. Das heißt, erst einmal ist der Auftrag ein Handelsauftrag an den Server. Später kann es dann sowohl als Handelsauftrag wie auch als dessen Ergebnis betrachtet werden. Aus Sicht von MQL5 ist der ganze Prozess komplexer, um ihn weniger mehrdeutig zu machen, da deutlich zwischen dem Handelsauftrag und dessen Ergebnis unterschieden wird. In MQL4 kann eine Position eröffnet werden und mit inzwischen anderen Eigenschaften wieder geschlossen werden, während in MQL5 alles auf die einzelne Aufträge zurückgeführt werden kann.

Sendet jemand einen Auftrag, gibt es nur zwei Möglichkeiten, durchgeführt oder nicht. Wurde ein Auftrag nicht durchgeführt heißt das kein "Deal", da der Handelsserver den Auftrag nicht durchführen konnte (normalerweise wegen eines Fehlers). Wurde aber der Auftrag in MQL5 durchgeführt, gibt für das Terminal und den Server einen "Deal". In diesem Fall wurde der Auftrag entweder komplett oder teilweise ausgeführt.

MetaTrader 4 hat diese Option nicht, da eine Auftrag entweder ganz oder gar nicht durchgeführt wird ("fill or kill").

Ein bemerkenswerter Nachteil dieses Modus in MetaTrader 5 ist, dass es kein "Hedging" erlaubt. Der Typ einer Position eines gegebenen Symbols kann wechseln. Existiert zum Beispiel ein Kaufposition eines Symbols mit 0.1 Lot und es folgt nun ein Verkauf mit 1.0 Lot, ergäbe das eine Verkaufsposition dieses Symbols mit 0.9 Lots.

MetaTrader 5 (Hedging)

Der Modus "Hedging" erlaubt nun die Konventionen des MetaTrader 4. Statt alle Positionen in einer zu konsolidieren, erlaubt der Modus "Hedging" die Existenz mehrerer Positionen mit demselben Symbol. Eine Position entsteht durch das Auslösen einer Pendingorder oder durch eine Marktorder durch den Handelsserver.

Art
MQL5 (Netting)
MQL4 (grobe Entsprechung)
OrderEröffnungsanfrage (Pending oder Marktorder)Eröffnungsanfrage (Pending oder Marktorder)
DealsDeal(s) auf Basis eines AuftragesMarktorder des Handelsterminals
PositionPositionen (konsolidiert) auf Basis einzelner HandelsaufträgeAufträge des Handelsterminals

Um es einen Cross-Plattform Expert Advisor zu ermöglichen, diese Unterschiede zu berücksichtigen, könnte man den Expert Advisor dazu bringen, alle Details der einzelnen Aufträge zu sichern. Jedes Mal, wenn ein Auftrag erfolgreich durchgeführt worden ist, wird eine Kopie des Auftrages in einem Klassenobjekt, der Klasse COrder, gesichert. Der folgende Code zeigt die Deklaration seiner Basisklasse:

class COrderBase : public CObject
  {
protected:
   bool              m_closed;
   bool              m_suspend;
   long              m_order_flags;
   int               m_magic;
   double            m_price;
   ulong             m_ticket;
   ENUM_ORDER_TYPE   m_type;
   double            m_volume;
   double            m_volume_initial;
   string            m_symbol;
public:
                     COrderBase(void);
                    ~COrderBase(void);
   //--- getters and setters     
   void              IsClosed(const bool);
   bool              IsClosed(void) const;
   void              IsSuspended(const bool);
   bool              IsSuspended(void) const;
   void              Magic(const int);
   int               Magic(void) const;
   void              Price(const double);
   double            Price(void) const;
   void              OrderType(const ENUM_ORDER_TYPE);
   ENUM_ORDER_TYPE   OrderType(void) const;
   void              Symbol(const string);
   string            Symbol(void) const;
   void              Ticket(const ulong);
   ulong             Ticket(void) const;
   void              Volume(const double);
   double            Volume(void) const;
   void              VolumeInitial(const double);
   double            VolumeInitial(void) const;
   //--- output
   virtual string    OrderTypeToString(void) const;
   //--- static methods
   static bool       IsOrderTypeLong(const ENUM_ORDER_TYPE);
   static bool       IsOrderTypeShort(const ENUM_ORDER_TYPE);
  };

Da der EA sich jetzt seiner Aufträge erinnert, kann er mit größerer Unabhängigkeit mit den unterschiedlichen Konventionen der Handelsplattformen, auf denen er läuft, umgehen. Sein Nachteil liegt allerdings in der Tatsache, dass die Instanzen dieser Klasse nur so lange existieren, wie der Expert Advisor läuft. Im Falle, dass der Expert Advisor oder die Handelsplattform neu gestartet werden muss, würden alle gesicherten Daten verloren gehen, es sei denn es gibt die Möglichkeit, sie zu sichern und wieder zu laden.

Positionskennung (Ticketnummer)

Ein weiteres Problem, das durch die Verwendung einer Instanz von COrder durch einen Cross-Plattform Expert Advisor entsteht, ist die Frage, wie die Ticketnummer des Auftrages oder der Position gesichert werden soll. Die Unterschiede sind in der folgenden Tabelle zusammengefasst:

Operation
 MQL4MQL5 (Netting)
 MQL5 (Hedging)
Auftrag SendenNeue TicketnummerNeue Ticketnummer des Auftrages (keine existierende Position) oder Ticketnummer eine existierenden Position (mit existierender Position)
Neue Ticketnummer einer Position
Teilweises SchließenNeue TicketnummerGleiche Ticketnummer (für den Rest), sonst N/A
Gleiche Ticketnummer

Wird ein Auftrag gesendet, werden diese drei Versionen in unterschiedlicher Weise gesichert. In MQL4, wenn ein Auftrag erfolgreich war, wird eine neue Position eröffnet. Die neue Position wird durch eine Kennung charakterisiert (Ticketnummer der Position). In MQL5, im Modus "Netting", erfordert jeder Handelsauftrag eine Auftragsnummer. Allerdings wäre eine Auftragsnummer nicht der beste Lösung, die Ticketnummer der eröffneten Position wäre natürlich besser. Der Grund ist, dass, anders als in MQL4, mit der Auftragsnummern nicht so ohne Weiteres mit den offenen Positionen weitergearbeitet werden kann (aber die Abfrage der Ticketnummern kann hilfreich sein, wenn man auf die Positionen, die aus den Aufträgen resultieren, zugreifen will). Weiters, wenn es eine Position gleichen Typs gibt, bleibt die Ticketnummer gleich (anders als in MQL4). Andererseits, erzeugt MQL5 im Modus "Hedging" jeder neue "Deal" eine neue Position (ein grobes Äquivalent zur Ticketnummer in MQL4). Im Unterschied zu MQL4, wo ein einzelner Auftrag immer eine einzelne Position nach sich zieht, kann in MQL5 ("Hedging" Modus) ein Auftrag mehrere Deals zur Folge haben (wenn die "Filling Policy" nicht auf SYMBOL_FILLING_FOK gesetzt ist).

Es gibt auch ein anderes Problem, wenn eine Position in MQL4 oder in MQL5 teilweise geschlossen werden soll. Wie bereits erwähnt, wird in MQL4 eine Position teilweise geschlossen, wenn das Volumen kleiner ist als ihr Gesamtvolumen (OrderLots), die Ticketnummer der ursprünglichen Position wird geschlossen und der verbleibenden Position gleichen Typs wird eine neue Ticketnummer zugewiesen. In MQL5 ist das anders. Im Modus "Netting" verlangt es einen Position in der entgegengesetzten Richtung (Kauf gegen Verkauf oder Verkauf gegen Kauf), um eine Position zu schließen (ganz oder teilweise). Im Modus "Hedging" ist das Vorgehen ähnlich wie in MQL4 (OrderClose versus CTrades PositionClose), aber, anders als in MQL4, ändert ein teilweises Schließen die Kennung der Position nicht.

Eine Möglichkeit, dieses Problem zu lösen, ist die Umsetzung aufzuteilen, wie mit den Kennungen der jeweiligen Plattform umzugehen ist. Da die Ticketnummer sich in MetaTrader 5 nicht ändert, können wir sie einer normalen numerische Variablen zuweisen. Für den MetaTrader 4 verwenden wir statt dessen eine Instanz von CArrayInt, um die Ticketnummer zu sichern. Für COrderBase (und daher für die MQL5 Version von COrder) verwenden wir den folgenden Code:

COrderBase::Ticket(const ulong value)
  {
   m_ticket=value;
  }

Diese Methode wird für die MQL4 Version mit folgendem Code überschrieben:

COrder::Ticket(const ulong ticket)
  {
   m_ticket_current.InsertSort((int)ticket);   
  }

Zustände

Intern gibt es für die Positionen unseres Cross-Plattform Expert Advisors zwei Zustände:

  • Geschlossen

  • In Schwebe

Bis auf einen grundsätzlichen Unterschied sind beide Zustände sehr ähnlich. Der geschlossenen Zustand einer Position bedeutet, die Position ist tatsächlich geschlossen und der Expert Advisor könnte diese Position ins Archiv der internen Daten übertragen. Dem entspricht in etwa, wenn in MQL4 eine Position in die "History" wechselt. Der Zustand in Schwebe tritt ein, wenn das Schließen einer Position oder die Veränderung ihrer Stopps fehlgeschlagen ist. In diesem Fall kann der Expert Advisor versuchen seinen Auftrag zu wiederholen, bis er erfolgreich ist.

Volumen

In MQL4 ist die Berechnung des Volumens ziemlich einfach. Sendet der Expert Advisor einen Handelsauftrag, ist das Volumen Teil des Auftrages und wird entweder akzeptiert oder zurückgewiesen. Die entspricht in MQL5 der Handhabung der Margins nach dem Prinzip "Fill or Kill" (FOK), welches auch die Standardeinstellung der Klassen (CTrade und CExpertTrade) ist. Dies gemeinsame Merkmal ist die FOK Handhabung des "Margin". Um jetzt die Behandlung der Volumina in MQL4 und MQL5 konsistent zu gestalten, könnte man das Volumen aus der Instanz von COrder auf Basis des Volumens des Handelsauftrages selbst ableiten. Dies würde jedoch bedeuten, dass wir für die MQL5-Version nur die FOK-Politik anwenden können. Es ist dennoch möglich, andere Margin-Politiken zu verwenden, aber die Ergebnisse sind etwas anders (d.h. die Anzahl der Instanzen von COrder in der MQL5-Version in einem vorgegebenen Testfall desselben EAs könnte größer sein).

Der "Order Container"

Wenn der Expert Advisor mehr als eine Instanz von COrder handhaben muss, könnte eine Methode für ihre Organisation erforderlich sein. Eine der Klassen, die das ermöglichen, ist der "Order Container" oder COrders. Diese Klasse erweitert CArrayObj und sichert die Instanzen von COrder. Das erlaubt ein einfaches Sichern und Abrufen der Positionen des Expert Advisors. Die Basisklasse dieser Klasse ist wie folgt:

#include <Arrays\ArrayObj.mqh>
#include "OrderBase.mqh"
class CExpertAdvisor;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class COrdersBase : public CArrayObj
  {
public:
                     COrdersBase(void);
                    ~COrdersBase(void);
   virtual bool      NewOrder(const ulong,const string,const int,const ENUM_ORDER_TYPE,const double,const double);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COrdersBase::COrdersBase(void)
  {
   if(!IsSorted())
      Sort();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COrdersBase::~COrdersBase(void)
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool COrdersBase::NewOrder(const ulong ticket,const string symbol,const int magic,const ENUM_ORDER_TYPE type,const double volume,const double price)
  {
   COrder *order=new COrder(ticket,symbol,type,volume,price);
   if(CheckPointer(order)==POINTER_DYNAMIC)
      if(InsertSort(GetPointer(order)))
         order.Magic(magic);
   return false;
  }
//+------------------------------------------------------------------+
#ifdef __MQL5__
#include "..\..\MQL5\Order\Orders.mqh"
#else
#include "..\..\MQL4\Order\Orders.mqh"
#endif
//+------------------------------------------------------------------+

Da die Hauptfunktion das Sichern der Instanzen von COrder ist, muss sie in der Lage sein, neue Instanzen zur erwähnten Klasse hinzuzufügen. Die Standardmethode Add von CArrayObj könnte nicht immer ideale dafür sein, da eine Instanz von COrder instantiiert werden muss. Dafür hätten wir die Methode NewOrder, die ja eine neue Instanz von COrder erzeugt und sie automatisch dem Array hinzufügt:

bool COrdersBase::NewOrder(const ulong ticket,const string symbol,const int magic,const ENUM_ORDER_TYPE type,const double volume,const double price)
  {
   COrder *order=new COrder(ticket,symbol,type,volume,price);
   if(CheckPointer(order)==POINTER_DYNAMIC)
      if(InsertSort(GetPointer(order)))
         order.Magic(magic);
   return false;
  }

Jetzt, da wir die Vorlage haben, können wir weiteren Methoden der Klasse hinzufügen. Ein Beispiel ist die Methode OnTick. In dieser Methode würde die Container-Klasse über die gesicherten Elemente (COrder) iterieren. Ein andere Möglichkeit wäre, dass die Klasse COrder über die Methode OnTick verfügt. Dann könnte man sie so schreiben, dass diese Methode von COrder bei jedem Tick aufgerufen würde.

Beispiel

In unserem Beispiel wird versucht eine Kaufposition zu eröffnen. Nach der Eingabe der Position werden ihre Details in einer Instanz von COrder gesichert. Dies wird erreicht durch den Aufruf der Methode NewOrder von COrders (die eine Instanz von COrder erzeugt).

Beide Versionen verwenden das Handelsobjekt (CExpertTradeX) und Objekte von COrders und CSymbolInfo. In der Funktion OnTick eines Expert Advisors wird das Handelsobjekt versuchen, einen Kaufposition mit der Methode Buy zu eröffnen. Der einzige Unterschied zwischen MQL4 und MQL5 besteht darin, die Details der Handels empfangen werden. In MQL5 werden die Details durch HistoryOrderSelect und anderen ähnlichen Funktionen empfangen. Die Ticketnummer liefert die Methode ResultOrder des Handelsobjekts. Die Umsetzung dieser Methode ist wie folgt:

ulong retcode=trade.ResultRetcode();
ulong order = trade.ResultOrder();
 if(retcode==TRADE_RETCODE_DONE)
 {
  if(HistoryOrderSelect(order))
  {
   ulong ticket=HistoryOrderGetInteger(order,ORDER_TICKET);
   ulong magic=HistoryOrderGetInteger(order,ORDER_MAGIC);
   string symbol = HistoryOrderGetString(order,ORDER_SYMBOL);
   double volume = HistoryOrderGetDouble(order,ORDER_VOLUME_INITIAL);
   double price=HistoryOrderGetDouble(order,ORDER_PRICE_OPEN);
   ENUM_ORDER_TYPE order_type=(ENUM_ORDER_TYPE)HistoryOrderGetInteger(order,ORDER_TYPE);
   orders.NewOrder((int)ticket,symbol,(int)magic,order_type,volume,price);
  }
 }

Das Handelsobjekt für MQL4 benötigt weniger Merkmale als die Version für MQL5. Man könnte das Handelsobjekt dafür erweitern oder einfach über alle offenen Positionen des Kontos iterieren, um die Position, die gerade eröffnet wurde, zu erhalten:

for(int i=0;i<OrdersTotal();i++)
{
 if(!OrderSelect(i,SELECT_BY_POS))
  continue;
 if(OrderMagicNumber()==12345)
  orders.NewOrder(OrderTicket(),OrderSymbol(),OrderMagicNumber(),(ENUM_ORDER_TYPE)OrderType(),OrderLots(),OrderOpenPrice());
}

Der ganze Code der Headerdatei folgt unten:

(test_orders.mqh)

#include <MQLx-Orders\Base\Trade\ExpertTradeXBase.mqh>
#include <MQLx-Orders\Base\Order\OrdersBase.mqh>
CExpertTradeX trade;
COrders orders;
CSymbolInfo symbolinfo;
//+------------------------------------------------------------------+
//| Initialisierungsfunktion des Experten                            |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!symbolinfo.Name(Symbol()))
     {
      Print("failed to initialize symbol");
      return INIT_FAILED;
     }
   trade.SetSymbol(GetPointer(symbolinfo));
   trade.SetExpertMagicNumber(12345);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Deinitialisierungsfunktion des Experten                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Experten Funktion OnTick                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(!symbolinfo.RefreshRates())
   {
      Print("cannot refresh symbol");
      return;
   }   
   if(trade.Buy(1.0,symbolinfo.Ask(),0,0))
     {
#ifdef __MQL5__
      int retcode=trade.ResultRetCode();
      ulong order = trade.ResultOrder();
      if(retcode==TRADE_RETCODE_DONE)
        {
         if(HistoryOrderSelect(order))
           {
            ulong ticket=HistoryOrderGetInteger(order,ORDER_TICKET);;
            ulong magic=HistoryOrderGetInteger(order,ORDER_MAGIC);
            string symbol = HistoryOrderGetString(order,ORDER_SYMBOL);
            double volume = HistoryOrderGetDouble(order,ORDER_VOLUME_INITIAL);
            double price=HistoryOrderGetDouble(order,ORDER_PRICE_OPEN);
            ENUM_ORDER_TYPE order_type=order_type;
            m_orders.NewOrder((int)ticket,symbol,(int)magic,order_type,volume,price);
           }
        }
#else
      for(int i=0;i<OrdersTotal();i++)
        {
         if(!OrderSelect(i,SELECT_BY_POS))
            continue;
         if(OrderMagicNumber()==12345)
            orders.NewOrder(OrderTicket(),OrderSymbol(),OrderMagicNumber(),(ENUM_ORDER_TYPE)OrderType(),OrderLots(),OrderOpenPrice());
        }
#endif
     }
   Sleep(5000);
   ExpertRemove();
  }
//+------------------------------------------------------------------+

Die Headerdatei enthält den gesamten benötigten Code. Daher muss der Hauptquellcode nur die Datei test_orders.mqh mit einer Direktive des Preprozessors laden:

(test_orders.mq4 und test_orders.mq5)

#include "test_orders.mqh"

Läuft der Expert Advisor auf einer Plattform, gibt es folgende Einträge im Log:

In MetaTrader 4 würde folgendes geschrieben werden:

Expert test_orders EURUSD,H1: loaded successfully
test_orders EURUSD,H1: initialized
test_orders EURUSD,H1: open #358063536 buy 1.00 EURUSD at 1.12470 ok
test_orders EURUSD,H1: ExpertRemove function called
test_orders EURUSD,H1: uninit reason 0
Expert test_orders EURUSD,H1: removed

Das Nächste ist ein Bild der Plattform während sie den EA ausführt. Beachten Sie, dass der EA die Funktion ExpertRemove aufruft und sich so automatisch selbst vom Chart entfernt, nachdem der Code ausgeführt wurde (OnTick wird nur einmal ausgeführt).



In MetaTrader 5 würde fast das Gleiche ins Log geschrieben werden:

Experts    expert test_orders (EURUSD,M1) loaded successfully
Trades    '3681006': instant buy 1.00 EURUSD at 1.10669 (deviation: 10)
Trades    '3681006': accepted instant buy 1.00 EURUSD at 1.10669 (deviation: 10)
Trades    '3681006': deal #75334196 buy 1.00 EURUSD at 1.10669 done (based on order #90114599)
Trades    '3681006': order #90114599 buy 1.00 / 1.00 EURUSD at 1.10669 done in 275 ms
Experts    expert test_orders (EURUSD,M1) removed

Anders aber als im MetaTrader 4 erscheinen die Einträge von oben im "Journal Tab" des Terminals (nicht im "Experts Tab"):


Der EA macht auch einen Eintrag im "Experts Tab". Diese Nachricht ist aber nicht über die Ausführung der Positionen, sondern nur, dass die Funktion ExpertRemove ausgeführt wurde, im Vergleich zum MetaTrader 4, der diese Nachricht in den "Experts Tab" schreibt:


Erweiterungen

Unserer augenblicklichen Umsetzung fehlen aber noch ein paar Fähigkeiten, die ein wirklicher Expert Advisor oft verwendet, wie das Folgende:

1. Anfängliche Werte für StopLoss und TakeProfit einer Position

2. Änderungen von SL und TP (d.h. Breakeven, Trailingstopps oder andere Methoden eines Nutzers)

3. Dauerhaftigkeit der Daten - es gibt Unterschiede, wie die beiden Plattformen die Positionen und ihre Stopps sichern. Unsere Klasse führt die Methoden der beiden zusammen, spart aber nur Speicherplatz. Daher benötigen wir ein Methode um die Daten dauerhaft zu sichern. Das heißt, wir brauchen eine Methode für unsere Expert Advisor zum Speichern und Laden der Informationen einer Position für Fälle, wie den Neustart eines Terminals oder dem Wechsel des Chart im MetaTrader, wenn der Cross-Plattform Expert Advisor auf dem Chart weiter läuft.

Dies wird in einem späteren Artikeln behandelt werden.

Schlussfolgerung

In diesem Artikel erläuterten wir eine Möglichkeit, durch die ein Cross-Plattform Expert Advisor die Details seines Handelns, die vom Handelsserver bearbeitet wurden, durch eine Instanz eines Klassenobjektes sichern kann. Die Instanz dieses Objektes kann von einem Expert Advisor verwendet werden, die damit ihre eigene Strategie umsetzen können. Eine grundlegende Vorlage wird hier in Form einen Klassenobjektes vorgestellt, die z.B. im Rahmen komplizierterer Handelsstrategien weiterentwickelt werden kann.

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

Beigefügte Dateien |
Orders.zip (208.87 KB)
Portfolio Trading in MetaTrader 4 Portfolio Trading in MetaTrader 4
Der Artikel zeigt die Grundsätze des Portfolio-Tradings und die Anwendung auf den Forex-Markt Wir werden hier ein paar einfache mathematische Portfolio-Anordnungen berücksichtigen. Der Artikel enthält Beispiele für die praktische Umsetzung des Portfolio Handels mit dem MetaTrader 4: einen Portfolio Indikator und Expert Advisor für den halbautomatischen Handel. Die Elemente der Trading-Strategien, sowie deren Vorteile und Fallstricke werden hier beschrieben.
Tiefes Neuronales Netzwerk mit geschichtetem RBM. Selbsttraining, Selbstkontrolle Tiefes Neuronales Netzwerk mit geschichtetem RBM. Selbsttraining, Selbstkontrolle
Dieser Artikel ist eine Fortsetzung des vorherigen Artikels über über tiefe Neuronale Netzwerke und Prädikatorauswahl. Wir besprechen hier die Eigenschaften der Neuronalen Netzwerke in Form des "Stacked RMB" (geschichtete Restricted Boltzmann Maschine) und deren Umsetzung durch das Paket "darch".
Lifehack für den Händler: "Stille" Optimierung oder die optische Auswertung des Handels Lifehack für den Händler: "Stille" Optimierung oder die optische Auswertung des Handels
Analyse des bisherigen Handels und das Zeichnen der Entwicklung der Handelsergebnisse in HTML abhängig vom Zeitpunkt der Positionseröffnung. Die Diagramme sind in drei Gruppen aufgeteilt - nach Stunde, nach Tag der Woche und nach Monat.
Rezepte MQL5 - Handelssignale der gleitenden Kanäle Rezepte MQL5 - Handelssignale der gleitenden Kanäle
Der Artikel beschreibt den Prozess der Entwicklung und Implementierung einer Klasse, die Signale auf der Basis gleitender Kanäle entwickelt. Auf der Basis dieser Signale, werden wir eine Handelsstrategie erstellen. Es werden die Klassen der Standardbibliothek zur Erstellung der abgeleiteten Unterklassen verwendet.