English Русский 中文 Español 日本語 Português
preview
Die Transaktionen des Handels Anfrage- und Antwortstrukturen, Beschreibung und Protokollierung

Die Transaktionen des Handels Anfrage- und Antwortstrukturen, Beschreibung und Protokollierung

MetaTrader 5Beispiele | 8 Dezember 2023, 09:46
441 0
Artyom Trishkin
Artyom Trishkin

Inhalt


Einführung

MQL5 verfügt über die Funktion OrderSend() zum Platzieren von schwebenden Aufträgen, zum Öffnen von Positionen sowie zum Ändern von Aufträgen und Positionen. Die erste Eingabe der Funktion ist die Struktur der Handelsanfrage MqlTradeRequest. Das Feld "Aktion" der Struktur gibt die Art der auszuführenden Aktion an, und die übrigen Felder werden in Abhängigkeit von der im Feld "Aktion" ausgewählten Aktion ausgefüllt. Wir senden also verschiedene Anfragen an den Server, indem wir die für eine Handelsanfrage erforderlichen Parameter an die Funktion übergeben.

Struktur der Handelsanfrage (MqlTradeRequest)

Die Interaktion zwischen dem Kundenterminal und dem Handelsserver in Bezug auf die Auftragsvergabe erfolgt über Handelsaufträge. Die Anfrage wird durch die spezielle, vordefinierte Struktur MqlTradeRequest dargestellt, die alle für die Durchführung von Geschäften erforderlichen Felder enthält:

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Type of a performed action
   ulong                         magic;            // EA stamp (magic number ID)
   ulong                         order;            // Order ticket
   string                        symbol;           // Symbol name
   double                        volume;           // Requested volume of a deal in lots
   double                        price;            // Price 
   double                        stoplimit;        // StopLimit order level
   double                        sl;               // Stop Loss order level
   double                        tp;               // Take Profit order level
   ulong                         deviation;        // Maximum acceptable deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order filling type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order lifetime type
   datetime                      expiration;       // Order expiration time (for ORDER_TIME_SPECIFIED type orders)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // Opposite position ticket
  };

Das erste Feld „action“ gibt die Art der auszuführenden Aktion an.

Die Art der Handelsoperation. Der Wert kann einer der Werte der Enumeration ENUM_TRADE_REQUEST_ACTIONS sein:

ID
Beschreibung
TRADE_ACTION_DEAL
Den Auftrag für ein sofortiges Handelsgeschäfts mit den angegebenen Parametern erteilen (einen Marktauftrag erteilen)
TRADE_ACTION_PENDING
Den Auftrag zur Durchführung eines Handelsgeschäfts zu bestimmten Konditionen erteilen (schwebenden Auftrag oder Pending Order)
TRADE_ACTION_SLTP
Ändern von Stop-Loss und Take-Profit einer offenen Position
TRADE_ACTION_MODIFY
Parameter des zuvor erteilten Handelsauftrags ändern
TRADE_ACTION_REMOVE
Zuvor erteilten schwebenden Auftrag entfernen
TRADE_ACTION_CLOSE_BY
Eine Position mit einer entgegengesetzten Position schließen

Die Strukturfelder müssen für jede Art von Maßnahme einzeln ausgefüllt werden.

Nachdem wir die erforderlichen Felder der Struktur ausgefüllt haben, können wir einen Handelsauftrag an den Server senden. Wir können auch zunächst prüfen, ob die Struktur korrekt gefüllt ist, indem wir die Funktion OrderCheck() verwenden, , die die zu prüfende Abfrage und die Variable des Strukturtyps MqlTradeCheckResult übermittelt. Das Ergebnis der Prüfung wird in die Variable eingetragen:

struct MqlTradeCheckResult
  {
   uint         retcode;             // Response code
   double       balance;             // Balance after performing a deal
   double       equity;              // Equity after performing a deal
   double       profit;              // Floating profit
   double       margin;              // Margin requirements
   double       margin_free;         // Free margin
   double       margin_level;        // Margin level
   string       comment;             // Comment on the response code (error description)
  };

Die Funktion gibt false zurück, wenn die Prüfung des Auftrags ergibt, dass die Mittel nicht ausreichen oder die Parameter nicht korrekt ausgefüllt sind. Ist die grundsätzliche Prüfung von Strukturen (Zeigern) erfolgreich, gibt die Funktion true zurück, was nicht bedeutet, dass die angeforderte Handelsoperation erfolgreich ausgeführt wird. Um eine detaillierte Beschreibung des Ergebnisses der Ausführung einer Funktion zu erhalten, sollten wir die Felder der oben vorgestellten Ergebnisstruktur analysieren.

Nach erfolgreicher Prüfung der Vollständigkeit der Felder der Handelsauftragsstruktur kann diese an den Server gesendet werden. Der Erfolg der Ausführung der Funktion OrderSend() bedeutet nicht, dass der Auftrag ausgeführt wurde. Wir verstehen einfach, dass die Bestellung bearbeitet und vom Server angenommen wurde. Das Ergebnis der Übermittlung eines Handelsauftrags an den Server sind die ausgefüllten Felder der Struktur MqlTradeResult, die die Antwort des Handelsservers auf die von der Funktion OrderSend() gesendete Anfrage enthält.

Das Ergebnis der Handelsoperation wird an eine Variable vom Typ MqlTradeResult zurückgegeben, die als zweiter Parameter an die Funktion OrderSend() zur Durchführung von Handelsoperationen übergeben wird.

Das Terminal setzt die Anfrage-ID in das Feld request_id, wenn es sie mit den Funktionen OrdersSend() und OrderSendAsync() an den Handelsserver sendet. Das Terminal erhält Nachrichten über durchgeführte Transaktionen vom Handelsserver und übergibt sie zur Verarbeitung an die Funktion OnTradeTransaction(), die die folgenden Komponenten als Parameter enthält:

  • Beschreibung der Handelstransaktionen in der Struktur MqlTradeTransaction;
  • Beschreibung der Handelsanfrage, die von der Funktion OrderSend() oder OrdersSendAsync() gesendet wurde. Die Anfrage-ID wird vom Terminal an den Handelsserver gesendet, während die Anfrage selbst und ihre request_id im Speicher des Terminals gespeichert werden;
  • das Ergebnis der Ausführung der Handelsanfrage als MqlTradeResult-Struktur mit dem Feld request_id, das die ID dieser Anfrage enthält.

Die Funktion OnTradeTransaction() erhält drei Eingabeparameter, wobei die letzten beiden nur für Transaktionen vom Typ TRADE_TRANSACTION_REQUEST analysiert werden sollten. In allen anderen Fällen werden die Daten über den Geschäftsantrag und sein Ausführungsergebnis nicht ausgefüllt. Beispiele für die Analyse von Parametern finden Sie im Abschnitt über die Struktur von Handelsanträgen.

Das Setzen der request_id durch das Terminal für die Handelsanfrage beim Senden an den Server wird hauptsächlich für die Arbeit mit der asynchronen Funktion OrderSendAsync() eingeführt. Diese Kennung ermöglicht es, die durchgeführte Aktion (OrderSend- oder OrderSendAsync-Funktionsaufruf) mit dem Ergebnis dieser an OnTradeTransaction() gesendeten Aktion zu verknüpfen.

So können wir die Annahme eines Handelsauftrags durch den Server, seine Platzierung im Handelssystem und seine Ausführung in der Funktion OnTradeTransaction() steuern. In diesem Artikel werde ich die Funktionen schreiben, um die Felder aller Strukturen, die an einer Handelsanforderung beteiligt sind, im Protokoll anzuzeigen, beginnend mit dem Ausfüllen der Struktur des Handelsauftrags und endend mit der Analyse der Ereignisse in OnTradeTransaction(). Das beabsichtigte Ergebnis ist ein kleiner informierender EA, der alle Handelsereignisse im Journal ausdruckt.

Die Abwicklung von Handelsaufträgen läuft auf Folgendes hinaus:

  1. Ausfüllen der Struktur der Handelsanfrage.
  2. Prüfen, ob die Struktur korrekt ausgefüllt ist und ob ein solchen Auftrag erteilt werden kann.
  3. Senden eines Handelsauftrags an den Server.
  4. Ggf. eine Analyse des Ergebnisses der Übermittlung eines Auftrags an den Server mit der Struktur,
  5. Erhalt der Ereignisse und Analyse von Meldungen im Protokoll der Ereignisbehandlung von OnTradeTransaction().
Bevor wir jedoch mit dem Schreiben von Funktionen zur Ausgabe von Beschreibungen von Strukturfeldern in das Protokoll beginnen, werden wir Hilfsfunktionen schreiben, die Beschreibungen bestimmter Arten von Aufträgen in Form der Werte von Enumerationen zurückgeben, sowie andere nützliche und notwendige Funktionen.

Hilfsfunktionen

Der am Ende des Artikels vorgestellte EA wird mit Hilfe von Tastenkombinationen gesteuert. Schreiben wir zwei Funktionen, um die Betätigung der Strg- und Umschalttaste zu ermitteln:

//+------------------------------------------------------------------+
//| Return the state of the Ctrl key                                 |
//+------------------------------------------------------------------+
bool IsCtrlKeyPressed(void) 
  { 
   return(::TerminalInfoInteger(TERMINAL_KEYSTATE_CONTROL)<0);
  }
//+------------------------------------------------------------------+
//| Return the state of the Shift key                                |
//+------------------------------------------------------------------+
bool IsShiftKeyPressed(void) 
  { 
   return(::TerminalInfoInteger(TERMINAL_KEYSTATE_SHIFT)<0);
  }

Jetzt können wir bei der Erkennung, dass eine Taste gedrückt wurde, das Flag für das Halten der Strg- oder Umschalttaste oder das gleichzeitige Halten beider Tasten prüfen, um auf eine Kombination aus Steuer- und alphanumerischen Tasten zu reagieren.


Bei der Rückgabe von Beschreibungen von Strukturfeldern müssen wir die Rückgabecodes des Handelsservers ausdrucken. Erstellen wir eine Funktion, die eine Beschreibung des Server-Antwort-Codes zurückgibt:

//+------------------------------------------------------------------+
//| Return a description of the trade server return code             |
//+------------------------------------------------------------------+
string RetcodeDescription(const uint retcode,bool ext_descr=false)
  {
   switch(retcode)
     {
      //--- Done
      case 0                                 :  return "OK (0)";
      //--- Requote
      case TRADE_RETCODE_REQUOTE             :  return "10004 REQUOTE"+(ext_descr ? " (Requote)" : "");
      //--- Request rejected
      case TRADE_RETCODE_REJECT              :  return "10006 REJECT"+(ext_descr ? " (Request rejected)" : "");
      //--- Request canceled by trader
      case TRADE_RETCODE_CANCEL              :  return "10007 CANCEL"+(ext_descr ? " (Request canceled by trader)" : "");
      //--- Order placed
      case TRADE_RETCODE_PLACED              :  return "10008 PLACED"+(ext_descr ? " (Order placed)" : "");
      //--- Request completed
      case TRADE_RETCODE_DONE                :  return "10009 DONE"+(ext_descr ? " (Request completed)" : "");
      //--- Request completed partially
      case TRADE_RETCODE_DONE_PARTIAL        :  return "10010 DONE_PARTIAL"+(ext_descr ? " (Only part of the request was completed)" : "");
      //--- Request processing error
      case TRADE_RETCODE_ERROR               :  return "10011 ERROR"+(ext_descr ? " (Request processing error)" : "");
      //--- Request canceled by timeout
      case TRADE_RETCODE_TIMEOUT             :  return "10012 TIMEOUT"+(ext_descr ? " (Request canceled by timeout)" : "");
      //--- Invalid request
      case TRADE_RETCODE_INVALID             :  return "10013 INVALID"+(ext_descr ? " (Invalid request)" : "");
      //--- Invalid volume in the request
      case TRADE_RETCODE_INVALID_VOLUME      :  return "10014 INVALID_VOLUME"+(ext_descr ? " (Invalid volume in the request)" : "");
      //--- Invalid price in the request
      case TRADE_RETCODE_INVALID_PRICE       :  return "10015 INVALID_PRICE"+(ext_descr ? " (Invalid price in the request)" : "");
      //--- Invalid stops in the request
      case TRADE_RETCODE_INVALID_STOPS       :  return "10016 INVALID_STOPS"+(ext_descr ? " (Invalid stops in the request)" : "");
      //--- Trading disabled
      case TRADE_RETCODE_TRADE_DISABLED      :  return "10017 TRADE_DISABLED"+(ext_descr ? " (Trade is disabled)" : "");
      //--- Market is closed
      case TRADE_RETCODE_MARKET_CLOSED       :  return "10018 MARKET_CLOSED"+(ext_descr ? " (Market is closed)" : "");
      //--- There is not enough money to complete the request
      case TRADE_RETCODE_NO_MONEY            :  return "10019 NO_MONEY"+(ext_descr ? " (There is not enough money to complete the request)" : "");
      //--- Prices changed
      case TRADE_RETCODE_PRICE_CHANGED       :  return "10020 PRICE_CHANGED"+(ext_descr ? " (Prices changed)" : "");
      //--- There are no quotes to process the request
      case TRADE_RETCODE_PRICE_OFF           :  return "10021 PRICE_OFF"+(ext_descr ? " (There are no quotes to process the request)" : "");
      //--- Invalid order expiration date in the request
      case TRADE_RETCODE_INVALID_EXPIRATION  :  return "10022 INVALID_EXPIRATION"+(ext_descr ? " (Invalid order expiration date in the request)" : "");
      //--- Order state changed
      case TRADE_RETCODE_ORDER_CHANGED       :  return "10023 ORDER_CHANGED"+(ext_descr ? " (Order state changed)" : "");
      //--- Too frequent requests
      case TRADE_RETCODE_TOO_MANY_REQUESTS   :  return "10024 TOO_MANY_REQUESTS"+(ext_descr ? " (Too frequent requests)" : "");
      //--- No changes in request
      case TRADE_RETCODE_NO_CHANGES          :  return "10025 NO_CHANGES"+(ext_descr ? " (No changes in request)" : "");
      //--- Autotrading disabled by server
      case TRADE_RETCODE_SERVER_DISABLES_AT  :  return "10026 SERVER_DISABLES_AT"+(ext_descr ? " (Autotrading disabled by server)" : "");
      //--- Autotrading disabled by client terminal
      case TRADE_RETCODE_CLIENT_DISABLES_AT  :  return "10027 CLIENT_DISABLES_AT"+(ext_descr ? " (Autotrading disabled by client terminal)" : "");
      //--- Request locked for processing
      case TRADE_RETCODE_LOCKED              :  return "10028 LOCKED"+(ext_descr ? " (Request locked for processing)" : "");
      //--- Order or position frozen
      case TRADE_RETCODE_FROZEN              :  return "10029 FROZEN"+(ext_descr ? " (Order or position frozen)" : "");
      //--- Invalid order filling type
      case TRADE_RETCODE_INVALID_FILL        :  return "10030 INVALID_FILL"+(ext_descr ? " (Invalid order filling type)" : "");
      //--- No connection with the trade server
      case TRADE_RETCODE_CONNECTION          :  return "10031 CONNECTION"+(ext_descr ? " (No connection with the trade server)" : "");
      //--- Operation allowed only for live accounts
      case TRADE_RETCODE_ONLY_REAL           :  return "10032 ONLY_REAL"+(ext_descr ? " (Operation is allowed only for live accounts)" : "");
      //--- Number of pending orders reached the limit
      case TRADE_RETCODE_LIMIT_ORDERS        :  return "10033 LIMIT_ORDERS"+(ext_descr ? " (The number of pending orders has reached the limit)" : "");
      //--- Volume of orders and positions for the symbol reached the limit
      case TRADE_RETCODE_LIMIT_VOLUME        :  return "10034 LIMIT_VOLUME"+(ext_descr ? " (The volume of orders and positions for the symbol has reached the limit)" : "");
      //--- Incorrect or prohibited order type
      case TRADE_RETCODE_INVALID_ORDER       :  return "10035 INVALID_ORDER"+(ext_descr ? " (Incorrect or prohibited order type)" : "");
      //--- Position with specified POSITION_IDENTIFIER already closed
      case TRADE_RETCODE_POSITION_CLOSED     :  return "10036 POSITION_CLOSED"+(ext_descr ? " (Position with the specified POSITION_IDENTIFIER has already been closed)" : "");
      //--- Close volume exceeds the current position volume
      case TRADE_RETCODE_INVALID_CLOSE_VOLUME:  return "10038 INVALID_CLOSE_VOLUME"+(ext_descr ? " (A close volume exceeds the current position volume)" : "");
      //--- Close order already exists for specified position
      case TRADE_RETCODE_CLOSE_ORDER_EXIST   :  return "10039 CLOSE_ORDER_EXIST"+(ext_descr ? " (A close order already exists for a specified position)" : "");
      //--- Number of positions reached the limit
      case TRADE_RETCODE_LIMIT_POSITIONS     :  return "10040 LIMIT_POSITIONS"+(ext_descr ? " (The number of positions has reached the limit)" : "");
      //--- Pending order activation request is rejected, order is canceled
      case TRADE_RETCODE_REJECT_CANCEL       :  return "10041 REJECT_CANCEL"+(ext_descr ? " (The pending order activation request is rejected, the order is canceled)" : "");
      //--- Request rejected, only long positions are allowed on symbol
      case TRADE_RETCODE_LONG_ONLY           :  return "10042 LONG_ONLY"+(ext_descr ? " (Only long positions are allowed)" : "");
      //--- Request rejected, only short positions are allowed on symbol
      case TRADE_RETCODE_SHORT_ONLY          :  return "10043 SHORT_ONLY"+(ext_descr ? " (Only short positions are allowed)" : "");
      //--- Request rejected, only position closing is allowed on symbol
      case TRADE_RETCODE_CLOSE_ONLY          :  return "10044 CLOSE_ONLY"+(ext_descr ? " (Only position closing is allowed)" : "");
      //--- Request rejected, position closing for trading account is allowed only by FIFO rule
      case TRADE_RETCODE_FIFO_CLOSE          :  return "10045 FIFO_CLOSE"+(ext_descr ? " (Position closing is allowed only by FIFO rule)" : "");
      //--- Request rejected, opposite positions on a single symbol are disabled for trading account
      case TRADE_RETCODE_HEDGE_PROHIBITED    :  return "10046 HEDGE_PROHIBITED"+(ext_descr ? " (Opposite positions on a single symbol are disabled)" : "");
      //--- Unknown return code 
      default                                :  return "Undefined ("+(string)retcode+")";
     }
  }

Die Funktion erhält den Antwort-Code des Servers und das Flag, das angibt, dass eine erweiterte Beschreibung zurückgegeben werden muss. Die Funktion gibt entweder einen digitalen Code mit einer konstanten Beschreibung zurück:

10034 LIMIT_VOLUME

oder eine detaillierte Beschreibung des Antwort-Codes des Servers:

10034 LIMIT_VOLUME (The volume of orders and positions for the symbol has reached the limit)


Die Funktion, die eine Beschreibung der Auftragsart zurückgibt:

//+------------------------------------------------------------------+
//| Return the order type description                                |
//+------------------------------------------------------------------+
string OrderTypeDescription(const ENUM_ORDER_TYPE type,const bool ext_descr=false)
  {
//--- "Cut out" the order type from the string obtained from enum
   string res=StringSubstr(EnumToString(type),11);
//--- Convert all received characters to lowercase and
   if(res.Lower())
     {
      //--- replace the first letter from small to capital
      res.SetChar(0,ushort(res.GetChar(0)-0x20));
      int total=(int)res.Length();  // Text length
      int index=0;                  // index to start searching for "_" in a text
      //--- Search for underscores in a loop through all characters
      for(int i=0;i<total;i++)
        {
         int pos=StringFind(res,"_",index);
         //--- If an underscore is found,
         if(pos>0)
           {
            //--- replace it with space and convert the next letter to uppercase 
            res.SetChar(pos,' ');
            res.SetChar(pos+1,ushort(res.GetChar(pos+1)-0x20));
            //--- Set a new index for starting the search for "_"
            index=pos;
           }
        }
     }
   string descr="";
   switch(type)
     {
      case ORDER_TYPE_BUY              :  descr=" (Market Buy order)";                                                                          break;
      case ORDER_TYPE_SELL             :  descr=" (Market Sell order)";                                                                         break;
      case ORDER_TYPE_BUY_LIMIT        :  descr=" (Buy Limit pending order)";                                                                   break;
      case ORDER_TYPE_SELL_LIMIT       :  descr=" (Sell Limit pending order)";                                                                  break;
      case ORDER_TYPE_BUY_STOP         :  descr=" (Buy Stop pending order)";                                                                    break;
      case ORDER_TYPE_SELL_STOP        :  descr=" (Sell Stop pending order)";                                                                   break;
      case ORDER_TYPE_BUY_STOP_LIMIT   :  descr=" (Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price)"; break;
      case ORDER_TYPE_SELL_STOP_LIMIT  :  descr=" (Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price)";break;
      case ORDER_TYPE_CLOSE_BY         :  descr=" (Order to close a position by an opposite one)";                                              break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Sell Limit (Sell Limit pending order)
   */
  }

Beim Senden einer Handelsanfrage mit dem Befehl OrderSend() sollte für einige Operationen eine Auftragsart angegeben werden. Der Auftragstyp wird im Feld type der Struktur MqlTradeRequest angegeben und kann Werte aus der Enumeration ENUM_ORDER_TYPE annehmen:

ID
Beschreibung
ORDER_TYPE_BUY
Kauf, eine Marktorder
ORDER_TYPE_SELL
Verkauf, eine Marktorder
ORDER_TYPE_BUY_LIMIT
Buy-Limit, eine schwebende Kauforder
ORDER_TYPE_SELL_LIMIT
Sell-Limit, eine schwebende Verkaufsorder
ORDER_TYPE_BUY_STOP
Buy-Stop, eine schwebende Kauforder
ORDER_TYPE_SELL_STOP
Sell-Stop, eine schwebende Verkaufsorder
ORDER_TYPE_BUY_STOP_LIMIT
Bei Erreichen des Orderpreises wird die schwebende Order Buy-Limit zum StopLimit-Preis platziert.
ORDER_TYPE_SELL_STOP_LIMIT
Bei Erreichen des Orderpreises wird die schwebende Order Sell-Limit zum StopLimit-Preis platziert.
ORDER_TYPE_CLOSE_BY
Auftrag, eine Position durch eine entgegengesetzte Position zu schließen.


Die Funktion, die eine Beschreibung der Auftragsart nach der Ausführung zurückgibt:

//+------------------------------------------------------------------+
//| Return the order type description by execution                   |
//+------------------------------------------------------------------+
string OrderTypeFillingDescription(const ENUM_ORDER_TYPE_FILLING type_filling,const bool ext_descr=false)
  {
   string res=StringSubstr(EnumToString(type_filling),14);
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital (for ORDER_FILLING_RETURN)
   if(type_filling==ORDER_FILLING_RETURN && res.Lower())
      res.SetChar(0,ushort(res.GetChar(0)-0x20));
   string descr="";
   switch(type_filling)
     {
      case ORDER_FILLING_FOK     :  descr=" (Fill or Kill. An order can be executed in the specified volume only)";                                               break;
      case ORDER_FILLING_IOC     :  descr=" (Immediate or Cancel. A deal with the volume maximally available in the market within that indicated in the order)";  break;
      case ORDER_FILLING_BOC     :  descr=" (Passive (Book or Cancel). The order can only be placed in the Depth of Market and cannot be immediately executed)";  break;
      case ORDER_FILLING_RETURN  :  descr=" (In case of partial filling, an order with remaining volume is not canceled but processed further)";                  break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further)
   */
  }

Wenn eine Handelsanfrage mit der Funktion OrderSend() gesendet wird, kann die erforderliche Volumenausführungspolitik im Feldtype_filling festgelegt werden, und zwar in der speziellen Struktur MqlTradeRequest. Es stehen die Werte aus der Enumeration ENUM_ORDER_TYPE_FILLING zur Verfügung. Um den Eigenschaftswert in einem bestimmten aktiven/abgeschlossenen Auftrag zu erhalten, verwendet man die Funktion OrderGetInteger() oder HistoryOrderGetInteger() mit dem Modifikator ORDER_TYPE_FILLING.

Vor dem Absenden eines Auftrags mit der Ausführung zum aktuellen Zeitpunkt können wir, damit der Wert ORDER_TYPE_FILLING (Ausführungsart nach Volumen) korrekt gesetzt wird, die Funktion SymbolInfoInteger() für jedes Finanzinstrument verwenden, um den Wert der Eigenschaft SYMBOL_FILLING_MODE zu erhalten, die die für dieses Symbol zulässigen Arten der Volumenfüllung als Kombination von Flags anzeigt. Die Ausführungsart ORDER_FILLING_RETURN ist immer aktiviert, außer im Modus "Marktausführung" (SYMBOL_TRADE_EXECUTION_MARKET).


Die Funktion, die eine Beschreibung der Handelstransaktionsart zurückgibt:

//+------------------------------------------------------------------+
//| Return a description of the trade transaction type               |
//+------------------------------------------------------------------+
string TradeTransactionTypeDescription(const ENUM_TRADE_TRANSACTION_TYPE transaction,const bool ext_descr=false)
  {
//--- "Cut out" the transaction type from the string obtained from enum
   string res=StringSubstr(EnumToString(transaction),18);
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital
   if(res.Lower())
      res.SetChar(0,ushort(res.GetChar(0)-0x20));
//--- Replace all underscore characters with space in the resulting line
   StringReplace(res,"_"," ");
   string descr="";
   switch(transaction)
     {
      case TRADE_TRANSACTION_ORDER_ADD       :  descr=" (Adding a new open order)";                                                                   break;
      case TRADE_TRANSACTION_ORDER_UPDATE    :  descr=" (Updating an open order)";                                                                    break;
      case TRADE_TRANSACTION_ORDER_DELETE    :  descr=" (Removing an order from the list of the open ones)";                                          break;
      case TRADE_TRANSACTION_DEAL_ADD        :  descr=" (Adding a deal to the history)";                                                              break;
      case TRADE_TRANSACTION_DEAL_UPDATE     :  descr=" (Updating a deal in the history)";                                                            break;
      case TRADE_TRANSACTION_DEAL_DELETE     :  descr=" (Deleting a deal from the history)";                                                          break;
      case TRADE_TRANSACTION_HISTORY_ADD     :  descr=" (Adding an order to the history as a result of execution or cancellation)";                   break;
      case TRADE_TRANSACTION_HISTORY_UPDATE  :  descr=" (Changing an order located in the orders history)";                                           break;
      case TRADE_TRANSACTION_HISTORY_DELETE  :  descr=" (Deleting an order from the orders history)";                                                 break;
      case TRADE_TRANSACTION_POSITION        :  descr=" (Changing a position not related to a deal execution)";                                       break;
      case TRADE_TRANSACTION_REQUEST         :  descr=" (The trade request has been processed by a server and processing result has been received)";  break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Order add (Adding a new open order)
   */
  }

Die Funktion liefert Beschreibungen der auf dem Konto ausgeführten Handelstransaktionsart .


Die Funktion, die eine Beschreibung des Auftragsstatus zurückgibt:

//+------------------------------------------------------------------+
//| Return an order state description                                |
//+------------------------------------------------------------------+
string OrderStateDescription(const ENUM_ORDER_STATE state,const bool ext_descr=false)
  {
//--- "Cut out" the order status from the string obtained from enum
   string res=StringSubstr(EnumToString(state),12);
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital
   if(res.Lower())
      res.SetChar(0,ushort(res.GetChar(0)-0x20));
//--- Replace all underscore characters with space in the resulting line
   StringReplace(res,"_"," ");
   string descr="";
   switch(state)
     {
      case ORDER_STATE_STARTED         :  descr=" (Order checked, but not yet accepted by broker)";            break;
      case ORDER_STATE_PLACED          :  descr=" (Order accepted)";                                           break;
      case ORDER_STATE_CANCELED        :  descr=" (Order canceled by client)";                                 break;
      case ORDER_STATE_PARTIAL         :  descr=" (Order partially executed)";                                 break;
      case ORDER_STATE_FILLED          :  descr=" (Order fully executed)";                                     break;
      case ORDER_STATE_REJECTED        :  descr=" (Order rejected)";                                           break;
      case ORDER_STATE_EXPIRED         :  descr=" (Order expired)";                                            break;
      case ORDER_STATE_REQUEST_ADD     :  descr=" (Order is being registered (placing to the trading system))";break;
      case ORDER_STATE_REQUEST_MODIFY  :  descr=" (Order is being modified (changing its parameters))";        break;
      case ORDER_STATE_REQUEST_CANCEL  :  descr=" (Order is being deleted (deleting from the trading system))";break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Placed (Order accepted)
   */
  }

Jeder Auftrag hat einen Status, der seinen Zustand beschreibt. Um die Informationen zu erhalten, verwenden wir die Funktion OrderGetInteger() oder HistoryOrderGetInteger() mit dem Modifikator ORDER_STATE. Gültige Werte sind in der Enumeration ENUM_ORDER_STATE gespeichert. Wenn eine Handelsanfrage an den Server gesendet wird, ändert sich der Status des Auftrags schrittweise. Zunächst wird sie vom Server geprüft, dann in das Handelssystem eingestellt und dann ausgelöst, wodurch ein Geschäft zustande kommt oder abgebrochen wird. Die Liste enthält alle möglichen Auftragszustände, die bei der Arbeit mit Handelsaufträgen berücksichtigt werden sollten.


Die Funktion, die eine Beschreibung der Transaktionsart zurückgibt:

//+------------------------------------------------------------------+
//| Return the deal type description                                 |
//+------------------------------------------------------------------+
string DealTypeDescription(const ENUM_DEAL_TYPE type,const bool ext_descr=false)
  {
//--- "Cut out" the deal type from the string obtained from enum
   string res=StringSubstr(EnumToString(type),(type==DEAL_DIVIDEND || type==DEAL_DIVIDEND_FRANKED || type==DEAL_TAX ? 5 : 10));
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital
   if(res.Lower())
      res.SetChar(0,ushort(res.GetChar(0)-0x20));
//--- Replace all underscore characters with space in the resulting line
   StringReplace(res,"_"," ");
   string descr="";
//--- Extended descriptions are added only to the deals whose description obtained from enum does not match the extended one
   switch(type)
     {
      case DEAL_TYPE_CHARGE                  : descr=" (Additional charge)";                          break;
      case DEAL_TYPE_COMMISSION              : descr=" (Additional commission)";                      break;
      case DEAL_TYPE_COMMISSION_DAILY        : descr=" (Daily commission)";                           break;
      case DEAL_TYPE_COMMISSION_MONTHLY      : descr=" (Monthly commission)";                         break;
      case DEAL_TYPE_COMMISSION_AGENT_DAILY  : descr=" (Daily agent commission)";                     break;
      case DEAL_TYPE_COMMISSION_AGENT_MONTHLY: descr=" (Monthly agent commission)";                   break;
      case DEAL_TYPE_INTEREST                : descr=" (Interest rate)";                              break;
      case DEAL_TYPE_BUY_CANCELED            : descr=" (Canceled buy deal)";                          break;
      case DEAL_TYPE_SELL_CANCELED           : descr=" (Canceled sell deal)";                         break;
      case DEAL_DIVIDEND                     : descr=" (Dividend operations)";                        break;
      case DEAL_DIVIDEND_FRANKED             : descr=" (Franked (non-taxable) dividend operations)";  break;
      case DEAL_TAX                          : descr=" (Tax charges)";                                break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Comission (Additional commission)
   */
  }

Jedes Geschäft ist durch einen Typ gekennzeichnet. Die möglichen Werte sind in ENUM_DEAL_TYPE aufgeführt. Um Daten zur Geschäftsart zu erhalten, verwenden Sie die Funktion HistoryDealGetInteger() mit dem Modifikator DEAL_TYPE.


Die Funktion, die eine Beschreibung der Auftragsart nach Ablauf zurückgibt:

//+------------------------------------------------------------------+
//| Return an order type description by expiration                   |
//+------------------------------------------------------------------+
string OrderTypeTimeDescription(const ENUM_ORDER_TYPE_TIME type_time,const bool ext_descr=false)
  {
//--- "Cut out" the order type by expiration from the string obtained from enum
   string res=StringSubstr(EnumToString(type_time),6);
//--- If the type by expiration is ORDER_TIME_GTC, add "Time GTC" to res
   if(type_time==ORDER_TIME_GTC)
      res="Time GTC";
//--- Otherwise, convert all obtained symbols to lower case and replace the first letter from small to capital
   else
     {
      if(res.Lower())
         res.SetChar(0,ushort(res.GetChar(0)-0x20));
      //--- Replace all underscore characters with space in the resulting line
      StringReplace(res,"_"," ");
     }
   string descr="";
   switch(type_time)
     {
      case ORDER_TIME_GTC           : descr=" (Good till cancel order)";                                          break;
      case ORDER_TIME_DAY           : descr=" (Good till current trade day order)";                               break;
      case ORDER_TIME_SPECIFIED     : descr=" (Good till expired order)";                                         break;
      case ORDER_TIME_SPECIFIED_DAY : descr=" (The order will be effective till 23:59:59 of the specified day)";  break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Time GTC (Good till cancel order)
   */
  }

Die Lebensdauer einer Order kann im Feld type_time der Struktur MqlTradeRequest festgelegt werden, wenn eine Handelsanfrage mit der Funktion OrderSend() gesendet wird. Die Werte aus der Enumeration ENUM_ORDER_TYPE_TIME sind gültig. Um den Eigenschaftswert zu erhalten, verwendet man die Funktion OrderGetInteger() oder HistoryOrderGetInteger() mit dem Modifikator ORDER_TYPE_TIME.

Handelstransaktionen können als Aufträge, Deals und Positionen auftreten. In jeder Kategorie solcher Transaktionen kann es verschiedene Arten geben: Hinzufügung, Änderung und Löschung. Aber manchmal müssen wir nur wissen, womit genau die Transaktion durchgeführt wurde, ohne Details zu nennen: mit einem Auftrag, einem Deal oder einer Position. Um dies zu erreichen, erstellen wir eine Funktion, die die Transaktionszugehörigkeit zurückgibt:

//+------------------------------------------------------------------+
//| Define and set transaction affiliation values                    |
//+------------------------------------------------------------------+
void SetTransactionBelong(const ENUM_TRADE_TRANSACTION_TYPE type,bool &request_flag,bool &order_flag,bool &deal_flag,bool &position_flag)
  {
   switch(type)
     {
      //--- Request
      case TRADE_TRANSACTION_REQUEST         : request_flag=true; order_flag=false; deal_flag=false; position_flag=false; break;
      //--- Order
      case TRADE_TRANSACTION_ORDER_ADD       :
      case TRADE_TRANSACTION_ORDER_UPDATE    :
      case TRADE_TRANSACTION_ORDER_DELETE    :
      case TRADE_TRANSACTION_HISTORY_ADD     :
      case TRADE_TRANSACTION_HISTORY_UPDATE  :
      case TRADE_TRANSACTION_HISTORY_DELETE  : request_flag=false; order_flag=true; deal_flag=false; position_flag=false; break;
      //--- Deal
      case TRADE_TRANSACTION_DEAL_ADD        :
      case TRADE_TRANSACTION_DEAL_UPDATE     :
      case TRADE_TRANSACTION_DEAL_DELETE     : request_flag=false; order_flag=false; deal_flag=true; position_flag=false; break;
      //--- Position
      case TRADE_TRANSACTION_POSITION        : request_flag=false; order_flag=false; deal_flag=false; position_flag=true; break;
      //---
      default: break;
     }
  }

Die Funktion erhält die Transaktionsart und, per Referenz, drei Flag-Variablen, die je nachdem, womit genau die Transaktion durchgeführt wurde, gesetzt/zurückgesetzt werden.


Die Funktion, die eine Beschreibung der Art des Handelsantrags zurückgibt:

//+------------------------------------------------------------------+
//| Return the trade request type description                        |
//+------------------------------------------------------------------+
string TradeActionDescription(const ENUM_TRADE_REQUEST_ACTIONS action,const bool ext_descr=false)
  {
//--- "Cut out" the operation type from the string obtained from enum
   string res=StringSubstr(EnumToString(action),13);
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital (except for TRADE_ACTION_SLTP)
   if(action!=TRADE_ACTION_SLTP && res.Lower())
      res.SetChar(0,ushort(res.GetChar(0)-0x20));
   string descr="";
   switch(action)
     {
      case TRADE_ACTION_DEAL     : descr=" (Place a trade order for an immediate execution with the specified parameters (market order))";break;
      case TRADE_ACTION_PENDING  : descr=" (Place a trade order for the execution under specified conditions (pending order))";           break;
      case TRADE_ACTION_SLTP     : descr=" (Modify Stop Loss and Take Profit values of an opened position)";                              break;
      case TRADE_ACTION_MODIFY   : descr=" (Modify the parameters of the order placed previously)";                                       break;
      case TRADE_ACTION_REMOVE   : descr=" (Delete the pending order placed previously)";                                                 break;
      case TRADE_ACTION_CLOSE_BY : descr=" (Close a position by an opposite one)";                                                        break;
      default: break;
     }
   return res+(!ext_descr ? "" : descr);
   /* Sample output:
      Pending (Place a trade order for the execution under specified conditions (pending order)):
   */
  }


Schauen wir uns die Struktur einer Handelsanfrage an, die Ausgabe einer Beschreibung ihrer Felder und die Erstellung einiger Handelsfunktionen, die erklären, wie man mit dieser Struktur arbeitet.

MqlTradeRequest-Struktur zur Erstellung einer Anfrage bei der Durchführung von Handelsgeschäften

Die Interaktion zwischen dem Kundenterminal und dem Handelsserver in Bezug auf die Auftragsvergabe erfolgt über Handelsaufträge. Die Anfrage wird durch die spezielle vordefinierte Struktur MqlTradeRequest dargestellt, die alle für die Durchführung des Handels notwendigen Felder enthält:

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Type of a performed action
   ulong                         magic;            // EA stamp (magic number ID)
   ulong                         order;            // Order ticket
   string                        symbol;           // Symbol name
   double                        volume;           // Requested volume of a deal in lots
   double                        price;            // Price 
   double                        stoplimit;        // StopLimit order level
   double                        sl;               // Stop Loss order level
   double                        tp;               // Take Profit order level
   ulong                         deviation;        // Maximum acceptable deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order filling type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order lifetime type
   datetime                      expiration;       // Order expiration time (for ORDER_TIME_SPECIFIED type orders)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // Opposite position ticket
  };

Um einen Handelsauftrag an den Server zu senden, müssen wir die Strukturfelder in der für den Auftrag geeigneten Weise ausfüllen. Das Feld „action“ muss ausgefüllt werden. Je nachdem, welche Aktion in dieses Feld geschrieben wird, werden auch andere Felder der für diese Aktion erforderlichen Struktur ausgefüllt. Dementsprechend enthalten ungenutzte Felder Nullen (vorausgesetzt, die Felder der Struktur werden vor dem Füllen auf Null gesetzt). Bei der Anzeige einer Beschreibung der Strukturfelder werden einige Felder nicht verwendet und enthalten Nullen. Dies sollte angezeigt werden, wenn ein nicht verwendetes Feld an das Protokoll gesendet wird. Verwenden Sie z. B. statt der Anzahl der Dezimalstellen für den Wert (1,12345) nur eine (0,0) - so wird deutlicher, dass dieses Feld einfach nicht ausgefüllt ist.

Bei der endgültigen Ausgabe der Struktur in das Protokoll werden wir jedoch nicht verwendete Felder je nach Transaktion berücksichtigen und sie einfach nicht anzeigen.


Art der durchgeführten Aktion

Die Art der Handelsoperation. Der Wert kann einer der Enumerationswerte ENUM_TRADE_REQUEST_ACTIONS sein.

//+------------------------------------------------------------------+
//| Return the type of a performed action as a string                |
//+------------------------------------------------------------------+
string MqlTradeRequestAction(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Action:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,TradeActionDescription(req.action,ext_descr));
   /* Sample output:
      Action: Pending (Place a trade order for the execution under specified conditions (pending order)):
   */
  }


Stempel eines Expert Advisors (die magische Zahl zur Kennzeichnung)

Die ID des Experten. Ermöglicht die Organisation der analytischen Bearbeitung von Handelsaufträgen. Jeder EA kann eine eindeutige ID festlegen, wenn er eine Handelsanfrage sendet.
//+------------------------------------------------------------------+
//| Return the EA stamp (magic number) as a string                   |
//+------------------------------------------------------------------+
string MqlTradeRequestMagic(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Magic:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.magic);
   /* Sample output:
      Magic: 1024
   */
  }


Ticket des Auftrags

Ticket bestellen. Erforderlich für die Änderung von schwebenden Aufträgen.

//+------------------------------------------------------------------+
//| Return the order ticket as a string                              |
//+------------------------------------------------------------------+
string MqlTradeRequestOrder(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Order:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.order);
   /* Sample output:
      Order: 1835982676
   */
  }


Name eines Handelsinstruments

Der Name des Handelsinstruments, für das der Auftrag erteilt wird. Er ist nicht erforderlich bei der Änderung von Aufträgen und der Schließung von Positionen.

//+------------------------------------------------------------------+
//| Return a trading instrument name                                 |
//+------------------------------------------------------------------+
string MqlTradeRequestSymbol(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Symbol:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,req.symbol);
   /* Sample output:
      Symbol: EURUSD
   */
  }


Gewünschtes Volumen eines Handelsgeschäft in Losgrößen

Angefordertes Volumen eines Handelsgeschäfts in Losgrößen. Ein echtes Volumen beim Abschluss eines Handelsgeschäfts hängt von der Art der Auftragsausführung ab.

//+------------------------------------------------------------------+
//| Return the requested volume of a deal in lots as a string        |
//+------------------------------------------------------------------+
string MqlTradeRequestVolume(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Volume:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places in the lot value. If the character is not specified, use 1
   int dg=(int)ceil(fabs(log10(SymbolInfoDouble(req.symbol,SYMBOL_VOLUME_STEP))));
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.volume);
   /* Sample output:
      Volume: 0.10
   */
  }


Preis

Preis, zu dem ein Auftrag ausgeführt werden soll. Der Preis wird nicht festgelegt, wenn es sich um Marktaufträge für Instrumente der Art „Market Execution“ (SYMBOL_TRADE_EXECUTION_MARKET) handelt, für die der Typ TRADE_ACTION_DEAL gesetzt wurde.

//+------------------------------------------------------------------+
//| Return the price as a string                                     |
//+------------------------------------------------------------------+
string MqlTradeRequestPrice(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Price:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(req.price!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.price);
   /* Sample output:
      Price: 1.09586
   */
  }


StopLimit-Auftragsebene

Für schwebende Aufträge der Typen BuyStopLimit und SellStopLimit. Ein Preis, zu dem eine schwebende Limit-Order gesetzt wird, wenn der Preis den Wert "price" erreicht (diese Bedingung ist obligatorisch). Der schwebende Auftrag wird erst zu diesem Zeitpunkt an das Handelssystem weitergeleitet.

//+------------------------------------------------------------------+
//| Return the StopLimit order level as a string                     |
//+------------------------------------------------------------------+
string MqlTradeRequestStopLimit(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="StopLimit:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(req.stoplimit!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.stoplimit);
   /* Sample output:
      StopLimit: 0.0
   */
  }


Stop-Loss-Auftragsebene

Der Kurs, bei dem eine Stop-Loss-Order aktiviert wird, wenn sich der Kurs in eine ungünstige Richtung bewegt.

//+------------------------------------------------------------------+
//| Return the Stop Loss order level as a string                     |
//+------------------------------------------------------------------+
string MqlTradeRequestStopLoss(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="SL:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(req.sl!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.sl);
   /* Sample output:
      SL: 0.0
   */
  }


Take-Profit-Auftragsebene

Der Preis, bei dem ein Take-Profit-Auftrag aktiviert wird, wenn sich der Kurs in eine günstige Richtung bewegt.

//+------------------------------------------------------------------+
//| Return the Take Profit order level as a string                   |
//+------------------------------------------------------------------+
string MqlTradeRequestTakeProfit(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="TP:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(req.tp!=0 ? (int)SymbolInfoInteger(req.symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,req.tp);
   /* Sample output:
      TP: 0.0
   */
  }


Abweichung vom geforderten Preis

Maximal akzeptable Abweichung vom geforderten Preis, angegeben in Punkten.

//+------------------------------------------------------------------+
//| Return the maximum acceptable                                    |
//| deviation from the requested price                               |
//+------------------------------------------------------------------+
string MqlTradeRequestDeviation(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Deviation:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.deviation);
   /* Sample output:
      Deviation: 5
   */
  }


Auftragsart

Art der Aufträge. Der Wert kann einer der Enumerationswerte ENUM_ORDER_TYPE sein.

//+------------------------------------------------------------------+
//| Return the order type as a string                                |
//+------------------------------------------------------------------+
string MqlTradeRequestType(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Type:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,OrderTypeDescription(req.type,ext_descr));
   /* Sample output:
      Type: Buy Limit (Buy Limit pending order)
   */
  }


Art der Auftragsabwicklung

Die Art der Auftragsabwicklung. Der Wert kann einer der Werte von ENUM_ORDER_TYPE_FILLING sein.

//+------------------------------------------------------------------+
//| Return the order type by execution as a string                   |
//+------------------------------------------------------------------+
string MqlTradeRequestTypeFilling(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Type filling:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,OrderTypeFillingDescription(req.type_filling,ext_descr));
   /* Sample output:
      Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further)
   */
  }


Laufzeittyp eines Auftrags

Auftragsart bezogen auf den Ablauf. Der Wert kann einer der Werte von ENUM_ORDER_TYPE_TIME sein.

//+------------------------------------------------------------------+
//| Return the order type by expiration time as a string             |
//+------------------------------------------------------------------+
string MqlTradeRequestTypeTime(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Type time:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,OrderTypeTimeDescription(req.type_time,ext_descr));
   /* Sample output:
      Type time: Time GTC (Good till cancel order)
   */
  }


Laufzeitende eines Auftrags

Laufzeitende eines schwebenden Auftrags (für Auftragsarten von ORDER_TIME_SPECIFIED).

//+------------------------------------------------------------------+
//| Return the order expiration time as a string                     |
//+------------------------------------------------------------------+
string MqlTradeRequestExpiration(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Expiration:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,(req.type_time==ORDER_TIME_SPECIFIED || req.type_time==ORDER_TIME_SPECIFIED_DAY ? (string)req.expiration : "0"));
   /* Sample output:
      Expiration: 0
   */
  }


Kommentar eines Auftrags

//+------------------------------------------------------------------+
//| Return the order comment                                         |
//+------------------------------------------------------------------+
string MqlTradeRequestComment(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Comment:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,req.comment);
   /* Sample output:
      Comment: TestMqlTradeTransaction
   */
  }


Ticket einer Position

Das Ticket einer Position. Füllen Sie es aus, wenn Sie eine Position ändern oder schließen, um sie eindeutig zu identifizieren. In der Regel ist es dasselbe wie das Ticket des Auftrags, der die Position eröffnet hat.

//+------------------------------------------------------------------+
//| Return the position ticket as a string                           |
//+------------------------------------------------------------------+
string MqlTradeRequestPosition(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Position:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.position);
   /* Sample output:
      Position: 1835982676
   */
  }


Ticket einer entgegengesetzten Position

Ticket für die gegenüberliegende Position. Es wird zugewiesen, wenn eine Position durch eine entgegengesetzte geschlossen wird (die mit gleichem Symbol, aber in entgegengesetzter Richtung eröffnet wurde).

//+------------------------------------------------------------------+
//| Return the opposite position ticket as a string                  |
//+------------------------------------------------------------------+
string MqlTradeRequestPositionBy(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Position by:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,req.position_by);
   /* Sample output:
      Position by: 1835987626
   */
  }


Beispiele für die Verwendung

Bei verschiedenen Arten von Handelsaufträgen werden die Strukturfelder je nach Auftrag individuell ausgefüllt. Betrachten wir einige Beispiele: Wir werden eine Funktion erstellen, die Beschreibungen von Strukturfeldern in Abhängigkeit von der durchgeführten Aktion protokolliert, sowie Handelsfunktionen für das Öffnen/Schließen von Positionen und das Setzen/Löschen von schwebenden Aufträgen.

Die Funktion, die die Beschreibung der Handelsanfrage im Journal anzeigt:

//+------------------------------------------------------------------+
//| Display the trading request description in the journal           |
//+------------------------------------------------------------------+
void TradeRequestPrint(const MqlTradeRequest &req,const uint header_width=0,const uint indent=0,bool ext_descr=false)
  {
//--- Get execution type by symbol
   ENUM_SYMBOL_TRADE_EXECUTION exemode=(ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger(req.symbol,SYMBOL_TRADE_EXEMODE);
//--- Header
   PrintFormat("Request %s:",TradeActionDescription(req.action,ext_descr));
//--- Place an order for an instant deal with the specified parameters (set a market order)
   if(req.action==TRADE_ACTION_DEAL)
     {
      //--- Depending on the transaction mode 
      switch(exemode)
        {
         //--- Trade order to open a position in the Request Execution mode
         //--- Trade order to open a position in the Instant Execution mode
         case SYMBOL_TRADE_EXECUTION_REQUEST    :
         case SYMBOL_TRADE_EXECUTION_INSTANT    :
            Print(MqlTradeRequestSymbol(req,header_width,indent));
            Print(MqlTradeRequestVolume(req,header_width,indent));
            Print(MqlTradeRequestPrice(req,header_width,indent));
            if(req.position==0)  // Only for opening a position 
               Print(MqlTradeRequestStopLoss(req,header_width,indent));
            if(req.position==0)  // Only for opening a position 
               Print(MqlTradeRequestTakeProfit(req,header_width,indent));
            Print(MqlTradeRequestDeviation(req,header_width,indent));
            Print(MqlTradeRequestType(req,header_width,indent,ext_descr));
            Print(MqlTradeRequestTypeFilling(req,header_width,indent,ext_descr));
            Print(MqlTradeRequestMagic(req,header_width,indent));
            if(req.position==0)  // Only for opening a position 
               Print(MqlTradeRequestComment(req,header_width,indent));
            //--- Closing
            if(req.position!=0)
               Print(MqlTradeRequestPosition(req,header_width,indent));
           break;
         //--- Trade order to open a position in the Market Execution mode
         //--- Trade order to open a position in the Exchange Execution mode
         case SYMBOL_TRADE_EXECUTION_MARKET     :
         case SYMBOL_TRADE_EXECUTION_EXCHANGE   :
            Print(MqlTradeRequestSymbol(req,header_width,indent));
            Print(MqlTradeRequestVolume(req,header_width,indent));
            Print(MqlTradeRequestType(req,header_width,indent,ext_descr));
            Print(MqlTradeRequestTypeFilling(req,header_width,indent,ext_descr));
            Print(MqlTradeRequestMagic(req,header_width,indent));
            if(req.position==0)  // Only for opening a position 
               Print(MqlTradeRequestComment(req,header_width,indent));
            //--- Closing
            if(req.position!=0)
               Print(MqlTradeRequestPosition(req,header_width,indent));
           break;
         default:
           break;
        }
     }
//--- Trading order to close a position by an opposite one
   if(req.action==TRADE_ACTION_CLOSE_BY)
     {
      Print(MqlTradeRequestSymbol(req,header_width,indent));
      Print(MqlTradeRequestPosition(req,header_width,indent));
      Print(MqlTradeRequestMagic(req,header_width,indent));
      Print(MqlTradeRequestComment(req,header_width,indent));
      Print(MqlTradeRequestPositionBy(req,header_width,indent));
     }
//--- Trading order to modify StopLoss and/or TakeProfit levels
   if(req.action==TRADE_ACTION_SLTP)
     {
      Print(MqlTradeRequestSymbol(req,header_width,indent));
      Print(MqlTradeRequestStopLoss(req,header_width,indent));
      Print(MqlTradeRequestTakeProfit(req,header_width,indent));
      Print(MqlTradeRequestPosition(req,header_width,indent));
     }
//--- Trading order to place a pending order
   if(req.action==TRADE_ACTION_PENDING)
     {
      Print(MqlTradeRequestSymbol(req,header_width,indent));
      Print(MqlTradeRequestVolume(req,header_width,indent));
      Print(MqlTradeRequestPrice(req,header_width,indent));
      if(req.type==ORDER_TYPE_BUY_STOP_LIMIT || req.type==ORDER_TYPE_SELL_STOP_LIMIT)
         Print(MqlTradeRequestStopLimit(req,header_width,indent));
      Print(MqlTradeRequestStopLoss(req,header_width,indent));
      Print(MqlTradeRequestTakeProfit(req,header_width,indent));
      Print(MqlTradeRequestType(req,header_width,indent,ext_descr));
      Print(MqlTradeRequestTypeFilling(req,header_width,indent,ext_descr));
      Print(MqlTradeRequestTypeTime(req,header_width,indent,ext_descr));
      Print(MqlTradeRequestExpiration(req,header_width,indent));
      Print(MqlTradeRequestMagic(req,header_width,indent));
      Print(MqlTradeRequestComment(req,header_width,indent));
     }
//--- Trading order to modify the price levels of a pending order
   if(req.action==TRADE_ACTION_MODIFY)
     {
      Print(MqlTradeRequestOrder(req,header_width,indent));
      Print(MqlTradeRequestPrice(req,header_width,indent));
      if(req.stoplimit!=0)
         Print(MqlTradeRequestStopLimit(req,header_width,indent));
      Print(MqlTradeRequestStopLoss(req,header_width,indent));
      Print(MqlTradeRequestTakeProfit(req,header_width,indent));
      Print(MqlTradeRequestTypeTime(req,header_width,indent,ext_descr));
      Print(MqlTradeRequestExpiration(req,header_width,indent));
     }
//--- Trading order to remove a pending order
   if(req.action==TRADE_ACTION_REMOVE)
     {
      Print(MqlTradeRequestOrder(req,header_width,indent));
     }
   /* Sample output:
      Request Pending (Place a trade order for the execution under specified conditions (pending order)):
        Symbol: EURUSD
        Volume: 0.10
        Price: 1.09586
        SL: 0.0
        TP: 0.0
        Type: Buy Limit (Buy Limit pending order)
        Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further)
        Type time: Time GTC (Good till cancel order)
        Expiration: 0
        Magic: 1024
        Comment: TestMqlTradeTransaction
   */
  }


OpenBuy, um eine Kaufposition zu eröffnen:

//+------------------------------------------------------------------+
//| Open Buy position                                                |
//+------------------------------------------------------------------+
bool OpenBuy(const string symbol,const double lots,const uint magic,const ulong deviation=5,const string comment="")
  {
//--- Set a symbol for a request
   string symbol_name=(symbol==NULL ? Symbol() : symbol);
//--- Declare and initialize the request and result structures
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- Get the normalized price
   double price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK),(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS));
//--- request parameters
   request.action    =  TRADE_ACTION_DEAL;                        // trading operation type
   request.symbol    =  symbol_name;                              // symbol
   request.volume    =  lots;                                     // position volume
   request.type      =  ORDER_TYPE_BUY;                           // order type
   request.price     =  price;                                    // open price
   request.deviation =  deviation;                                // allowed deviation from the price
   request.magic     =  magic;                                    // order MagicNumber
   request.comment   =  comment;                                  // Order comment
//--- If failed to send a request, inform of that and return 'false'
   if(!OrderSend(request,result))
     {
      PrintFormat("%s: OrderSend for %s %s error: %s",__FUNCTION__,
                  TradeActionDescription(request.action),OrderTypeDescription(request.type),RetcodeDescription(result.retcode,true)
                 );
      return false;
     }
//--- OrderSend OK, return 'true'
   return true;
  }


OpenSell, um eine Verkaufsposition zu eröffnen:

//+------------------------------------------------------------------+
//| Open a Sell position                                             |
//+------------------------------------------------------------------+
bool OpenSell(const string symbol,const double lots,const uint magic,const ulong deviation=5,const string comment="")
  {
//--- Set a symbol for a request
   string symbol_name=(symbol==NULL ? Symbol() : symbol);
//--- Declare and initialize the request and result structures
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- Get the normalized price
   double price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID),(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS));
//--- request parameters
   request.action    =  TRADE_ACTION_DEAL;                        // trading operation type
   request.symbol    =  symbol_name;                              // symbol
   request.volume    =  lots;                                     // position volume
   request.type      =  ORDER_TYPE_SELL;                          // order type
   request.price     =  price;                                    // open price
   request.deviation =  deviation;                                // allowed deviation from the price
   request.magic     =  magic;                                    // order MagicNumber
   request.comment   =  comment;                                  // Order comment
//--- If failed to send a request, inform of that and return 'false'
   if(!OrderSend(request,result))
     {
      PrintFormat("%s: OrderSend for %s %s error: %s",__FUNCTION__,
                  TradeActionDescription(request.action),OrderTypeDescription(request.type),RetcodeDescription(result.retcode,true)
                 );
      return false;
     }
//--- OrderSend OK, return 'true'
   return true;
  }


ClosePosition, um eine bestimmte Position zu schließen:

//+------------------------------------------------------------------+
//| Close position by ticket                                         |
//+------------------------------------------------------------------+
bool ClosePosition(const ulong ticket,const ulong deviation=5)
  {
//--- Declare request and result structures
   MqlTradeRequest request;
   MqlTradeResult  result;
//--- If failed to select a position by ticket, inform of the error and leave
   ResetLastError();
   if(!PositionSelectByTicket(ticket))
     {
      Print("PositionSelectByTicket failed, error: ",(string)GetLastError());
      return false;
     }
//--- Get the data on the closed position
   string position_symbol=PositionGetString(POSITION_SYMBOL);                       // symbol 
   int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);             // number of decimal places
   double volume=PositionGetDouble(POSITION_VOLUME);                                // position volume
   ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);   // position type
   ulong magic=PositionGetInteger(POSITION_MAGIC);                                  // position MagicNumber
//--- Set request and result values to zero
   ZeroMemory(request);
   ZeroMemory(result);
//--- Set operation parameters
   request.action    =  TRADE_ACTION_DEAL;   // trading operation type
   request.position  =  ticket;              // position ticket
   request.symbol    =  position_symbol;     // symbol 
   request.volume    =  volume;              // position volume
   request.deviation =  deviation;           // allowed deviation from the price
   request.magic     =  magic;               // position MagicNumber
//--- Set order price and type depending on the position type
   if(type==POSITION_TYPE_BUY)
     {
      request.price=NormalizeDouble(SymbolInfoDouble(position_symbol,SYMBOL_BID),digits);
      request.type =ORDER_TYPE_SELL;
     }
   else
     {
      request.price=NormalizeDouble(SymbolInfoDouble(position_symbol,SYMBOL_ASK),digits);
      request.type =ORDER_TYPE_BUY;
     }
//--- If failed to send a request, inform of that and return 'false'
   if(!OrderSend(request,result))
     {
      PrintFormat("%s: OrderSend for %s %s #%llu error: %s",__FUNCTION__,
                  TradeActionDescription(request.action),OrderTypeDescription(request.type),ticket,RetcodeDescription(result.retcode,true)
                 );
      return false;
     }
//--- OrderSend OK, return 'true'
   return true;
  }


ClosePositionsAll, um alle Positionen zu schließen:

//+------------------------------------------------------------------+
//| Close all positions on a symbol                                  |
//+------------------------------------------------------------------+
uint ClosePositionsAll(const string symbol,const ulong magic=0)
  {
//--- Declare the variable for storing the result and the number of closed positions
   bool res=true;
   uint num=0;
//--- iterate over open positions
   int total=PositionsTotal();                     // number of open positions
   for(int i=total-1; i>=0; i--)
     {
      ulong  position_ticket=PositionGetTicket(i); // position ticket
      if(position_ticket==0)
         continue;
      if(PositionGetInteger(POSITION_MAGIC)!=magic)
         continue;
      //--- If MagicNumber is not specified (zero) or position magic number matches the specified one
      if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
        {
         //--- if the position symbol matches the one passed or NULL is passed, close the position on the ticket 
         if(symbol==NULL || PositionGetString(POSITION_SYMBOL)==symbol)
           {
            //--- Get the result of closing a position on a ticket and increase the counter of closed positions if successful 
            res &=ClosePosition(position_ticket);
            if(res)
               num++;
           }
        }
     }
   if(!res)
      PrintFormat("%s: Not all positions were able to close without errors",__FUNCTION__);
   return num;
  }


SetPending für die Platzierung eines schwebenden Auftrags:

//+------------------------------------------------------------------+
//| Place a specified pending order                                  |
//+------------------------------------------------------------------+
bool SetPending(const string symbol,const ENUM_ORDER_TYPE order_type,const double lots,const uint magic,const int distance,const int stoplimit=0,const string comment="")
  {
//--- Set a symbol for a request
   string symbol_name=(symbol==NULL ? Symbol() : symbol);
//--- Declare and initialize the request and result structures
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- Set operation parameters
   request.action    =  TRADE_ACTION_PENDING;                     // trading operation type
   request.type      =  order_type;                               // order type
   request.symbol    =  symbol_name;                              // symbol
   request.volume    =  lots;                                     // volume
   request.magic     =  magic;                                    // order MagicNumber
   request.comment   =  comment;                                  // Order comment
//--- Get Point and Digits
   double point=SymbolInfoDouble(symbol_name,SYMBOL_POINT);
   int digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
//--- Calculate the distance from the price depending on the order type
//--- Buy order
   if(order_type==ORDER_TYPE_BUY_STOP)
      request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK)+distance*point,digits);  // normalized setting price 
   if(order_type==ORDER_TYPE_BUY_LIMIT)
      request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK)-distance*point,digits);  // normalized setting price 
   if(order_type==ORDER_TYPE_BUY_STOP_LIMIT)
     {
      request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_ASK)+distance*point,digits);  // normalized Stop order trigger price 
      request.stoplimit=NormalizeDouble(request.price-stoplimit*point,digits);                        // normalized Limit order setting price
     }
//--- Sell order
   if(order_type==ORDER_TYPE_SELL_STOP)
      request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID)-distance*point,digits);  // normalized setting price 
   if(order_type==ORDER_TYPE_SELL_LIMIT)
      request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID)+distance*point,digits);  // normalized setting price 
   if(order_type==ORDER_TYPE_SELL_STOP_LIMIT)
     {
      request.price=NormalizeDouble(SymbolInfoDouble(symbol_name,SYMBOL_BID)-distance*point,digits);  // normalized Stop order trigger price 
      request.stoplimit=NormalizeDouble(request.price+stoplimit*point,digits);                        // normalized Limit order setting price
     }
//--- If failed to send a request, inform of that and return 'false'
   if(!OrderSend(request,result))
     {
      PrintFormat("%s: OrderSend for %s %s error: %s",__FUNCTION__,
                  TradeActionDescription(request.action),OrderTypeDescription(request.type),RetcodeDescription(result.retcode,true)
                 );
      return false;
     }
//--- OrderSend OK, return 'true'
   return true;
  }


Ausgehend von der oben vorgestellten Funktion können Funktionen erstellt werden, die einen bestimmten Typ eines schwebenden Auftrags festlegen:

SetBuyStop, um eine schwebende BuyStop-Order zu setzen:

//+------------------------------------------------------------------+
//| Place BuyStop pending order                                      |
//+------------------------------------------------------------------+
bool SetBuyStop(const string symbol,const double lots,const uint magic,const int distance,const string comment="")
  {
//--- Call the SetPending function with BuyStop parameters
   return SetPending(symbol,ORDER_TYPE_BUY_STOP,lots,magic,distance,0,comment);
  }


SetBuyLimit, um das BuyLimit für schwebende Aufträge zu setzen:

//+------------------------------------------------------------------+
//| Place BuyLimit pending order                                     |
//+------------------------------------------------------------------+
bool SetBuyLimit(const string symbol,const double lots,const uint magic,const int distance,const string comment="")
  {
//--- Call the SetPending function with BuyLimit parameters
   return SetPending(symbol,ORDER_TYPE_BUY_LIMIT,lots,magic,distance,0,comment);
  }


SetBuyStopLimit zum Setzen des BuyStopLimit für schwebende Aufträge:

//+------------------------------------------------------------------+
//| Place BuyStopLimit pending order                                 |
//+------------------------------------------------------------------+
bool SetBuyStopLimit(const string symbol,const double lots,const uint magic,const int distance,const int stoplimit,const string comment="")
  {
//--- Call the SetPending function with BuyStopLimit parameters
   return SetPending(symbol,ORDER_TYPE_BUY_STOP_LIMIT,lots,magic,distance,stoplimit,comment);
  }


SetSellStop zum Setzen des Verkaufsstopps für schwebende Aufträge:

//+------------------------------------------------------------------+
//| Place SellStop pending order                                     |
//+------------------------------------------------------------------+
bool SetSellSellStop(const string symbol,const double lots,const uint magic,const int distance,const string comment="")
  {
//--- Call the SetPending function with SellStop parameters
   return SetPending(symbol,ORDER_TYPE_SELL_STOP,lots,magic,distance,0,comment);
  }


SetSellLimit, um das Verkaufslimit für schwebende Aufträge zu setzen:

//+------------------------------------------------------------------+
//| Place SellLimit pending order                                    |
//+------------------------------------------------------------------+
bool SetSellLimit(const string symbol,const double lots,const uint magic,const int distance,const string comment="")
  {
//--- Call the SetPending function with SellLimit parameters
   return SetPending(symbol,ORDER_TYPE_SELL_LIMIT,lots,magic,distance,0,comment);
  }


SetSellStopLimit, um den schwebenden Auftrag SellStopLimit zu setzen:

//+------------------------------------------------------------------+
//| Place SellStopLimit pending order                                |
//+------------------------------------------------------------------+
bool SetSellStopLimit(const string symbol,const double lots,const uint magic,const int distance,const int stoplimit,const string comment="")
  {
//--- Call the SetPending function with SellStopLimit parameters
   return SetPending(symbol,ORDER_TYPE_SELL_STOP_LIMIT,lots,magic,distance,stoplimit,comment);
  }


DeleteOrder, um einen angegebenen schwebenden Auftrag zu entfernen:

//+------------------------------------------------------------------+
//| Delete a pending order by ticket                                 |
//+------------------------------------------------------------------+
bool DeleteOrder(const ulong ticket)
  {
//--- declare and initialize the trade request and result
   MqlTradeRequest request={};
   MqlTradeResult  result={};
   ResetLastError();
//--- If failed to select an order by ticket, inform of the error and leave
   if(!OrderSelect(ticket))
     {
      PrintFormat("%s: OrderSelect failed, error: %d",__FUNCTION__,GetLastError());
      return false;
     }
//--- Set request and result values to zero
   ZeroMemory(request);
   ZeroMemory(result);
//--- Set operation parameters
   request.action=TRADE_ACTION_REMOVE;                   // trading operation type
   request.order = ticket;                               // order ticket
//--- If failed to send a request, inform of that and return 'false'
   if(!OrderSend(request,result))
     {
      PrintFormat("%s: OrderSend for %s %s #%llu error: %s",__FUNCTION__,
                  TradeActionDescription(request.action),OrderTypeDescription((ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE)),ticket,RetcodeDescription(result.retcode,true)
                 );
      return false;
     }
//--- OrderSend OK, return 'true'
   return true;
  }


DeleteOrdersAll, um alle schwebenden Aufträge zu entfernen:

//+------------------------------------------------------------------+
//| Delete all pending orders by symbol                              |
//+------------------------------------------------------------------+
uint DeleteOrdersAll(const string symbol,const long magic=WRONG_VALUE)
  {
//--- Declare the variable for storing the result and the number of removed orders
   bool res=true;
   uint num=0;
//--- iterate over all placed pending orders
   int total=OrdersTotal(); // number of pending orders
   for(int i=total-1; i>=0; i--)
     {
      ulong  order_ticket=OrderGetTicket(i);             // order ticket
      if(order_ticket==0)
         continue;
      //--- If MagicNumber is not specified (zero) or order magic number matches the specified one
      if(magic==WRONG_VALUE || OrderGetInteger(ORDER_MAGIC)==magic)
        {
         //--- if the order symbol matches the one passed or NULL is passed, remove order by ticket
         if(symbol==NULL || OrderGetString(ORDER_SYMBOL)==symbol)
           {
            res &=DeleteOrder(order_ticket);
            if(res)
               num++;
           }
        }
     }
   if(!res)
      PrintFormat("%s: Not all orders were able to close without errors",__FUNCTION__);
   return num;
  }

Alle oben vorgestellten Handelsfunktionen sind einfache Beispielfunktionen. Sie behandeln oder korrigieren keine Fehler in Abhängigkeit vom Fehlercode und dem Server-Rückgabecode. Sie können solche Funktionen auf deren Grundlage implementieren, aber das würde den Rahmen dieses Artikels sprengen.

Nachdem wir die Struktur des Handelsauftrags ausgefüllt haben, können wir seine Gültigkeit überprüfen. Dies kann mit Hilfe der Funktion OrderCheck() geschehen, die prüft, ob die Mittel ausreichen, um die gewünschte Handelsoperation durchzuführen.

Bei unzureichenden Mitteln oder falsch ausgefüllten Parametern gibt die Funktion false zurück. Ist die grundsätzliche Prüfung von Strukturen (Zeigern) erfolgreich, gibt die Funktion true zurück, was nicht bedeutet, dass die angeforderte Handelsoperation erfolgreich ausgeführt wird. Um eine detaillierte Beschreibung des Ergebnisses der Funktionsausführung zu erhalten, müssen wir das Strukturfeld result analysieren.

Die Prüfergebnisse werden in die Felder der Struktur MqlTradeCheckResult eingetragen. Implementieren wir nun die notwendigen Funktionen, um die Beschreibungen der Strukturfelder anzuzeigen.


Die Struktur MqlTradeCheckResult zur Überprüfung einer vorbereiteten Anfrage vor deren Absendung

Ich empfehle, einen Handelsvorgang zu überprüfen, bevor Sie eine entsprechende Anfrage an den Handelsserver senden. Die Prüfung wird von der Funktion OrderCheck() durchgeführt, die die zu prüfende Anfrage und die Variable des Strukturtyps MqlTradeCheckResult erhält. Das Ergebnis der Prüfung wird in die Variable eingetragen.

struct MqlTradeCheckResult
  {
   uint         retcode;             // Response code
   double       balance;             // Balance after performing a deal
   double       equity;              // Equity after performing a deal
   double       profit;              // Floating profit
   double       margin;              // Margin requirements
   double       margin_free;         // Free margin
   double       margin_level;        // Margin level
   string       comment;             // Comment on the response code (error description)
  };


Rückgabecode

Der RückgabecodeAlle Aufträge zur Durchführung von Handelsoperationen werden mittels der Struktur MqlTradeRequest von der Funktion OrderSend() gesendet. Das Ergebnis der Ausführung der Funktion wird der Struktur MqlTradeResult zugewiesen. Dessen Feld retcode enthält den Rückgabecode des Handelsservers. Nach der Prüfung des Handelsauftrags kann der Rückgabecode im Feld retcode der Struktur MqlTradeCheckResult gelesen werden.

//+------------------------------------------------------------------+
//| Return the response code as a string                             |
//+------------------------------------------------------------------+
string MqlTradeCheckResultRetcode(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Retcode:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,RetcodeDescription(result.retcode,ext_descr));
   /* Sample output:
      Retcode: OK (0)
   */
  }


Saldo nach Durchführung eines Handelsgeschäfts

Der Saldowert nach Ausführung einer Handelsoperation.

//+----------------------------------------------------------------------+
//| Returns the balance as a string after a trade operation is performed |
//+----------------------------------------------------------------------+
string MqlTradeCheckResultBalance(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Balance:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the account currency
   string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- Get the number of decimal places
   int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.balance,currency);
   /* Sample output:
      Balance: 10016.80 USD
   */
  }


Kapital nach Abschluss eines Geschäfts

Das Kapital nach Ausführung einer Handelsoperation.

//+--------------------------------------------------------------------+
//| Return the equity as a string after a trade operation is performed |
//+--------------------------------------------------------------------+
string MqlTradeCheckResultEquity(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Equity:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the account currency
   string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- Get the number of decimal places
   int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.equity,currency);
   /* Sample output:
      Equity: 10016.80 USD
   */
  }


Fließender Gewinn

Der fließende (floating) Gewinn nach Ausführung einer Handelsoperation.

//+---------------------------------------------------------------------------+
//|Return the floating profit as a string after a trade operation is performed|
//+---------------------------------------------------------------------------+
string MqlTradeCheckResultProfit(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Profit:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the account currency
   string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- Get the number of decimal places
   int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.profit,currency);
   /* Sample output:
      Profit: 0.00 USD
   */
  }


Margenanforderungen

Die Höhe der für das notwendige Handelsgeschäft erforderlichen Marge.

//+------------------------------------------------------------------+
//| Return the margin,                                               |
//| required for the necessary trading operation, as a string        |
//+------------------------------------------------------------------+
string MqlTradeCheckResultMargin(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Margin:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the account currency
   string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- Get the number of decimal places
   int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.margin,currency);
   /* Sample output:
      Margin: 128.66 USD
   */
  }


Freie Marge

Der Wert des Kapitals, der nach der Durchführung einer Handelsoperation verbleibt.

//+------------------------------------------------------------------+
//| Return the value of equity                                       |
//| to be left after conducting a trading operation as a string      |
//+------------------------------------------------------------------+
string MqlTradeCheckResultMarginFree(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Margin free:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the account currency
   string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- Get the number of decimal places
   int dg=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f %s",indent,"",w,header,dg,result.margin_free,currency);
   /* Sample output:
      Margin free: 9888.14 USD
   */
  }


Höhe der Marge

Die Höhe der Marge (margin level), der nach Abschluss der gewünschten Handelsoperation festgelegt wird.

//+-----------------------------------------------------------------------+
//| Return the margin level                                               |
//| to be set after completing the required trading operation as a string |
//+-----------------------------------------------------------------------+
string MqlTradeCheckResultMarginLevel(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Margin level:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.2f %%",indent,"",w,header,result.margin_level);
   /* Sample output:
      Margin level: 7785.48 %
   */
  }


Kommentar zum Rückgabecode

Kommentar zum Rückgabecode, Fehlerbeschreibung.

//+------------------------------------------------------------------+
//| Return comment on the response code, error description           |
//+------------------------------------------------------------------+
string MqlTradeCheckResultComment(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Comment:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,result.comment);
   /* Sample output:
      Comment: Done
   */
  }


Beispiele für die Verwendung

Die Funktion, die alle Felder der Struktur MqlTradeCheckResult im Journal anzeigt:

//+------------------------------------------------------------------+
//| Display the MqlTradeCheckResult structure fields in the journal  |
//| as a result of OrderCheck                                        |
//+------------------------------------------------------------------+
void OrderCheckResultPrint(const MqlTradeCheckResult &result,const uint header_width=0,const uint indent=0,bool ext_descr=false)
  {
   Print("OrderCheck result:");
   Print(MqlTradeCheckResultRetcode(result,header_width,indent,ext_descr));
   Print(MqlTradeCheckResultBalance(result,header_width,indent));
   Print(MqlTradeCheckResultEquity(result,header_width,indent));
   Print(MqlTradeCheckResultProfit(result,header_width,indent));
   Print(MqlTradeCheckResultMargin(result,header_width,indent));
   Print(MqlTradeCheckResultMarginFree(result,header_width,indent));
   Print(MqlTradeCheckResultMarginLevel(result,header_width,indent));
   Print(MqlTradeCheckResultComment(result,header_width,indent));
   /* Sample output:
      OrderCheck result:
        Retcode:      Undefined (0)
        Balance:      10016.80 USD
        Equity:       10016.80 USD
        Profit:       0.00 USD
        Margin:       128.66 USD
        Margin free:  9888.14 USD
        Margin level: 7785.48 %
        Comment:      Done
   */
  }

Nach der Prüfung eines abgeschlossenen Handelsauftrags können wir im Falle eines Fehlers die abgeschlossene Struktur MqlTradeCheckResult an das Journal senden, um den Fehler zu analysieren.


Die Struktur MqlTradeResult einer Server-Antwort auf eine von der Funktion OrderSend() gesendete Auftrag

Als Antwort auf eine Handelsanfrage zur Erteilung eines Auftrags im Handelssystem liefert der Handelsserver Daten mit Informationen über das Ergebnis der Bearbeitung der Handelsanfrage in Form einer speziellen MqlTradeResult-Struktur zurück.

struct MqlTradeResult
  {
   uint     retcode;          // Operation result code
   ulong    deal;             // Deal ticket if executed
   ulong    order;            // Order ticket if placed
   double   volume;           // Deal volume confirmed by a broker
   double   price;            // Deal price confirmed by a broker
   double   bid;              // The current market Bid price (requote price)
   double   ask;              // The current market Ask price (requote price)
   string   comment;          // Broker comment to operation (by default, it is filled by the trade server return code description)
   uint     request_id;       // Request ID set by the terminal when sending 
   int      retcode_external; // Response code of an external trading system
  };

Das Ergebnis der Handelsoperation wird an eine Variable vom Typ MqlTradeResult zurückgegeben, die als zweiter Parameter der Funktion OrderSend() zur Durchführung von Handelsoperationen einzutragen ist.

Wir implementieren die folgenden Funktionen, um die Beschreibungen der Strukturfelder anzuzeigen:

Code für das Ergebnis der Operation

Der Rückgabecode eines Handelsservers
//+------------------------------------------------------------------+
//| Return the operation result code as a string                     |
//+------------------------------------------------------------------+
string MqlTradeResultRetcode(const MqlTradeResult &result,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Retcode:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,RetcodeDescription(result.retcode,ext_descr));
   /* Sample output:
      Retcode: 10009 DONE (Request completed)
   */
  }


Ticket eines Deals

Das Ticket des Deals, wenn ein Deal durchgeführt wurde. Es ist für einen Handelsvorgang vom Typ TRADE_ACTION_DEAL verfügbar.
//+------------------------------------------------------------------+
//| Return the deal ticket if it is completed                        |
//+------------------------------------------------------------------+
string MqlTradeResultDeal(const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Deal:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,result.deal);
   /* Sample output:
      Deal: 0
   */
  }


Ticket des Auftrags

Das Ticket eines Auftrags, wenn ein schwebender Auftrag eingetragen wurde. Es ist für die Handelsoperation TRADE_ACTION_PENDING verfügbar.
//+------------------------------------------------------------------+
//| Return the order ticket as a string if the order is set          |
//+------------------------------------------------------------------+
string MqlTradeResultOrder(const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Order:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,result.order);
   /* Sample output:
      Order: 1821552382
   */
  }


Volumen eines Deals

Von einem Makler bestätigtes Geschäftsvolumen. Es hängt von der Art der Auftragsabwicklung ab.
//+------------------------------------------------------------------+
//| Return the deal volume confirmed by a broker as a string         |
//+------------------------------------------------------------------+
string MqlTradeResultVolume(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Volume:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places in the lot value
   int dg=(int)ceil(fabs(log10(SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP))));
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.volume);
   /* Sample output:
      Volume: 0.10
   */
  }


Deal-Preis

Der Preis des Deals wurde von einem Makler bestätigt. Er ist abhängig von dem Feld deviation (Abweichung) im Handelsauftrag und/oder von der Art der Handelsdurchführung.

//+------------------------------------------------------------------+
//| Return a deal price, confirmed by a broker, as a string          |
//+------------------------------------------------------------------+
string MqlTradeResultPrice(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Price:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(result.price!=0 ? (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.price);
   /* Sample output:
      Price: 0.0
   */
  }


Aktueller Geldkurs (Bid)

Der aktuelle Geldkurs (Requote-Preis).
//+------------------------------------------------------------------+
//| Return the current market Bid price as a string                  |
//+------------------------------------------------------------------+
string MqlTradeResultBid(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Bid:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(result.bid!=0 ? (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.bid);
   /* Sample output:
      Bid: 0.0
   */
  }


Aktueller Briefkurs (Ask)

Der aktuelle Briefkurs (Requote-Preis).
//+------------------------------------------------------------------+
//| Return the current market Ask price as a string                  |
//+------------------------------------------------------------------+
string MqlTradeResultAsk(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Ask:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places
   int dg=(result.ask!=0 ? (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,result.ask);
   /* Sample output:
      Ask: 0.0
   */
  }

Wenn Sie einen schwebenden Auftrag erteilen, bleiben die Geld- und Briefkurse in der Struktur leer. Wenn der Auftrag aufgrund eines Requotes (neue Preise) nicht angenommen wurde, werden in den Feldern Bid und Ask die Preise angezeigt, die zu dem Zeitpunkt galten, als der Auftrag zur Platzierung abgelehnt wurde.


Kommentar des Maklers zu einem Handelsgeschäft

Kommentar des Maklers zum Vorgang (standardmäßig wird er durch die Beschreibung des Rückgabecodes des Handelsservers ausgefüllt).
//+------------------------------------------------------------------+
//| Return broker's comment on a deal                                |
//+------------------------------------------------------------------+
string MqlTradeResultComment(const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Comment:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,result.comment);
   /* Sample output:
      Comment: Request executed
   */
  }


ID anfordern

Auftrags-ID, die vom Terminal beim Senden an den Handelsserver festgelegt wird.
//+------------------------------------------------------------------+
//| Return request ID as a string                                    |
//+------------------------------------------------------------------+
string MqlTradeResultRequestID(const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Request ID:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-lu",indent,"",w,header,result.request_id);
   /* Sample output:
      Request ID: 3768213261
   */
  }

Das Setzen der request_id durch das Terminal für die Handelsanfrage beim Senden an den Server wird hauptsächlich für die Arbeit mit der asynchronen Funktion OrderSendAsync() eingeführt. Diese Kennung ermöglicht es, die durchgeführte Aktion (OrderSend- oder OrderSendAsync-Funktionsaufruf) mit dem Ergebnis dieser Aktion zu verknüpfen, das an den OnTradeTransaction()-Handler gesendet wird.


Rückgabecode des externen Handelssystems

Vom externen Handelssystem zurückgegebener Fehlercode. Die Verwendung und die Art dieser Fehler hängen vom Broker und dem externen Handelssystem ab, an das die Handelsgeschäfte gesendet werden.
//+-------------------------------------------------------------------+
//| Return the response code of an external trading system as a string|
//+-------------------------------------------------------------------+
string MqlTradeResultRetcodeExternal(const MqlTradeResult &result,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Retcode External:";
   uint w=(header_width==0 ? header.Length()+1 : header_width-1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%- ld",indent,"",w,header,result.retcode_external);
   /* Sample output:
      Retcode External:  0
   */
  }


Beispiele für die Verwendung

Die Funktion, die alle Felder der Ergebnisstruktur der Handelsanfrage im Journal anzeigt:

//+------------------------------------------------------------------+
//| Display MqlTradeResult structure fields in the journal           |
//| as a result of a trade request                                   |
//+------------------------------------------------------------------+
void TradeResultPrint(const string symbol,const MqlTradeResult &result,const uint header_width=0,const uint indent=0,bool ext_descr=false)
  {
   string symbol_name=(symbol==NULL ? Symbol() : symbol);
   Print("OrderSend result:");
   Print(MqlTradeResultRetcode(result,header_width,indent,ext_descr));
   Print(MqlTradeResultDeal(result,header_width,indent));
   Print(MqlTradeResultOrder(result,header_width,indent));
   Print(MqlTradeResultVolume(symbol_name,result,header_width,indent));
   Print(MqlTradeResultPrice(symbol_name,result,header_width,indent));
   Print(MqlTradeResultBid(symbol_name,result,header_width,indent));
   Print(MqlTradeResultAsk(symbol_name,result,header_width,indent));
   Print(MqlTradeResultComment(result,header_width,indent));
   Print(MqlTradeResultRequestID(result,header_width,indent));
   Print(MqlTradeResultRetcodeExternal(result,header_width,indent));
   /* Sample output:
      OrderSend result:
        Retcode:          10009 DONE (Request completed)
        Deal:             0
        Order:            1821671230
        Volume:           0.10
        Price:            0.0
        Bid:              0.0
        Ask:              0.0
        Comment:          Request executed
        Request ID:       3768213265
        Retcode External: 0
   */
  }


Die Struktur MqlTradeTransaction mit einer Beschreibung der Handelstransaktionen

Durch die Durchführung bestimmter Aktionen mit einem Handelskonto ändert sich dessen Zustand. Diese Maßnahmen umfassen:

  • Senden einer Handelsanfrage durch eine beliebige MQL5-Anwendung vom Client-Terminal unter Verwendung der Funktionen OrderSend und OrderSendAsync und deren anschließende Ausführung;
  • Absenden eines Handelsauftrags über die grafische Schnittstelle des Terminals und dessen anschließende Ausführung;
  • Auslösung von schwebenden und Stop-Aufträgen auf dem Server;
  • Durchführung von Operationen auf der Seite des Handelsservers.

Als Ergebnis dieser Aktionen werden die folgenden Handelstransaktionen auf dem Konto durchgeführt:

  • Bearbeitung einer Handelsanfrage;
  • Änderung offener Aufträge;
  • Änderung der Bestellhistorie;
  • Änderung der Historie der Handelsgeschäfte;
  • Änderung von Positionen.

Wenn Sie zum Beispiel einen Marktorder Kauf senden, wird dieser verarbeitet, ein entsprechender Kaufauftrag für das Konto erstellt, der Auftrag ausgeführt, aus der Liste der offenen Aufträge entfernt und zur Auftragshistorie hinzugefügt. Dann wird das entsprechende Handelsgeschäft in die Historie aufgenommen und eine neue Position erstellt. Alle diese Aktionen sind Handelstransaktionen.

MQL5 bietet für die Ereignisbehandlung OnTradeTransaction() für den Empfang von Handelstransaktionen, die auf ein Konto angewendet werden, an. Der erste Parameter dieses Handlers erhält die Struktur MqlTradeTransaction, die die Handelstransaktionen beschreibt.

struct MqlTradeTransaction
  {
   ulong                         deal;             // Deal ticket
   ulong                         order;            // Order ticket
   string                        symbol;           // Symbol name
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Trading transaction type
   ENUM_ORDER_TYPE               order_type;       // Order type
   ENUM_ORDER_STATE              order_state;      // Order state
   ENUM_DEAL_TYPE                deal_type;        // Deal type
   ENUM_ORDER_TYPE_TIME          time_type;        // Order lifetime type
   datetime                      time_expiration;  // Order expiration time
   double                        price;            // Price 
   double                        price_trigger;    // Stop limit order trigger price
   double                        price_sl;         // Stop Loss level
   double                        price_tp;         // Take Profit level
   double                        volume;           // Volume in lots
   ulong                         position;         // Position ticket
   ulong                         position_by;      // Opposite position ticket
  };


Lassen Sie uns die folgenden Funktionen implementieren, um Beschreibungen aller Strukturfelder zurückzugeben.

Ticket eines Deals

//+------------------------------------------------------------------+
//| Return the deal ticket as a string                               |
//+------------------------------------------------------------------+
string MqlTradeTransactionDeal(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Deal:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.deal);
   /* Sample output:
      Deal: 0
   */
  }


Ticket des Auftrags

//+------------------------------------------------------------------+
//| Return the order ticket as a string                              |
//+------------------------------------------------------------------+
string MqlTradeTransactionOrder(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Order:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.order);
   /* Sample output:
      Order: 1825990224
   */
  }


Name eines Handelsinstruments

Der Name des Handelssymbols, für das die Transaktion ausgeführt wurde.

//+------------------------------------------------------------------+
//| Return an order symbol as a string                               |
//+------------------------------------------------------------------+
string MqlTradeTransactionSymbol(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Symbol:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,trans.symbol);
   /* Sample output:
      Symbol: EURUSD
   */
  }


Art der Handelstransaktionen

Art des Handelstransaktion. Der Wert kann einen aus der Enumeration ENUM_TRADE_TRANSACTION_TYPE annehmen.

//+------------------------------------------------------------------+
//| Return the trading transaction type as a string                  |
//+------------------------------------------------------------------+
string MqlTradeTransactionType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Type:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,TradeTransactionTypeDescription(trans.type,ext_descr));
   /* Sample output:
      Type: Order delete (Removing an order from the list of the open ones)
   */
  }


Auftragsart

Art des Handelsauftrags. Der Wert kann einen aus der Enumeration ENUM_ORDER_TYPE annehmen.

//+------------------------------------------------------------------+
//| Return the order type as a string                                |
//+------------------------------------------------------------------+
string MqlTradeTransactionOrderType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Declare variables to indicate transaction affiliation
   bool trans_req=false;   // Request
   bool trans_order=false; // Order
   bool trans_deal=false;  // Deal
   bool trans_pos=false;   // Position
//--- Set transaction affiliation
   SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos);
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Order type:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_order ? OrderTypeDescription(trans.order_type,ext_descr) : "0"));
   /* Sample output:
      Order type: Sell Limit (Sell Limit pending order)
   */
  }

Die Funktion bestimmt die Zugehörigkeit der Handelstransaktion. Wurde die Transaktion mit einem Auftrag durchgeführt, so wird dessen Typ zurückgegeben, andernfalls '0'.


Status des Handelsauftrags.

Der Status des Handelsauftrags. Der Wert kann eine aus der Enumeration ENUM_ORDER_STATE annehmen.

//+------------------------------------------------------------------+
//| Return the order status as a string                              |
//+------------------------------------------------------------------+
string MqlTradeTransactionOrderState(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Declare variables to indicate transaction affiliation
   bool trans_req=false;   // Request
   bool trans_order=false; // Order
   bool trans_deal=false;  // Deal
   bool trans_pos=false;   // Position
//--- Set transaction affiliation
   SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos);
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Order state:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_order ? OrderStateDescription(trans.order_state,ext_descr) : "0"));
   /* Sample output:
      Order state: Started (Order checked, but not yet accepted by broker)
   */
  }

Die Funktion bestimmt die Zugehörigkeit der Handelstransaktion. Wenn die Transaktion mit einem Auftrag durchgeführt wurde, wird dessen Status zurückgegeben, andernfalls '0'.


Deal-Typ

Die Art des Handelsgeschäfts. Der Wert kann einen aus der Enumeration ENUM_DEAL_TYPE annehmen.

//+------------------------------------------------------------------+
//| Return the deal type as a string                                 |
//+------------------------------------------------------------------+
string MqlTradeTransactionDealType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Declare variables to indicate transaction affiliation
   bool trans_req=false;   // Request
   bool trans_order=false; // Order
   bool trans_deal=false;  // Deal
   bool trans_pos=false;   // Position
//--- Set transaction affiliation
   SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos);
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Deal type:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_deal || trans_pos ? DealTypeDescription(trans.deal_type,ext_descr) : "0"));
   /* Sample output:
      Deal type: Buy
   */
  }

Die Funktion bestimmt die Zugehörigkeit der Handelstransaktion. Wurde die Transaktion mit einem Deal durchgeführt, so wird dessen Typ zurückgegeben, andernfalls '0'.


Laufzeittyp eines Auftrags

Auftragsart nach Verfallszeit. Der Wert kann einen aus der Enumeration ENUM_ORDER_TYPE_TIME annehmen.

//+------------------------------------------------------------------+
//| Return the order type by expiration time as a string             |
//+------------------------------------------------------------------+
string MqlTradeTransactionTimeType(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Declare variables to indicate transaction affiliation
   bool trans_req=false;   // Request
   bool trans_order=false; // Order
   bool trans_deal=false;  // Deal
   bool trans_pos=false;   // Position
//--- Set transaction affiliation
   SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos);
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Time type:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,(trans_order ? OrderTypeTimeDescription(trans.time_type,ext_descr) : "0"));
   /* Sample output:
      Order type time: Time GTC (Good till cancel order)
   */
  }

Die Funktion bestimmt die Zugehörigkeit der Handelstransaktion. Wurde die Transaktion mit einem Auftrag durchgeführt, so wird dessen Typ der Verfallszeit zurückgegeben, andernfalls '0'.


Laufzeitende eines Auftrags

Der Ablaufzeitpunkt eines schwebenden Auftrags (für Aufträge der Typen ORDER_TIME_SPECIFIED und ORDER_TIME_SPECIFIED_DAY).

//+------------------------------------------------------------------+
//| Return the order expiration time as a string                     |
//+------------------------------------------------------------------+
string MqlTradeTransactionTimeExpiration(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Time expiration:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Set the expiration time as a string. If 0, then set 0
   string tm=(trans.time_expiration==0 ? "0" : (string)trans.time_expiration);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s",indent,"",w,header,tm);
   /* Sample output:
      Time expiration: 0
   */
  }

Wenn der Ablaufzeitpunkt im Strukturfeld auf Null gesetzt ist, wird '0' angezeigt, andernfalls der Ablaufzeitpunkt im Datumsformat. Wenn wir den Feldwert nicht auf Null prüfen, wird der Nullwert als 01.01.1970 00:00:00 angezeigt, was für eine fehlende Ablaufzeit der Bestellung nicht sehr ästhetisch aussieht.


Preis

Der Preis. Je nach Art der Handelstransaktion kann dies der Preis eines Auftrags, einer Transaktion oder einer Position sein.

//+------------------------------------------------------------------+
//| Return the order/deal/position price as a string                 |
//+------------------------------------------------------------------+
string MqlTradeTransactionPrice(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Price:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Receive symbol's Digits. If the character is not specified, use 1
   int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price);
   /* Sample output:
      Price: 1.10331
   */
  }


Auslösepreis einer Stop-Limit-Order

Stop-Preis (Auslösepreis) einer Stop-Limit-Order (ORDER_TYPE_BUY_STOP_LIMIT und ORDER_TYPE_SELL_STOP_LIMIT).

//+------------------------------------------------------------------+
//| Return the stop limit order trigger price as a string            |
//+------------------------------------------------------------------+
string MqlTradeTransactionPriceTrigger(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Price trigger:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Receive symbol's Digits. If a symbol is not specified or there is no stop price, use 1
   int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1);
   if(trans.price_trigger==0)
      dg=1;
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price_trigger);
   /* Sample output:
      Price trigger: 0.0
   */
  }

Wenn der Stop-Limit-Orderpreis nicht angegeben ist, wird '0.0' angezeigt, andernfalls der Orderpreis.


Stop-Loss-Preis

Der Stop-Loss-Preis Je nach Handelstransaktion kann es sich um den eines Auftrags, eines Deals oder einer Position handeln.

//+------------------------------------------------------------------+
//| Return Stop Loss price as a string                               |
//+------------------------------------------------------------------+
string MqlTradeTransactionPriceSL(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Price SL:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Receive symbol's Digits. If a symbol is not specified or a Stop Loss price is absent, use 1
   int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1);
   if(trans.price_sl==0)
      dg=1;
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price_sl);
   /* Sample output:
      Price SL: 0.0
   */
  }

Wenn kein Stop-Loss gesetzt ist, wird '0.0' angezeigt, andernfalls der Stop-Loss-Preis.


Take-Profit-Ebene

Take-Profit Preis. Je nach Handelstransaktion kann es sich um den eines Auftrags, eines Deals oder einer Position handeln.

//+------------------------------------------------------------------+
//| Return a Take Profit price as a string                           |
//+------------------------------------------------------------------+
string MqlTradeTransactionPriceTP(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Price TP:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Receive symbol's Digits. If a symbol is not specified or a Take Profit price is absent, use 1
   int dg=(trans.symbol!="" ? (int)SymbolInfoInteger(trans.symbol,SYMBOL_DIGITS) : 1);
   if(trans.price_tp==0)
      dg=1;
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.price_tp);
   /* Sample output:
      Price TP: 0.0
   */
  }

Wenn der Preis für die Gewinnmitnahme nicht festgelegt ist, wird '0.0' angezeigt, andernfalls Preis für die Gewinnmitnahme.


Volumen in Losgrößen

Das Volumen in Losgrößen (lots). Je nach Art der Handelstransaktion kann es das aktuelle Volumen von Aufträgen, Deals oder Position definieren.

//+------------------------------------------------------------------+
//| Return volume in lots as a string                                |
//+------------------------------------------------------------------+
string MqlTradeTransactionVolume(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Volume:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get the number of decimal places in the lot value. If the character is not specified, use 1
   int dg=(trans.symbol!="" ? (int)ceil(fabs(log10(SymbolInfoDouble(trans.symbol,SYMBOL_VOLUME_STEP)))) : 1);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,trans.volume);
   /* Sample output:
      Volume: 0.10
   */
  }


Ticket einer Position

Das Ticket einer Position, die die Transaktion darstellt.

//+------------------------------------------------------------------+
//| Return the position ticket as a string                           |
//+------------------------------------------------------------------+
string MqlTradeTransactionPosition(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Position:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.position);
   /* Sample output:
      Position: 0
   */
  }


Ticket einer entgegengesetzten Position

Ticket für die gegenüberliegende Position. Sie wird verwendet, wenn eine Position durch eine entgegengesetzte geschlossen wird (die zum gleichen Symbol, aber in entgegengesetzter Richtung eröffnet wurde).

//+------------------------------------------------------------------+
//| Return the opposite position ticket as a string                  |
//+------------------------------------------------------------------+
string MqlTradeTransactionPositionBy(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Position by:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-llu",indent,"",w,header,trans.position_by);
   /* Sample output:
      Position by: 0
   */
  }


Beispiele für die Verwendung

Mit den oben vorgestellten Funktionen können wir alle Felder der Struktur MqlTradeTransaction im Journal anzeigen:

//+------------------------------------------------------------------+
//| Display the MqlTradeTransaction structure fields in the journal  |
//+------------------------------------------------------------------+
void MqlTradeTransactionPrint(const MqlTradeTransaction &trans,const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
   Print(MqlTradeTransactionDeal(trans,header_width,indent));
   Print(MqlTradeTransactionOrder(trans,header_width,indent));
   Print(MqlTradeTransactionSymbol(trans,header_width,indent));
   Print(MqlTradeTransactionType(trans,header_width,indent,ext_descr));
   Print(MqlTradeTransactionOrderType(trans,header_width,indent,ext_descr));
   Print(MqlTradeTransactionOrderState(trans,header_width,indent,ext_descr));
   Print(MqlTradeTransactionDealType(trans,header_width,indent,ext_descr));
   Print(MqlTradeTransactionTimeType(trans,header_width,indent,ext_descr));
   Print(MqlTradeTransactionTimeExpiration(trans,header_width,indent));
   Print(MqlTradeTransactionPrice(trans,header_width,indent));
   Print(MqlTradeTransactionPriceTrigger(trans,header_width,indent));
   Print(MqlTradeTransactionPriceSL(trans,header_width,indent));
   Print(MqlTradeTransactionPriceTP(trans,header_width,indent));
   Print(MqlTradeTransactionVolume(trans,header_width,indent));
   Print(MqlTradeTransactionPosition(trans,header_width,indent));
   Print(MqlTradeTransactionPositionBy(trans,header_width,indent));
   /* Sample output:
      Deal:             0
      Order:            1829189788
      Symbol:           EURUSD
      Type:             Order add
      Order type:       Buy Limit
      Order state:      Started
      Deal type:        0
      Time type:        Time GTC
      Time expiration:  0
      Price:            1.09861
      Price trigger:    0.0
      Price SL:         0.0
      Price TP:         0.0
      Volume:           0.10
      Position:         0
      Position by:      0
   */
  }

Die vorgestellte Funktion zeigt alle Felder der MqlTradeTransaction-Struktur im Journal an. Die Strukturfelder werden für verschiedene Handelsereignisse unterschiedlich ausgefüllt:

Der wesentliche Parameter für die Analyse der empfangenen Transaktion ist ihr Typ, der im Feldtype angegeben ist . Wenn eine Transaktion beispielsweise vom Typ TRADE_TRANSACTION_REQUEST ist (ein Ergebnis der Bearbeitung einer Handelsanfrage durch den Server wurde empfangen), hat die Struktur nur das Feld type gefüllt. Andere Felder werden nicht analysiert. In diesem Fall können wir zwei zusätzliche Anfrage- und Ergebnisparameter analysieren, die an die Ereignisbehandlung von OnTradeTransaction() übermittelt werden, wie unten dargestellt.

Wenn wir die Art einer Handelsoperation kennen, können wir uns entscheiden, den aktuellen Stand der Aufträge, Positionen und Deals auf einem Handelskonto zu analysieren. Beachten Sie, dass eine vom Terminal an den Server gesendete Handelsanfrage mehrere Handelstransaktionen auslösen kann. Die Reihenfolge ihres Eintreffens am Terminal ist nicht garantiert.

Die Struktur MqlTradeTransaction wird je nach Handelstransaktionsart (ENUM_TRADE_TRANSACTION_TYPE) unterschiedlich ausgefüllt:

TRADE_TRANSACTION_ORDER_* und TRADE_TRANSACTION_HISTORY_*

Für Handelstransaktionen im Zusammenhang mit der Bearbeitung offener Aufträge (TRADE_TRANSACTION_ORDER_ADD, TRADE_TRANSACTION_ORDER_UPDATE and TRADE_TRANSACTION_ORDER_DELETE) und die Auftragshistorie (TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_HISTORY_UPDATE, TRADE_TRANSACTION_HISTORY_DELETE) werden die folgenden Felder in der Struktur MqlTradeTransaction ausgefüllt:

  • order — Ticket des Auftrags;
  • symbol — Bezeichnung eines Finanzinstruments im Auftrag;
  • type — Art der Handelstransaktion;
  • order_type — Art des Auftrags;
  • orders_state — aktueller Status eines Auftrags;
  • time_type — Art der Auftragsausführung;
  • time_expiration — Verfallszeit des Auftrags (für Aufträge mit ORDER_TIME_SPECIFIED und dem Verfallstyp ORDER_TIME_SPECIFIED_DAY);
  • price — vom Händler angegebener Preis;
  • price_trigger — für Stop-Limit-Order der Trigger des Stop-Preises (nur für ORDER_TYPE_BUY_STOP_LIMIT und ORDER_TYPE_SELL_STOP_LIMIT);
  • price_sl — Preis von Stop-Loss (ausgefüllt, wenn im Auftrag angegeben);
  • price_tp — Preis von Take-Profit (ausgefüllt, wenn im Auftrag angegeben);
  • volume — aktuelles Auftragsvolumen (nicht ausgeführt). Das ursprüngliche Auftragsvolumen kann mit Hilfe der Funktionen HistoryOrders* aus der Auftragshistorie ermittelt werden.
  • position — Ticket einer Position, die infolge einer Auftragsausführung eröffnet, geändert oder geschlossen wurde. Zugewiesen nur für Marktaufträge. Nicht ausgefüllt für TRADE_TRANSACTION_ORDER_ADD.
  • position_by — Ticket für die entgegengesetzten Position. Wird nur bei Aufträgen zur Schließung einer Gegenposition (close by) ausgefüllt.

HANDEL_TRANSAKTION_ABSCHLIESSEN_*

Die folgenden Felder werden für die Handelstransaktionen im Zusammenhang mit der Abwicklung von Deals (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE und TRADE_TRANSACTION_DEAL_DELETE) in der Struktur MqlTradeTransaction ausgefüllt:

  • deal — Ticket des Deals;
  • order — Ticket eines Auftrags, auf dem der Deal basiert;
  • symbol — Bezeichnung eines Finanzinstruments des Deals;
  • type — Art der Handelstransaktion;
  • deal_type — Art des Deals;
  • price — Preis des Deals;
  • price_sl — Stop-Loss-Kurs (wird ausgefüllt, wenn er in der Order angegeben ist, auf der der Deal basiert);
  • price_tp — Preis für die Gewinnmitnahme (wird ausgefüllt, wenn er in der Order angegeben ist, auf der der Deal basiert);
  • volume — Volumen des Deals in Losgrößen.
  • position — Ticket der Position, die infolge der Durchführung eines Deals eröffnet, geändert oder geschlossen wurde.
  • position_by — Ticket für die entgegengesetzten Position. Wird nur bei Aufträgen zur Schließung einer Gegenposition (close by) ausgefüllt.

TRADE_TRANSACTION_POSITION

Die folgenden Felder werden in der Struktur MqlTradeTransaction für die Handelstransaktionen ausgefüllt, die sich auf Änderungen der Positionen beziehen und nichts mit der Ausführung eines Deals zu tun haben (TRADE_TRANSACTION_POSITION):

  • symbol — Bezeichnung der Position des Finanzinstruments;
  • type — Art der Handelstransaktion;
  • deal_type — Positionsart (DEAL_TYPE_BUY oder DEAL_TYPE_SELL);
  • price — gewichteter durchschnittlicher Preis der offenen Position;
  • price_sl — Stop-Loss-Preis;
  • price_tp — Take-Profit-Preis;
  • volume — Positionsgröße in Lots, falls geändert.
  • position — Ticket der Position.

Das Ändern einer Position (Hinzufügen, Ändern oder Entfernen) als Ergebnis eines Deals hat nicht die Transaktion TRADE_TRANSACTION_POSITION zur Folge.

HANDEL_TRANSAKTION_ANFORDERUNG

In der Struktur MqlTradeTransaction für Handelstransaktionen wird nur ein Feld ausgefüllt, das beschreibt, dass eine Handelsanfrage vom Server bearbeitet wurde und das Ergebnis empfangen wurde (TRADE_TRANSACTION_REQUEST):

  • type — Art der Handelstransaktion;
Bei Handelstransaktionen dieser Art sollte nur ein Feld analysiert werden, nämlich die Art (Handelsgeschäftsart). Es ist notwendig, den zweiten und dritten Parameter der Funktion OnTradeTransaction (request und result) zu analysieren, um zusätzliche Informationen zu erhalten.

Dementsprechend können wir eine Funktion erstellen, die eingehende Handelsereignisse berücksichtigt und nur die Felder der MqlTradeTransaction-Struktur protokolliert, die für jede Art von Transaktion erforderlich sind:

//+------------------------------------------------------------------+
//| Trading transaction informer                                     |
//+------------------------------------------------------------------+
void TradeTransactionInformer(const MqlTradeTransaction &trans,const MqlTradeRequest& request,const MqlTradeResult& result,
                              const uint header_width=0,const uint indent=0,const bool ext_descr=false)
  {
//--- Declare variables to indicate transaction affiliation
   bool trans_req=false;   // Request
   bool trans_order=false; // Order
   bool trans_deal=false;  // Deal
   bool trans_pos=false;   // Position
//--- Set transaction affiliation
   SetTransactionBelong(trans.type,trans_req,trans_order,trans_deal,trans_pos);
//--- Depending on the transaction affiliation, display descriptions of the corresponding structure fields
   //--- Trading request
   if(trans_req)
     {
      //--- Inform of the "trading request" transaction type and indicate that it is necessary to analyze the fields of the trading request and server response structure
      PrintFormat("Transaction %s\n%*sThe second and third parameters of OnTradeTransaction function (request and result) must be analyzed for additional data:",
         MqlTradeTransactionType(trans,0,0,true),indent,"");
      //--- Display the description of the trade request and the request result received from the server
      TradeRequestPrint(request,header_width,indent,ext_descr);
      TradeResultPrint(trans.symbol,result,header_width,indent,ext_descr);
     }
   //--- Otherwise, if the order/deal/position 
   else
     {
      //--- Display the transaction type in the journal
      PrintFormat("Transaction %s",MqlTradeTransactionType(trans,0,0,true));
      //--- Order
      if(trans_order)
        {
         Print(MqlTradeTransactionOrder(trans,header_width,indent));
         Print(MqlTradeTransactionSymbol(trans,header_width,indent));
         Print(MqlTradeTransactionOrderType(trans,header_width,indent,ext_descr));
         Print(MqlTradeTransactionOrderState(trans,header_width,indent,ext_descr));
         Print(MqlTradeTransactionTimeType(trans,header_width,indent,ext_descr));
         if(trans.time_type==ORDER_TIME_SPECIFIED || trans.time_type==ORDER_TIME_SPECIFIED_DAY)
            Print(MqlTradeTransactionTimeExpiration(trans,header_width,indent));
         Print(MqlTradeTransactionPrice(trans,header_width,indent));
         if(trans.order_type==ORDER_TYPE_BUY_STOP_LIMIT || trans.order_type==ORDER_TYPE_SELL_STOP_LIMIT)
            Print(MqlTradeTransactionPriceTrigger(trans,header_width,indent));
         Print(MqlTradeTransactionPriceSL(trans,header_width,indent));
         Print(MqlTradeTransactionPriceTP(trans,header_width,indent));
         Print(MqlTradeTransactionVolume(trans,header_width,indent));
         if(trans.type!=TRADE_TRANSACTION_ORDER_ADD && (trans.order_type==ORDER_TYPE_BUY || trans.order_type==ORDER_TYPE_SELL))
            Print(MqlTradeTransactionPosition(trans,header_width,indent));
         if(trans.order_type==ORDER_TYPE_CLOSE_BY)
            Print(MqlTradeTransactionPositionBy(trans,header_width,indent));
        }
      //--- Deal
      if(trans_deal)
        {
         Print(MqlTradeTransactionDeal(trans,header_width,indent));
         Print(MqlTradeTransactionOrder(trans,header_width,indent));
         Print(MqlTradeTransactionSymbol(trans,header_width,indent));
         Print(MqlTradeTransactionDealType(trans,header_width,indent,ext_descr));
         Print(MqlTradeTransactionPrice(trans,header_width,indent));
         Print(MqlTradeTransactionPriceSL(trans,header_width,indent));
         Print(MqlTradeTransactionPriceTP(trans,header_width,indent));
         Print(MqlTradeTransactionVolume(trans,header_width,indent));
         Print(MqlTradeTransactionPosition(trans,header_width,indent));
        }
      //--- Position
      if(trans_pos)
        {
         Print(MqlTradeTransactionSymbol(trans,header_width,indent));
         Print(MqlTradeTransactionDealType(trans,header_width,indent,ext_descr));
         Print(MqlTradeTransactionPrice(trans,header_width,indent));
         Print(MqlTradeTransactionPriceSL(trans,header_width,indent));
         Print(MqlTradeTransactionPriceTP(trans,header_width,indent));
         Print(MqlTradeTransactionVolume(trans,header_width,indent));
         Print(MqlTradeTransactionPosition(trans,header_width,indent));
        }
     }
   /* Sample output when setting the Sell Limit order:
      Transaction Type: Order add (Adding a new open order)
        Order: 1833072954
        Symbol: EURUSD
        Order type: Sell Limit (Sell Limit pending order)
        Order state: Started (Order checked, but not yet accepted by broker)
        Time type: Time GTC (Good till cancel order)
        Price: 1.10516
        Price SL: 0.0
        Price TP: 0.0
        Volume: 0.10
      Transaction Type: Order update (Updating an open order)
        Order: 1833072954
        Symbol: EURUSD
        Order type: Sell Limit (Sell Limit pending order)
        Order state: Placed (Order accepted)
        Time type: Time GTC (Good till cancel order)
        Price: 1.10516
        Price SL: 0.0
        Price TP: 0.0
        Volume: 0.10
      Transaction Type: Request (The trade request has been processed by a server and processing result has been received)
        The second and third parameters of OnTradeTransaction function (request and result) must be analyzed for additional data:
      Request Pending (Place a trade order for the execution under specified conditions (pending order)):
        Symbol: EURUSD
        Volume: 0.10
        Price: 1.10516
        SL: 0.0
        TP: 0.0
        Type: Sell Limit (Sell Limit pending order)
        Type filling: Return (In case of partial filling, an order with remaining volume is not canceled but processed further)
        Type time: Time GTC (Good till cancel order)
        Expiration: 0
        Magic: 1024
        Comment: TestMqlTradeTransaction
      OrderSend result:
        Retcode: 10009 DONE (Request completed)
        Deal: 0
        Order: 1833072954
        Volume: 0.10
        Price: 0.0
        Bid: 0.0
        Ask: 0.0
        Comment: 
        Request ID: 3768213464
        Retcode External:  0
      //---
      Here, when placing a Buy Limit pending order, we received three transactions:
         1. Request - a request to place a pending order was accepted by the server and a response was received. 
            To clarify information, it is necessary to analyze the fields of the MqlTradeRequest trade request structure 
            and the MqlTradeResult server response – 'request' and 'result', respectively.
         2. Adding a new pending order with the ticket #1829788294. Its status - Started.
         3. Changing an open order with the ticket #1829788294. Its status changed from Started to Placed.
      The order of transactions is not respected, but this is clearly indicated in the Help section concerning the OnTradeTransaction handler: 
      https://www.mql5.com/en/docs/event_handlers/ontradetransaction.
   */
  }


