¿Un poco de ayuda?

 

Así que estoy aprendiendo mql4 después de otros lenguajes, y yo (o eso creía) acabo de terminar la primera versión de mi primer EA, un simple trader de media móvil. Lo dejé funcionando durante todo el día de ayer sin ninguna preocupación, la entrada y la salida eran las esperadas, y pensé que estaba listo para funcionar. Esta mañana me he encontrado con todo tipo de problemas, primero, el código cuando lo reanudé sólo vendía sin tener en cuenta la posición, y ahora, después de un poco de manipulación, comprará y venderá en las posiciones correctas, pero al comprar la operación se cerrará en el siguiente tick sin tener en cuenta. Esto no sucede cuando estoy vendiendo a pesar de mantener el mismo formato - ¿puede alguien indicarme por qué?

(Como nota al margen, mi equipo fue capaz de ejecutar el código de todo el día de ayer sin mucho más de un zumbido (CPU promedio de 12%) hoy su ir como campanas del infierno para ejecutar el código (~ 60-90%))

Código:

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

No he profundizado demasiado en su código

¡¿Por qué RefreshRates y luego dormir durante 1 segundo, cuando el mercado se está moviendo rápidamente, los datos estarán fuera de fecha!

Estás calculando en ticks, no en barras, así que 1 tick puede activar una orden por una MA que se mueva por encima/por debajo de la otra por una cantidad mínima. Si el siguiente tick (después del sueño) se invierte, las MAs se cruzan de nuevo y la orden se cerrará.

 

La idea es simplemente mantener en el bucle mientras que las condiciones esperan hasta que las condiciones de cierre se producen (Aka el cambio de sma) - es cierto que no es la mejor manera de hacerlo, pero uno de los más baratos computacionalmente.

Las SMA's se mueven rápidamente por encima/debajo de cada una es uno de los problemas del código - pero no veo ninguna razón por la cual, cuando hay actualmente 10 - 15 pips entre las dos que estoy ejecutando, llevaría a cerrar... las condiciones son definitivamente sostenidas para que el bucle while permanezca en control, en lugar de saltar instantáneamente al cierre (mi suposición es que el bucle while está siendo ignorado para la compra pero no para la venta - y no sé por qué)

 
j.w.msb:

La idea es simplemente mantener en el bucle mientras que las condiciones esperan hasta que las condiciones de cierre se producen (Aka el cambio de sma) - es cierto que no es la mejor manera de hacerlo, pero uno de los más baratos computacionalmente.

Las SMA's se mueven rápidamente por encima/debajo de cada una es uno de los problemas del código - pero no veo ninguna razón por la que, cuando hay actualmente 10 - 15 pips entre las dos que estoy ejecutando, llevaría a cerrar... las condiciones son definitivamente sostenidas para que el bucle while permanezca en control, en lugar de saltar instantáneamente al cierre (mi suposición es que el bucle while está siendo ignorado para la compra pero no para la venta - y no sé por qué)


Si sólo estás comprobando si una MA está por encima/debajo de la otra, dudo que sea normalmente de 10 a 15 pips de diferencia, puede ser de 0,1 pips y así el siguiente tick puede revertirlo fácilmente.

Es sólo mi opinión, pero cuando se trabaja con cruces, creo que es mejor calcular sólo en barras cerradas para evitar demasiadas señales contrarias

 

También en tu init

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

tu else sólo se aplica al último if, así que si el EA no cierra una orden de venta abierta, el total se incrementará en 1. ¿Por qué quieres esto?

 
GumRai:


Si sólo se está comprobando si una MA está por encima/debajo de la otra, dudo que sea normalmente de 10 a 15 pips de diferencia, puede ser de 0,1 pips y así el siguiente tick puede revertirlo fácilmente.

Es sólo mi opinión, pero cuando se trabaja con cruces, creo que es mejor calcular sólo en barras cerradas para evitar demasiadas señales contrarias


fue un error de cálculo de mi parte en términos de pips! mi culpa! Pero el punto es que ciertamente hay un espacio de respiro entre los dos para que no haya una señal de cruce que fuerce la venta. Reemplazando el Sleep(1000) con while (TimeSecond(TimeCurrent)!=59) {Sleep(1000)} aseguraría la prueba del crossover sólo en el cierre de la vela?


He quitado el OrderClose en la sección de compra y la orden sigue abriéndose al ejecutarse y cerrándose en el siguiente pip :s


Luego he cambiado OP_BUY y OP_SELL y la venta se mantiene como se esperaba cuando la 6SMA está por encima de la 21SMA - estoy esperando el próximo cruce para ver qué pasa (obviamente estoy probando esto en el marco de tiempo de un minuto por el momento)

 

Hay mucho que cambiar..... una cosa para trabajar

¿Qué magicnumber tienen los oficios de su EA está creando ...

por qué no lo hace como una variable de entrada externa para que pueda hacer un número único y no es el cierre de las operaciones de otros EA

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

lo que pasa aquí...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(O rderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

no cuentes con la comprobación de las operaciones, fallará si cierras las operaciones dentro del bucle como haces ahora

Echa un vistazo aquí para ver por qué tienes que trabajar y cómo contar hacia abajo

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

esta condición puede cambiar varias veces en pocos momentos cuando un nuevo tick viene en cada comercio que usted paga spread

condición no es siempre cambiar una vez ....on una sola barra

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

lo que siempre se ejecuta se deja dormir

y de manera normal cuando el tick esta hecho y el nuevo tick viene se llama a start() de nuevo

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

de esta manera ejecutando el código sólo cuando el segundo es 0 fallará a menudo

porque puede ocurrir a menudo que en un segundo no llegue un nuevo tick

si el primer tick del minuto llega a 1 segundo tienes que esperar el nuevo minuto y esperar que el nuevo tick llegue al segundo 0 el próximo minuto

Comprueba la función RefreshRates()

hay más cosas como hacer que funcione tanto el broker de 4 como el de 5 dígitos

comprobar returncodes....

El deslizamiento de su valor 0 ¿por qué es necesario? para tenerlo más grande

 
deVries:

Hay mucho que cambiar..... una cosa para trabajar

¿Qué magicnumber tienen los oficios de su EA está creando ...

por qué no lo hace como una variable de entrada externa para que pueda hacer un número único y no es el cierre de las operaciones de otros EA

lo que pasa aquí...

no cuentes con la comprobación de las operaciones, fallará si cierras las operaciones dentro del bucle como haces ahora

Echa un vistazo aquí para ver por qué tienes que trabajar y cómo contar hacia abajo

https://www.mql5.com/en/forum/139654

esta condición puede cambiar varias veces en pocos momentos cuando un nuevo tick viene en cada comercio que usted paga spread

condición no es siempre cambiar una vez ....on una sola barra

lo que siempre se ejecuta se deja dormir

y de manera normal cuando el tick esta hecho y el nuevo tick viene se llama a start() de nuevo

de esta manera ejecutando el código sólo cuando el segundo es 0 fallará a menudo

porque puede ocurrir a menudo que en un segundo no llegue un nuevo tick

si el primer tick del minuto llega a 1 segundo tienes que esperar el nuevo minuto y esperar que el nuevo tick llegue al segundo 0 el próximo minuto

Comprueba la función RefreshRates()

hay más cosas como hacer que funcione tanto el broker de 4 como el de 5 dígitos

comprobar returncodes....

El deslizamiento de su valor 0 ¿por qué es necesario? para tenerlo más grande

¡gracias por su ayuda, estoy haciendo cambios ahora y voy a ver cómo va! ¡Errores tontos agravados por errores estúpidos de mi parte! ¡Es casi una maravilla por qué se ejecutó en el primer lugar!
 

Por lo tanto, despojé el código para que se ejecute en la más simple de las capacidades (es decir, el cruce = posiciones inversas) - su causando un montón de órdenes de compra / venta cuando las dos SMA están cerca, pero Im no se preocupe por eso (por ahora) y se ejecuta bien en una cuenta de demostración. Lo que me preocupa ahora es que si ejecuto mi código en el Probador de Estrategias, abre la primera posición correctamente, pero luego no avanza en el tiempo, por lo que las SMA nunca se cruzan. ¿Qué estoy haciendo mal? Mi lista de impresión es:

2013.10.22 23:41:26 2013.09.18 00:41 Comprobador: la orden #1 está cerrada

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1: cargado con éxito

Código:



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: Lo que me preocupa ahora es que si ejecuto mi código en el Probador de Estrategias, abre la primera posición correctamente, pero luego no avanza en el tiempo,
  1. int start(){
       while (AccountBalance()>50){
          :
    Por supuesto que no. RTFM. Sólo se obtiene un nuevo tick cuando se vuelve del inicio.
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM & Limitaciones del probador NO se puede dormir en el probador
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    ¿Qué son los valores de retorno de las funciones? ¿Cómo los utilizo? - Foro MQL4
 
RefreshRates no cambia ningún valor en el probador, por lo que está atascado en un bucle while porque no tiene ningún valor nuevo con el que trabajar.