Need a hand with a simple pending order issue (Edit: things just got a little wierd)

 

I am trying to write a section in my EA that will delete a pending order if a signal is received to enter a trade. I have tried a couple of ways which are pasted below.

Basically the script should find the most recent (unopened) BUYSTOP and close it if there is a signal to open a SELLSTOP (SELLsignal).

Seems simple enough but the entire block does not seem to be called as none of the check messages are printed in the journal.

The first code is for deleting BUYSTOP only (in the interest of space) and the second is for both BUYSTOP and SELLSTOP.

I realise this question has been asked a million times but for the life of me I can't seem to get this working. Both bits of code are based on answers and solutions from similar threads with a few changes.

Any help with what is no doubt a simple problem would be great.

Thanks :)

for(cnt=OrdersTotal()-1;cnt>=0;cnt--){
   if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
      if(OrderType()>=OP_BUYLIMIT && OrderSymbol()==Symbol()
         && OrderMagicNumber()==MagicNumber
         && iBarShift(NULL,0,OrderOpenTime(),false)>0){
            
if(OrderType()==OP_BUYSTOP)
      {
       if(SELLsignal)
      {            
       deleted=orderDeleteReliable(OrderTicket());
       if (deleted>0)
         {
          Print("BUYSTOP order ",OrderTicket()," deleted by signal");
          return(1);
         }
         else
         {
          Print("Deleting BUYSTOP order ",OrderTicket(), " failed @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
          return(1);
         }
      }         
   }

}
} 
{
int j,a;
for (j=total-1; j >=0; j--)
   {
    OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
    if(OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)
   {
for (a=total-1; a >=0; a--)
   {
    OrderSelect(a,SELECT_BY_POS,MODE_TRADES);


   if(OrderType()==OP_SELLSTOP)
     {
      if(BUYsignal)
     {  
      OrderDelete(OrderTicket());
      Print("Deleting SELLSTOP",OrderTicket(), " @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
      return(1);
     }
     } 
      
      
   if(OrderType()==OP_BUYSTOP)
     {
      if(SELLsignal)
     { 
      OrderDelete(OrderTicket());
      Print("Deleting BUY_STOP"," Ordertype:",OrderType());
      return(1);
     }
     }
}}}}  
 

Ok, so I have made a little progress over the past 24hrs. Here is the order delete/replace code in its current form.

for(cnt=OrdersTotal()-1;cnt>=0;cnt--){
   if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)) continue;{
      if(OrderSymbol()==Symbol() && 
         OrderMagicNumber()==MagicNumber){
            
if(OrderType()==OP_BUYSTOP)
      {
       if(SELLsignal)
       Print("SELLsignal: ",SELLsignal);
      {            
       deleted=OrderDelete(OrderTicket());
       if (deleted>0)
         {
          Print("BUYSTOP order ",OrderTicket()," deleted by signal");
          if(!orderSendReliable(Symbol(),OP_SELLSTOP,Lots,NormalizeDouble(Bid-TradeGap*pips2dbl,Digits),Slippage*pips2points,0,
               NormalizeDouble(Bid-(TakeProfit*pips2dbl+TradeGap*pips2dbl),Digits),"macd sample",MagicNumber,0,Red));
          Print("Could not replace BUYSTOP: ",OrderTicket()," @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));  
         }
         else
         {
          Print("Deleting BUYSTOP order ",OrderTicket(), " failed @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
          return(0);
         }
      }
      }
    
if(OrderType()==OP_SELLSTOP) 
     {
       if(BUYsignal)
       Print("BUYsignal: ",BUYsignal);
      {           
       deleted=OrderDelete(OrderTicket());
       if (deleted>0)
         {
          Print("SELLSTOP order ",OrderTicket()," deleted by signal");
          if(!orderSendReliable(Symbol(),OP_BUYSTOP,Lots,NormalizeDouble(Ask+TradeGap*pips2dbl,Digits),Slippage*pips2points,0, 
               NormalizeDouble(Ask+(TakeProfit*pips2dbl+TradeGap*pips2dbl),Digits),"macd sample",MagicNumber,0,Red));
          Print("Could not replace SELLSTOP: ",OrderTicket()," @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));     
         }
         else
         {
          Print("Deleting SELLSTOP order ",OrderTicket(), " failed @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
          return(0);
         }
       }
      }     
    }
   }
  }

This loop works though there is one very peculiar anomaly. 

The loop will only find and delete pending orders as instructed if the following scripts "ord" variable is set to >1. This unacceptably allows two orders to exist simultaneously.

for(i=0;i<total;i++)
   {
    OrderSelect(i,SELECT_BY_POS);
    if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)ord++;
   }

if(ord>1)      <----If this value is set to 0 (thus allowing only 1 trade to exist at a time) then the delete order fails to operate) 
   return (0); //Abort! A Position For This Pair is Already Open

I'm not entirely sure what is going on here. Could someone please help me understand why I must allow two trades to exist for orders to be deleted. I fell it has something to do with the "for" loop which counts the orders for the deletion/replacement operations.

Any ideas?

 
  1. Always count down Loops and Closing or Deleting Orders - MQL4 forum
  2. Always check OrderSelect return codes What are Function return values ? How do I use them ? - MQL4 forum
  3.        deleted=OrderDelete(OrderTicket());
           if (deleted>0)
    
    OrderDelete does not return an int
  4. "why I must allow two trades to exist for orders to be deleted" You haven't posted any code that shows the problem - post all the code. Are you setting ord=0 before counting?
 

Hi William,


Thanks for the response.

All loops must count down? I thought this only applies to loops that were searching for an order, not counting total orders. Obviously I was wrong :S

Is the method that the orderselect is checked in the first loop correct?

if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)) continue;
 
Or should it be something like this
if(OrderSelect(cnt,SELECT_BY_POS,MO DE_TRADES)==true){


I set ord=0 before the loop on the way out the door this morning and it didn't seem to solve the problem (even though it is the correct thing to do).

I will have to make the changes to orderselect and the loop decrement when I get home tonight.

As for the the order deletion itself, I didn't realise OrderDelete was a bool ooperator. I guess the correct check for this would be:

deleted=OrderDelete(OrderTicket());
if(deleted)

Thanks again.

 

Ok so some more progress today.

I went through and checked/fixed all the spots where there should be return values checked and now have an EA which is alert free when compiled in the editor.

I also fixed all the loops so they decrement and made sure the correct data type were being used for the return values.

After all that, it turned out that the issue (well one of them) with the order delete loop was some out of place {} immediately preceding that loop which led to a return command being outside of the {} and thus returning the EA to start before the delete loop was reached.

Now, where I am at, is still with the loop. The loop operates and deletes pending orders and replaces them with an order of the opposite pending-stop type.

The problem now is, when I add a condition in the loop to only delete the order under a specific condition, it no longer operates.

The condition is calculated further upstream in the EA and is used for the initial sending of orders. A print statement (highlighted below) returns the values under which the order was deleted. These values are used to generate bool BUYsignal and bool SELLsignal. The values are calculated from indicator values and as mentioned above, all values and bool operators behave normally when they are used to place orders.


Any suggestions as to why these bool operators are not being called correctly from the preceding code yet the values used to generate them are called normally?

//+------------------------------------------------------------------+
//|      Delete Pending Orders when opposite signal recieved         |
//+------------------------------------------------------------------+
int del=0;
RefreshRates();

for(del=OrdersTotal()-1;del>=0;del--){
   if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)){
      if(OrderSymbol()==Symbol() && 
         OrderMagicNumber()==MagicNumber){
            
if(OrderType()==OP_BUYSTOP)
//if(SELLsignal)
      {            
       if(OrderDelete(OrderTicket()))
         {
          Print("BUYSTOP order ",OrderTicket()," deleted by signal slope12: ", slope12," slope13: ",slope13);
          if(orderSendReliable(Symbol(),OP_SELLSTOP,Lots,NormalizeDouble(Bid-TradeGap*pips2dbl,Digits),Slippage*pips2points,0,
               NormalizeDouble(Bid-(TakeProfit*pips2dbl+TradeGap*pips2dbl),Digits),"macd sample",MagicNumber,0,Red)<0)
          Print("Could not replace BUYSTOP: ",OrderTicket()," @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));  
         }
          else
         {
          Print("Deleting BUYSTOP order ",OrderTicket(), " failed @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
          return(0);
         }
      }
       
if(OrderType()==OP_SELLSTOP)
//if(BUYsignal) 
      {           
       if(OrderDelete(OrderTicket()))
         {
          Print("SELLSTOP order ",OrderTicket()," deleted by signal slope12: ", slope12," slope13: ",slope13);
          if(orderSendReliable(Symbol(),OP_BUYSTOP,Lots,NormalizeDouble(Ask+TradeGap*pips2dbl,Digits),Slippage*pips2points,0, 
               NormalizeDouble(Ask+(TakeProfit*pips2dbl+TradeGap*pips2dbl),Digits),"macd sample",MagicNumber,0,Red)<0)
          Print("Could not replace SELLSTOP: ",OrderTicket(), " @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));     
         }
          else
         {
          Print("Deleting SELLSTOP order ",OrderTicket(), " failed @ ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
          return(0);
         }
       }
      }     
    }
   }
Reason: