Checking Candle Open

 

Hi guys,

I'm fairly new to coding in mql4 and have really been trying to get my first EA to work. I would honestly appreciate help with the following. It's just a basic cross-over so-to-speak, but instead of moving averages crossing over, it's just price crossing over a moving average.

I need an order to be triggered on Candle Open if: (Current candle open price is > than moving average) and if (the previous candle closed below the moving average).

So far, I have the following code in the main area:


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

int start()

  {

//---

    

  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);

  

//----------------------Main calculation starts here


   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);

  }

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

 

Whatever I do, I just can't seem to work, and I don't think I'm doing something right here. Again, I'd really appreciate the help! 

 
    

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

This value is changing while the candle is current

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

 This is not

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

 CurrentCandleOpen is unlikely to be a valid entry price for many ticks

If you must use this logic, only calculate once when a new bar opens. 

Check the return values if the OrderSend fails 

 
GumRai:

This value is changing while the candle is current

 This is not

 CurrentCandleOpen is unlikely to be a valid entry price for many ticks

If you must use this logic, only calculate once when a new bar opens. 

Check the return values if the OrderSend fails 


Thanks for the quick response! Let me see if I understood that correctly:

  1. The CurrentSlow won't really work, because it is still forming. Okay, that's fine, I can use the value of the moving average that formed for the previous candle. That shouldn't be a problem.
  2. Since CurrentCandleOpen is not a moving value...then I'm assuming that part of the code is correct?
  3. How can I make this work, so that it is close enough to the CandleOpen?--You have mentioned to only calculate once when a new bar opens. Could you please expand on that? I don't quite know how to do that
Thanks again GumRai. 

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

   
The code within the curly brackets will only be executed at the first tick of a new bar
 
GumRai:
The code within the curly brackets will only be executed at the first tick of a new bar

Thanks for the code! I updated the following as discussed earlier:

  1. Changed MA's current slow to Previous Slow.
  2. Removed CurrentCandleOpen with Ask. Whenever I used CurrentCandleOpen, instead of Ask, it did not take any trades. However, when I replaced that with Ask, it worked, but of course trades whenever Ask crosses the MA, and not on Candle open.

But after this, when I put it in your code as follows, it's not taking any trades again at all. Have I inserted this correctly?

 

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);
  }
 

Why place the iMA calls outside of the new bar code? That means that they are called every tick when not needed - inefficient.

   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
               }
     }

 Don't use Ask to compare values on an MT4 chart, they are based on the Bid price

Check for errors if the OrderSend fails.

You may not get many instances where the first tick of a new bar is above an MA when the last tick of the previous bar was below it. 

 

Thank you so much GumRai. I genuinely appreciate the help.

 Your code works like a charm. I'm still trying to learn the ropes here, and saw the iMA being put on it's own like that separately. Will follow your method instead.

***smacks self on the head***

I'll re-work my code. Your last line pointed out the flaw in what I wanted and what actually I coded.

What I actually need to do is:

  • Step 1 candle closes below MA, 
  • step 2: Candle crosses and closes above MA 
  • Step 3: enter trade on new candle open.

Last question, and I think I've got it...

for the Step 1 above, the iMA, the SlowMaShift would be 2 correct? Since it is 2 bars behind? and the iClose would be: iClose(NULL,0,2) for that comparison correct?

 

Seems like you have the idea.

Modify and post your code and I or someone else will comment on it 

 
GumRai:

Seems like you have the idea.

Modify and post your code and I or someone else will comment on it 

I was able to make it work! Thanks GumRai.
Now I'm doing the same but using the opposite rules to take the short. Independently that works fine, but I don't know how to use the OrderCloseBy function so that if the long is open, and the short triggers, it closes the long primarily because I have no clue on how to find the order ticket... I tried bypassing the OrderCloseBy by doing the following:

 

 

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)

cannot be satisfied as it is inside the condition block

 

         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);
           }
        }
     }

 

 I think that the above is more like you intended

You should check error return codes 

 
GumRai:

 I think that the above is more like you intended

You should check error return codes 

Thanks for the code...unfortunately, didn't really work, since it now enters a short more than once. Here's what I've tried to do instead--I'm breaking it down separately--long entry and exit, and then I'll create the opposite for short entry and exit. It'll be more manageable for me, and a bit easier to tweak. I'm working on just getting the long entry and exit part down first. But somehow, this isn't closing trades when the candle closes below the Moving Average for the short. Any idea what I'm doing wrong? It gives an error: Return value of 'OrderClose' should be checked. I googled for a solution all morning, but it doesn't seem to work.

 

   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);
          
        }
     

Update: I've gotten rid of the error code but the close ticket still doesn't seem to work. All I want is for it to close the buy once the candle crosses over and closes below the MA.

Reason: