Struktur der Handelstransaktion (MqlTradeTransaction)

Als Ergebnis der Durchführung von bestimmten Aktionen auf dem Handelskonto, ändert sich der Kontostand. Zu solchen Aktionen gehören:

  • Senden der Handelsanfrage aus einer beliebigen MQL5-Anwendung in dem Client-Terminal mittels der Funktionen OrderSend und OrderSendAsync und ihre nachfolgende Ausführung;
  • Senden der Handelsanfrage über die grafische Oberfläche des Terminals und ihre nachfolgende Ausführung;
  • Auslösen von aufgeschobenen Ordern und Stop-Ordern auf dem Server;
  • Ausführen von Operationen auf der Seite der Handel-Server.

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

  • Die Verarbeitung der Handelsanfrage;
  • Änderung der offenen Aufträge;
  • Änderung der Ordergeschichte;
  • Änderung der Dealgeschichte;
  • Änderung der Position.

Zum Beispiel, beim Senden Marktkauforder, wird Marktkauforder behandelt und eine entsprechende Marktkauforder für das Konto erstellt. Ist die Order ausgeführt, wird sie aus der Auftragsliste entfernt und zur Ordergeschichte hinzugefügt. Dann wird der entsprechende Deal zur Geschichte hinzugefügt und eine neue Position wird erstellt. Alle diese Aktionen sind Handelstransaktionen.

Um die auf das Konto angewendeten Handelstransaktionen zu erhalten, ist der spezielle Handler OnTradeTransaction im MQL5 vorgesehen. In den ersten Parameter wird die Struktur MqlTradeTransaction übergeben, die Handelstransaktionen beschreibt.

struct MqlTradeTransaction
  {
   ulong                         deal;             // Ticket des Deals
   ulong                         order;            // Ticket der Order
   string                        symbol;           // Name des Handelsinstrumentes
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Typ der Handelstransaktion
   ENUM_ORDER_TYPE               order_type;       // Typ der Order
   ENUM_ORDER_STATE              order_state;      // Zustand der Order
   ENUM_DEAL_TYPE                deal_type;        // Typ des Deals
   ENUM_ORDER_TYPE_TIME          time_type;        // Typ der Order nach der Zeit der Aktion
   datetime                      time_expiration;  // Ablaufzeit der Order
   double                        price;            // Preis 
   double                        price_trigger;    // Aktivierungspreis von Stop-Limit-Order
   double                        price_sl;         // Stop Loss Ebene
   double                        price_tp;         // Take Profit Ebene
   double                        volume;           // Volumen in Lots
   ulong                         position;         // Position ticket
   ulong                         position_by;      // Ticket of an opposite position
  };

Felder Beschreibung

Feld

Beschreibung

deal

Ticket des Deals

order

Ticket der Order

symbol

Name des Handelsinstrumente, nach dem die Transaktion durchgeführt wurde.

type

Typ der Handelstransaktion Der Wert kann einer der Enumerationswerte ENUM_TRADE_TRANSACTION_TYPE sein.

order_type

Typ der Handelsorder. Der Wert kann einer der Enumerationswerte ENUM_ORDER_TYPE sein.

order_state

Zustand der Handelsorder. Der Wert kann einer der Enumerationswerte ENUM_ORDER_STATE sein.

deal_type

Typ des Deals. Der Wert kann einer der Enumerationswerte ENUM_DEAL_TYPE sein.

time_type

Typ der Order nach Ablauf. Der Wert kann einer der Enumerationswerte ENUM_ORDER_TYPE_TIME sein.

time_expiration

Ablaufzeit der aufgeschobenen Order (für die Order von Typ ORDER_TIME_SPECIFIED und ORDER_TIME_SPECIFIED_DAY).

price

Preis. Je nach Typ der Handelstransaktion kann es ein Preis von einer Order, eines Deals oder einer Position sein.

price_trigger

Stop-Kurs (Aktivierungspreis) von Stop-Limit-Order (ORDER_TYPE_BUY_STOP_LIMIT und ORDER_TYPE_SELL_STOP_LIMIT).

price_sl

Stop Loss Preis. Je nach Typ der Handelstransaktion kann es sich auf eine Order, einen Deal oder eine Position beziehen.

price_tp

Take Profit Preis. Je nach Typ der Handelstransaktion kann es sich auf eine Order, einen Deal oder eine Position beziehen.

volume

Volumen in Lots. Je nach Typ der Handelstransaktion kann es das aktuelle Volumen von einer Order, einem Deal oder einer Position zeigen.

position

Das Ticket der Position, die die Transaktion beeinflußt hat.

position_by

Das Ticket der Gegenposition. Wird beim Schließen einer Position zur Gegenposition verwendet, die auf demselben Symbol, aber in einer entgegengesetzten Richtung eröffnet wurde.

Der bestimmende Parameter für die Analyse der empfangenen Transaktion ist sein Typ, der ins Feld type übergeben wird. Zum Beispiel, wenn eine Transaktion der Typ TRADE_TRANSACTION_REQUEST (das Ergebnis der Bearbeitung der Handelsanforderung vom Server ist erhalten) ist, hat die Struktur nur ein ausgefülltes Feld type. Die anderen Felder müssen nicht analysiert werden. In diesem Fall kann man zwei zusätzliche Parameter request und result analysieren, die an den Handler OnTradeTransaction() übergeben werden, wie im Beispiel unten gezeigt.

Wenn Sie den Typ der Handelsoperation wissen, können Sie über eine Analyse des aktuellen Zustandes von Ordern, Positionen und Deals auf dem Handelskonto entscheiden. Es ist zu beachten, dass eine Handelsanforderung, die aus dem Terminal an den Server gesendet wird, mehrere Handelstransaktionen auslösen kann, deren Reihenfolge des Eingangs ins Terminal nicht gewährleistet wird.

Die Struktur MqlTradeTransaction wird auf unterschiedlicher Weise je nach Typ der Handelstransaktion (ENUM_TRADE_TRANSACTION_TYPE) ausgefüllt:

TRADE_TRANSACTION_ORDER_* und TRADE_TRANSACTION_HISTORY_*

Für die Handelstransaktionen betreffend die Bearbeitung der offenen Ordern (TRADE_TRANSACTION_ORDER_ADD, TRADE_TRANSACTION_ORDER_UPDATE und TRADE_TRANSACTION_ORDER_DELETE) und der Ordergeschichte (TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_HISTORY_UPDATE, TRADE_TRANSACTION_HISTORY_DELETE), werden in der Struktur MqlTradeTransaction die folgenden Felder ausgefüllt:

  • order - Ticket der Order;
  • symbol - Name eines Finanzinstrumentes in der Order;
  • type - Typ der Handelstransaktion;
  • order_type - Typ der Order;
  • orders_state - aktueller Zustand der Order;
  • time_type - Typ des Ablaufs der Order;
  • time_expiration - Ablaufzeit der Order (für die Ordern mit dem Typ des Ablaufs von ORDER_TIME_SPECIFIED und ORDER_TIME_SPECIFIED_DAY);
  • price - Preis in der Order, der von einem Kunden angegeben ist;
  • price_trigger - Stop-Kurs des Auslösens von Stop-Limit-Order (nur für ORDER_TYPE_BUY_STOP_LIMIT und ORDER_TYPE_SELL_STOP_LIMIT);
  • price_sl - Stop Loss der Order (wird ausgefüllt, wenn in der Order angegeben ist);
  • price_tp - Take Profit Preis der Order (wird ausgefüllt, wenn in der Order angegeben ist);
  • volume - aktuelles Volumen der Order (nicht ausgeführt). Anfangsvolumen der Order kann man in der Ordergeschichte mit Hilfe der Funktion HistoryOrders* finden.
  • position - das Ticket der Position, die durch die Ausführung einer Order eröffnet, modifiziert oder geschlossen wurde. Das Feld ist nur für Marktorders auszufüllen. Für TRADE_TRANSACTION_ORDER_ADD wird das Feld nicht ausgefüllt.
  • position_by - das Ticket der Gegenposition. Ist nur für die Orders auszufüllen, die eine Position zur Gegenposition schließen (close by).

TRADE_TRANSACTION_DEAL_*

Für die Handelstransaktionen betreffend die Bearbeitung des Deals (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE und TRADE_TRANSACTION_DEAL_DELETE), werden in der Struktur MqlTradeTransaction die folgenden Felder ausgefüllt:

  • deal - Ticket des Deals;
  • order - Ticket der Order, auf dessen Grundlage der Deal abgeschlossen wurde;
  • symbol - Name eines Finanzinstrumentes im Deal;
  • type - Typ der Handelstransaktion;
  • deal_type - Typ des Deals;
  • price - Preis, zu dem einen Deal abgeschlossen wurde;
  • price_sl - Stop Loss Preis ( wird ausgefüllt, wenn in der Order angegeben ist, auf dessen Grundlage der Deal abgeschlossen wurde);
  • price_tp - Take Profit Preis (wird ausgefüllt, wenn in der Order angegeben ist, auf dessen Grundlage der Deal abgeschlossen wurde);
  • volume - Volumen des Deals in Lots.
  • position - das Ticket der Position, die durch die Ausführung einer Order eröffnet, modifiziert oder geschlossen wurde.
  • position_by - das Ticket der Gegenposition. Nur für die Trades auszufüllen, die eine Position zur Gegenposition schließen (out by).

TRADE_TRANSACTION_POSITION

Für die Handelstransaktionen betreffend die Änderungen von Positionen, die mit der Ausführung des Deals nicht verbunden sind (TRADE_TRANSACTION_POSITION), werden in der Struktur MqlTradeTransaction die folgenden Felder ausgefüllt:

  • symbol - Name eines Finanzinstrumentes der Position;
  • type - Typ der Handelstransaktion;
  • deal_type - Typ der Position (DEAL_TYPE_BUY oder DEAL_TYPE_SELL);
  • price - gewogener Durchschnittskurs der Eröffnung von Position;
  • price_sl - Stop Loss Preis;
  • price_tp - Take Profit Preis;
  • volume - Volumen der Position in Lots, wenn es geändert wurde.
  • position - das Ticket der Position.

Änderung der Position (Hinzufügen, Änderung oder Liquidation) als Ergebnis des Abschlusses des Deals zieht kein Erscheinen der Transaktion TRADE_TRANSACTION_POSITION nach sich.

TRADE_TRANSACTION_REQUEST

Nur ein Feld wird in der Struktur MqlTradeTransaction für die Handelstransaktionen ausgefüllt, die die Tatsache beschreiben, dass die Handelsanfrage vom Server bearbeitet ist und das Ergebnis seiner Bearbeitung empfangen ist (TRADE_TRANSACTION_REQUEST):

  • type - Typ der Handelstransaktion;

Für Transaktionen dieses Typs muss nur type Feld (Typ der Handelstransaktion) analysiert werden. Für zusätzliche Informationen muss man die zweiten und dritten Parameter der Funktion OnTradeTransaction (request und result) analysieren.

Beispiel:

input int MagicNumber=1234567;
 
//--- die Klasse CTrade einfügen und die Variable deklarieren
#include <Trade\Trade.mqh>
CTrade trade;
//--- Flags für das Platzieren und Löschen einer Pending Order
bool pending_done=false;
bool pending_deleted=false;
//--- das Ticket der Pending Order hier speichern
ulong order_ticket;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- setzen wir eine MagicNumber, mit deren alle unsere Orders markiert werden
   trade.SetExpertMagicNumber(MagicNumber);
//--- Trade Requests werden im asynchronen Modus mithilfe der Funktion OrderSendAsync() gesendet
   trade.SetAsyncMode(true);
//--- die Variable mit Null initialisieren
   order_ticket=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Pending Order platzieren
   if(!pending_done)
     {
      double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
      bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
      //--- wenn die Funktion BuyStop() erfolgreich war
      if(res)
        {
         pending_done=true;
         //--- das Ergebnis der Anfrage aus ctrade erhalten
         MqlTradeResult trade_result;
         trade.Result(trade_result);
         //--- request_id für die gesendete Anfrage erhalten
         uint request_id=trade_result.request_id;
         Print("Anfrage zum Platzieren einer Pending Order gesendet. Identifikator der Anfrage Request_ID=",request_id);
         //--- das Ticket der Order speichern (im asynchronen Modus in CTrade gleich Null)
         order_ticket=trade_result.order;
         //--- alles erledigt, OnTick() vorzeitig verlassen
         return;
        }
     }
//--- Pending Order löschen
   if(!pending_deleted)
      //--- zusätzliche Überprüfung
      if(pending_done && (order_ticket!=0))
        {
         //--- versuchen, eine Pending Order zu löschen
         bool res=trade.OrderDelete(order_ticket);
         Print("OrderDelete=",res);
         //--- beim erfolgreichen Senden der Löschanfrage
         if(res)
           {
            pending_deleted=true;
            //--- das Ergebnis der Ausführung der Anfrage erhalten
            MqlTradeResult trade_result;
            trade.Result(trade_result);
            //--- den Identifikator dem dem Ergebnis der Anfrage entnehmen
            uint request_id=trade_result.request_id;
            //--- im Journal anzeigen
            Print("Löschanfrage für die Order #",order_ticket, gesendet
                  ". Der Identifikator der Anfrage Request_ID=",request_id,
                  "\r\n");
            //--- das Ticket der Order aus dem Ergebnis der Anfrage schreiben
            order_ticket=trade_result.order;
           }
        }
//---        
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- den Typ der Transaktion als einen Wert der Aufzählung erhalten
   ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
//--- wenn die Transaktion das Ergebnis der Anfrage darstellt, nur ihren Namen anzeigen
   if(type==TRADE_TRANSACTION_REQUEST)
     {
      Print(EnumToString(type));
      //--- die Beschreibung der bearbeiteten Anfrage anzeigen
      Print("------------RequestDescription\r\n",RequestDescription(request));
      //--- die Beschreibung des Ergebnisses der Anfrage anzeigen
      Print("------------ResultDescription\r\n",TradeResultDescription(result));
      //--- das Ticket der Order speichern, um diese bei der nächsten Bearbeitung in OnTick() zu löschen
      if(result.order!=0)
        {
         //--- die Order beim nächsten Aufruf von OnTick() nach dem Ticket löschen
         order_ticket=result.order;
         Print(" Ticket der Pending Order ",order_ticket,"\r\n");
        }
     }
   else // für Transaktionen von einem anderen Typ eine vollständige Beschreibung anzeigen
//--- die Beschreibung der Transaktion im Journal anzeigen
      Print("------------TransactionDescription\r\n",TransactionDescription(trans));
 
//---     
  }
//+------------------------------------------------------------------+
//| Gibt eine textuelle Beschreibung der Transaktion zurück                       |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
  {
//--- 
   string desc=EnumToString(trans.type)+"\r\n";
   desc+="Symbol: "+trans.symbol+"\r\n";
   desc+="Deal ticket: "+(string)trans.deal+"\r\n";
   desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
   desc+="Order ticket: "+(string)trans.order+"\r\n";
   desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
   desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
   desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
   desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
   desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
   desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
   desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
   desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
   desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
   desc+="Position: "+(string)trans.position+"\r\n";
   desc+="Position by: "+(string)trans.position_by+"\r\n";
//--- den erhaltenen String zurückgeben
   return desc;
  }
//+------------------------------------------------------------------+
//| Gibt die textuelle Beschreibung der Handelsanfrage zurück                  |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
  {
//---
   string desc=EnumToString(request.action)+"\r\n";
   desc+="Symbol: "+request.symbol+"\r\n";
   desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
   desc+="Order ticket: "+(string)request.order+"\r\n";
   desc+="Order type: "+EnumToString(request.type)+"\r\n";
   desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
   desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
   desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
   desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
   desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
   desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
   desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
   desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
   desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
   desc+="Comment: "+request.comment+"\r\n";
//--- den erhaltenen String zurückgeben
   return desc;
  }
//+------------------------------------------------------------------+
//| Gibt die textuelle Beschreibung der bearbeiteten Anfrage zurück     |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
  {
//---
   string desc="Retcode "+(string)result.retcode+"\r\n";
   desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
   desc+="Order ticket: "+(string)result.order+"\r\n";
   desc+="Deal ticket: "+(string)result.deal+"\r\n";
   desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
   desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
   desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
   desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
   desc+="Comment: "+result.comment+"\r\n";
//--- den erhaltenen String zurückgeben
   return desc;
  }

Sehen Sie auch

Typen der Handelstransaktionen, OnTradeTransaction