OrderSend

OrderSend() viene utilizzato per l'esecuzione di operazioni di trade inviando richieste al trade server .

bool  OrderSend(
   MqlTradeRequest&  request,      // struttura della query
   MqlTradeResult&   result        // struttura della risposta
   );

Parametri

request

[in] Puntatore ad una struttura di tipo MqlTradeRequest descrivente l'attività di trade del client.

result

[in, out] Puntatore ad una struttura di tipo MqlTradeResult che descrive il risultato dell' operazione di trade in caso di completamento (se viene restituito true).

Valore restituito

In caso di un controllo di base di successo delle strutture (controllo index) restituisce true. Tuttavia, questo non è segno di esecuzione di un'operazione di trade avvenuta con successo. Per una descrizione più dettagliata del risultato dell'esecuzione della funzione, analizzare i campi della struttura result .

Nota

Le richieste di trade passano attraverso diverse fasi di verifica su un trade server. Prima di tutto, controlla se tutti i campi richiesti del parametro request vengono compilati correttamente. Se non ci sono errori, il server accetta l'ordine per ulteriori elaborazioni. Se l'ordine è correttamente accettato dal trade server, la funzione OrderSend() restituisce true.

Si consiglia di verificare la richiesta prima di inviarla ad un un trade server. Per controllare le richieste, utilizzare la funzione OrderCheck(). Essa verifica se ci sono fondi sufficienti per eseguire l'operazione di trade, e restituisce una serie di parametri utili ai risultati dei controlli della richiesta di trade:

  • codice di ritorno contenente informazioni sugli errori nella richiesta controllata;
  • valore di bilancio che verrà visualizzato dopo che l'operazione di trade è eseguita;
  • valore dell'equità che verrà visualizzato dopo che l'operazione di trade è eseguita;
  • valore a virgola mobile che verrà visualizzato dopo che l'operazione di trade è eseguita;
  • margine richiesto per l'operazione di trade;
  • quantità di equità libera che rimarrà dopo l'esecuzione dell' operazione di trade;
  • il livello di margine che sarà fissato dopo che l'operazione di trade è eseguita;
  • commento al codice di risposta, descrizione dell'errore.

Quando si invia un ordine di mercato (MqlTradeRequest.action=TRADE_ACTION_DEAL), il risultato con successo della funzione OrderSend() non significa che l'ordine sia stato eseguito (i trades appropriati sono stati eseguiti). In questo caso, 'true' significa solo che l'ordine è stato inserito con successo nel sistema di trading per l'ulteriore esecuzione. Il trade server può compilare l' affare o ordine (valori dei campi) nel risultato della struttura restituito, se è a conoscenza di questi dati quando si forma una risposta ad una chiamata OrderSend(). Generalmente, gli eventi di esecuzione di trades corrispondenti ad un ordine possono verificarsi dopo aver inviato una risposta alla chiamata OrderSend(). Pertanto, per qualsiasi tipo di richiesta di trade, quando si riceve il risultato delll'esecuzione di OrderSend(), dovremmo prima controllare il codice di responso del trade server retcode e (se necessario) il codice di responso del sistema esterno retcode_external disponibile nel risultato della struttura ottenuto.

Ogni ordine accettato viene memorizzato sul trade server in attesa di elaborazione fino a quando si verifica una delle condizioni per la sua esecuzione:

  • espirazione (scadenza),
  • comparsa di una richiesta opposta,
  • esecuzione dell'ordine quando appare il prezzo di esecuzione,
  • una richiesta di annullare viene ricevuta.

Al momento dell'elaborazione dell'ordine, il trade server invia al terminale un messaggio circa il verificarsi dell'evento di Trade, che può essere elaborato dalla funzione OnTrade().

Il risultato della esecuzione della richiesta di trade su un server, inviata da OrderSend() può essere monitorata dall'handler OnTradeTransaction. Va notato che l'handler OnTradeTransaction verrà chiamato più volte durante l'esecuzione di una richiesta di trade.

Per esempio, quando si invia un ordine di acquisto di mercato, esso viene gestito, un ordine di acquisto appropriata viene creato per l'account, l'ordine quindi viene eseguito e rimosso dalla lista di quelli aperti, e poi viene aggiunto alla cronistoria ordini, un appropriato aff viene aggiunto alla cronistoria ed una nuova posizione viene creata. La funzione OnTradeTransaction verrà chiamata per ognuno di questi eventi.

Esempio:

//--- valore per ORDER_MAGIC
input long order_magic=55555;
//+--------------------------------------------------------------------------------+
//| Funzione di start del programma Script                                         |
//+--------------------------------------------------------------------------------+
voidOnStart()
  {
//--- si assicura che l'account sia demo
   if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
     {
      Alert("L'operazione dello Script non è consentita su un account live!");
      return;
     }
//--- piazza l'ordine o lo cancella
   if(GetOrdersTotalByMagic(order_magic)==0) 
     {
      //--- nessun ordine correntemente - piazza un ordine
      uint res=SendRandomPendingOrder(order_magic);
      Print("Codice di ritorno del trade server",res);
     }
   else // ci sono ordini - elimina ordini
     {
      DeleteAllOrdersByMagic(order_magic);
     }
//---
  }
//+--------------------------------------------------------------------------------+
//| Riceve il numero attuale di ordini con ORDER_MAGIC specificato                 |
//+--------------------------------------------------------------------------------+
int GetOrdersTotalByMagic(long const magic_number)
  {
   ulong order_ticket;
   int total=0;
//--- passa attraverso tutti gli ordini pendenti
   for(int i=0;i<OrdersTotal();i++)
      if((order_ticket=OrderGetTicket(i))>0)
         if(magic_number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
   return(total);
  }
//+--------------------------------------------------------------------------------+
//| Elimina tutti gli ordini pendenti con ORDER_MAGIC specificato                  |
//+--------------------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
  {
   ulong order_ticket;
//--- passa attraverso tutti gli ordini pendenti
   for(int i=OrdersTotal()-1;i>=0;i--)
      if((order_ticket=OrderGetTicket(i))>0)
         //--- ordine con l'appropriato ORDER_MAGIC
         if(magic_number==OrderGetInteger(ORDER_MAGIC))
           {
            MqlTradeResult result={};
            MqlTradeRequest request={};
            request.order=order_ticket;
            request.action=TRADE_ACTION_REMOVE;
            OrderSend(request,result);
            //--- scrive la risposta del server nel registro
            Print(__FUNCTION__,": ",result.comment," reply code ",result.retcode);
           }
//---
  }
//+--------------------------------------------------------------------------------+
//| Importa un ordine pendente in modo casuale                                     |
//+--------------------------------------------------------------------------------+
uint SendRandomPendingOrder(long const magic_number)
  {
//--- prepara una richiesta
   MqlTradeRequest request={};
   request.action=TRADE_ACTION_PENDING;         // imposta un ordine pendente
   request.magic=magic_number;                  // ORDER_MAGIC
   request.symbol=_Symbol;                      // symbol
   request.volume=0.1;                          // volume in 0.1 lotti
   request.sl=0;                                // Stop Loss non è specificato 
   request.tp=0;                                // Take Profit non è specificato 
//--- forma il tipo di ordine
   request.type=GetRandomType();                // tipo di ordine
//--- forma il prezzo per l'ordine pendente
   request.price=GetRandomPrice(request.type);  // open price
//--- invia una richiesta di trade
   MqlTradeResult result={};
   OrderSend(request,result);
//--- scrive la risposta del server nel registro  
   Print(__FUNCTION__,":",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- restitiusce il codice della risposta data dal trade server
   return result.retcode;
  }
//+--------------------------------------------------------------------------------+
//| Restituisce il tipo di ordine pendente in modo casuale                         |
//+--------------------------------------------------------------------------------+
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);
     }
//--- valore non corretto
   return(WRONG_VALUE);
  }
//+--------------------------------------------------------------------------------+
//| Restituisce il prezzo in modo casuale                                          |
//+--------------------------------------------------------------------------------+
double GetRandomPrice(ENUM_ORDER_TYPE type)
  {
   int t=(int)type;
//--- livelli di stop per il simbolo
   int distance=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
//--- riceve i dati dell'ultimo tick
   MqlTick last_tick={};
   SymbolInfoTick(_Symbol,last_tick);
//--- calcola il prezzo in base al tipo
   double price;
   if(t==2 || t==5) // ORDER_TYPE_BUY_LIMIT or ORDER_TYPE_SELL_STOP
     {
      price=last_tick.bid; // partenza dal prezzo Bid
      price=price-(distance+(MathRand()%10)*5)*_Point;
     }
   else             // ORDER_TYPE_SELL_LIMIT or ORDER_TYPE_BUY_STOP
     {
      price=last_tick.ask; // partenza dal prezzo Ask
      price=price+(distance+(MathRand()%10)*5)*_Point;
     }
//---
   return(price);
  }

Vedi anche

Tipi di Operazioni di Trade, Struttura Richieste di Trade, Struttura dei Risultati della Richiesta del Controllo, Struttura del Risultato della Richiesta di Trade