Multiple Order Entry Problem for live account with a specific broker - page 2

 
Malacarne:

Hi BlindMist, it does make sense to check your local database to verify if your account is synchronized with the broker server.

Please take a look at the suggested post to address this problem. 

I just went through the suggested post and it doesn't mention how to prevent orders from being executed multiple times...

Even with Sleep() function, how long do you have to wait for to be certain that the trade failed?...

In my EA i had an order send request time out after 10 seconds before trying again... but sometimes the order gets executed 15 -20 seconds after the initial request; thus, resulting in unwanted double trade.

 
BlindMist:

I just went through the suggested post and it doesn't mention how to prevent orders from being executed multiple times...

Even with Sleep() function, how long do you have to wait for to be certain that the trade failed?...

In my EA i had an order send request time out after 10 seconds before trying again... but sometimes the order gets executed 15 -20 seconds after the initial request; thus, resulting in unwanted double trade.

Hi BlindMist, my idea on that topic, that I still think is the only way to check it (instead of just one test of PositionSelect or just one Sleep), is create something like a fatal error after waits a long time, or jump as soon as you have the symbol position (code below). 

The only good thing about this problem is that probably PositionSelect, soon or late, will get the updated position from the server, so what we have to do is wait a maximal time (our timeout) to indicate a fatal error and make small samples to check if it is OK (100 ms in my example). 

bool fatalError=false; // atention: declare this as global

....

if (fatalError==false) {
  if (m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0)) {
    Print("Position opened in ", Symbol());
    int maxTimeout=0;
    while (!PositionSelect(Symbol())) {
       Sleep(100);
       maxTimeout++;
       if (maxTimeout>100) {
          Print("### PositionSelect fatal error!");
          fatalError=true;
          break;
       }
    }
    Print("--> PositionSelect delay=",maxTimeout*100);
    break;
  }
}

Another way to do this more modular is create a function to control timeout, for instance:

bool PositionSelectTimeout(string symbol,int timeout) 
  { // timeout in seconds
   int maxTimeout=0;
   while(!PositionSelect(symbol)) 
     {
      Sleep(100);
      maxTimeout++;
      if(maxTimeout>(timeout*10)) return(false); // fatal error (timeout)
     }
   return(true); // position selected
  }

The main idea here is my PositionSelectTimeout() replace the original PositionSelect(), as a workaround of course, since just MQ can address a really good and definitive solution.

For example:

if (PositionSelectTimeout(Symbol(),60)) { // 60 seconds timeout
 ...
}

// instead of ...

if (PositionSelect(Symbol())) {
 ...
}

So, in my opinion, FinanceEngineer must do the same to fix the problem, and insert this test inside his loop, to double check if position is OK to take a break.

 
figurelli:

Hi BlindMist, my idea on that topic, that I still think is the only way to check it (instead of just one test of PositionSelect or just one Sleep), is create something like a fatal error after waits a long time, or jump as soon as you have the symbol position (code below). 

The only good thing about this problem is that probably PositionSelect, soon or late, will get the updated position from the server, so what we have to do is wait a maximal time (our timeout) to indicate a fatal error and make small samples to check if it is OK (100 ms in my example). 

Another way to do this more modular is create a function to control timeout, for instance:

The main idea here is my PositionSelectTimeout() replace the original PositionSelect(), as a workaround of course, since just MQ can address a really good and definitive solution.

For example:

So, in my opinion, FinanceEngineer must do the same to fix the problem, and insert this test inside his loop, to double check if position is OK to take a break.

Thanks figurelli, very detailed reply. I'll give it a shot and see if it betters my system.
 
BlindMist:
Thanks figurelli, very detailed reply. I'll give it a shot and see if it betters my system.
Thanks, you are welcome.
 
BlindMist:

I just went through the suggested post and it doesn't mention how to prevent orders from being executed multiple times...

Even with Sleep() function, how long do you have to wait for to be certain that the trade failed?...

In my EA i had an order send request time out after 10 seconds before trying again... but sometimes the order gets executed 15 -20 seconds after the initial request; thus, resulting in unwanted double trade.

15 seconds for one order execution. This is really bad. The problem here is that we can't get anything from Broker's sever (For example, even simple status checking piece of code, etc)
 
FinanceEngineer:
15 seconds for one order execution. This is really bad. The problem here is that we can't get anything from Broker's sever (For example, even simple status checking piece of code, etc)

Hi FinanceEngineer, you are right, however the first thing to manage is select a low latency broker, since markets are each time faster, and it will be usual such problems.

Also, it's always good think about the worst case, because you can have a low latency broker but at some moments of day a big delay, for instance when you have relevant news.

Anyway, OrderSend() in MT5 is not so easy to manage as MT4, because MT4 returned value is a Ticket. This change was necessary at MT5 because asynchronous communication of stock markets, introduced at MQL5 architecture, that is enabled to communicate with broker OMS protocol (like FIX, for instance).

But I think this is the big change of OMS for order management today, since it's very hard get a real time Ticket, and MT5 is updated to this new scenario, mainly if we use stock markets, where we have more latency.

In this sense, the more relevant thing you do after a OrderSend() at MT5 is check PositionSelect(), and I strongly suggest use my proposed PositionSelectTimeout() workaround, for all reasons above.

The only way I see to think about worst cases is manage all the if { } else { } conditions after sending an order to the market, in a way you can manage any situation.

I would like to have catch { } too, but we can use GetLastError() to do something near this.

This because you also need the Ticket to confirm a position and MT5 OrderSend() don't return the ticket as sychronous as MT4 does.

 
BlindMist:

I just went through the suggested post and it doesn't mention how to prevent orders from being executed multiple times...

Even with Sleep() function, how long do you have to wait for to be certain that the trade failed?...

In my EA i had an order send request time out after 10 seconds before trying again... but sometimes the order gets executed 15 -20 seconds after the initial request; thus, resulting in unwanted double trade.

      This is my code I am using currently. So far, I don't have any problem. You can try this code and if it works for that broker.

 

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

 
FinanceEngineer:

      This is my code I am using currently. So far, I don't have any problem. You can try this code and if it works for that broker.

 

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

What you do with checkOrderSend variable?

How do you prevent multiple orders be executed without checking the server deal completion?

 
figurelli:

What you do with checkOrderSend variable?

How do you prevent multiple orders be executed without checking the server deal completion?

Hello figurelli

My point was to check both 10009 and 10008 code at the end of OrderSend function. Because I found many people only check either of one return code (i.e. 10009 or 10008) and getting many multiple orders as they normally place a for loop to avoid no order situation.

In my case, my for loop will attempt 10 times if I don't get any order with that broker. So it is probably worth to clarify if someone is getting multiple order then they should check if they are stop their Ordersending loop by checking both 10009 and 10008.

However, ironnically, in demo account, checking only one return code is fine. It won't give you any multiple order problem. So here I found live account and demo account behave slightly differently.

 

Kind regards.

 
FinanceEngineer:

Hello figurelli

My point was to check both 10009 and 10008 code at the end of OrderSend function. Because I found many people only check either of one return code (i.e. 10009 or 10008) and getting many multiple orders as they normally place a for loop to avoid no order situation.

In my case, my for loop will attempt 10 times if I don't get any order with that broker. So it is probably worth to clarify if someone is getting multiple order then they should check if they are stop their Ordersending loop by checking both 10009 and 10008.

However, ironnically, in demo account, checking only one return code is fine. It won't give you any multiple order problem. So here I found live account and demo account behave slightly differently.

 

Kind regards.

Hello FinanceEngineer, maybe would be better start checking your original code multiple orders problem, since if we do this probably we will address other critical points here and don't lose the focus, what do you think about?
Reason: