Borrar una orden pendiente

La eliminación de una orden pendiente se realiza a nivel de programa mediante la operación TRADE_ACTION_REMOVE: esta constante debe asignarse al campo action de la estructura MqlTradeRequest antes de llamar a una de las versiones de la función OrderSend. El único campo obligatorio además de action es order para especificar el ticket de la orden que se va a borrar.

El método remove de la estructura de la aplicación MqlTradeRequestSync del archivo MqlTradeSync.mqh es bastante básico.

struct MqlTradeRequestSyncpublic MqlTradeRequest
{
   ...
   bool remove(const ulong ticket)
   {
      if(!OrderSelect(ticket)) return false;
      action = TRADE_ACTION_REMOVE;
      order = ticket;
      ZeroMemory(result);
      return OrderSend(thisresult);
   }

La comprobación del hecho de borrar una orden se realiza tradicionalmente en el método completed.

   bool completed()
   {
      ...
      else if(action == TRADE_ACTION_REMOVE)
      {
         result.order = order;
         return result.removed(timeout);
      }
      ...
   }

La espera de la retirada efectiva de la orden se realiza en el método removed de la estructura MqlTradeResultSync.

struct MqlTradeResultSyncpublic MqlTradeResult
{
   ...
   bool removed(const ulong msc = 1000)
   {
      if(retcode != TRADE_RETCODE_DONE)
      {
         return false;
      }
   
      if(!wait(orderRemovedmsc))
      {
         Print("Order removal timeout: #=" + (string)order);
         return false;
      }
      
      return true;
   }
   
   static bool orderRemoved(MqlTradeResultSync &ref)
   {
      return !OrderSelect(ref.order) && HistoryOrderSelect(ref.order);
   }

Ejemplo del Asesor Experto (PendingOrderDelete.mq5) que muestra la eliminación de una orden que construiremos casi por entero basada en PendingOrderSend.mq5. Esto se debe al hecho de que es más fácil garantizar la existencia de una orden antes de borrarla. Así, inmediatamente después del lanzamiento, el Asesor Experto creará una nueva orden con los parámetros especificados. A continuación, la orden se eliminará en el manejador OnDeinit. Si cambia los parámetros de entrada del Asesor Experto, el símbolo o el marco temporal del gráfico, también se eliminará la orden antigua y se creará una nueva.

Se ha añadido la variable global OwnOrder para almacenar el ticket de la orden. Se rellena como resultado de la llamada a PlaceOrder (la función en sí no se modifica).

ulong OwnOrder = 0;
   
void OnTimer()
{
   // execute the code once for the current parameters
   EventKillTimer();
   
   const string symbol = StringLen(Symbol) == 0 ? _Symbol : Symbol;
   OwnOrder = PlaceOrder((ENUM_ORDER_TYPE)TypesymbolVolume,
      Distance2SLTPExpirationUntilMagicComment);
}

He aquí una simple función de borrado RemoveOrder, que crea el objeto request y llama secuencialmente a los métodos remove y completed para él.

void OnDeinit(const int)
{
   if(OwnOrder != 0)
   {
      RemoveOrder(OwnOrder);
   }
}
   
void RemoveOrder(const ulong ticket)
{
   MqlTradeRequestSync request;
   if(request.remove(ticket) && request.completed())
   {
      Print("OK order removed");
   }
   Print(TU::StringOf(request));
   Print(TU::StringOf(request.result));
}

En el siguiente registro se muestran las entradas que aparecieron como resultado de colocar el Asesor Experto en el gráfico EURUSD, después de lo cual el símbolo fue cambiado a XAUUSD, y luego el Asesor Experto fue eliminado.

(EURUSD,H1)        Autodetected daily range: 0.0094

(EURUSD,H1)        OK order placed: #=1284920879

(EURUSD,H1)        TRADE_ACTION_PENDING, EURUSD, ORDER_TYPE_BUY_STOP, V=0.01, ORDER_FILLING_FOK, »

» @ 1.11011, ORDER_TIME_GTC, M=1234567890

(EURUSD,H1)        DONE, #=1284920879, V=0.01, Request executed, Req=1

(EURUSD,H1)        OK order removed

(EURUSD,H1)        TRADE_ACTION_REMOVE, EURUSD, ORDER_TYPE_BUY, ORDER_FILLING_FOK, #=1284920879

(EURUSD,H1)        DONE, #=1284920879, Request executed, Req=2

(XAUUSD,H1)        Autodetected daily range: 47.45

(XAUUSD,H1)        OK order placed: #=1284921672

(XAUUSD,H1)        TRADE_ACTION_PENDING, XAUUSD, ORDER_TYPE_BUY_STOP, V=0.01, ORDER_FILLING_FOK, »

» @ 1956.68, ORDER_TIME_GTC, M=1234567890

(XAUUSD,H1)        DONE, #=1284921672, V=0.01, Request executed, Req=3

(XAUUSD,H1)        OK order removed

(XAUUSD,H1)        TRADE_ACTION_REMOVE, XAUUSD, ORDER_TYPE_BUY, ORDER_FILLING_FOK, #=1284921672

(XAUUSD,H1)        DONE, #=1284921672, Request executed, Req=4

Vamos a ver otro ejemplo de supresión de órdenes para aplicar la estrategia OCO («One Cancel Other») en la sección de eventos OnTrade.