Random 4108 (invalid ticket) error in OrderClose() function

 

Hi all,

 after days trying to debug this error I finally come here to ask for your help.

 I am developing two EAs that have a file in common. This file has a class which is an Expert Advisor base I wrote with typical functions such as TradeOpen(), TradeClose(), CheckNewBar(), etc. I explain this because the error I get is within this file in the function TradeClose(). This function has the following code:

bool CExpertBase::TradeClose(int _ticket, int _slip=3)
{
   if (_ticket < 0) return(TRUE);
   if (!OrderSelect(_ticket, SELECT_BY_TICKET)) {
      SetError(0, __FUNCTION__ + " - OrderSelect()");
      return(FALSE);
   }
   if (OrderCloseTime() != 0) return(TRUE);
   double price;
   bool result;
   int attempts = 0;
   const int max_attempts = 5;
   do {
      RefreshRates();
      price = (OrderType() == OP_BUY) ? Bid : Ask;
      result = OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(price, m_digits), _slip);
      if (!result) Sleep(5000);
   } while (!result && ++attempts <= max_attempts);
   if (!result) {
      string msg = __FUNCTION__ + " - OrderClose() | ticket = " + IntegerToString(_ticket) + " | OrderCloseTime() = " + TimeToString(OrderCloseTime());
      SetError(0, msg);
   }
   return (result);
} 

As it can be seen, I do the OrderClose() in a loop to repeat the process if there is any error. If there are 5 failed functions, then is when the EA enters in the error state.

 

This piece of code works well most of the time. The experts open and close positions without any problem, but from time to time I get the error 4108. I have a log here with some successfully closed orders and the error at the end:

[+] 2015.01.14 19:58: Normal position opened.

INTERNAL VARS:

ticket = 35854853 | current_sl = 1.82098 | current_tp = 1.82192

in_news = false | total_profit = 78.90 | total_loss = -305.05


[+] 2015.01.14 19:59: Order closed.

INTERNAL VARS:

ticket = -2 | current_sl = 0.00000 | current_tp = 0.00000

in_news = false | total_profit = 82.16 | total_loss = -305.05


[+] 2015.01.14 19:59: Normal position opened.

INTERNAL VARS:

ticket = 35854863 | current_sl = 1.82169 | current_tp = 1.82264

in_news = false | total_profit = 82.16 | total_loss = -305.05


[+] 2015.01.14 20:00: Order closed.

INTERNAL VARS:

ticket = -2 | current_sl = 0.00000 | current_tp = 0.00000

in_news = false | total_profit = 82.16 | total_loss = -309.89


[+] 2015.01.14 20:00: Normal position opened.

INTERNAL VARS:

ticket = 35854919 | current_sl = 1.82144 | current_tp = 1.82232

in_news = false | total_profit = 82.16 | total_loss = -309.89


[+] 2015.01.14 20:02: ERROR: GetLastError() = 04108 | CExpertBase::TradeClose - OrderClose() | ticket = 35854919 | OrderCloseTime() = 1970.01.01 00:00

 So that's the problem. I cannot understand what is raising this error because the ticket is a valid one, or at least it seems to be. Also the OrderCloseTime() is 0 so the order is still opened. In addition, any of the programs do not modify any order (with OrderModify()), they only open the trade, save the ticket in an internal variable, and use it once they want to close the position.

 

Anyone knows something I could try to look for? I have no ideas missing and I don't know how to continue debugging this error.

 
The only thing that springs to mind is that you are trying to close a pending order instead of deleting it.
 

or you try to close an order that meanwhile was closed by StoppLoss || ProfitTarget || missing margins.

 
  1. Simplify
    // price = (OrderType() == OP_BUY) ? Bid : Ask;
    // result = OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(price, m_digits), _slip);
       result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice()               , _slip);
  2. Your posted code can't create your posted message. Post the real code.
 
GumRai:
The only thing that springs to mind is that you are trying to close a pending order instead of deleting it.

All the orders are opened orders, not pending ones.

 

gooly:

or you try to close an order that meanwhile was closed by StoppLoss || ProfitTarget || missing margins.


 I already check if the order is still open with:

if (OrderCloseTime() != 0) return(TRUE);

 before doing anything else. But I will try to put this line just before the OrderClose() function to see what happens. Anyway, it is strange because once I come to my PC and see the error, there is no order opened so it must have hit the SL or TP, but in the log it says the order is still opened because OrderCloseTime() is 0.

 

WHRoeder:
  1. Simplify
  2. Your posted code can't create your posted message. Post the real code.

I did not simplify because the code is so short and simple that I thought it was not necessary. I know that the log I posted is not created only by the function I posted, actually only the last line is. I posted the log to show you that the order ticket is correctly stored, so the OrderClose() function is using the correct ticket.

By the way, this code:

result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), _slip);

 using OrderClosePrice() in an order that is still opened is ok?

 

Is it possible you have 2 EAs trying to close the same ticket ?

What was the actual state of this order at the time you got this error ?

 
angevoyageur:

Is it possible you have 2 EAs trying to close the same ticket ?

What was the actual state of this order at the time you got this error ?

No, only one EA on each symbol.

 I don't understand your second question... I mean, the order was probably opened (I cannot say it for sure). The EA only uses market stops and profits for security. This is, if an order has a stop of 5 pips, it is the EA that manages to close the order if the price is hitting the virtual stop. But few days ago I added market stops and profits, in this case 5 pips away from the virtual stops, to avoid big losses if the internet connection is lost, for example. Anyway, if the order had been closed by the market stop because of a market big move, the function would have returned TRUE before entering into the OrderClose() loop.

 

UPDATE: Yesterday I made another test, printing in the log the error after the OrderClose() function call inside the loop, and this is what I got:

[+] 2015.01.15 14:36:36: WARNING: Attempt 1/12 in OrderClose(). GetLastError() = 3 | ticket = 35867852

[+] 2015.01.15 14:36:49: WARNING: Attempt 2/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:05: WARNING: Attempt 3/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:16: WARNING: Attempt 4/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:27: WARNING: Attempt 5/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:38: WARNING: Attempt 6/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:48: WARNING: Attempt 7/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:00: WARNING: Attempt 8/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:11: WARNING: Attempt 9/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:21: WARNING: Attempt 10/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:32: WARNING: Attempt 11/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:43: WARNING: Attempt 12/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

The sleep, as it can be seen, was 10 seconds among attempts. This is only one out of many that happened since yesterday night. All are the same, the first error is number 3 (invalid trade parameters) and the others are the 4108 (invalid ticket). I understand the first one being caused, for example, by a big market move, but the others I can't.

After seeing this, I decided trying to remove the do-while loop, because the functions that call this function also check the return value, and the error has gone away. Well, actually I get the error 3, but at the next tick the EA successfully closes the order. This does not happen all the time, maybe 1 every 40 or 50 orders.

 So now my question is... Anybody knows what could be happening here?

 Thank you all for the help. 

 
xiruko:

No, only one EA on each symbol.

 I don't understand your second question... I mean, the order was probably opened (I cannot say it for sure). The EA only uses market stops and profits for security. This is, if an order has a stop of 5 pips, it is the EA that manages to close the order if the price is hitting the virtual stop. But few days ago I added market stops and profits, in this case 5 pips away from the virtual stops, to avoid big losses if the internet connection is lost, for example. Anyway, if the order had been closed by the market stop because of a market big move, the function would have returned TRUE before entering into the OrderClose() loop.

 

UPDATE: Yesterday I made another test, printing in the log the error after the OrderClose() function call inside the loop, and this is what I got:

[+] 2015.01.15 14:36:36: WARNING: Attempt 1/12 in OrderClose(). GetLastError() = 3 | ticket = 35867852

[+] 2015.01.15 14:36:49: WARNING: Attempt 2/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:05: WARNING: Attempt 3/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:16: WARNING: Attempt 4/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:27: WARNING: Attempt 5/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:38: WARNING: Attempt 6/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:37:48: WARNING: Attempt 7/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:00: WARNING: Attempt 8/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:11: WARNING: Attempt 9/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:21: WARNING: Attempt 10/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:32: WARNING: Attempt 11/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

[+] 2015.01.15 14:38:43: WARNING: Attempt 12/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

The sleep, as it can be seen, was 10 seconds among attempts. This is only one out of many that happened since yesterday night. All are the same, the first error is number 3 (invalid trade parameters) and the others are the 4108 (invalid ticket). I understand the first one being caused, for example, by a big market move, but the others I can't.

After seeing this, I decided trying to remove the do-while loop, because the functions that call this function also check the return value, and the error has gone away. Well, actually I get the error 3, but at the next tick the EA successfully closes the order. This does not happen all the time, maybe 1 every 40 or 50 orders.

 So now my question is... Anybody knows what could be happening here?

 Thank you all for the help. 

One way or an other your order was closed already closed at your 2nd to 12th attempt. You checked for OrderCloseTime!=0 outside your loop.

[+] 2015.01.15 14:36:49: WARNING: Attempt 2/12 in OrderClose(). GetLastError() = 4108 | ticket = 35867852

Check your trades history what was the close time of this order, and you will see that your order 35867852 was already closed at 14:36:49.

 
Either the ticket is not updated correctly by the ea or the counting logic is wrong.
Reason: