OrderSend

Die Funktion OrderSend() wird für die Durchführung von Handelsoperationen durch das Senden von Anfragen an einen Handelsserver verwendet.

bool  OrderSend(
   MqlTradeRequest&  request      // Struktur einer Anfrage 
   MqlTradeResult&   result       // Struktur einer Antwort 
   );

Parameter

request

[in] Pointer auf eine Struktur vom Typ MqlTradeRequest, die die Aktion des Kunden beschreibt.

result

[in,out] Pointer auf eine Struktur vom Typ MqlTradeResult, die das Ergebnis einer Handelsoperation beschreibt, wenn diese erfolgreich durchgeführt wurde (wenn true zurückgegeben wurde).

Rückgabewert

Wenn die Basisprüfung der Strukturen erfolgreich war (Prüfung der Indexe), wird true zurückgegeben - das heißt allerdings nicht, dass eine Handelsoperation erfolgreich durchgeführt wurde. Um eine ausführliche Beschreibung des Ergebnisses der Funktion zu bekommen, sollte man die Felder der Struktur result analysieren.

Hinweis

Eine Handelsanfrage durchläuft mehrere Stufen der Prüfungen auf dem Handelsserver. Zunächst wird überprüft, ob alle benötigten Felder des Parameters request korrekt ausgefüllt werden. Wenn es keine Fehler gibt, akzeptiert der Server die Order für die weitere Verarbeitung. Wird die Order erfolgreich vom Handelsserver akzeptiert, gibt die Funktion OrderSend() den Wert true zurück.

Es ist empfehlenswert, die Anfrage vor dem Senden an den Handelsserver selbständig zu überprüfen. Um die Anfrage zu überprüfen, verwenden Sie die Funktion OrderCheck(). Sie prüft, ob es genügend Geld für die Ausführung der Transaktion gibt und gibt viele nützliche Parameter in den Ergebnissen der Prüfung der Handelsanfrage zurück:

  • Rückgabecode, der über Fehler in der zu prüfenden Anfrage informiert;
  • Kontostand nach der Ausführung der Handelsoperation;
  • Equity nach der Ausführung der Handelsoperation;
  • Floating Profit nach der Ausführung der Handelsoperation;
  • Margin, die für die Handelsoperation erforderlich ist;
  • Freie Eigenmittel, die nach Ausführung der Handelsoperation bleiben;
  • Level der Margin, der nach der Ausführung der Handelsoperation gesetzt wird;
  • Kommentar zum Antwort-Code, Beschreibung des Fehlers.

Beim Senden einer Marktorder (MqlTradeRequest.action=TRADE_ACTION_DEAL) bedeutet das erfolgreiche Ergebnis der Funktion OrderSend() nicht, dass die Order ausgeführt wurde (die entsprechenden Trades ausgeführt wurden). In diesem Fall bedeutet true nur, dass die Order im Handelssystem erfolgreich platziert wurde. Der Handelsserver kann die Felder deal oder order in der Struktur des Ergebnisses result ausfüllen, wenn diese Werte im Moment der Erzeugung einer Antwort auf einen Aufruf von OrderSend() bekannt sein werden. Im allgemeinen Fall kann das Ereignis oder die Ereignisse der Ausführung von Trades, die einer Order entsprechen, bereits nach dem Senden einer Antwort auf den Aufruf von OrderSend() eintreten. Deswegen muss man beim Erhalten des Ergebnisses der Ausführung von OrderSend() in erster Linie den Rückgabecode des Handelsservers retcode und den Antwort-Code des externen Handelssystems retcode_external (wenn nötig) überprüfen, die in der Struktur result verfügbar sind.

Jede akzeptierte Order wird während des Wartens auf die Verarbeitung auf dem Handelsserver gespeichert, bis eine der Bedingungen für ihre Ausführung erfüllt wird:

  • Ablaufzeit,
  • Erscheinen einer entgegengesetzten Anfrage,
  • Auslösung der Order beim Erscheinen des Ausführungspreises,
  • Eintreffen einer Anfrage, die Order zu löschen.

Zum Zeitpunkt der Orderbearbeitung sendet der Handelsserver eine Meldung an das Terminal über das Auftreten des Handelsereignisses Trade, das mit der Funktion OnTrade() verarbeitet werden kann.

Das Ergebnis der Ausführung der Handelsanfrage, die mit der Funktion OrderSend() gesendet wurde, kann mithilfe des Handlers OnTradeTransaction auf dem Server verfolgt werden. Dabei ist es zu beachten, dass der Handler OnTradeTransaction infolge der Ausführung einer Handelsanfrage mehrmals aufgerufen wird.

Zum Beispiel, beim Senden einer Market Buy Order wird sie verarbeitet, und eine entsprechende Kauforder wird für das Konto erstellt. Die Order wird ausgeführt, von der Liste der offenen entfernt und der Orderhistorie hinzugefügt. Dann wird der entsprechende Abschluss der Historie hinzugefügt und eine neue Position wird eröffnet. Für jedes dieser Ereignisse wird die Funktion OnTradeTransaction aufgerufen.

Beispiel:

//--- Werte für ORDER_MAGIC
input long order_magic=55555;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
 { 
//--- stell sicher, dass es ein Demokonto ist
   if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
     { 
      Alert("Ausführung des Scripts auf einem Realkonto verboten!");
      return;
     }
//--- platziere oder lösche eine Order
   if(GetOrdersTotalByMagic(order_magic)==0) 
     { 
      //--- wenn es keine aktuellen Orders gibt, platziere eine Order 
      uint res=SendRandomPendingOrder(order_magic);
      Print("Rückgabewert des Handelsservers ",res);
     }
   else // wenn es die Orders gibt, lösche diese 
     { 
      DeleteAllOrdersByMagic(order_magic);
     }
//---
 }
//+--------------------------------------------------------------------+
//|Erhält die aktuelle Anzahl der Orders mit der angegebenen ORDER_MAGIC 
//+--------------------------------------------------------------------+
int GetOrdersTotalByMagic(long const magic_number)
  { 
   ulong order_ticket;
   int total=0;
//--- durchlaufe alle Pending Orders
   for(int i=0;i<OrdersTotal();i++)
      if((order_ticket=OrderGetTicket(i))>0)
         if(magic_number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
   return(total);
  }
//+---------------------------------------------------------------------+
//| Entfernt alle Pending Orders mit der angegebenen ORDER_MAGIC        |
//+---------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
  { 
   ulong order_ticket;
//--- durchlaufe alle Pending Orders  
   for(int i=0;i<OrdersTotal();i++)
      if((order_ticket=OrderGetTicket(i))>0)
         //--- Order mit der entsprechenden ORDER_MAGIC
         if(magic_number==OrderGetInteger(ORDER_MAGIC))
           { 
            MqlTradeResult result={0};
            MqlTradeRequest request={0};
            request.order=order_ticket;
            request.action=TRADE_ACTION_REMOVE;
            OrderSend(request,result);
            //--- Antwort des Servers im Journal ausgeben 
            Print(__FUNCTION__,":",result.comment,"Antwortcode",result.retcode);
           }
//---
  }
//+------------------------------------------------------------------+
//| Platziere eine Pending Order auf zufällige Weise                 |
//+------------------------------------------------------------------+
uint SendRandomPendingOrder(long const magic_number)
 { 
//--- bereite eine Anfrage vor
   MqlTradeRequest request={0};
   request.action=TRADE_ACTION_PENDING;         // Platzieren einer Pending Order 
   request.magic=magic_number;                  // ORDER_MAGIC
   request.symbol=_Symbol;                      // Instrument
   request.volume=0.1;                          // Volumen von 0.1 Lot
   request.sl=0;                                // Stop Loss nicht angegeben 
   request.tp=0;                                // Take Profit nicht angegeben     
//--- bilde den Ordertyp
   request.type=GetRandomType();                // Ordertyp
//--- bilde den Preis für die Pending Order
   request.price=GetRandomPrice(request.type);  // Eroeffnungspreis 
//--- sende eine Handelsanfrage
   MqlTradeResult result={0};
   OrderSend(request,result);
//--- die Antwort des Servers im Journal ausgeben  
   Print(__FUNCTION__,":",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- den Antwort-Code des Handelsservers zurückgeben
   return result.retcode;
  }
//+------------------------------------------------------------------+
//| Erhält den Typ einer Pending Order auf zufällige Weise           |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE GetRandomType()
 { 
   int t=MathRand()%4;
//---   0<=t<4
   switch(t)
    { 
      case(0):return(ORDER_TYPE_BUY_LIMIT);
      case(1):return(ORDER_TYPE_SELL_LIMIT);
      case(2):return(ORDER_TYPE_BUY_STOP);
      case(3):return(ORDER_TYPE_SELL_STOP);
     }
//--- ungültiger Wert
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Erhält den Preis auf zufällige Weise                             |
//+------------------------------------------------------------------+
double GetRandomPrice(ENUM_ORDER_TYPE type)
 { 
   int t=(int)type;
//--- Stoplevel für Symbol 
   int distance=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
//--- erhalte Daten des letzten Ticks
   MqlTick last_tick={0};
   SymbolInfoTick(_Symbol,last_tick);
//--- berechne den Preis entsprechend dem Typ
   double price;
   if(t==2 || t==5) // ORDER_TYPE_BUY_LIMIT oder ORDER_TYPE_SELL_STOP
    { 
      price=last_tick.bid; // gehen wir vom Preis Bid aus
      price=price-(distance+(MathRand()%10)*5)*_Point;
     }
   else             // ORDER_TYPE_SELL_LIMIT oder ORDER_TYPE_BUY_STOP
    { 
      price=last_tick.ask; // gehen wir vom Preis Ask aus
      price=price+(distance+(MathRand()%10)*5)*_Point;
     }
//--- 
   return(price);
  }

Sehen Sie auch

Typen der Handelsoperationen, Struktur der Handelsanfrage, Struktur des Ergebnisses einer Handelsanfrage