Comprobación de la apertura de la vela

 

Hola chicos,

Soy bastante nuevo en la codificación en mql4 y he estado tratando de conseguir mi primera EA para trabajar. Honestamente agradecería ayuda con lo siguiente. Es sólo un cruce básico por así decirlo, pero en lugar de promedios móviles que se cruzan, es sólo el precio que cruza sobre una media móvil.

Necesito una orden que se active en la apertura de la vela si: (El precio de apertura de la vela actual es > que la media móvil) y si (la vela anterior cerró por debajo de la media móvil).

Hasta ahora, tengo el siguiente código en el área principal:


//+------------------------------------------------------------------+

int inicio()

{

//---

double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);

double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);

double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);

double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);

double PreviousPriceClose= iClose(NULL, 0, 1);

double CurrentCandleOpen= iOpen(NULL,0,0);

//----------------------El cálculo principal comienza aquí


if(PreviousPriceClose<PreviousSlow && (CurrentCandleOpen>(CurrentSlow))

if(OrdersTotal () == 0)

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

//--------------

return(0);

return(0);

}

//+------------------------------------------------------------------+

Haga lo que haga, parece que no me funciona y creo que algo estoy haciendo bien. De nuevo, ¡agradecería mucho la ayuda!

 
    

  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);   

Este valor está cambiando mientras la vela es actual

double CurrentCandleOpen= iOpen(NULL,0,0);

Esto no es

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

Espoco probable que CurrentCandleOpen sea un precio de entrada válido para muchos ticks

Si debe utilizar esta lógica, calcule sólo una vez cuando se abra una nueva barra.

Compruebe los valores de retorno si el OrderSend falla

 
GumRai:

Este valor está cambiando mientras la vela es actual

Esto no es

Espoco probable que CurrentCandleOpen sea un precio de entrada válido para muchos ticks

Si debe utilizar esta lógica, calcule sólo una vez cuando se abra una nueva barra.

Compruebe los valores de retorno si el OrderSend falla


Gracias por la rápida respuesta. A ver si lo he entendido bien:

  1. El CurrentSlow no funcionará realmente, porque todavía se está formando. Vale, está bien, puedo usar el valor de la media móvil que se formó para la vela anterior. Eso no debería ser un problema.
  2. Dado que CurrentCandleOpen no es un valor móvil... ¿asumo que esa parte del código es correcta?
  3. ¿Cómo puedo hacer que esto funcione, para que esté lo suficientemente cerca de CandleOpen? ¿Podría ampliar esto? No sé muy bien cómo hacerlo.
Gracias de nuevo GumRai.

 
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      //Code to process the signal
     }

   
El código dentro de las llaves sólo se ejecutará en el primer tick de una nueva barra
 
GumRai:
El código dentro de los corchetes sólo se ejecutará en el primer tick de una nueva barra

¡Gracias por el código! Actualicé lo siguiente como se discutió anteriormente:

  1. Cambié la lentitud actual de MA por la lentitud anterior.
  2. Eliminado CurrentCandleOpen con Ask. Siempre que usaba CurrentCandleOpen, en lugar de Ask, no tomaba ninguna operación. Sin embargo, cuando reemplacé eso con Ask, funcionó, pero por supuesto comercia cada vez que Ask cruza la MA, y no en Candle open.

Pero después de esto, cuando lo puse en su código de la siguiente manera, no está tomando ningún comercio de nuevo en absoluto. ¿He insertado esto correctamente?

int start()
  {
//---
    
  double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);     //1 at the end signifies that we want it on candle close

  double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);     //1 at the end signifies that we want it on candle close
   
  double PreviousPriceClose= iClose(NULL, 0, 1);
  double CurrentPriceClose= iOpen(NULL, 0, 0);
  
//----------------------Main calculation starts here

 static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
   if(PreviousPriceClose<PreviousSlow && Ask>PreviousSlow)
      if(OrdersTotal () == 0)
         BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,Ask, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);
   }
//--------------
   return(0);
   return(0);
  }
 

¿Por qué colocar las llamadas de iMA fuera del nuevo código de barras? Eso significa que se llaman cada tick cuando no se necesitan - ineficiente.

   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod, SlowMaAppliedTo,1);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(PreviousPriceClose<PreviousSlow && Bid>PreviousSlow)
         if(OrdersTotal()==0)
            {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
            if(BuyTicket==-1)
               {
               //Error checking code
               }
     }

No utilice Ask para comparar valores en un gráfico MT4, se basan en el precio Bid

Compruebe si hay errores si el OrderSend falla.

No hay muchos casos en los que el primer tick de una nueva barra esté por encima de una MA cuando el último tick de la barra anterior estaba por debajo.

 

Muchas gracias GumRai. Realmente aprecio la ayuda.

Tu código funciona de maravilla. Todavía estoy tratando de aprender las cuerdas aquí, y vio el iMA se pone en su propia como que por separado. Voy a seguir su método en su lugar.

***Se golpea a sí mismo en la cabeza***

Voy a rehacer mi código. Su última línea señaló el defecto en lo que quería y lo que realmente codificado.

Lo que realmente necesito hacer es:

  • Paso 1 la vela cierra por debajo de la MA,
  • Paso 2: La vela cruza y cierra por encima de la MA
  • Paso 3: entrar en el comercio en la nueva vela abierta.

Última pregunta, y creo que lo tengo...

para el paso 1 de arriba, el iMA, el SlowMaShift sería 2 correcto? Ya que está 2 barras atrás? y el iClose sería: iClose(NULL,0,2) para esa comparación correcta?

 

Parece que tienes la idea.

Modifica y publica tu código y yo o alguien más lo comentará

 
GumRai:

Parece que tienes la idea.

Modifica y publica tu código y yo o alguien más lo comentará

¡He podido hacerlo funcionar! Gracias GumRai.
Ahora estoy haciendo lo mismo pero usando las reglas contrarias para tomar el corto. Independientemente eso funciona bien, pero no sé cómo usar la función OrderCloseBy para que si el largo está abierto, y el corto se dispara, cierre el largo principalmente porque no tengo idea de cómo encontrar la entrada de la orden... He intentado evitar el OrderCloseBy haciendo lo siguiente:

int start()
  {
//---
 static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod, SlowMaAppliedTo,1);
      double PreviousSlow2 = iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod, SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      double PreviousPriceClose2=iClose(NULL, 0,2);
      if(PreviousPriceClose2<PreviousSlow2 && PreviousPriceClose>PreviousSlow && Bid>(PreviousSlow+PipsBeforeEntry*Pips))
         if(OrdersTotal()==0)
            {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)
         {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink) && OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
                  }
         if(OrdersTotal()==0)
         {
            OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
            }
     }
//--------------
   return(0);
   return(0);
  }
  return(0);
  }
 
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)

no puede satisfacerse porque está dentro del bloque de condiciones

         if(OrdersTotal()==0)

   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && PreviousPriceClose>PreviousSlow && Bid>(PreviousSlow+PipsBeforeEntry*Pips))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
        {
         if(OrdersTotal()==1)
           {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
         else
         if(OrdersTotal()==0)
           {
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
        }
     }

Creo que lo anterior es más parecido a lo que pretendías

Deberías comprobar los códigos de retorno de los errores

 
GumRai:

Creo que lo anterior es más bien lo que pretendías

Usted debe comprobar los códigos de retorno de error

Gracias por el código ... por desgracia, no funcionó realmente, ya que ahora entra en un corto más de una vez. Esto es lo que he tratado de hacer en su lugar - Estoy dividiendo por separado - entrada y salida larga, y luego voy a crear lo contrario para la entrada y salida corta. Será más manejable para mí, y un poco más fácil de ajustar. Estoy trabajando en sólo conseguir la entrada larga y la parte de salida hacia abajo en primer lugar. Pero de alguna manera, esto no es el cierre de las operaciones cuando la vela se cierra por debajo de la media móvil para el corto. ¿Alguna idea de lo que estoy haciendo mal? Da un error: El valor de retorno de 'OrderClose' debe ser comprobado. He buscado una solución en Google toda la mañana, pero no parece funcionar.

   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && PreviousPriceClose>PreviousSlow && Bid>(PreviousSlow+PipsBeforeEntry*Pips))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow && Bid<PreviousSlow)
        {
          OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
          
        }
     

Actualización: He eliminado el código de error pero el ticket de cierre sigue sin funcionar. Todo lo que quiero es que cierre la compra una vez que la vela cruce y cierre por debajo de la MA.

Razón de la queja: