Discusión sobre el artículo "Guía paso a paso para escribir un Expert Advisor en MQL5 para principiantes"

 

Artículo publicado Guía paso a paso para escribir un Expert Advisor en MQL5 para principiantes:

La programación de los Expert Advisors en MQL5 es sencilla, y se puede aprender con facilidad. En esta guía paso a paso, podrás ver los pasos básicos que requiere la escritura de un Expert Advisor sencillo, basándose en una elaborada estrategia de trading. La guía incluye la estructura de un Expert Advisor, el uso de los funciones de trading e indicadores técnicos integrados, los detalles del modo depuración y el uso del Simulador de estrategias.

Figure 15. Debugger stops at the first breakpoint

Autor: Samuel

 

¡¡Hola!! muy buen tutorial, está bien explicado. ¡Gracias!

Pero tengo un problema, me aparecé este error:

  mercado fallido comprar 0.10 EURUSD sl: 1.04917 tp: 1.06217 [Solicitud no válida]

 Alerta: no se pudo completar la solicitud de pedido de compra-error: 4756


 

Hola, en el archivo .mq5 descarcable hay dos errores:

En las líneas 210 y 256 el atributo "type_filling" debe ser ORDER_FILLING_FOK en lugar de ORDER_FILLING_AON, quedaría así: mrequest.type_filling = ORDER_FILLING_FOK;

Un saludo!

 

Hola, me aparece un error:

return value of ´OrderSend´should be checked líneas 213 y 259


lo habéis resuelto?

 
Tchuso:

Hola, me aparece un error:

return value of ´OrderSend´should be checked líneas 213 y 259


lo habéis resuelto?

Buenos días Tchuso,

A mi me pasó lo mismo. Lo arreglé sustituyendo esas líneas en ambas operaciones por esto.

if(!OrderSend(mrequest,mresult))
PrintFormat("OrderSend error %d",GetLastError());

Dime si te vale la ayuda que yo también soy nuevo.

Un saludo!

 

El ódigo de ejemplo me gusta bastante, soy nuevo en esto tambien, arregle el codigo tal como aparece en los comentarios y ya no da errores.

El problema es que el robot no abre operacciones, ni siquiera abre una operación

¿Alguno pudo resolver este problema?


Estoy usando La opción "Unico" del probador de estrategías: ¿Es un error mio?


Gracias por su tiempo y en apoyarme
 


Me di cuenta que el Robot intenta abris las ordenes pero siempre da error:


Salida:

2020.05.06 20:35:16.141    Core 1    2020.04.20 20:25:00   failed market sell 0.10 EURUSD sl: 1.08965 tp: 1.07665 [Invalid request]


He cambiado Varias cosas en el código pero ne se me da, les agrego el código que tengo:


Original: mrequest.type_filling = "Lo he puesto de las 3 formas que estan en la documentación"

 mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // latest ask price
         mrequest.sl = NormalizeDouble(latest_price.ask - STP*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits); // Take Profit
         mrequest.symbol = _Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_BUY;                                        // Buy Order
         mrequest.type_filling = ORDER_FILLING_RETURN;                             // Order execution type
         mrequest.deviation=100;                      
        



Tambien he probado este codigo:

 //--- declaracion e inicializacion de la solicitud y el resultado
               MqlTradeRequest request={0};
               MqlTradeResult  result={0};
            //--- parametros de la solicitud
               request.action   =TRADE_ACTION_DEAL;                     // tipo de operacion comercial
               request.symbol   =Symbol();                              // simbolo
               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;                                     // desviacion permisible del precio
               request.magic    =EA_Magic;                          // Numero magico de la orden

               //--- envio de la solicitud
               if(!OrderSend(request,result))
               PrintFormat("OrderSend error %d",GetLastError());     // si no se ha logrado enviar la solicitud, introducir el codigo de error
               //--- informacion sobre la operacion
               PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);

        

 
Libni Colina:


Me di cuenta que el Robot intenta abris las ordenes pero siempre da error:


Salida:

2020.05.06 20:35:16.141    Core 1    2020.04.20 20:25:00   failed market sell 0.10 EURUSD sl: 1.08965 tp: 1.07665 [Invalid request]


He cambiado Varias cosas en el código pero ne se me da, les agrego el código que tengo:


Original: mrequest.type_filling = "Lo he puesto de las 3 formas que estan en la documentación"

        

Añade esto arriba del codigo:

#include <Trade\Trade.mqh>

Y luego para abrir una operacion solo tienes que escribir esto:

double volumen= 0.01; // O el volumen que quieras

CTrade m_trade;

m_trade.Buy(volumen); // Compra

m_trade.Sell(volumen); // Vende
 
Buen día, Si alguien me pudiera ayudar por favor. A mi entender, hice todo lo que se indica en el articulo. Pero no logro poder tener dos operaciones simultaneas abiertas, mas allá de lo que entiendo que el autor quiso hacer de no colocar compra si ya había compra o venta si ya había venta. Mi estrategia, manda por ejemplo señal de venta cuando tengo una orden abierta de compra, y en lugar de abrir una venta, el codigo me cierra la operación de compra sin que esta pueda tocar el tp/sl. Y asi me quedo sin venta ni compra. La venta cierra compra y compra cierra venta. Estoy usando en mi estrategia solo un par, solo una temporalidad y solo un tamaño de lote. Me podrían decir como puedo tener compra y venta abiertas al mismo tiempo si así lo llega a activar la estrategia? Es decir, que las ordenes ÚNICAMENTE se cierren mediante tp/sl. De antemano, muchas gracias.
 

Hola, 

Muchas gracias por el artículo Samuel. ¡Eres un crack!

Me ha costado un poco que me funcionase con mi broker porque el artículo es en versión en modo "net" y he tenido que buscar información para ponerlo en modo "hedging". El primer problema que me encontré es con el mrequest.type_filling. 

Para el broker XM, el que funciona es: 

mrequest.type_filling = ORDER_FILLING_IOC;                                          // Tipo de ejecución de la orden

Si no sabes cual es la que permite tu MT5, mi recomendación es que uses la función TypeFilling() en un Print(TypeFilling()) o un Comment( TypeFilling()) y este devuelve el tipo; si te dice que es 1 (ORDER_FILLING_FOK) o 2 (ORDER_FILLING_IOC) ya sabes cual tienes que poner (https://www.mql5.com/es/docs/constants/tradingconstants/orderproperties#enum_order_type_filling) ya que a mi el  ORDER_FILLING_FOK (1) no me funciona con este broker. 


Una vez arreglado eso, el problema es que con el PositionSelect abre muchísimas posiciones. Aunque no lo dice Samuel en su estrategia, entiendo que el objetivo es abrir una única posición buy o sell (la que primero se de) con el criterio establecido (los 4 pasos booleanos) y que hasta que no se cierre esta posición, no podemos abrir otra. 

Yo lo que he hecho es cambiar este código ...

//--- no tenemos errores, así que continuamos
//--- ¿Tenemos posiciones abiertas ya?
    bool Buy_opened=false;  // variable que almacena el resultado de la posición abierta Compra
    bool Sell_opened=false; // variable que almacena el resultado de la posición abierta Venta
    
    if (PositionSelect(_Symbol) ==true)  // tenemos una posición abierta
    {
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
            Buy_opened = true;  // Es una Compra
         }
         else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
            Sell_opened = true; // Es una Venta
         }
    }

Por este... 

//--- No tenemos errores así que continuamos
//--- ¿Tenemos posiciones abiertas ya?
   bool Buy_opened = false;               // Variable que almacena el resultado de la posición abierta de Compra
   bool Sell_opened = false;              // Variable que almacena el resultado de la posición abierta de Venta
   
   // Vamos a recorrer todas las órdenes para ver si hay alguna abierta
   for(int i = 0; i < PositionsTotal(); i++)   
        {
         ulong ticket = PositionGetTicket(i);
         PositionSelectByTicket(ticket);
    
    if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
         {
          Buy_opened = true;       // es una compra
         }
         else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
         {
          Sell_opened = true;      // es una venta
         }
   }

// si hay una posición abierta esperamos hasta que la operación activa se cierre (que toque el SL o elTP)
   if (Buy_opened || Sell_opened) return; 

Nota: Justo después viene la linea...

//--- Copiar el precio de cierre de la barra anterior a la barra actual, que es la barra1
   p_close=mrate[1].close;

De esta forma me ha funcionado bien. Espero que os sirva. 

Un saludo.