Please help me correct this function

 

The idea of this function is to delete the pending order if not executed in 290 seconds from the time order is placed. However, at 290 seconds the order is NOT being deleted. It takes an extra 10 to 20 seconds for the order to delete and I have no idea why. Can you please look into this code and help me fix it. Thanks in advance.

extern int OrderKillInSeconds = 290;
int    buyv,cmd,totalp;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Del();
    Other conditions to buy and sell goes here
 }            
//+------------------------------------------------------------------+

/* Delete Pending Orders  - Kill Order in seconds */
bool Del()
{
//----
   totalp=OrdersTotal();
//----
   for(int i=0; i<totalp; i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         cmd=OrderType();
         buyv = TimeCurrent() - OrderOpenTime();
         //---- pending orders only are considered
         if((cmd!=OP_BUY && cmd!=OP_SELL) && (buyv > Minute() +
OrderKillInSeconds)  )
           {
            //---- print selected order
            OrderPrint();
            //---- delete first pending order
            result=OrderDelete(OrderTicket());
            if(result!=TRUE) Print("LastError = ", GetLastError());
            break;
           }
        }
      else { Print( "Error when order select ", GetLastError()); break; }
     }
//----
   return(0);
}
/* Delete Pending Orders */
 
Brijesh Kuttan:

The idea of this function is to delete the pending order if not executed in 290 seconds from the time order is placed. However, at 290 seconds the order is NOT being deleted. It takes an extra 10 to 20 seconds for the order to delete and I have no idea why. Can you please look into this code and help me fix it. Thanks in advance.

Why do you add the Minute()? You should use this condition:

if((cmd!=OP_BUY && cmd!=OP_SELL) && (buyv>=OrderKillInSeconds))

But it isn't much reliable way to delete pending order. Why don't you use parameter "expiration" in the OrderSend function? If you need to use it this way you should check it in OnTimer instead of OnTick because of "lazy" Symbols.

 
Petr Nosek:

Why do you add the Minute()? You should use this condition:

But it isn't much reliable way to delete pending order. Why don't you use parameter "expiration" in the OrderSend function? If you need to use it this way you should check it in OnTimer instead of OnTick because of "lazy" Symbols.

I cannot use the expiration on OrderSend because the minimum order expiry time is 10 mins (600 seconds). My

idea is to kill the pending order in just under 5 minutes(300 seconds).


I am not very clear on how to run the Ontimer function. Can you please help.

 
Brijesh Kuttan:
I cannot use the expiration on OrderSend because the minimum order expiry time is 10 mins (600 seconds). My

idea is to kill the pending order in just under 5 minutes(300 seconds).


I am not very clear on how to run the Ontimer function. Can you please help.

here is an example for the OnTimer function:
int OnInit()
  {
   EventSetTimer(1); // Set one second timer
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer(); // Kill the timer
  }

void OnTimer()
  {
   Del(); // Your function that checks deleting pending orders
  }
 
Brijesh Kuttan:

The idea of this function is to delete the pending order if not executed in 290 seconds from the time order is placed. However, at 290 seconds the order is NOT being deleted. It takes an extra 10 to 20 seconds for the order to delete and I have no idea why. Can you please look into this code and help me fix it. Thanks in advance.

Hi,

I think the problem is in the below line, in the TimeCurrent() function. It returns last known server time. So the time when the last quote was received. That might cause the delay you have.

buyv = TimeCurrent() - OrderOpenTime();

I would suggest to use your local PC time instead, TimeLocal(), but you need to make sure that your broker has the same time (is in the same time zone) - you can always adjust it if it's different.

TimeLocal();

Hope it helps,

______________________

www.tradingfalcon.com

 
Lukasz Gasiulewicz:

Hi,

I think the problem is in the below line, in the TimeCurrent() function. It returns last known server time. So the time when the last quote was received. That might cause the delay you have.

I would suggest to use your local PC time instead, TimeLocal(), but you need to make sure that your broker has the same time (is in the same time zone) - you can always adjust it if it's different.

Hope it helps,

______________________

www.tradingfalcon.com

Are you joking?

The delay causes the Minute() in the condition. Could I guess? The delay is between 1 and 60 seconds ;-)

 
Petr Nosek:

Are you joking?

The delay causes the Minute() in the condition. Could I guess? The delay is between 1 and 60 seconds ;-)

0 and 59 :-p
 
Alain Verleyen:
0 and 59 :-p

If you read OP's code carefully you'll realize I was right. There is ">" not ">="

:-p

 

As Lukasz mentions you need to run your logic in the OnTimer event handler and you also need to use your PC time instead of the last known tick time. Also you need to account for the time offset between you PC and the broker. An easy way to do that is to use OnTick to set a global variable to the time offset and then call your delete pending function in the OnTick handler. Also, whenever you are deleting/closing orders make sure you iterate the pool in reverse, otherwise you will get errors. 


extern int  inpOrderKillInSeconds = 290;
int    g_time_offset = INT_MAX;
//+------------------------------------------------------------------+
int OnInit()
{
   EventSetTimer(1);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnTick()
{
   g_time_offset = TimeLocal() - TimeCurrent();
}
//+------------------------------------------------------------------+
void OnTimer()
{
   if(!delete_pending(inpOrderKillInSeconds, g_time_offset))
      Alert("Something Wrong!");
}
//+------------------------------------------------------------------+
#include <stdlib.mqh>
bool delete_pending(int expire_seconds, int time_offset)
{
   if(time_offset == INT_MAX)
      return true;
   for(int i=OrdersTotal()-1; i>=0; --i)
   {
      if(OrderSelect(i, SELECT_BY_POS) 
         && OrderType() > 1
         && TimeLocal() - time_offset - OrderOpenTime() >= expire_seconds
      ){
         if(!OrderDelete(OrderTicket())){
            Print("OrderDeleteError: ", ErrorDescription(_LastError));
            return false;
         }
      }
   }
   return true;
}
 
nicholi shen:

As Lukasz mentions you need to run your logic in the OnTimer event handler and you also need to use your PC time instead of the last known tick time. Also you need to account for the time offset between you PC and the broker. An easy way to do that is to use OnTick to set a global variable to the time offset and then call your delete pending function in the OnTick handler. Also, whenever you are deleting/closing orders make sure you iterate the pool in reverse, otherwise you will get errors. 


Maybe I've missed something but I think you don't have to use TimeLocal() because TimeCurrent() stops counting only if the terminal has lost connection (in this case you can't also delete pending orders).
 
Petr Nosek:
Maybe I've missed something but I think you don't have to use TimeLocal() because TimeCurrent() stops counting only if the terminal has lost connection (in this case you can't also delete pending orders).
TimeCurrent doesn't count. It returns the last known trade server time which is only updated with a new tick. No tick, no time; thus it is necessary to use timelocal which fetches the PC clock time.
Reason: