should we retry if context or server is busy?

 
Hi

The majority of EA's I saw call OrderSend, without worrying about the sever or the context being busy.

Its true that most EAs in all the examples detects an error and prints a err. message but shouldn't the function, which tries to open and order check for these "busy" errors and retry several times instead of print error and return? For example, something like this (note the while loop and the Sleep function):
int OpenAtMarket (  int iOrderType,
                    double fLots,
                    double fPrice,
                    int iSlippage, 
                    int iMagicNumber )
{
    if(iOrderType != OP_BUY && iOrderType != OP_SELL)
        return(-1);
 
    double fStopLoss = Ask-10000*Point; // no stop loss!
    double fTakeProfit = Ask+10000*Point; // no take profit!
    color iColor = RoyalBlue;
    
    if( OP_SELL == iOrderType )
    {        
        fStopLoss = Bid+10000*Point;
        fTakeProfit = Bid-10000*Point;
        iColor = OrangeRed;
    }
 
    // is server or context busy - try 3 times to submit the order
    int iNumRetries=3, iMillisecondsToSleep=1000;
 
    while(iNumRetries>0)
    {
        int iTicket = 
        OrderSend(    Symbol(), iOrderType, 
                    NormalizeDouble(fLots, 1), NormalizeDouble(fPrice, 4),
                    iSlippage, fStopLoss, fTakeProfit,
                    "", iMagicNumber, 0, iColor );
 
        iNumRetries--;
 
        if( -1 == iTicket )
        {
            int iError = GetLastError();
 
            // retry if error is "busy", otherwise give up
            if( ERR_SERVER_BUSY == iError || ERR_TRADE_CONTEXT_BUSY == iError )
                Sleep(iMillisecondsToSleep);
            else
            {
                iMaxNumRetries = 0;
                Alert("OpenAtMarket: OrderSend Error ", GetLastError() );
            }
        }
        else
            iMaxNumRetries = 0;
    }
 
    return(iTicket);
}
Also, the Help says that ERR_SERVER_BUSY may mean that we should retry after several MINUTES!? Is it a bad idea then, to Sleep and retry on this error?

I saw that there is a IsTradeContextBusy() function but it looks somewhat useless, because this TradeContext thing is probably real-time data, kind of like a mutex. It's useless to check a mutex - whether it is locked or not - because even if your "check_mutex" function returns and tells you that the mutex is not locked - it may already be locked in the mean time by anotehr thread. So your mutex state information is useless. The only way to check it is to try to lock it. I assume the trading context is also like thaht. The only way to know if your OrderSend will succeed is to try and execute an OrderSend. And if it fails because of busy context - retry. So what is the purpose of the IsTradeContextBusy() function then?

thanks
 
TradeContextBusy could be a real killer, especially if you run an expert. It happened to me once recently. I sent a manual order and it got stuck, when I tired to cancel it, I got tradecontextisbusy message and I couldn't do anything until I restarted the whole program. Obviously contextbusy condition got lodged, the order was lost and the whole thing was incapacitated.
As far as sending the order, I've built a function that check error code and does one of 3 things based on type of error:

sleep certain amount before resending on server busy, context busy, etc.
refresh and resend immedeately on invalid price, requote etc.
cancel and return error msg on anything else.
 
stringo - very interesting article, thanks. There is one line in the TradeIsNotBusy function from this article which looks suspicious, can you please verify that it is correct?
void TradeIsNotBusy()
  {
    int _GetLastError;
    // at testing, there is no sense to divide the trade context - just terminate 
    // the function
    if(IsTesting()) 
      { 
        return(0); 
      }
    while(true)
      {
        // if the expert was terminated by the user, прекращаем работу
        if(IsStopped()) 
          { 
            Print("The expert was terminated by the user!"); 
            return(-1); 
          }
...

I am talking about
if(IsStopped())... return (-1);
What if the expert is stopped in the middle of executing the order? Then it will enter this function, hit the "if stopped" statement and return -1 without releasing the global semaphore! Other experts won't be able to trade because this expert left the GlobalVariable equal to 1.
Would it not be better to remove this if statement to ensure that the global variable is always released?

Also - I think it is a *very good idea* to call the TradeIsNotBusy function from the deinit function. Tis way we'll ensure we always release the trade context before termination.

stringo - please tell me what you think about these suggestions, especially - if I am wrong please explain why. I also add this comment to the article page...

thanks
P.S. irusoh1 - interesting observation about te context... Your function, as you describe it, seems to be similar to my function above (sleep and retry on busy, return err. on other errors). Except it retires immediately on requote errors. I should probably add this to my function. thx.
 
Yes. Semaphore must be released, it can be done in the deinit function. But make sure that semafore to be released was occupied by this expert.
Reason: