EA not closing correctly on cross

 

Hi,

I've done an EA that is supposed to open a trade when the MA's are a certain distance apart and then close the order when they cross.

But the EA misses some crosses and closes at a later cross, sometimes even missing 2 crosses and closing on the third cross.

int direction = 0;
int prevDirection = 0;
string symb;
double numLots = 1;
int orderNumber;
int openOrderNumber;
double openOrderLots;
int start()
  {
//----
   symb = Symbol();
   double movingAverage5 = iMA(NULL, 0, 5, 0, MODE_SMA, PRICE_CLOSE, 0);
   double movingAverage5Prev = iMA(NULL, 0, 5, 0, MODE_SMA, PRICE_CLOSE, 1);
   double movingAverage18 = iMA(NULL, 0, 18, 0, MODE_SMA, PRICE_CLOSE, 0);
   double movingAverage18Prev = iMA(NULL, 0, 18, 0, MODE_SMA, PRICE_CLOSE, 1);
   double trigger = 35 * Point;
   //double xx = movingAverage5Prev - movingAverage18Prev;
   double movingAverageDif = MathAbs(movingAverage5Prev - movingAverage18Prev);
   if (movingAverageDif > trigger)
   {
      if (IsOrderOpen() == false)
      {
         if (direction > 0)
         {
            Alert("BUY!!");
            orderNumber = OrderSend(symb, OP_SELL, numLots, Bid, 2, 0, 0, NULL, 0, 0, Green);
         }
         else
         {
            Alert("SELL!!");
            orderNumber = OrderSend(symb, OP_BUY, numLots, Ask, 3, 0, 0, NULL, 0, 0, Red);
         }
         OrderSelect(orderNumber, SELECT_BY_TICKET);
         if (OrderType() == OP_BUY)
         {
            OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*200,0,0,Blue);
         }
         else
         {
            OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*200,0,0,Blue);   
         }
      }
   }
   else
   {
      if( movingAverage5Prev<movingAverage18Prev && movingAverage5>movingAverage18) 
      { 
         prevDirection = direction; 
         direction = 1; 
         if (prevDirection != direction) 
         {
            Alert("CLOSE SELL!!");
            OrderClose(openOrderNumber, openOrderLots, Ask, 3);
         } 
      }//Buy_Trigger
      if( movingAverage5Prev>movingAverage18Prev && movingAverage5<movingAverage18) 
      { 
         prevDirection = direction; 
         direction= -1; 
         if (prevDirection != direction) 
         {
            Alert("CLOSE BUY!!");
            OrderClose(openOrderNumber, openOrderLots, Bid, 3);
         } 
      }//Sell_Trigger
      //Not closing order so modify
      
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+

bool IsOrderOpen(){
   for(int i=0; i<OrdersTotal(); i++)                      // Loop through all open orders
   {                    
      if (OrderSelect(i,SELECT_BY_POS))                     // Select the open order at the position of the index
      {                   
         if (OrderType() > 1)
         {
            //Alert("Pending Order");
            return (true);                                  // Return true as pending order
         }
         if (OrderSymbol()== symb)
         {
            //Alert("Open Order Ticket ", OrderTicket());
            openOrderNumber = OrderTicket();
            openOrderLots = OrderLots();
            return (true);                                  // Return true (meaning order open for the current security)
         }
      }
   }
   //Alert("NO Open Order");
   return (false);
}

 

Why do you alert "Buy" when sending a sell order and v-v.?

Direction initiates as 0, so no matter whichever MA is above the other, the first order will be a sell.

If the next cross is 5 moving below 18 MA, the EA will try to close the sell order at Bid, which will fail.

You need to add some error handling code.

Also, if you have a pending order open, openordernumber may not get updated.

 
 
         prevDirection = direction; 
         direction = 1; 
         if (prevDirection != direction) 
         {
            Alert("CLOSE SELL!!");
            OrderClose(openOrderNumber, openOrderLots, Ask, 3);  //If this fails for whatever reason, direction has already been set to 
                                                                 // 1, so this will not be called again until there has been 2 more
                                                                 // crosses
         } 
 

Thanks GumRai! Your reasons explain exactly the issues I was seeing!

WHRoeder, have no idea why you linked that, but thanks... I think?

 
GBen:

Thanks GumRai! Your reasons explain exactly the issues I was seeing!

WHRoeder, have no idea why you linked that, but thanks... I think?

He gave you that link because you don't test the return values from any of your trading functions . . . don't you want to know if they fail ? and if they do fail don't you want to know what the error was ? or the values of the variables involved at the time so you can determine the cause of the failure ?
 
Ah, sorry. Thanks Raptor, makes sense. That sample above was not my full code, I just pulled out a sample from what would show the issue with the make order, close order. Sorry, should have been clearer. I do have a close order function that if errors tries again taken form these forums, I think it was actually you or WHRoeder who I stole it off :)
 
GBen:
Ah, sorry. Thanks Raptor, makes sense. That sample above was not my full code, I just pulled out a sample from what would show the issue with the make order, close order. Sorry, should have been clearer. I do have a close order function that if errors tries again taken form these forums, I think it was actually you or WHRoeder who I stole it off :)

You need to check all of your trading functions, not just OrderSend() . . . OrderSelect(), OrderModify(), OrderClose(), OrderDelete(), etc, etc . . . and then don't skimp on what you Print when there is an error, the error number is not enough, you need to Print everything you need to be able to go back and forensically figure out why your function failed.

You may think this is overkill but when trading live or Demo you can't go back in time and replay the exact scenario that caused the failure . . . not even with the Strategy Tester, so you need to gather the pertinent information in real time.

Reason: