English Русский 中文 Deutsch 日本語 Português
preview
Colocando órdenes en MQL5

Colocando órdenes en MQL5

MetaTrader 5Trading | 8 febrero 2024, 16:02
973 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introducción

En cualquier sistema comercial, tenemos que lidiar con órdenes, tales como la apertura de posiciones y el establecimiento de stop loss y take profit, así como el cambio de órdenes. Por lo tanto, resulta esencial comprender cómo procesar las operaciones con órdenes en MQL5 al crear un sistema comercial para MetaTrader5. El propósito de este artículo es ofrecer una guía sencilla para la mayoría de las operaciones con órdenes y posiciones. Así, hoy abarcaremos los temas que siguen:

Esperamos que este artículo le ayude a desarrollar sin problemas su sistema comercial en MetaTrader 5 en cuanto a la colocación de órdenes. Pruebe todas las aplicaciones de este artículo para asegurarse de que resulten rentables y se adapten a su estilo comercial. El objetivo principal de dichas aplicaciones es ofrecer un ejemplo de cómo crear un sistema comercial utilizando dos métodos diferentes de trabajo con órdenes, transacciones y posiciones.

¡Atención! Toda la información del presente artículo se ofrece «tal cual», únicamente con fines ilustrativos, y no supone ningún tipo de recomendación. El artículo no garantiza ningún resultado en absoluto. Todo lo que ponga en práctica usando este artículo como base, lo hará bajo su propia cuenta y riesgo; el autor no garantiza resultado alguno.

Órdenes, posiciones y transacciones

En esta parte, hablaremos de términos importantes para comprender cómo trabajar eficazmente con las órdenes. También veremos la diferencia entre tres conceptos vinculados con las órdenes en MetaTrader 5, a saber: la orden, la transacción y la posición. Podemos pensar en estos términos como pasos necesarios para completar una transacción.

Orden: solicitud recibida por el servidor comercial para abrir una transacción de compra o venta con un lote o volumen determinado a un precio determinado. Existen dos tipos de órdenes: de mercado y pendientes.

  • Una orden de mercado se puede ejecutar inmediatamente al actual precio de mercado.
  • Una orden pendiente se ejecuta a un precio y en un momento predeterminados. 

Las órdenes pendientes, a su vez, son de los tipos siguientes:

    • Buy stop: orden pendiente de compra a un precio determinado que es superior al precio actual en el mercado.
    • Buy limit: orden pendiente de compra a un precio determinado que es inferior al precio actual en el mercado.
    • Sell ​​stop: orden pendiente de venta a un precio determinado que es inferior al precio actual en el mercado.
    • Sell limit: orden pendiente de venta a un precio determinado que es superior al precio actual en el mercado.

Una vez colocada una orden, ya sea una orden de mercado o una orden pendiente, se podrá encontrar en la pestaña "Comercio" de la barra de herramientas de MetaTrader 5. A continuación le mostramos un ejemplo:

1. Pestaña "Comercio"


Cuando una orden se cierra o cancela sin ejecución, se podrá encontrar en la pestaña "Historia" en la ventana "Herramientas".

2. Pestaña "Historia"

A continuación, consideraremos la modificación de las órdenes abiertas.

Una transacción es el resultado de la ejecución de una orden comercial. Estas son las acciones de entrada/salida del mercado. Digamos que se ha ejecutado una orden para comprar un lote. Después de eso, hemos cerrado parte de la posición de 0,5 lotes y luego hemos cerrado los 0,5 lotes restantes. La secuencia de transacciones será la siguiente:

  • entrada de 1 lote
  • venta de 0.5 lote
  • venta de 0.5 lote

Podemos mostrar las transacciones haciendo clic derecho en la pestaña "Historia" de la ventana "Herramientas" y seleccionando "Transacciones".

3. Transacciones

Una posición es una secuencia de transacciones largas o cortas para comprar o vender un activo financiero. Podremos encontrar las posiciones activas en la pestaña "Comercio" o en la pestaña "Historia", si elegimos la representación de posiciones.

4. Posiciones

El precio ejecutable de la orden de compra es el precio Ask, mientras que el precio ejecutable al cierre es el precio Bid. Por otro lado, el precio ejecutable de la orden de venta es el precio Bid, mientras que el precio ejecutable al cierre es el precio Ask.

OrderSend()

Tras revisar los términos importantes relacionados con la ejecución de transacciones en MetaTrader 5, ahora aprenderemos cómo ejecutar órdenes automáticamente en MQL5. Podrá familiarizarse con la sección "Funciones comerciales" en la guía de ayuda de MQL5.

Vamos a ver la función OrderSend(), que se puede utilizar para realizar operaciones comerciales enviando solicitudes al servidor comercial. En otras palabras, podremos utilizarla para colocar, modificar y cerrar órdenes.

A continuación le mostramos el formato de esta función:

bool  OrderSend(
   MqlTradeRequest&  request,      
   MqlTradeResult&   result        
   );

Como podemos ver, la función tiene dos parámetros:

  • La estructura MqlTradeRequestcontiene parámetros de la orden y todos los campos o variables necesarios para ejecutar transacciones comerciales. Los objetos son transmitidos por referencia, según el signo et. TradeRequest es un método de interacción entre el terminal del cliente y el servidor comercial para la ejecución de órdenes.
  • La estructura MqlTradeResult: TradeResult retorna los resultados de la solicitud de orden. Los objetos también se transmiten por referencia.

Estructura de MqlTradeRequest:

Una estructura es una colección de datos relacionados de diferentes tipos. La definición de la estructura MqlTradeRequest tiene el aspecto siguiente:

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Trade operation type
   ulong                         magic;            // Expert Advisor ID (magic number)
   ulong                         order;            // Order ticket
   string                        symbol;           // Trade symbol
   double                        volume;           // Requested volume for a deal in lots
   double                        price;            // Price
   double                        stoplimit;        // StopLimit level of the order
   double                        sl;               // Stop Loss level of the order
   double                        tp;               // Take Profit level of the order
   ulong                         deviation;        // Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order expiration type
   datetime                      expiration;       // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // The ticket of an opposite position
  };

Podemos declarar el objeto MqlTradeRequest utilizando la siguiente línea de código:

MqlTradeRequest request;

Luego podemos asignar parámetros comerciales a las variables del objeto de solicitud creado añadiendo un punto (.) después del objeto, como se muestra en el siguiente ejemplo:

request.symbol = _Symbol;
request.volume = 0.01;
request.type = ORDER_TYPE_BUY;

A continuación le mostramos una lista de todos los miembros o variables de la estructura MqlTradeRequest, así como sus valores válidos para la asignación.

Variable Descripción Valor tomado para la asignación
action Tipo de operación comercial

Uno de ENUM_TRADE_REQUEST_ACTIONS(TRADE_ACTION_DEAL, TRADE_ACTION_PENDING, TRADE_ACTION_SLTP, TRADE_ACTION_MODIFY, TRADE_ACTION_REMOVE, TRADE_ACTION_CLOSE_BY)

magic ID del asesor para identificar las órdenes colocadas por un asesor específico Cualquier valor ulong
order Ticket de la orden. Se requiere al usar TRADE_ACTION_MODIFY o TRADE_ACTION_REMOVE en una variable de acción.  Cualquier valor ulong
symbol El símbolo o instrumento especificado para comerciar. (_SYMBOL) se refiere al actual Cualquier símbolo string
volume Volumen comercial o lotes  Cualquier valor double permitido
price Precio de apertura Valor double
stoplimit Precio de apertura de una orden límite pendiente. La acción deberá ser TRADE_ACTION_PENDING, mientras que la variable de tipo deberá ser ORDER_TYPE_BUY_STOP_LIMIT o ORDER_TYPE_SELL_STOP_LIMIT. La variable será obligatoria para las órdenes stop-limit. Valor double
sl Precio del stop loss comercial Valor double
tp Precio del take profit de la transacción Valor double
deviation Desviación máxima del precio en puntos Valor ulong
type Tipo de orden Uno de ENUM_ORDER_TYPE(ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP, 
ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT,  ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT)
type_filling Tipo o política de ejecución de las órdenes Uno de ENUM_ORDER_TYPE_FILLING(ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_BOC, ORDER_FILLING_RETURN)
type_time Tipo de vencimiento de una orden pendiente Uno de ENUM_ORDER_TYPE_TIME(ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY)
expiration Tiempo de vencimiento de una orden pendiente. Requerido si type_time es ORDER_TIME_SPECIFIED Valor datetime
comment Comentarios a la orden Valor string
position Ticket de la posición. Requerido al cambiar o cerrar una posición para identificarla. Valor ulong
position_by Ticket de la posición opuesta. Se usa al cerrar una posición opuesta para el mismo símbolo. Valor ulong

Ahora observaremos algunas acciones importantes que se deben utilizar al colocar órdenes en MQL5.

  • Orden de mercado
  • Añadir un stop loss y take profit
  • Orden pendiente
  • Cambiar una orden pendiente
  • Eliminar una orden pendiente

Orden de mercado:

En este tipo de acción, necesitaremos colocar una orden de mercado, lo cual significa que la orden se colocará al precio de mercado actual. Usaremos la acción (TRADE_ACTION_DEAL). Si es una orden de compra, se colocará al precio Ask actual, y si es una orden de venta, se colocará al precio Bid actual. Aquí tenemos cómo hacerlo: 

Después de declarar los objetos MqlTradeRequest y MqlTradeResult, asignaremos los siguientes valores a las variables necesarias:

request.action = TRADE_ACTION_DEAL;                    &nbsthe p;   //market order palcement
request.type = ORDER_TYPE_BUY;                             //type of order is buy
request.symbol = _Symbol;                                  //applied for the cuurrent symbol
request.volume = 0.1;                                      //the lot size
request.type_filling = ORDER_FILLING_FOK;                  //the filling policy fill or kill
request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);      //the price is the current ask for buy
request.sl = 0;                                            //stop loss is 0
request.tp = 0;                                            //take profit is 0
request.deviation = 50;                                    //slippage is 50
OrderSend(request, result);                                //calling the OrderSend function

Como podemos ver, no hemos añadido valores de stop loss y take profit. Podemos añadir sus valores al código junto con otras variables, o podemos añadirlos usando otra acción, como se muestra en la siguiente sección.

Añadiendo stop loss y take profit:

Cuando necesitemos añadir stop loss y take profit, asignaremos TRADE_ACTION_SLTP a la variable de acción como se muestra en el siguiente ejemplo.

request.action = TRADE_ACTION_SLTP;          //adding sl and tp
request.symbol = _Symbol;                    //applied for the cuurrent symbol
request.sl = 1.07000;                        //sl price
request.sl = 1.09000;                        //tp price
OrderSend(request, result);                  //calling the OrderSend function


Orden pendiente:

Si queremos colocar una orden pendiente, podremos usar otra acción (TRADE_ACTION_PENDING). Luego determinaremos el tipo de orden. Podemos configurar la hora si necesitamos el tiempo de vencimiento de la orden pendiente.

request.action = TRADE_ACTION_PENDING;          //pending order placement
request.type = ORDER_TYPE_BUY_STOP;             //type of order is buy stop
request.symbol = _Symbol;                       //applied for the cuurrent symbol
request.volume = 0.1;                           //the lot size
request.price = 1.07000;                        //opening price
request.sl = 1.06950;                           //stop loss
request.tp = 1.07100;                           //take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.08.31 00.00';       //expiration time - datetime constant          
request.type_filling = ORDER_FILLING_FOK;       //the filling policy fill or kill
request.stoplimit = 0;                          //for stoplimit order only
OrderSend(request, result);                     //calling the OrderSend function


Cambiando una orden pendiente:

Al cambiar una orden pendiente, necesitaremos obtener su número de ticket. Para ello podemos utilizar la función OrderGetTicket. Esta función retornará el ticket de la orden correspondiente, desde el cual podremos seleccionar la orden y trabajar con ella.

ulong  OrderGetTicket( 
   int  index      // Number in the list of orders 
   );

Digamos que tenemos una variable (ticket) que contiene un ticket de orden. Podemos usar esta variable para asignar el ticket de la orden a la variable de la orden del objeto de solicitud. Luego podremos modificar la orden usando la acción (TRADE_ACTION_MODIFY) como en el siguiente ejemplo.

request.action = TRADE_ACTION_MODIFY;           //pending order modyfying
request.order = ticket;                         //ticket variable that holds the pending order ticket to modify
request.price = 1.07050;                        //new opening price
request.sl = 1.07000;                           //new stop loss
request.tp = 1.07150;                           //new take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.09.01 00.00';       //new expiration time - datetime constant        
OrderSend(request, result);                     //calling the OrderSend function

Eliminar una orden pendiente:

Si necesitamos eliminar una orden pendiente, podremos hacerlo usando una acción (TRADE_ACTION_REMOVE). También necesitaremos el número de ticket de la orden pendiente que necesitamos eliminar. Podremos utilizar un ticket de variable con la expectativa de que contenga el número de ticket requerido.

request.action = TRADE_ACTION_REMOVE;           //pending order remove
request.order = ticket;                         //ticket variable that holds the pending order ticket to remove
OrderSend(request, result);                     //calling the OrderSend function

Estructura de MqlTradeResult:

La estructura MqlTradeResult retorna el resultado sobre el éxito de una orden después de haberla colocado usando la función OrderSend(). Contiene información del servidor comercial, como el número del ticket, el volumen y el precio.

A continuación le mostramos la definición de la estructura MqlTradeResult:

struct MqlTradeResult
  {
   uint     retcode;          // Operation return code
   ulong    deal;             // Deal ticket, if it is performed
   ulong    order;            // Order ticket, if it is placed
   double   volume;           // Deal volume, confirmed by broker
   double   price;            // Deal price, confirmed by broker
   double   bid;              // Current Bid price
   double   ask;              // Current Ask price
   string   comment;          // Broker comment to operation (by default it is filled by description of trade server return code)
   uint     request_id;       // Request ID set by the terminal during the dispatch 
   int      retcode_external; // Return code of an external trading system
  };

Podemos declarar el objeto con el nombre result y transmitirlo como segundo parámetro después del primero (request) al llamar a la función OrderSend().

MqlTradeResult result;

Como podemos ver en las variables de estructura MqlTradeResult, la variable retcode resulta esencial porque retorna el código del servidor comercial para indicar si la solicitud ha tenido éxito.

Si la operación no se ha colocado, el código de retorno indicará un error. Podrá estudiar la lista de códigos de retorno en la guía de ayuda de MQL5. Es de vital importancia incluir en nuestro sistema comercial un código que nos indique si se retorna un error o no, como se muestra en el siguiente ejemplo:

   if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
     {
      Print("Trade Placed Successfully");
     }
   else
     {
      Print("Trade Not Placed, Error ", result.retcode);
     }

Como podemos ver, después de la solicitud, se mostrará un mensaje con el resultado y se rellenarán las variables de resultado. Al abrir una transacción, recibiremos un mensaje y, si hay algún problema, se nos enviará un código de error.

Usando OrderSend()

Necesitamos crear un sistema comercial simple que pueda ejecutar transacciones usando la función OrderSend(). El sistema comercial supone un cruce simple de medias móviles y la acción será únicamente colocar una orden de mercado.

El objetivo aquí es comprender las diferencias al crear el mismo sistema comercial usando OrderSend() y la clase CTrade. A continuación le mostraremos los pasos para crear un cruce de MA usando la función OrderSend().

En el área global crearemos dos variables enteras (simpleMA, barTotal) sin asignación. La asignación la realizaremos más tarde, en OnInit.

int simpleMA;
int barsTotal;

SimpleMA se asignará a la función iMA, que retornará el identificador del indicador técnico de media móvil. Los parámetros serán estos:

  • symbol - nombre del símbolo, _Symbol se refiere al instrumento actual.
  • period - marco temporal. Usaremos PERIOD_H1 - el marco temporal de una hora.
  • ma_period - periodo de la media móvil. Usaremos 50.
  • ma_shift - desplazamiento horizontal.
  • ma_method - tipo de media móvil. Indicaremos la MA simple.
  • apply_price - tipo de precio para calcular la media móvil. Usaremos el precio de cierre.

BarsTotal se asignará a la función iBars, que retornará el número de barras. Parámetros:

  • symbol - nombre del símbolo
  • timeframe - periodo del marco temporal
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);

En OnTick() crearemos dos arrays: uno para los precios usando MqlRates para almacenar la información sobre los precios, volúmenes y spreads, y otro para la media móvil con la variable tipo double

   MqlRates priceArray[];
   double mySMAArray[];

Definición de precios de oferta y demanda.

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

Crearemos dos objetos para la función OrderSend(): uno para la solicitud usando MqlTradeReuest y otro para el resultado usando MqlTradeResult, y luego restableceremos la variable request por referencia.

ZeroMemory(request);

A continuación, estableceremos el indicador AS_SERIES para los dos arrays creados priceArray y mySMAArray usando la función ArraySetAsSeries. Parámetros:

  • array[] - array necesario
  • flag - dirección de indexación del array.
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

Obtención de datos históricos de MqlRates usando la función CopyRates. Parámetros:

  • symbol - nombre del símbolo o _Symbol para el símbolo o instrumento actual.
  • time frame - periodo del marco temporal o _period para el marco temporal actual.
  • start position - posición inicial.
  • count - cantidad de datos para copiar.
  • rate_array - array de destino para copiar.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

Obtener el búfer de datos del indicador usando la función CopyBuffer. Parámetros:

  • indicator_handle - manejador del indicador (MA).
  • buffer_num - número del búfer de indicador.
  • start_pos - posición inicial del cálculo.
  • count - volumen a copiar.
  • buffer[] - array objetivo.
CopyBuffer(simpleMA,0,0,3,mySMAArray);

Definición del último precio, el anterior precio de cierre y los valores anterior y último de SMA

   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

Crearemos la variable entera bar y la asignaremos a iBars.

int bars=iBars(_Symbol,PERIOD_H1);

Luego comprobaremos si barsTotal y la variable bars son iguales.

if(barsTotal != bars)

Y actualizaremos el valor barsTotal para que sea igual a bars si no son iguales entre sí

barsTotal=bars;

Después comprobaremos la condición de la estrategia para abrir una operación: si el último cierre supera el último valor de SMA después de que el cierre anterior haya sido menor que el valor de SMA anterior.

if(prevClose<prevSMAVal && lastClose>SMAVal)

A continuación, abriremos una orden de mercado de compra utilizando las variables correspondientes vinculadas con la función MqlTradeRequest.

         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

Y comprobaremos la condición de la estrategia para abrir una operación de venta: el último cierre es inferior al último valor de SMA después de que el cierre anterior haya sido mayor que el valor de SMA anterior.

if(prevClose>prevSMAVal && lastClose<SMAVal)
Después abriremos una orden de mercado de venta utilizando las variables correspondientes asociadas con la función MqlTradeRequest.
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

A continuación le mostramos el código completo para crear este tipo de sistema comercial utilizando la función OrderSend().

//+------------------------------------------------------------------+
//|                                     OrderSend_Trading_system.mq5 |
//+------------------------------------------------------------------+
int simpleMA;
int barsTotal;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   MqlTradeRequest request;
   MqlTradeResult result;
   ZeroMemory(request);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
     }
  }

La clase CTrade

Hemos aprendido cómo colocar órdenes usando la función OrderSend() y hemos logrado una forma fácil de acceder a las funciones comerciales. Podemos utilizar la clase CTrade ya preparada ofrecida por MQL5 o crear la nuestra propia. ¿Cómo puedo usar la clase CTrade ya preparada en MQL5? Podrá encontrar información adicional en la sección CTrade de la guía de ayuda de MQL5.

Primero, podremos encontrar el archivo de inclusión de la clase CTrade en la carpeta Trade de la carpeta include de los archivos de instalación de MetaTrader 5. Todo lo que necesitaremos es incluir este archivo en el asesor para llamar y utilizar todas las funciones comerciales de la siguiente manera:

#include <Trade\Trade.mqh>

Creamos un objeto de la clase CTrade.

CTrade trade;

Después de ello, podremos usar todas las funciones comerciales en la clase CTrade utilizando trade antes del punto (.) y la función deseada. Podremos utilizar todas las funciones de las operaciones con órdenes y posiciones, el acceso a los parámetros de la última solicitud, los resultados de verificación y ejecución de la última solicitud, y otros.

Mencionaremos algunas funciones importantes de la misma forma que con OrderSend() para comprender las diferencias entre los dos métodos. Vamos a averiguar cómo hacer lo siguiente:

  • Orden de mercado
  • Añadir un stop loss y take profit
  • Orden pendiente
  • Cambiar una orden pendiente
  • Eliminar una orden pendiente

Orden de mercado:

Después de crear nuestro objeto comercial, podremos usar la función PositionOpen para colocar una orden de mercado. Aquí tenemos sus parámetros:

  • symbol - símbolo requerido
  • order_type - tipo de orden para abrir una posición
  • volumen - tamaño del lote
  • price - precio de apertura de la posición
  • sl - precio de stop loss
  • tp - precio de take profit
  • comment - comentario o NULL

A continuación le mostramos un ejemplo:

trade.PositionOpen(
   _Symbol,             //to be applied for the current symbol
   ORDER_TYPE_BUY,      //to place buy order
   0.1,                 //lot size or volume
   Ask,                 //opening price of the order - current ask
   Ask-(500*_Point),    //sl
   Ask+(1000*_Point),   //tp
   NULL                 //NULL
);

Para abrir una orden de mercado, también podemos usar métodos adicionales en CTrade, como Buy o Sell, en lugar de PositionOpen.

Añadiendo stop loss y take profit:

Podemos cambiar la posición según el símbolo o el número de ticket usando la función PositionModify. Parámetros:

  • symbol or ticket - al cambiar la posición según el símbolo, indicaremos el símbolo; al cambiar según el ticket, indicaremos el número del ticket.
  • sl - nuevo precio de stop loss
  • tp - precio de take profit

Ejemplo de cambio según el símbolo:

trade.PositionModify(
   EURUSD,       //the symbol name
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Ejemplo de cambio según el ticket:

trade.PositionModify(
   ticket,       //the ticket variable that holds the needed ticket number to modify
   1.06950,      //the new sl
   1.07100,      //the new tp
);

Orden pendiente:

Si necesitamos realizar una orden pendiente usando la clase CTrade, podremos usar la función OrderOpen. Parámetros:

  • symbol - nombre del símbolo
  • order_type - tipo de orden pendiente
  • volume - tamaño del lote
  • limit_price - precio stop-limit
  • price - precio de ejecución de una orden pendiente
  • sl - stop loss
  • tp - take profit
  • type_time - tipo de vencimiento
  • expiration - variable de fecha y hora de vencimiento
  • comment - comentario

El siguiente ejemplo muestra cómo colocar una orden de compra pendiente utilizando la función OrderOpen.

         trade.OrderOpen(
            "EURUSD",                 // symbol
            ORDER_TYPE_BUY_LIMIT,     // order type
            0.1,                      // order volume
            0,                        // StopLimit price
            1.07000,                  // execution price
            1.06950,                  // Stop Loss price
            1.07100,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            ""                        // comment
         );

Cambiando una orden pendiente:

Si necesitamos modificar una orden pendiente ya colocada, podremos hacerlo usando la clase CTrade con la ayuda de la función OrderModify. Parámetros:

  • ticket - ticket de la orden pendiente que debe cambiarse
  • price - nuevo precio de ejecución
  • sl - nuevo precio de stop loss
  • tp - nuevo precio de take profit
  • type_time - tipo de vencimiento
  • expiration - variable de fecha y hora de vencimiento
  • stoplimit - precio de la orden límite

A continuación le mostramos un ejemplo de cómo cambiar una orden pendiente

         trade.OrderModify(
            ticket,                   // ticket number of the pending order to modify
            1.07050,                  // execution price
            1.07000,                  // Stop Loss price
            1.07150,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            0,                        // StopLimit price
         );

Eliminar una orden pendiente:

Si necesitamos eliminar una orden pendiente, podremos hacerlo utilizando la función OrderDelete. Para eliminarla se requerirá el número de ticket de la orden pendiente. A continuación le mostramos un ejemplo de esta función.

         trade.OrderDelete(
            ticket,                 // tick number of the pending order to delete
         );

Usando CTrade

Crearemos el mismo sistema comercial que hemos creado usando OrderSend(). Utilizaremos la clase CTrade para comprender las diferencias en el funcionamiento de las funciones.

A continuación le mostramos los únicos pasos diferentes para crear un sistema comercial utilizando la clase CTrade. Los pasos restantes serán iguales a los discutidos anteriormente.

Incluiremos el archivo Trade usando el preprocesador #include

#include <Trade\Trade.mqh>

Luego crearemos un objeto comercial a partir de la clase CTrade.

CTrade trade;

Cuando se cumpla la condición de compra usaremos PositionOpen, el tipo de orden será ORDER_TYPE_BUY o un método de compra adicional, como en el siguiente código.

trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);

Cuando se cumpla la condición de venta, utilizaremos PositionOpen junto con el tipo de orden ORDER_TYPE_SELL o un método de venta adicional, como se muestra en el siguiente código.

trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);

A continuación le mostramos el código completo para crear un sistema comercial utilizando la clase CTrade:

//+------------------------------------------------------------------+
//|                                        CTrade_Trading_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
int simpleMA;
int barsTotal;
CTrade trade;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
        }
     }
  }

Conclusión

Hoy hemos analizado cómo funcionan las órdenes, posiciones y transacciones en MQL5; asimismo, hemos visto cómo crear un sistema comercial utilizando dos métodos de operaciones comerciales: OrderSend y CTrade.

También hemos definido la colocación de órdenes pendientes y de mercado, la adición de stop loss y take profit, la modificación de órdenes pendientes y la eliminación de órdenes pendientes utilizando estos dos métodos.

Además, hemos analizado dos aplicaciones sencillas para crear el mismo sistema comercial de cruce de medias móviles utilizando dos métodos.

  • OpenSend_Trading_System
  • CTrade_Trading_System

El propósito de las aplicaciones mencionadas consiste puramente en proporcionar una comprensión práctica de las diferencias entre ellas, así que tenga cuidado: deberá probarlas antes de usarlas en cualquier cuenta real para asegurarse de que resulten rentables y adecuadas para sus operaciones.

Confío en que aprecie la facilidad de uso de la clase CTrade ya lista para usar al trabajar con operaciones comerciales. Ahorra mucho tiempo y esfuerzo, aparte de otras características destacables de las clases de programación en general.

Si quiere aprender más sobre la programación orientada a objetos en MQL5, puede leer mi artículo anterior"Programación orientada a objetos (OOP) en MQL5". Espero que le sea útil. MQL5 ofrece las herramientas necesarias para el desarrollo y la creación de aplicaciones comerciales de forma sencilla y eficiente.

Esperamos que el artículo le resulte útil y le ayude a alcanzar sus objetivos comerciales. En la sección "Artículos" de mi perfil encontrará una serie de artículos sobre la creación de sistemas comerciales basados ​​en los indicadores técnicos más populares. Espero que los encuentre igualmente útiles.

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/13229

Teoría de categorías en MQL5 (Parte 19): Inducción cuadrática de la naturalidad Teoría de categorías en MQL5 (Parte 19): Inducción cuadrática de la naturalidad
Continuamos analizando las transformaciones naturales considerando la inducción cuadrática de la naturalidad. Pequeñas restricciones en la implementación de las capacidades multidivisa para los asesores ensamblados usando el wizard MQL5 significan que estamos demostrando nuestras capacidades en la clasificación de datos usando un script. Las principales áreas de aplicación son la clasificación de las variaciones de precios y, como consecuencia, su previsión.
Desarrollo de un sistema de repetición (Parte 28): Proyecto Expert Advisor — Clase C_Mouse (I) Desarrollo de un sistema de repetición (Parte 28): Proyecto Expert Advisor — Clase C_Mouse (I)
Cuando los primeros sistemas capaces de factorizar algo comenzaron a ser producidos, todo requería la intervención de ingenieros con un amplio conocimiento sobre lo que se estaba diseñando. Estamos hablando de los albores de la computación, una época en la que ni siquiera existían terminales que permitieran la programación de algo. A medida que el desarrollo avanzaba y crecía el interés para que más personas pudieran crear algo, surgían nuevas ideas y métodos para programar esas máquinas, que antes dependían de la modificación de la posición de los conectores. Fue entonces cuando aparecieron los primeros terminales.
Redes neuronales: así de sencillo (Parte 57): Stochastic Marginal Actor-Critic (SMAC) Redes neuronales: así de sencillo (Parte 57): Stochastic Marginal Actor-Critic (SMAC)
Hoy le proponemos introducir un algoritmo bastante nuevo, el Stochastic Marginal Actor-Critic (SMAC), que permite la construcción de políticas de variable latente dentro de un marco de maximización de la entropía.
Desarrollo de un sistema de repetición (Parte 27): Proyecto Expert Advisor — Clase C_Mouse (I) Desarrollo de un sistema de repetición (Parte 27): Proyecto Expert Advisor — Clase C_Mouse (I)
En este artículo, daremos vida a la clase C_Mouse. Está diseñada para permitir programar al más alto nivel posible. Sin embargo, hablar de programar a niveles altos o bajos no está relacionado con incluir palabrotas o jerga en el código. Todo lo contrario. Cuando mencionamos programación de alto o bajo nivel, nos referimos a lo fácil o difícil que es para otro programador entender el código.