English Русский 中文 Español 日本語 Português
preview
Verständnis der Auftragsvergabe in MQL5

Verständnis der Auftragsvergabe in MQL5

MetaTrader 5Handel | 14 Dezember 2023, 13:31
351 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Einführung

In jedem Handelssystem müssen wir uns mit Aufträgen und ihren Operationen befassen, z. B. mit dem Eröffnen von Positionen, dem Setzen von Stop-Loss und Gewinnmitnahmen sowie dem Ändern von Aufträgen. Daher ist es sehr wichtig zu verstehen, wie man Aufträge in mql5 handhabt, wenn man ein Handelssystem für MetaTrader5 erstellt. Ziel dieses Artikels ist es, Ihnen eine einfache Anleitung für die meisten Auftrags- und Positionsvorgänge an die Hand zu geben, damit Sie sich effektiv mit diesem Thema befassen können. In diesem Artikel werden wir die folgenden Themen behandeln:

Ich hoffe, dass Sie diesen Artikel nützlich und wertvoll finden, um Ihr MetaTrader5-Handelssystem in Bezug auf die Auftragsvergabe reibungslos zu entwickeln. Alle Anwendungen in diesem Artikel müssen Sie testen, bevor Sie sie verwenden, um sicherzustellen, dass sie profitabel oder für Ihren Handel geeignet sind. Denn der Hauptzweck der Erwähnung ist nur ein Beispiel für ein Handelssystem mit zwei verschiedenen Methoden für die Arbeit mit Order, Deal und Position.

Haftungsausschluss: Alle Informationen werden in der vorliegenden Form nur zu Informationszwecken bereitgestellt und sind nicht für Handelszwecke oder als Ratschläge gedacht. Die Informationen garantieren keinerlei Ergebnis. Wenn Sie sich dafür entscheiden, diese Materialien auf einem Ihrer Handelskonten zu verwenden, tun Sie dies auf eigenes Risiko und Sie sind allein verantwortlich.

Begriffe für Aufträge, Positionen und Deals

In diesem Teil werden wir über wichtige Begriffe sprechen, um zu verstehen, wie man mit Aufträgen effektiv umgeht. Wir werden die Unterschiede zwischen drei verwandten Begriffen für Aufträge im MetaTrader 5 verstehen. Diese Begriffe sind Order, Deal und Position. Wir können diese Begriffe als Schritte zur Ausführung des Handelsgeschäfts betrachten.

Auftrag: ist eine vom Handelsserver empfangene Aufforderung, einen Kauf- oder Verkaufshandel mit einem bestimmten Lot oder Volumen zu einem bestimmten Preis zu eröffnen. Es gibt zwei Arten von Aufträgen: den Marktauftrag und den schwebenden Auftrag.

  • Marktauftrag: ein Auftrag, der sofort zum aktuellen Marktpreis ausgeführt werden kann.
  • Schwebenden Auftrag oder Pending Order: ein Auftrag, der den Handel zu vorher festgelegten Bedingungen hinsichtlich des Preises, zu dem der Handel ausgeführt werden soll, und der Zeit, zu der der Handel ausgeführt werden soll, ausführt. 

Bei diesen schwebenden Aufträgen kann es sich um einen der folgenden handeln:

    • Buy stop: Es wird ein schwebender Kaufauftrag zu einem bestimmten Preis, der über dem aktuellen Marktpreis lieg, erteilt.
    • Buy limit: Es wird ein schwebender Kaufauftrag zu einem bestimmten Preis, der unter dem aktuellen Marktpreis liegt.
    • Sell stop: Es wird ein schwebender Verkaufsauftrag zu einem bestimmten Preis, der unter dem aktuellen Marktpreis liegt, erteilt.
    • Sell limit: Es wird ein schwebender Verkaufsauftrag zu einem bestimmten Preis, der über dem aktuellen Marktpreis liegt, erteilt.

Sobald der schwebende Auftrag platziert ist, unabhängig davon, ob es sich um eine Market- oder Pending-Order handelt, kann er in der Registerkarte "Handel" der Toolbox im MetaTrader 5 gefunden werden. Nachfolgend sehen Sie ein Beispiel:

1 Registerkarte Handel


Wenn der Auftrag geschlossen oder ohne Ausführung storniert wird, können wir sie in der Registerkarte History der Toolbox finden.

2 Registerkarte Historie

Wenn wir eine aktuelle Position mit MQL5 ändern wollen, müssen wir mit diesen Aufträgen genauso verfahren, wie wir es später bei der Änderung von Aufträgen tun werden.

Deal: Es ist das Ergebnis, wenn der Handelsauftrag ausgeführt oder erfüllt wird. Es handelt sich um Ein- und Ausstiegsaktionen, die auf der Ausführung des Handels basieren. Angenommen, es wird ein Kaufauftrag über ein Lot ausgeführt. Danach haben wir einen Teil der Position, nämlich 0,5 Lots, geschlossen und dann die restlichen 0,5 Lots geschlossen. Die Deals werden also die gleichen sein wie die folgenden:

  • 1 Kauf
  • 0,5 Verkauf
  • 0,5 Verkauf

Wir können diese Geschäfte in der Registerkarte "Historie" der Toolbox des MetaTrader 5 finden, indem wir die Geschäftsdaten mit der rechten Maustaste anklicken und sie auswählen.

3- Deals

Position: Es handelt sich um den Saldo der Kauf- oder Verkaufsgeschäfte, die auf dem Kauf oder Verkauf des finanziellen Vermögenswertes basieren. Wir können sie auf der Registerkarte Handel als aktiven Handel oder auf der Registerkarte Historie finden, wenn wir die Anzeige von Positionen auswählen.

4 Positionen

Es ist gut zu erwähnen, dass der ausführbare Preis des Kaufauftrags der Briefkurs (Ask) und der ausführbare Preis beim Schließen der Geldkurs (Bid) ist. Andererseits ist der ausführbare Preis der Verkaufsorder der Geldkurs und der ausführbare Preis beim Schließen der Briefkurs.

OrderSend()

Nachdem wir wichtige Begriffe über die Handelsausführung in MetaTrader 5 verstanden haben, müssen wir lernen, wie wir Aufträge in MQL5 automatisch ausführen sollten. Zunächst können Sie sich in der MQL5-Referenz über die Handelsfunktionen informieren, um mehr über Funktionen zur Verwaltung von Aktivitäten zu erfahren.

Wir werden die Funktion OrderSend() erörtern, die zur Ausführung von Handelsoperationen durch das Senden von Anfragen an einen Handelsserver verwendet werden kann. Mit anderen Worten: Sie können damit Aufträge erteilen, ändern und schließen.

Das Format dieser Funktion ist wie folgt:

bool  OrderSend(
   MqlTradeRequest&  request,      
   MqlTradeResult&   result        
   );

Wie wir sehen können, hat die Funktion zwei Parameter:

  • Die Struktur MqlTradeRequest: Sie enthält die Auftragsparameter und alle notwendigen Felder oder Variablen, um Handelsgeschäfte durchzuführen. Objekte, die als Referenz gemäß den Ampersands (&) übergeben werden. Der TradeRequest ist die Methode für die Interaktion zwischen dem Kundenterminal und dem Handelsserver zur Ausführung von Aufträgen.
  • Die Struktur MqlTradeResult: Das TradeResult liefert die Ergebnisse der Auftragsanfrage. Auch Objekte werden als Referenz übergeben.

Die Struktur MqlTradeRequest:

Die Struktur besteht aus einer Reihe von zusammenhängenden Daten unterschiedlicher Art. Die Strukturdefinition von MqlTradeRequest sieht wie folgt aus:

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Trade operation type
   ulong                         magic;            // Expert Advisor ID (magic number)
   ulong                         order;            // Order ticket
   string                        symbol;           // Trade symbol
   double                        volume;           // Requested volume for a deal in lots
   double                        price;            // Price
   double                        stoplimit;        // StopLimit level of the order
   double                        sl;               // Stop Loss level of the order
   double                        tp;               // Take Profit level of the order
   ulong                         deviation;        // Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order expiration type
   datetime                      expiration;       // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // The ticket of an opposite position
  };

Wenn wir ein MqlTradeRequest-Objekt deklarieren wollen, können wir dies durch die folgende Codezeile tun:

MqlTradeRequest request;

Dann können wir die Handelsparameter den Variablen des erstellten Anfrageobjekts zuweisen, indem wir den Punktoperator (.) nach dem Objekt hinzufügen, wie im folgenden Beispiel gezeigt:

request.symbol = _Symbol;
request.volume = 0.01;
request.type = ORDER_TYPE_BUY;

Es folgt eine Liste aller Mitglieder oder Variablen der MqlTradeRequest-Struktur mit ihren akzeptierten Werten für die Zuweisung.

Variabel Beschreibung Akzeptierter Wert für die Zuordnung
action Es steht für die Art des Handelsgeschäfts

Eine aus ENUM_TRADE_REQUEST_ACTIONS (TRADE_ACTION_DEAL, TRADE_ACTION_PENDING, TRADE_ACTION_SLTP, TRADE_ACTION_MODIFY, TRADE_ACTION_REMOVE, TRADE_ACTION_CLOSE_BY)

magic Es handelt sich um die MagicNumber, die der Expertenberaters zur Identifizierung der seiner Aufträge und Positionen vergibt. Beliebiger ulong-Wert
order Es ist die serverseitige Ticketnummer des Auftrags. Es ist erforderlich, wenn TRADE_ACTION_MODIFY oder TRADE_ACTION_REMOVE in der Aktionsvariablen verwendet wird.  Beliebiger ulong-Wert
symbol Das angegebene Symbol oder das zu handelnde Instrument. _SYMBOL bezieht sich auf das aktuelle Symbol des Charts. Beliebiges String-Symbol
volume Es gibt das Handelsvolumen oder die Losgröße an.  Jeder zulässige reelle Wert
price Der Eröffnungspreis double-Wert
stoplimit Der Eröffnungskurs der schwebenden Limit-Order. Für „action“ muss der Wert TRADE_ACTION_PENDING gesetzt sein und das Feld „type“ muss ORDER_TYPE_BUY_STOP_LIMIT oder ORDER_TYPE_SELL_STOP_LIMIT lauten für eine gültige Stop-Limit-Order. double-Wert
sl Der Stop-Loss-Kurs des Auftrags. double-Wert
tp Der Take-Profit-Kurs des Auftrags. double-Wert
deviation Die maximal erlaubte Preisabweichung in Punkten. ulong-Wert
type Die Auftragsart Einer Wert aus ENUM_ORDER_TYPE (ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP, 
AUFTRAGSART_KAUF_LIMIT, AUFTRAGSART_VERKAUF_LIMIT, AUFTRAGSART_KAUF_STOP_LIMIT, AUFTRAGSART_VERKAUF_STOP_LIMIT)
type_filling Art der Auftragsausführung oder die Ausführungspolitik des Auftrags Ein Wert aus ENUM_ORDER_TYPE_FILLING (ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_BOC, ORDER_FILLING_RETURN)
type_time Die Art des Ablaufs des ausstehenden Auftrags Ein Wert aus ENUM_ORDER_TYPE_TIME (ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY)
expiration Die Ablaufzeit des ausstehenden Auftrags. Sie ist erforderlich, wenn type_time ORDER_TIME_SPECIFIED lautet. datetime value
comment Der Kommentar zum Auftrag Zeichenkette
Position Die Ticketnummer einer Position. Sie ist erforderlich, wenn eine Position geändert oder geschlossen wird, um sie zu identifizieren. ulong-Wert
position_by Das Ticket einer entgegengesetzten Position. Es wird verwendet, wenn eine Position durch eine offene Position in der entgegengesetzten Richtung für dasselbe Symbol geschlossen werden soll. ulong-Wert

Jetzt werden wir einige wichtige Aktionen erwähnen, die wir bei der Auftragserteilung in MQL5 verwenden müssen.

  • Marktauftrag
  • Hinzufügen von Stop-Loss und Take-Profit
  • Schwebender Auftrag
  • Ändern eines schwebenden Auftrags
  • Entfernen eines schwebenden Auftrags

Marktauftrag:

Bei dieser Art von Aktion platzieren wir eine Marktorder, was bedeutet, dass die Order zum aktuellen Marktpreis realisiert wird. Dazu weisen wir „action“ (TRADE_ACTION_DEAL) zu. Handelt es sich um einen Kaufauftrag, wird der Auftrag zum aktuellen Briefkurs (Ask) erteilt, handelt es sich um einen Verkaufsauftrag, wird der Auftrag zum aktuellen Geldkurs (Bid) erteilt. Und so geht's: 

Nachdem wir die Objekte MqlTradeRequest und MqlTradeResult deklariert haben, können wir die folgenden Werte den folgenden Variablen zuweisen:

request.action = TRADE_ACTION_DEAL;                    &nbsthe p;   //market order palcement
request.type = ORDER_TYPE_BUY;                             //type of order is buy
request.symbol = _Symbol;                                  //applied for the cuurrent symbol
request.volume = 0.1;                                      //the lot size
request.type_filling = ORDER_FILLING_FOK;                  //the filling policy fill or kill
request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);      //the price is the current ask for buy
request.sl = 0;                                            //stop loss is 0
request.tp = 0;                                            //take profit is 0
request.deviation = 50;                                    //slippage is 50
OrderSend(request, result);                                //calling the OrderSend function

Wie wir im vorherigen Code sehen können, haben wir keine Stop-Loss- und Take-Profit-Werte hinzugefügt. Wir können ihre Werte zusammen mit den anderen Variablen in den Code einfügen, oder wir können sie über eine andere Aktion hinzufügen, wie wir im nächsten Punkt sehen werden.

Hinzufügen von Stop-Loss und Take-Profit:

Wenn wir Stop-Loss und Take-Profit hinzufügen müssen, weisen wir TRADE_ACTION_SLTP der Variablen action zu, wie im folgenden Beispiel gezeigt.

request.action = TRADE_ACTION_SLTP;          //adding sl and tp
request.symbol = _Symbol;                    //applied for the cuurrent symbol
request.sl = 1.07000;                        //sl price
request.sl = 1.09000;                        //tp price
OrderSend(request, result);                  //calling the OrderSend function


Schwebender Auftrag:

Wenn wir einen schwebenden Auftrag erteilen wollen, müssen wir den Wert (TRADE_ACTION_PENDING) für action verwenden. Dann bestimmen wir die Art des Auftrags. Wir können die Zeit einstellen, wenn wir eine Verfallszeit für den schwebenden Auftrag benötigen.

request.action = TRADE_ACTION_PENDING;          //pending order placement
request.type = ORDER_TYPE_BUY_STOP;             //type of order is buy stop
request.symbol = _Symbol;                       //applied for the cuurrent symbol
request.volume = 0.1;                           //the lot size
request.price = 1.07000;                        //opening price
request.sl = 1.06950;                           //stop loss
request.tp = 1.07100;                           //take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.08.31 00.00';       //expiration time - datetime constant          
request.type_filling = ORDER_FILLING_FOK;       //the filling policy fill or kill
request.stoplimit = 0;                          //for stoplimit order only
OrderSend(request, result);                     //calling the OrderSend function


Ändern eines schwebenden Auftrags:

Wenn wir den schwebenden Auftrag ändern müssen, müssen wir die Nummer des Auftragstickets des schwebenden Auftrags abrufen, den wir ändern wollen. Wir können uns mit der Funktion OrderGetTicket den schwebenden Auftrag holen. Diese Funktion gibt das Ticket des entsprechenden Auftrags zurück, mit dem wir den Auftrag auswählen und damit arbeiten können.

ulong  OrderGetTicket( 
   int  index      // Number in the list of orders 
   );

Nehmen wir an, wir haben eine Variable namens (ticket), die die Nummer des Auftrags enthält. Wir können diese Variable verwenden, um die Ticketnummer des Auftrags der Auftragsvariablen des Anfrageobjekts „request“ zuzuweisen. Wir können dann den Auftrag mit Hilfe der Aktion(TRADE_ACTION_MODIFY) ändern, wie im folgenden Beispiel.

request.action = TRADE_ACTION_MODIFY;           //pending order modyfying
request.order = ticket;                         //ticket variable that holds the pending order ticket to modify
request.price = 1.07050;                        //new opening price
request.sl = 1.07000;                           //new stop loss
request.tp = 1.07150;                           //new take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.09.01 00.00';       //new expiration time - datetime constant        
OrderSend(request, result);                     //calling the OrderSend function

Entfernen eines schwebenden Auftrags:

Wenn wir den schwebenden Auftrag entfernen müssen, können wir das mit der Aktion (TRADE_ACTION_REMOVE) tun. Außerdem benötigen wir die Ticketnummer des schwebenden Auftrags, den wir entfernen möchten. Wir können die Variable ticket verwenden, wenn wir davon ausgehen, dass sie die benötigte Ticketnummer enthält.

request.action = TRADE_ACTION_REMOVE;           //pending order remove
request.order = ticket;                         //ticket variable that holds the pending order ticket to remove
OrderSend(request, result);                     //calling the OrderSend function

Die Struktur MqlTradeResult:

Die Struktur MqlTradeResult gibt das Ergebnis zurück, ob die Order erfolgreich war oder nicht, nachdem eine Order durch die Funktion OrderSend() erteilt wurde. Sie enthält Handelsinformationen vom Handelsserver, wie die Ticketnummer, das Volumen und den Preis.

Es folgt die Definition der Struktur MqlTradeResult:

struct MqlTradeResult
  {
   uint     retcode;          // Operation return code
   ulong    deal;             // Deal ticket, if it is performed
   ulong    order;            // Order ticket, if it is placed
   double   volume;           // Deal volume, confirmed by broker
   double   price;            // Deal price, confirmed by broker
   double   bid;              // Current Bid price
   double   ask;              // Current Ask price
   string   comment;          // Broker comment to operation (by default it is filled by description of trade server return code)
   uint     request_id;       // Request ID set by the terminal during the dispatch 
   int      retcode_external; // Return code of an external trading system
  };

Wir können ein Objekt namens result deklarieren, um es als zweiten Parameter nach dem ersten (request) an den Aufruf der Funktion OrderSend() zu übergeben.

MqlTradeResult result;

Wie in den Variablen der Struktur MqlTradeResult zu sehen ist, ist die Variable retcode sehr wichtig, da sie den Code vom Handelsserver zurückgibt, der angibt, ob die Anfrage erfolgreich war oder nicht.

Wenn der Handel nicht zustande kommt, zeigt der Rückgabecode einen Fehler an. Weitere Informationen finden Sie in der Liste der Rückgabecodes in der MQL5-Referenz. Es ist wichtig, einen Code in unser Handelssystem einzubauen, der meldet, ob ein Fehler vorliegt oder nicht, wie im folgenden Beispiel:

   if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
     {
      Print("Trade Placed Successfully");
     }
   else
     {
      Print("Trade Not Placed, Error ", result.retcode);
     }

Wie im vorherigen Code zu sehen ist, wird nach der Anfrage eine Nachricht mit dem Ergebnis gedruckt und die Ergebnisvariablen werden ausgefüllt. Wenn der Handel platziert wurde, erhalten wir eine entsprechende Nachricht, und wenn es ein Problem gibt, wird eine Fehlermeldung ausgedruckt und der Fehlercode zurückgegeben, um die Suche nach dem Problem zu erleichtern.

OrderSend() anwenden

Wir müssen ein einfaches Handelssystem erstellen, das mit der Funktion OrderSend() Abschlüsse ausführen kann. Das Handelssystem, das wir erstellen müssen, ist ein einfaches Crossover des gleitenden Durchschnitts, und die Aktion besteht ausschließlich in der Platzierung einer Marktorder.

Ziel ist es, die Unterschiede bei der Erstellung desselben Handelssystems unter Verwendung von OrderSend() und der Klasse CTrade zu verstehen. Im Folgenden werden die Schritte zur Erstellung dieses MA-Crossovers mit Hilfe der Funktion OrderSend() beschrieben.

Erstellen Sie im globalen Bereich zwei Integer-Variablen (simpleMA, barsTotal) ohne Zuweisung; sie werden später im OnInit-Teil zugewiesen.

int simpleMA;
int barsTotal;

Der simpleMA wird der Funktion iMA zugewiesen, die den Handle des technischen Indikators des gleitenden Durchschnitts zurückgibt. Die Parameter sind:

  • symbol: ist der Namen des Symbols, _Symbol bezieht sich auf das aktuelle Instrument des Charts.
  • period: ist für die Angabe des Zeitrahmens wird PERIOD_H1, was sich auf den Zeitrahmen von einer Stunde bezieht.
  • ma_period: die Periodenlänge des gleitenden Durchschnitts, wir nehmen 50.
  • ma_shift: zur Angabe der erforderlichen horizontalen Verschiebung.
  • ma_method: bestimmt den Typ des gleitenden Durchschnitts, wir wählen hier den einfachen Durchschnitt.
  • applied_price: legt die Art des Preises fest, der für die Berechnung des MA verwendet wird, wir verwenden den Schlusskurs.

Der Wert barsTotal wird der Funktion iBars zugewiesen, die die Anzahl der Balken zurückgibt. Die Parameter sind:

  • symbol: der Name des Symbols
  • timeframe: der Zeitrahmen
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);

In OnTick erstellen wir zwei Arrays, eines für den Preis unter Verwendung des Typs MqlRates, der Informationen über Preis, Volumen und Spread speichert, und das andere für den gleitenden Durchschnitt mit dem Typ double:

   MqlRates priceArray[];
   double mySMAArray[];

Abfragen der Geld- und Briefkurse:

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

Wir erstellen zwei Objekte für die Funktion OrderSend(), eines für die Anfrage unter Verwendung von MqlTradeReuest und das andere für das Ergebnis unter Verwendung von MqlTradeResult per Referenz und setzen die Anforderungsvariable zurück:

ZeroMemory(request);

Jetzt setzen wir das Flag AS_SERIES für die beiden erstellten Arrays priceArray und mySMAArray mit Hilfe der Funktion ArraySetAsSeries. Die Parameter:

  • array[]: Angabe des benötigten Arrays
  • flag: Richtung der Array-Indizierung.
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

Abrufen historischer Daten von MqlRates mit der Funktion CopyRates. Die Parameter sind:

  • symbol: der Symbolname oder _Symbol für das aktuelle Symbol oder Instrument des Charts.
  • time frame: Zeitrahmenperiode oder _Periode für den aktuellen Zeitrahmen des Charts.
  • start position: die Position, von der aus gestartet werden soll.
  • count: Anzahl der zu kopierenden Daten.
  • rates_array: das zu kopierende Ziel-Array.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

Abrufen des Indikatordatenpuffers mit Hilfe der Funktion CopyBuffer. Die Parameter:

  • indicator_handle: Das Handle MA-Indikators.
  • buffer_num: Zur Angabe der Nummer des Indikatorpuffers.
  • start_pos: die Startposition, ab der gezählt wird.
  • count: zu kopierende Anzahl.
  • buffer[]: das Ziel-Array.
CopyBuffer(simpleMA,0,0,3,mySMAArray);

Definition der letzten und vorherigen Schlusskurse sowie der letzten und vorherigen SMA-Werte.

   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

Erstellen einer ganzzahligen Variablen der Balken, die iBars zugewiesen werden soll;

int bars=iBars(_Symbol,PERIOD_H1);

Überprüfung der Balken, wenn barsTotal nicht gleich der Variablen bars ist:

if(barsTotal != bars)

Aktualisierung des Wertes von barsTotal, sodass er den Balken entspricht, wenn diese nicht gleich sind:

barsTotal=bars;

Überprüfung der Bedingung der Strategie, ein Handelsgeschäft zu eröffnen, wenn der letzte Schlusskurs größer ist als der letzte SMA-Wert, nachdem der vorherige Schlusskurs kleiner war als der vorherige SMA-Wert:

if(prevClose<prevSMAVal && lastClose>SMAVal)

Eröffnung eines Marktkaufauftrags unter Verwendung geeigneter Variablen in Verbindung mit der Funktion MqlTradeRequest:

         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Überprüfung der Bedingung der Strategie zur Eröffnung eines Verkaufsgeschäfts, wenn der letzte Schlusskurs kleiner als der letzte SMA-Wert ist, nachdem der vorherige Schlusskurs größer als der vorherige SMA-Wert war:

if(prevClose>prevSMAVal && lastClose<SMAVal)
Eröffnung eines Marktverkaufsauftrags unter Verwendung geeigneter Variablen in Verbindung mit der Funktion MqlTradeRequest:
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Im Folgenden finden Sie den vollständigen Code in einem Block, um diese Art von Handelssystem unter Verwendung der Funktion OrderSend() zu erstellen:

//+------------------------------------------------------------------+
//|                                     OrderSend_Trading_system.mq5 |
//+------------------------------------------------------------------+
int simpleMA;
int barsTotal;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   MqlTradeRequest request;
   MqlTradeResult result;
   ZeroMemory(request);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
     }
  }

Die Klasse CTrade

Nachdem wir gelernt haben, wie wir mit der Funktion OrderSend() Aufträge erteilen können, haben wir eine einfache Methode, um auf Handelsfunktionen zuzugreifen. Wir können die vorgefertigte Klasse CTrade von MQL5 verwenden oder unsere eigene Klasse erstellen, wenn wir mehr persönliche Präferenzen haben. Jetzt werden wir erwähnen, wie wir die vorgefertigte Klasse CTrade in MQL5 verwenden können. Sie können alles über die CTrade-Klasse in der MQL5-Referenz nachlesen, um weitere Informationen zu erhalten.

Zunächst finden wir die Include-Datei der Klasse CTrade im Ordner Trade im Include-Ordner in den MetaTrader 5-Installationsdateien. Alles, was wir brauchen, ist, diese Datei in den Expert Advisor einzubinden, um alle Handelsfunktionen aufzurufen und zu verwenden, wie im Folgenden beschrieben:

#include <Trade\Trade.mqh>

Erstellen eines Objekts der Klasse CTrade:

CTrade trade;

Danach können wir alle Handelsfunktionen in der CTrade-Klasse verwenden, indem wir nach trade einen Punkt(.) gefolgt von der gewünschten Funktion setzen. Wir können alle Funktionen der Vorgänge mit Aufträgen, der Vorgänge mit Positionen, des Zugriffs auf die Parameter der letzten Anfrage, des Zugriffs auf die Ergebnisse der Prüfung der letzten Anfrage, des Zugriffs auf die Ergebnisse der Ausführung der letzten Anfrage und andere nutzen.

Wir werden einige wichtige Funktionen wie bei OrderSend() erwähnen, um die Unterschiede zwischen den beiden Methoden zu verstehen. Wir werden verstehen, wie wir Folgendes tun können:

  • Marktauftrag
  • Hinzufügen von Stop-Loss und Take-Profit
  • Schwebender Auftrag
  • Ändern eines schwebenden Auftrags
  • Entfernen eines schwebenden Auftrags

Marktauftrag:

Nachdem wir unser Objekt „trade“ erstellt haben, können wir die Funktion PositionOpen verwenden, um eine Marktorder zu platzieren:

  • symbol: für die Angabe des benötigten Symbols
  • order_type: zur Angabe der Auftragsart zur Eröffnung einer Position
  • volume: zur Angabe der Losgröße
  • price: zur Angabe des Preises für die Positionseröffnung
  • sl: zur Angabe des Stop-Loss-Kurses
  • tp: zur Angabe des Preises für Take-Profit
  • comment: zur Angabe eines Kommentars oder NULL

Ein Beispiel dafür ist das Folgende:

trade.PositionOpen(
   _Symbol,             //to be applied for the current symbol
   ORDER_TYPE_BUY,      //to place buy order
   0.1,                 //lot size or volume
   Ask,                 //opening price of the order - current ask
   Ask-(500*_Point),    //sl
   Ask+(1000*_Point),   //tp
   NULL                 //NULL
);

Wir können auch die zusätzlichen Methoden in CTrade wie Buy, Sell anstelle von PositionOpen verwenden, um eine Marktorder zu eröffnen.

Hinzufügen von Stop-Loss und Take-Profit:

Mit der Funktion PositionModify können wir die Position eines Symbols oder einer Ticketnummer ändern. Die Parameter sind:

  • Symbol oder Ticket: zur Angabe der zu ändernden Position; bei Änderung nach Symbol wird der Name des Symbols angegeben, bei Änderung nach Ticket die Ticketnummer.
  • sl: der neue Stop-Loss-Preis
  • tp: der neue Preis für Take-Profit

Beispiel für das Ändern nach dem Symbol:

trade.PositionModify(
   EURUSD,       //the symbol name
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Beispiel für das Ändern nach der Ticketnummer:

trade.PositionModify(
   ticket,       //the ticket variable that holds the needed ticket number to modify
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Schwebender Auftrag:

Wenn wir einen schwebenden Auftrag mit der CTrade-Klasse platzieren müssen, können wir die Funktion OrderOpen verwenden. Die Parameter sind:

  • symbol: der Name des Symbols
  • order_type: zur Bestimmung der Art des schwebenden Auftrags
  • volume: zur Angabe der Losgröße
  • limit_price: zur Angabe des Stop-Limit-Preises
  • price: zur Angabe des Ausführungspreises für den schwebenden Auftrag
  • sl: zur Angabe des Stop-Loss
  • tp: zur Angabe des Take-Profit
  • type_time: zur Angabe des Typs der Ablaufzeit
  • expiration: zur Angabe der „datetime“-Variablen für das Ablaufdatum
  • Kommentar: zur Angabe eines Kommentars, falls erforderlich

Das folgende Beispiel zeigt, wie eine schwebende Kauf-Limit-Order mit der Funktion OrderOpen platziert wird:

         trade.OrderOpen(
            "EURUSD",                 // symbol
            ORDER_TYPE_BUY_LIMIT,     // order type
            0.1,                      // order volume
            0,                        // StopLimit price
            1.07000,                  // execution price
            1.06950,                  // Stop Loss price
            1.07100,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            ""                        // comment
         );

Ändern eines schwebenden Auftrags:

Wenn wir den platzierten schwebenden Auftrag ändern müssen, können wir dies mit der CTrade-Klasse über die Funktion OrderModify tun. Die Parameter sind:

  • ticket: Angabe des zu ändernden Tickets für schwebende Aufträge
  • price: der neue Ausführungspreis
  • sl: der neue Stop-Loss-Preis
  • tp: der neue Take-Profit-Preis
  • type_time: zur Angabe des Typs der Ablaufzeit
  • expiration: zur Angabe der „datetime“-Variablen für das Ablaufdatum
  • stoplimit : zur Bestimmung des Limitpreises des Auftrags

Nachfolgend ein Beispiel für die Änderung eines schwebenden Auftrags

         trade.OrderModify(
            ticket,                   // ticket number of the pending order to modify
            1.07050,                  // execution price
            1.07000,                  // Stop Loss price
            1.07150,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            0,                        // StopLimit price
         );

Einen schwebenden Auftrag löschen:

Wenn Sie einen schwebenden Auftrag löschen müssen, können Sie dies mit der Funktion OrderDelete tun, für die die Ticketnummer des zu löschenden schwebenden Auftrags benötigt wird. Im Folgenden wird ein Beispiel für diese Funktion gegeben:

         trade.OrderDelete(
            ticket,                 // tick number of the pending order to delete
         );

Die Anwendung der Klasse CTrade

Wir müssen das gleiche Handelssystem erstellen, das wir mit OrderSend() erstellt haben. Wir werden die Klasse CTrade verwenden, um die Unterschiede in der Funktionsweise der beiden Klassen zu verstehen.

Die folgenden Schritte sind die einzigen, die sich bei der Erstellung dieses Handelssystems mit der Klasse CTrade unterscheiden. Die übrigen Schritte sind die gleichen wie zuvor.

Einbindung der Include-Datei „Trade.mqh“ mit #include:

#include <Trade\Trade.mqh>

Erstellen eines Handelsobjekts mit der Klasse CTrade:

CTrade trade;

Wenn die Kaufbedingung erfüllt ist, können wir PositionOpen verwenden, und der Auftragstyp wird ORDER_TYPE_BUY oder die zusätzliche Kaufmethode sein, die dem folgenden Code entspricht:

trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);

Wenn die Verkaufsbedingung erfüllt ist, können wir die PositionOpen zusammen mit dem Auftragstyp ORDER_TYPE_SELL oder die zusätzliche Verkaufsmethode wie den folgenden Code verwenden:

trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);

Im Folgenden finden Sie den vollständigen Code zur Erstellung des Handelssystems unter Verwendung der Klasse CTrade:

//+------------------------------------------------------------------+
//|                                        CTrade_Trading_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
int simpleMA;
int barsTotal;
CTrade trade;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
        }
     }
  }

Schlussfolgerung

Wenn Sie diesen Artikel zu Ende gelesen haben, sollten Sie verstehen, wie Aufträge, Positionen und Geschäfte in MQL5 funktionieren. Zusätzlich zum Verständnis, wie wir ein Handelssystem reibungslos mit den beiden Methoden der Handelsoperationen, der OrderSend-Methode und der CTrade-Methode, erstellen können.

Wir haben ermittelt, wie wir mit den beiden Methoden Marktaufträge und schwebende Aufträge platzieren, Stop-Loss und Take-Profit hinzufügen, schwebende Aufträge ändern und schwebende Aufträge entfernen oder löschen.