Ein EA für Informationen über die Handelstransaktionen

Um die Funktionsweise der oben beschriebenen Funktionen zu überprüfen, erstellen wir einen EA, der alle Handelstransaktionen und Serverantworten verfolgt und Beschreibungen der eingehenden Handelstransaktionen im Journal anzeigt. Implementieren wir es so, dass wir schwebende Aufträge (BuyStop, SellStop, BuyLimit und SellLimit) und offene Positionen (Buy und Sell) durch Drücken der in den Einstellungen ausgewählten Tasten setzen können. Standardmäßig werden der Handelsverwaltung die folgenden Schlüssel zugewiesen:

Auftragsart
Tastaturkürzel zum Öffnen/Installieren
Tastaturkürzel zum Schließen/Löschen
 Kaufen (buy)
 B
 X
 Verkaufen (sell)
 S
 X
 Buy Stop
 Umschalttaste+B
 Umschalt+X, Strg+Umschalt+X
 Buy Limit
 Strg+Umschalt+B
 Umschalt+X, Strg+Umschalt+X
 Sell Stop
 Umschalttaste+S
 Umschalt+X, Strg+Umschalt+X
 Sell Limit
 Strg+Umschalt+S
 Umschalt+X, Strg+Umschalt+X

Tasten können in den Einstellungen beliebig belegt werden. Der EA wird sie automatisch in Großbuchstaben umwandeln. Wir können drei Schlüssel festlegen - für den Kauf, den Verkauf und das Schließen von Positionen/Löschen von Aufträgen. Die Steuerungstasten Strg und Umschalttaste zum Ändern der Art der schwebenden Aufträge in einer Anforderung sind standardmäßig zugewiesen und können nicht geändert werden. Wenn Sie "B" drücken, wird eine Kaufposition eröffnet, wenn Sie die Umschalttaste gedrückt halten und "B" drücken, wird ein schwebender Kauf-Stop-Auftrag gesetzt. Wenn Sie gleichzeitig die Tasten Strg und Shift gedrückt halten und die Taste B drücken, wird ein schwebender Kauf-Limit-Auftrag erteilt. Dasselbe gilt für das Verkaufen - ein einfaches Drücken von "S" eröffnet eine Verkaufsposition, während ein Gedrückthalten der Steuerungstasten zum Setzen eines Verkaufsstopps und eines Verkaufslimits führt. Das Schließen aller offenen Positionen erfolgt durch Drücken der Schaltfläche "X". Wenn Sie die Umschalttaste oder Strg+Umschalttaste (spielt keine Rolle) gedrückt halten und "X" drücken, werden alle schwebenden Aufträge gelöscht.

//+------------------------------------------------------------------+
//|                                      TestMqlTradeTransaction.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input double   InpLots        =  0.1;     /* Lots                       */ // Requested volume
input int      InpMagic       =  1024;    /* Magic number               */ // EA ID
input int      InpDistance    =  300;     /* Orders placement distance  */ // Distance for setting pending orders
input uint     InpDeviation   =  5;       /* Price deviation            */ // Allowed deviation from the price
input string   InpKeyBuy      =  "B";     /* Key to open Buy            */ // Key to open a Buy position (with Shift - Stop, with Ctrl+Shift - Limit)
input string   InpKeySell     =  "S";     /* Key to open Sell           */ // Key to open Sell (with Shift - Stop, with Ctrl+Shift - Limit)
input string   InpKeyClose    =  "X";     /* Key to close/delete        */ // Key for closing a position (without control keys) or deleting an order (with Shift or Shift+Ctrl)
//--- Global variables
ushort         key_buy;                   // Key to send a buy order 
ushort         key_sell;                  // Key to send a sell order
ushort         key_close;                 // Key to close or delete
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Convert the text assigned to Buy to uppercase and get the code of the first character
   string tmp=InpKeyBuy;
   tmp.Upper();
   key_buy=StringGetCharacter(tmp,0);
//--- Convert the text assigned to Sell to uppercase and get the code of the first character
   tmp=InpKeySell;
   tmp.Upper();
   key_sell=StringGetCharacter(tmp,0);
//--- Convert the text assigned to Close to uppercase and get the code of the first character
   tmp=InpKeyClose;
   tmp.Upper();
   key_close=StringGetCharacter(tmp,0);

//--- If the keys assigned to Buy and Sell match, report this and exit with an error
   if(key_sell==key_buy)
     {
      PrintFormat("The key assigned to Sell ('%c') is the same as the key assigned to Buy ('%c')",key_sell,key_buy);
      return INIT_PARAMETERS_INCORRECT;
     }
//--- If the keys assigned to Close and Buy match, report this and exit with an error
   if(key_close==key_buy)
     {
      PrintFormat("The key assigned to Close ('%c') is the same as the key assigned to Buy ('%c')",key_close,key_buy);
      return INIT_PARAMETERS_INCORRECT;
     }
//--- If the keys assigned to Close and Sell match, report this and exit with an error
   if(key_close==key_sell)
     {
      PrintFormat("The key assigned to Close ('%c') is the same as the key assigned to Sell ('%c')",key_close,key_sell);
      return INIT_PARAMETERS_INCORRECT;
     }
//--- Successful initialization. Display the assigned keys in the journal and return successful execution
   string kb="Key assigned to Buy: ";
   string ks="Key assigned to Sell: ";
   string kc="Key assigned to Close: ";
   PrintFormat("%-23s%c (key code %lu)\n%-23s%c (key code %lu)\n%-23s%c (key code %lu)",kb,key_buy,key_buy,ks,key_sell,key_sell,kc,key_close,key_close);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- If a key is pressed
   if(id==CHARTEVENT_KEYDOWN)
     {
      //--- If neither Ctrl nor Shift are held 
      if(!IsCtrlKeyPressed() && !IsShiftKeyPressed())
        {
         //--- If the button is assigned to the Buy position, open Buy
         if(lparam==key_buy)
            OpenBuy(NULL,InpLots,InpMagic,InpDeviation,"TestMqlTradeTransaction");
         //--- If the button is assigned to the Sell position, open Sell
         if(lparam==key_sell)
            OpenSell(NULL,InpLots,InpMagic,InpDeviation,"TestMqlTradeTransaction");
         //--- If the button is assigned to closing positions, close all positions 
         if(lparam==key_close)
            ClosePositionsAll(Symbol());
        }
      //--- If only Shift is held 
      if(IsShiftKeyPressed() && !IsCtrlKeyPressed())
        {
         //--- If the button is assigned to Buy order, open Buy Stop order
         if(lparam==key_buy)
            SetBuyStop(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction");
         //--- If the button is assigned to Sell order, open Sell Stop order
         if(lparam==key_sell)
            SetSellSellStop(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction");
         //--- If the button is assigned to delete orders, delete all orders 
         if(lparam==key_close)
            DeleteOrdersAll(NULL);
        }
         //--- If Shift is held together with Ctrl
      if(IsShiftKeyPressed() && IsCtrlKeyPressed())
        {
         //--- If the button is assigned to Buy order, open Buy Limit order
         if(lparam==key_buy)
            SetBuyLimit(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction");
         //--- If the button is assigned to Sell order, open Sell Limit order
         if(lparam==key_sell)
            SetSellLimit(NULL,InpLots,InpMagic,InpDistance,"TestMqlTradeTransaction");
         //--- If the button is assigned to delete orders, delete all orders 
         if(lparam==key_close)
            DeleteOrdersAll(Symbol());
        }
     }
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
//--- Set all incoming trade transactions to the journal
   TradeTransactionInformer(trans,request,result,18,2,true);
  }

Das Platzieren von Aufträgen und das Eröffnen von Positionen wird in der Ereignisbehandlung von OnChartEvent() des EA implementiert. In OnTradeTransaction() wird die oben genannte Funktion TradeTransactionInformer() aufgerufen. Es wird jede eingehende Transaktion im Journal eingetragen. Der EA verwendet alle in diesem Artikel besprochenen Funktionen in seiner Arbeit, daher sollten sie in der EA-Datei enthalten sein, damit sie fehlerfrei kompiliert werden können.

Wenn Sie einen BuyLimit-Auftrag erteilen, werden die folgenden Einträge aller verarbeiteten Transaktionen im Journal angezeigt:

Transaction Type: Order add (Adding a new open order)
  Order:            1838106218
  Symbol:           EURUSD
  Order type:       Buy Limit (Buy Limit pending order)
  Order state:      Started (Order checked, but not yet accepted by broker)
  Time type:        Time GTC (Good till cancel order)
  Price:            1.09449
  Price SL:         0.0
  Price TP:         0.0
  Volume:           0.10
Transaction Type: Order update (Updating an open order)
  Order:            1838106218
  Symbol:           EURUSD
  Order type:       Buy Limit (Buy Limit pending order)
  Order state:      Placed (Order accepted)
  Time type:        Time GTC (Good till cancel order)
  Price:            1.09449
  Price SL:         0.0
  Price TP:         0.0
  Volume:           0.10
Transaction Type: Request (The trade request has been processed by a server and processing result has been received)
  The second and third parameters of OnTradeTransaction function (request and result) must be analyzed for additional data:
Request Pending (Place a trade order for the execution under specified conditions (pending order)):
  Symbol:           EURUSD
  Volume:           0.10
  Price:            1.09449
  SL:               0.0
  TP:               0.0
  Type:             Buy Limit (Buy Limit pending order)
  Type filling:     Return (In case of partial filling, an order with remaining volume is not canceled but processed further)
  Type time:        Time GTC (Good till cancel order)
  Expiration:       0
  Magic:            1024
  Comment:          TestMqlTradeTransaction
OrderSend result:
  Retcode:          10009 DONE (Request completed)
  Deal:             0
  Order:            1838106218
  Volume:           0.10
  Price:            0.0
  Bid:              0.0
  Ask:              0.0
  Comment:          
  Request ID:       930808478
  Retcode External: 0

Bei der nachträglichen Löschung eines erteilten Auftrags erhalten wir folgende Einträge im Terminaljournal:

Transaction Type: Order update (Updating an open order)
  Order:            1838106218
  Symbol:           EURUSD
  Order type:       Buy Limit (Buy Limit pending order)
  Order state:      Request cancel (Order is being deleted (deleting from the trading system))
  Time type:        Time GTC (Good till cancel order)
  Price:            1.09449
  Price SL:         0.0
  Price TP:         0.0
  Volume:           0.10
Transaction Type: Order delete (Removing an order from the list of the open ones)
  Order:            1838106218
  Symbol:           EURUSD
  Order type:       Buy Limit (Buy Limit pending order)
  Order state:      Canceled (Order canceled by client)
  Time type:        Time GTC (Good till cancel order)
  Price:            1.09449
  Price SL:         0.0
  Price TP:         0.0
  Volume:           0.10
Transaction Type: History add (Adding an order to the history as a result of execution or cancellation)
  Order:            1838106218
  Symbol:           EURUSD
  Order type:       Buy Limit (Buy Limit pending order)
  Order state:      Canceled (Order canceled by client)
  Time type:        Time GTC (Good till cancel order)
  Price:            1.09449
  Price SL:         0.0
  Price TP:         0.0
  Volume:           0.10
Transaction Type: Request (The trade request has been processed by a server and processing result has been received)
  The second and third parameters of OnTradeTransaction function (request and result) must be analyzed for additional data:
Request Remove (Delete the pending order placed previously):
  Order:            1838106218
OrderSend result:
  Retcode:          10009 DONE (Request completed)
  Deal:             0
  Order:            1838106218
  Volume:           0.00
  Price:            0.0
  Bid:              0.0
  Ask:              0.0
  Comment:          
  Request ID:       930808479
  Retcode External: 0


Schlussfolgerung

Wir haben alle Strukturen für die Erstellung eines Handelsauftrags, seine Prüfung und seine Übermittlung an den Server berücksichtigt und eine vollständige Beschreibung aller Handelsvorgänge auf dem Konto als Ergebnis der Handelsoperationen erhalten.

Alle vorgeschlagenen Funktionen können „so wie sie sind“ verwendet werden. Sie können sie aber auch so abändern, dass sie Ihren Vorstellungen von ihrer Verwendung entsprechen.

Die EA-Datei mit allen in diesem Artikel behandelten Funktionen ist im Anhang enthalten. Sie können es herunterladen und alles selbst testen.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/13052

Beigefügte Dateien |
Kategorientheorie in MQL5 (Teil 20): Ein Abstecher über die Selbstaufmerksamkeit (Self-Attention) und den Transformer Kategorientheorie in MQL5 (Teil 20): Ein Abstecher über die Selbstaufmerksamkeit (Self-Attention) und den Transformer
Wir schweifen in unserer Serie ab, indem wir über einen Teil des Algorithmus zu chatGPT nachdenken. Gibt es Ähnlichkeiten oder Konzepte, die den natürlichen Transformationen entlehnt sind? Wir versuchen, diese und andere Fragen in einem unterhaltsamen Stück zu beantworten, mit unserem Code in einem Signalklassenformat.
Kategorientheorie in MQL5 (Teil 19): Induktion natürlicher Quadrate Kategorientheorie in MQL5 (Teil 19): Induktion natürlicher Quadrate
Wir setzen unseren Blick auf natürliche Transformationen fort, indem wir die Induktion natürlicher Quadrate besprechen. Leichte Einschränkungen bei der Implementierung von Mehrfachwährungen für Experten, die mit dem MQL5-Assistenten zusammengestellt wurden, bedeuten, dass wir unsere Fähigkeiten zur Datenklassifizierung mit einem Skript demonstrieren. Die wichtigsten Anwendungen sind die Klassifizierung von Preisänderungen und damit deren Vorhersage.
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!
Entwicklung eines Replay Systems — Marktsimulation (Teil 15): Die Geburt des SIMULATORS (V) - RANDOM WALK Entwicklung eines Replay Systems — Marktsimulation (Teil 15): Die Geburt des SIMULATORS (V) - RANDOM WALK
In diesem Artikel werden wir die Entwicklung eines Simulators für unser System abschließen. Das Hauptziel besteht darin, den im vorherigen Artikel beschriebenen Algorithmus zu konfigurieren. Dieser Algorithmus zielt darauf ab, eine zufällige Bewegung, einen „RANDOM WALK“ zu erzeugen. Um das heutige Material zu verstehen, ist es daher notwendig, den Inhalt der früheren Artikel zu kennen. Wenn Sie die Entwicklung des Simulators nicht verfolgt haben, empfehle ich Ihnen, diese Sequenz von Anfang an zu lesen. Andernfalls könnten Sie verwirrt sein über das, was hier erklärt wird.