Tipos de transacciones comerciales

La actividad comercial se realiza mediante el envío de las ordenaciones de apertura de posiciones usando la función OrderSend(), también mediante las ordenaciones de colocación, modificación y eliminación de órdenes pendientes. Cada orden comercial contiene la especificación del tipo de la operación comercial solicitada. Las operaciones comerciales se describen en la enumeración ENUM_TRADE_REQUEST_ACTIONS.

ENUM_TRADE_REQUEST_ACTIONS

Identificador

Descripción

TRADE_ACTION_DEAL

Colocar una orden comercial de conclusión inmediata de un transacción según los parámetros especificados (colocar una orden de mercado)

TRADE_ACTION_PENDING

Colocar una orden comercial para la conclusión de una transacción bajo unas condiciones especificadas (orden pendiente)

TRADE_ACTION_SLTP

Modificar los valores Stop Loss y Take Profit de una posición abierta

TRADE_ACTION_MODIFY

Modificar los parámetros de una orden comercial colocada anteriormente

TRADE_ACTION_REMOVE

Eliminar una orden pendiente colocada anteriormente

TRADE_ACTION_CLOSE_BY

Сlose a position by an opposite one

 
Ejemplo de la operación comercial TRADE_ACTION_DEAL para abrir una posición Buy:

#define EXPERT_MAGIC 123456   // Número mágico del experto
//+------------------------------------------------------------------+
//| Apertura de posición Buy                                         |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración e inicialización de la solicitud y el resultado
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- parámetros de la solicitud
   request.action   =TRADE_ACTION_DEAL;                     // tipo de operación comercial
   request.symbol   =Symbol();                              // símbolo
   request.volume   =0.1;                                   // volumen de 0.1 lote
   request.type     =ORDER_TYPE_BUY;                        // tipo de orden
   request.price    =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // precio de apertura
   request.deviation=5;                                     // desviación permisible del precio
   request.magic    =EXPERT_MAGIC;                          // Número mágico de la orden
//--- envío de la solicitud
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // si no se ha logrado enviar la solicitud, introducir el código de error
//--- información sobre la operación
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_DEAL para abrir una posición Sell:

#define EXPERT_MAGIC 123456   // Número mágico del experto
//+------------------------------------------------------------------+
//| Apertura de posición Sell                                        |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración e inicialización de la solicitud y el resultado
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- parámetros de la solicitud
   request.action   =TRADE_ACTION_DEAL;                     // tipo de operación comercial
   request.symbol   =Symbol();                              // símbolo
   request.volume   =0.2;                                   // volumen 0.2 lote
   request.type     =ORDER_TYPE_SELL;                       // tipo de orden
   request.price    =SymbolInfoDouble(Symbol(),SYMBOL_BID); // precio de apertura
   request.deviation=5;                                     // desviación permisible del precio
   request.magic    =EXPERT_MAGIC;                          // Número mágico de la orden
//--- envío de la solicitud
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // si no se ha logrado enviar la solicitud, mostrar el código de error
//--- información sobre la operación
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_DEAL para cerrar una posición:

#define EXPERT_MAGIC 123456   // Número mágico del experto
//+------------------------------------------------------------------+
//| Cierre de todas las posiciones                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración de la solicitud y el resultado
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // número de posiciones abiertas   
//--- iteración de todas las posiciones abiertas
   for(int i=total-1; i>=0; i--)
     {
      //--- parámetros de la orden
      ulong  position_ticket=PositionGetTicket(i);                                      // ticket de la posición
      string position_symbol=PositionGetString(POSITION_SYMBOL);                        // símbolo 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);              // número de dígitos tras la coma
      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                  // Número mágico de la posición
      double volume=PositionGetDouble(POSITION_VOLUME);                                 // volumen de la posición
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);    // tipo de posición
      //--- mostrar la información de la posición
      PrintFormat("#%I64u %s  %s  %.2f  %s [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  magic);
      //--- si el número mágico coincide
      if(magic==EXPERT_MAGIC)
        {
         //--- reseteo de los valores de la solicitud y el resultado
         ZeroMemory(request);
         ZeroMemory(result);
         //--- establecer los parámetros de la operación
         request.action   =TRADE_ACTION_DEAL;        // tipo de operación comercial
         request.position =position_ticket;          // ticket de la posición
         request.symbol   =position_symbol;          // símbolo 
         request.volume   =volume;                   // volumen de la posición
         request.deviation=5;                        // desviación permisible del precio
         request.magic    =EXPERT_MAGIC;             // Número mágico de la posición
         //--- establecer el precio y el tipo de orden dependiendo del tipo de posición
         if(type==POSITION_TYPE_BUY)
           {
            request.price=SymbolInfoDouble(position_symbol,SYMBOL_BID);
            request.type =ORDER_TYPE_SELL;
           }
         else
           {
            request.price=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
            request.type =ORDER_TYPE_BUY;
           }
         //--- mostrar información sobre el cierre
         PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
         //--- envío de la solicitud
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // si no se ha logrado enviar la solicitud, mostrar el código de error
         //--- información sobre la operación   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         //---
        }
     }
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_PENDING para colocar una orden pendiente:

#property description "Ejemplo de colocación de órdenes pendientes"
#property script_show_inputs
#define EXPERT_MAGIC 123456                             // Número mágico del experto
input ENUM_ORDER_TYPE orderType=ORDER_TYPE_BUY_LIMIT;   // tipo de orden
//+------------------------------------------------------------------+
//| Colocar órdenes pendientes                                       |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración e inicialización de la solicitud y el resultado
   MqlTradeRequest request={};
   MqlTradeResult  result={};
//--- parámetros para la colocación de una orden pendiente
   request.action   =TRADE_ACTION_PENDING;                             // tipo de operación comercial
   request.symbol   =Symbol();                                         // símbolo
   request.volume   =0.1;                                              // volumen 0.1 lote
   request.deviation=2;                                                // desviación permisible del precio
   request.magic    =EXPERT_MAGIC;                                     // Número mágico de la orden
   int offset = 50;                                                    // distancia con respecto al precio actual para poner la orden, en puntos
   double price;                                                       // precio de activación de la orden
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);                // tamaño del punto
   int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);                // número de dígitos tras la coma (precisión)
   //--- comprobación del tipo de operación
   if(orderType==ORDER_TYPE_BUY_LIMIT)
     {
      request.type     =ORDER_TYPE_BUY_LIMIT;                          // tipo de orden
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;        // precio de apertura 
      request.price    =NormalizeDouble(price,digits);                 // precio de apertura normalizado 
     }
   else if(orderType==ORDER_TYPE_SELL_LIMIT)
     {
      request.type     =ORDER_TYPE_SELL_LIMIT;                          // tipo de orden
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point;         // precio de apertura 
      request.price    =NormalizeDouble(price,digits);                  // precio de apertura normalizado 
     }
   else if(orderType==ORDER_TYPE_BUY_STOP)
     {
      request.type =ORDER_TYPE_BUY_STOP;                                // tipo de orden
      price        =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // precio de apertura 
      request.price=NormalizeDouble(price,digits);                      // precio de apertura normalizado 
     }
   else if(orderType==ORDER_TYPE_SELL_STOP)
     {
      request.type     =ORDER_TYPE_SELL_STOP;                           // tipo de orden
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;         // precio de apertura 
      request.price    =NormalizeDouble(price,digits);                  // precio de apertura normalizado 
     }
   else Alert("Este ejemplo es solo para colocar órdenes pendientes");   // si no se ha elegido una orden pendiente
//--- enviar solicitud
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());                 // si no se ha logrado enviar la solicitud, mostrar el código de error
//--- información sobre la operación
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_SLTP para cambiar los valores de Stop Loss y Take Profit de una posición abierta:

#define EXPERT_MAGIC 123456  // Número mágico del experto
//+------------------------------------------------------------------+
//| Modificación de Stop Loss y Take Profit de la posición           |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración de la solicitud y el resultado
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // número de posiciones abiertas   
//--- iteración de todas las posiciones abiertas
   for(int i=0; i<total; i++)
     {
      //--- parámetros de la orden
      ulong  position_ticket=PositionGetTicket(i);// ticket de la posición
      string position_symbol=PositionGetString(POSITION_SYMBOL); // símbolo 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // número de dígitos tras la coma
      ulong  magic=PositionGetInteger(POSITION_MAGIC); // Número mágico de la posición
      double volume=PositionGetDouble(POSITION_VOLUME);    // volumen de la posición
      double sl=PositionGetDouble(POSITION_SL);  // Stop Loss de la posición
      double tp=PositionGetDouble(POSITION_TP);  // Take Profit de la posición
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);  // tipo de posición
      //--- mostrar información de la posición
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  tp: %s  [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),
                  DoubleToString(tp,digits),
                  magic);
      //--- si el número mágico coincide, Stop Loss y Take Profit no han sido establecidos
      if(magic==EXPERT_MAGIC && sl==0 && tp==0)
        {
         //--- cálculo de los niveles de precio actuales
         double price=PositionGetDouble(POSITION_PRICE_OPEN);
         double bid=SymbolInfoDouble(position_symbol,SYMBOL_BID);
         double ask=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
         int    stop_level=(int)SymbolInfoInteger(position_symbol,SYMBOL_TRADE_STOPS_LEVEL);
         double price_level;
         //--- si el nivel de separación máxima permitida en puntos con respecto al precio de cierre actual no ha sido establecido
         if(stop_level<=0)
            stop_level=150; // establecemos una separación de 150 puntos con respecto el precio de cierre actual
         else
            stop_level+=50; // tomaremos un nivel de separación igual a (SYMBOL_TRADE_STOPS_LEVEL + 50) puntos para estar seguros
 
         //--- cálculo y redondeo de los valores de Stop Loss y Take Profit
         price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
         if(type==POSITION_TYPE_BUY)
           {
            sl=NormalizeDouble(bid-price_level,digits);
            tp=NormalizeDouble(ask+price_level,digits);
           }
         else
           {
            sl=NormalizeDouble(ask+price_level,digits);
            tp=NormalizeDouble(bid-price_level,digits);
           }
         //--- reseteo de los valores de la solicitud y el resultado
         ZeroMemory(request);
         ZeroMemory(result);
         //--- establecer los parámetros de la operación
         request.action  =TRADE_ACTION_SLTP// tipo de operación comercial
         request.position=position_ticket;   // ticket de la posición
         request.symbol=position_symbol;     // símbolo 
         request.sl      =sl;                // Stop Loss de la posición
         request.tp      =tp;                // Take Profit de la posición
         request.magic=EXPERT_MAGIC;         // Número mágico de la posición
         //--- mostrar información de la modificación
         PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
         //--- envío de la solicitud
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // si no se ha logrado enviar la solicitud, mostrar el código de error
         //--- información sobre la operación   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
        }
     }
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_MODIFY para modificar los niveles de precio de las órdenes pendientes:

#define EXPERT_MAGIC 123456  // Número mágico del experto
//+------------------------------------------------------------------+
//| Modificación de órdenes pendientes                               |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración e incialización de la solicitud y el resultado
   MqlTradeRequest request={};
   MqlTradeResult  result={};
   int total=OrdersTotal(); // número de órdenes pendientes colocadas
//--- iteración de todas las órdenes pendientes colocadas
   for(int i=0; i<total; i++)
     {
      //--- parámetros de la orden
      ulong  order_ticket=OrderGetTicket(i);                             // ticket de la orden
      string order_symbol=Symbol();                                      // símbolo
      int    digits=(int)SymbolInfoInteger(order_symbol,SYMBOL_DIGITS);  // número de dígitos tras la coma
      ulong  magic=OrderGetInteger(ORDER_MAGIC);                         // Número mágico de la orden
      double volume=OrderGetDouble(ORDER_VOLUME_CURRENT);                // volumen actual de la orden
      double sl=OrderGetDouble(ORDER_SL);                                // Stop Loss actual de la orden
      double tp=OrderGetDouble(ORDER_TP);                                // Take Profit actual de la orden
      ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); // tipo de orden
      int offset = 50;                                                   // distancia con respecto al precio actual para la colocación de una orden, en puntos
      double price;                                                      // precio de activación de la orden
      double point=SymbolInfoDouble(order_symbol,SYMBOL_POINT);          // tamaño del punto
      //--- mostrar información sobre la orden
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  tp: %s  [%I64d]",
                  order_ticket,
                  order_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),
                  DoubleToString(tp,digits),
                  magic);
      //--- si el número mágico coincide, Stop Loss y Take Profit no han sido establecidos
      if(magic==EXPERT_MAGIC && sl==0 && tp==0)
        {
         request.action=TRADE_ACTION_MODIFY;                           // tipo de operación comercial
         request.order = OrderGetTicket(i);                            // ticket de la orden
         request.symbol   =Symbol();                                   // símbolo
         request.deviation=5;                                          // desviación permisible del precio
        //--- establecer los niveles de precio, Take Profit y Stop Loss de la orden dependiendo de su tipo
         if(type==ORDER_TYPE_BUY_LIMIT)
           {
            price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; 
            request.tp = NormalizeDouble(price+offset*point,digits);
            request.sl = NormalizeDouble(price-offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                // precio de apertura normalizado
           }
         else if(type==ORDER_TYPE_SELL_LIMIT)
           {
           price = SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point; 
            request.tp = NormalizeDouble(price-offset*point,digits);
            request.sl = NormalizeDouble(price+offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                 // precio de apertura normalizado
           }
         else if(type==ORDER_TYPE_BUY_STOP)
           {
           price = SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point; 
            request.tp = NormalizeDouble(price+offset*point,digits);
            request.sl = NormalizeDouble(price-offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                 // precio de apertura normalizado
           }
         else if(type==ORDER_TYPE_SELL_STOP)
           {
           price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point; 
            request.tp = NormalizeDouble(price-offset*point,digits);
            request.sl = NormalizeDouble(price+offset*point,digits);
            request.price    =NormalizeDouble(price,digits);                 // precio de apertura normalizado
           }
         //--- envío de la solicitud
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // si no se ha logrado enviar la solicitud, mostrar el código de error
         //--- información sobre la operación   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         //--- reseteo de los valores de la solicitud y el resultado
         ZeroMemory(request);
         ZeroMemory(result);
        }
     }
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_REMOVE para eliminar órdenes pendientes:

#define EXPERT_MAGIC 123456  // Número mágico del experto
//+------------------------------------------------------------------+
//| Eliminación de órdenes pendientes                                |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración e inicialización de la solicitud y el resultado
   MqlTradeRequest request={};
   MqlTradeResult  result={};
   int total=OrdersTotal(); // cantidad de órdenes pendientes establecidas
//--- iteración de todas las órdenes pendientes establecidas
   for(int i=total-1; i>=0; i--)
     {
      ulong  order_ticket=OrderGetTicket(i);                   // ticket de la orden
      ulong  magic=OrderGetInteger(ORDER_MAGIC);               // Número mágico de la orden
      //--- si el número mágico coincide
      if(magic==EXPERT_MAGIC)
        {
         //--- reseteo de los valores de la solicitud y el resultado
         ZeroMemory(request);
         ZeroMemory(result);
         //--- establecer los parámetros de la operación     
         request.action=TRADE_ACTION_REMOVE;                   // tipo de operación comercial
         request.order = order_ticket;                         // ticket de la orden
         //--- envío de la solicitud
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // si no se ha logrado enviar la solicitud, mostrar el código de error
         //--- información sobre la operación   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
        }
     }
  }
//+------------------------------------------------------------------+

 
Ejemplo de la operación comercial TRADE_ACTION_CLOSE_BY para cerrar una posición con otra opuesta:

#define EXPERT_MAGIC 123456  // Número mágico del experto
//+------------------------------------------------------------------+
//| Cierre de todas las posiciones                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declaración de la solicitud y el resultado
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // número de posiciones abiertas   
//--- iteración de todas las posiciones abiertas
   for(int i=total-1; i>=0; i--)
     {
      //--- parámetros de la orden
      ulong  position_ticket=PositionGetTicket(i);                                    // ticket de la posición
      string position_symbol=PositionGetString(POSITION_SYMBOL);                      // símbolo 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS);            // número de dígitos tras la coma
      ulong  magic=PositionGetInteger(POSITION_MAGIC);                                // Número mágico de la posición
      double volume=PositionGetDouble(POSITION_VOLUME);                               // volumen de la posición
      double sl=PositionGetDouble(POSITION_SL);                                       // Stop Loss de la posición
      double tp=PositionGetDouble(POSITION_TP);                                       // Take Profit de la posición
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);  // tipo de posición
      //--- mostrar la información de la posición
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  tp: %s  [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),
                  DoubleToString(tp,digits),
                  magic);
      //--- si el número mágico coincide
      if(magic==EXPERT_MAGIC)
        {
         for(int j=0; j<i; j++)
           {
            string symbol=PositionGetSymbol(j); // símbolo de la posición opuesta
            //--- si los símbolos de la posición opuesta y la buscada coinciden
            if(symbol==position_symbol && PositionGetInteger(POSITION_MAGIC)==EXPERT_MAGIC)
              {
               //--- establecer el tipo de posición opuesta
               ENUM_POSITION_TYPE type_by=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
               //--- salir si los tipos de la posición original y la opuesta coinciden
               if(type==type_by)
                  continue;
               //--- reseteo de los valores de la solicitud y el resultado
               ZeroMemory(request);
               ZeroMemory(result);
               //--- establecer los parámetros del resultado
               request.action=TRADE_ACTION_CLOSE_BY;                         // tipo de operación comercial
               request.position=position_ticket;                             // ticket de la posición
               request.position_by=PositionGetInteger(POSITION_TICKET);      // ticket de la posición opuesta
               //request.symbol     =position_symbol;
               request.magic=EXPERT_MAGIC;                                   // Número mágico de la posición
               //--- mostrar la información sobre el cierre por posición opuesta
               PrintFormat("Close #%I64d %s %s by #%I64d",position_ticket,position_symbol,EnumToString(type),request.position_by);
               //--- envío de la solicitud
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError()); // si no se ha logrado enviar la solicitud, mostrar el código de error
 
               //--- información sobre la operación   
               PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+