Es wird davon ausgegangen, dass Sie verstanden haben, wie man alle vorherigen Methoden anwendet, um eine Anwendung zu erstellen, da wir zwei einfache Anwendungen zur Verfügung gestellt haben, um dasselbe Handelssystem mit gleitendem Durchschnitts-Crossover unter Verwendung der beiden Methoden zu erstellen.

  • OpenSend_Trading_System
  • CTrade_Trading_System

Das Ziel der erwähnten Anwendungen ist es nur, die Unterschiede zwischen ihnen praktisch zu verstehen. Sie müssen sie also unbedingt testen, bevor Sie sie in einem Live-Konto verwenden, um sicherzustellen, dass sie profitabel und für Ihren Handel geeignet sind.

Ich glaube, Sie haben bereits festgestellt, wie einfach es ist, die vorgefertigte CTrade-Klasse bei der Arbeit mit Handelsoperationen zu verwenden, weil sie viel Zeit und Mühe spart. Zusätzlich zu anderen Funktionen bei der Verwendung von Klassen in der Programmierung im Allgemeinen.

Wenn Sie mehr darüber und über die objektorientierte Programmierung in MQL5 erfahren möchten, können Sie meinen früheren Artikel Objektorientierte Programmierung (OOP) in MQL5 verstehen lesen. Ich hoffe, dass er Ihnen hilft. MQL5 hat viel Arbeit und Mühe investiert, um uns Werkzeuge zur Verfügung zu stellen, mit denen wir reibungslos und einfach Handelssoftware entwickeln und erstellen können.

Ich hoffe, dass Sie diesen Artikel nützlich fanden und viele nützliche Einsichten gewonnen haben, um Ihre Arbeit nach diesen Einsichten zu verstehen und leicht zu erledigen. Wenn Sie mehr Artikel von mir lesen möchten, können Sie in meiner Publikation viele Artikel über die Erstellung von Handelssystemen mit den populärsten technischen Indikatoren und anderen finden, und ich hoffe, dass Sie sie nützlich finden werden.

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

Das Preisbewegungsmodell und seine wichtigsten Aspekte. (Teil 3): Berechnung der optimalen Parameter des Börsenhandels Das Preisbewegungsmodell und seine wichtigsten Aspekte. (Teil 3): Berechnung der optimalen Parameter des Börsenhandels
Im Rahmen des vom Autor entwickelten technischen Ansatzes, der auf der Wahrscheinlichkeitstheorie basiert, werden die Bedingungen für die Eröffnung einer profitablen Position gefunden und die optimalen (gewinnmaximierenden) Take-Profit- und Stop-Loss-Werte berechnet.
Datenkennzeichnung für Zeitreihenanalyse (Teil 2): Datensätze mit Trendmarkern mit Python erstellen Datenkennzeichnung für Zeitreihenanalyse (Teil 2): Datensätze mit Trendmarkern mit Python erstellen
In dieser Artikelserie werden verschiedene Methoden zur Kennzeichnung von Zeitreihen vorgestellt, mit denen Daten erstellt werden können, die den meisten Modellen der künstlichen Intelligenz entsprechen. Eine gezielte und bedarfsgerechte Kennzeichnung von Daten kann dazu führen, dass das trainierte Modell der künstlichen Intelligenz besser mit dem erwarteten Design übereinstimmt, die Genauigkeit unseres Modells verbessert wird und das Modell sogar einen qualitativen Sprung machen kann!
Brute-Force-Ansatz zur Mustersuche (Teil V): Neue Blickwinkel Brute-Force-Ansatz zur Mustersuche (Teil V): Neue Blickwinkel
In diesem Artikel werde ich einen völlig anderen Ansatz für den algorithmischen Handel vorstellen, den ich nach langer Zeit gefunden habe. Das alles hat natürlich mit meinem Brute-Force-Programm zu tun, das eine Reihe von Änderungen erfahren hat, die es ihm ermöglichen, mehrere Probleme gleichzeitig zu lösen. Dennoch ist der Artikel allgemeiner und so einfach wie möglich gehalten, weshalb er auch für diejenigen geeignet ist, die nichts über Brute-Force wissen.
Datenkennzeichnung für Zeitreihenanalyse (Teil 1):Erstellen eines Datensatzes mit Trendmarkierungen durch den EA auf einem Chart Datenkennzeichnung für Zeitreihenanalyse (Teil 1):Erstellen eines Datensatzes mit Trendmarkierungen durch den EA auf einem Chart
In dieser Artikelserie werden verschiedene Methoden zur Kennzeichnung von Zeitreihen vorgestellt, mit denen Daten erstellt werden können, die den meisten Modellen der künstlichen Intelligenz entsprechen. Eine gezielte und bedarfsgerechte Kennzeichnung von Daten kann dazu führen, dass das trainierte Modell der künstlichen Intelligenz besser mit dem erwarteten Design übereinstimmt, die Genauigkeit unseres Modells verbessert wird und das Modell sogar einen qualitativen Sprung machen kann!