curious behaviour for two EA in parallel

 

hi,

i am running an EA on two currencies (GBP and EURUSD) on H1 charts. i 13:00 each of the EAs were supposed to initiate two pending orders (one BUYSTOP and one SELLSTOP each). here is the log:

13:00:00 grapple GBPUSD,H1:   type:      sell stop
13:00:00 grapple GBPUSD,H1:   volume:    0.29000
13:00:00 grapple GBPUSD,H1:   entry:     1.54006
13:00:00 grapple GBPUSD,H1:   stoploss:  1.54166
13:00:00 grapple GBPUSD,H1:   target:    1.53259
13:00:00 grapple GBPUSD,H1:   ask:       1.54703
13:00:00 grapple GBPUSD,H1:   bid:       1.54692
13:00:00 grapple EURUSD,H1: trade context busy
13:01:01 grapple GBPUSD,H1: ERROR [128] trade timeout
13:01:01 grapple GBPUSD,H1:   entry:     1.54006
13:01:01 grapple GBPUSD,H1:   stoploss:  1.54166
13:01:01 grapple GBPUSD,H1:   target:    1.53259
13:01:01 grapple GBPUSD,H1:   ask:       1.54713
13:01:01 grapple GBPUSD,H1:   bid:       1.54699
13:01:01 grapple GBPUSD,H1: open #136121932 sell stop 0.29 GBPUSD at 1.54006 sl: 1.54166 tp: 1.53259 ok
13:01:01 grapple GBPUSD,H1:   type:      buy stop
13:01:01 grapple GBPUSD,H1:   volume:    0.50000
13:01:01 grapple GBPUSD,H1:   entry:     1.54824
13:01:01 grapple GBPUSD,H1:   stoploss:  1.54732
13:01:01 grapple GBPUSD,H1:   target:    1.55218
13:01:01 grapple GBPUSD,H1:   ask:       1.54713
13:01:01 grapple GBPUSD,H1:   bid:       1.54696
13:01:01 grapple EURUSD,H1: trade context has become free
13:01:01 grapple EURUSD,H1:   type:      sell stop
13:01:01 grapple EURUSD,H1:   volume:    0.27000
13:01:01 grapple EURUSD,H1:   entry:     1.26140
13:01:01 grapple EURUSD,H1:   stoploss:  1.26312
13:01:01 grapple EURUSD,H1:   target:    1.25314
13:01:01 grapple EURUSD,H1:   ask:       1.26773
13:01:01 grapple EURUSD,H1:   bid:       1.26764
13:01:02 grapple GBPUSD,H1: open #136121945 sell stop (instead of buy stop) 0.27 EURUSD at 1.26140 sl: 1.26312 tp: 1.25314 ok
13:04:22 grapple EURUSD,H1: ERROR [128] trade timeout
13:04:22 grapple EURUSD,H1:   entry:     1.26140
13:04:22 grapple EURUSD,H1:   stoploss:  1.26312
13:04:22 grapple EURUSD,H1:   target:    1.25314
13:04:22 grapple EURUSD,H1:   ask:       1.26758
13:04:22 grapple EURUSD,H1:   bid:       1.26750
13:04:22 grapple EURUSD,H1: open #136122482 sell stop 0.27 EURUSD at 1.26140 sl: 1.26312 tp: 1.25314 ok
13:04:22 grapple EURUSD,H1:   type:      buy stop
13:04:22 grapple EURUSD,H1:   volume:    0.46000
13:04:22 grapple EURUSD,H1:   entry:     1.27191
13:04:22 grapple EURUSD,H1:   stoploss:  1.27091
13:04:22 grapple EURUSD,H1:   target:    1.27649
13:04:22 grapple EURUSD,H1:   ask:       1.26757
13:04:22 grapple EURUSD,H1:   bid:       1.26750
13:04:24 grapple EURUSD,H1: open #136122486 buy stop 0.46 EURUSD at 1.27191 sl: 1.27091 tp: 1.27649 ok

you can see that GBPUSD starts first and, half way through, EURUSD also starts, but finds that the trade context is busy (i have implemented some of the code at https://www.mql5.com/en/articles/1412 to handle this), so it waits. GBPUSD gets a timeout and then tries again, when it successfully places SELLSTOP #136131932. GBPUSD immediately tries to enter the BUYSTOP but half way through this EURUSD realises that the context is free and quickly slips in its SELLSTOP. now something weird happens: the line logged by the server starts with "13:01:02 grapple GBPUSD,H1" but the order is still place against EURUSD with the comment "sell stop (instead of buy stop)". the parameters are all correct for the EURUSD SELLSTOP order though. but, peculiarly, the next line indicates that EURUSD encountered a timeout... so how was that SELLSTOP entered then? or, how did the GBPUSD EA get the parameters for the EURUSD trade? so, after the timeout the EURUSD EA tries again and this time gets the order through without incident (the same parameters again though). finally, EURUSD submits its BUYSTOP order.

so the mysterious thing in all of this is how the trade parameters from the EURUSD EA got somehow transferred across to the GBPUSD EA? does anyone have any ideas?

best regards, andrew.

 
Do you use global variables?
 
jcadong5:
Do you use global variables?

no, not at all. why?
 
Global variables are shared by all EAs in the terminal.
 

Do you use a for loop involving OrdersTotal()?

If you do then this might be the error. If one of the EA's is in the loop and the other EA opens a trade or closes a trade, while the other is still in the loop, the position number of each trade changes, which could cause the EA to mess up.

It is better to work with ticket numbers so that you know the EA will be reliable. Another reason to use ticket numbers is because when you open a trade sometimes there is a lag between when it appears in the trade window and when it was opened, which could cause multiple trades to be opened if not using ticket numbers.

If it isn't this, then I would guess it is a rare glitch. If it was live, try negotiating with your broker to find out what went wrong, because it is probably a glitch in their trade server.

Chris

 

Maybe show some of your code, instead of just the result.

 


I reproduced same behaviour recently.. In my situation (5 parallel EAs) the OrderSend function kept returning one trade number for ~19 minutes, see the timeline in both expert and terminal logs:

1 20:16:39 logger USDJPY,M1: INFO: FYI the chart shows Ask price. I sell at Ask: 85.29 mystoplevel:0.05 enter:84.99 stoploss:85.16 lot: 0.06
2 20:16:44 'xxxxx': order buy stop 0.07 EURUSD opening at 1.3212 sl: 1.3195 tp: 1.3272 failed [Trade context is busy]
3 20:16:44 tradelib USDJPY,M1: open #13608767 buy stop (instead of sell stop) 0.07 EURUSD at 1.32 sl: 1.32 tp: 1.33 ok
4 20:16:48 'xxxxx': order was opened : #13608767 buy stop 0.07 EURUSD at 1.3212 sl: 1.3195 tp: 1.3272
5 20:16:50 'xxxxx': modify pending order #13608767 buy stop 0.07 EURUSD at 1.3212 sl: 1.3195 tp: 1.3272 -> price: 85.6100 sl: 85.4400 tp: 86.2100
6 20:16:50 tradelib EURUSD,M1: open #13608767 buy stop 0.07 EURUSD at 85.6100 sl: 85.4400 tp: 86.2100 ok
7 20:20:03 tradelib AUDUSD,M1: open #13608767 buy stop 0.07 EURUSD at 85.6400 sl: 85.4700 tp: 86.2400 ok
8 20:34:45 tradelib USDCAD,M1: open #13608767 buy stop (instead of sell stop) 0.07 EURUSD at 1.3255 sl: 1.3238 tp: 1.3315 ok
9 20:35:46 tradelib NZDUSD,M1: open #13608767 buy stop 0.07 EURUSD at 85.6500 sl: 85.4800 tp: 86.2500 ok

I'm going to resolve this on higher level functions - eg. when an EA instance finds it works with trade associated with different pair it will report misbehaviour to other EAs through global variable (blacklist idea).. The relevant instance of EA will close its trade that leaked to another EA instances and removes it from blacklist.

 
I have seen this strange log message on some forum already but I cant remember the cause and the solution.
 

They are all referring to the same ticket number.

3 20:16:44 tradelib USDJPY,M1: open #13608767 buy stop (instead of sell stop) 0.07 EURUSD at 1.32 sl: 1.32 tp: 1.33 ok

tradelib USDJPY is the offending code and the chart it is running on, this is generated by MT4 automatically. EURUSD is the currency of the actual ticket.

According to the manual an .ex4 lib will (unlike a dll) be loaded as many times as there are EAs using it (and even some more sometimes, it sounds like a totally messed up and half-baked implementation), according to this each should theoretically have its own heap and global variables but I never tested this. Maybe the manual is wrong or incomplete (maybe they tried to fix it or some aspects of it without updating the manual) and an .ex4 library behaves now more like an ordinary DLL or there are some other things they just don't mention. I would not use .ex4 libraries for anything after having read this section of the manual!


I always use include files for all my code re-usage, never any mql4 libs. This will link it statically and I can be absolutely sure that each instance will not accidentally share any global variables or any other state like OrderSelect() for example with any other EA instance.


This is only a theory. I never actually tested whether some state can be shared via .ex4 libs, but including your functions instead of loading a lib (possibly shared lib) would definitely rule out any accident of this sort.

 

In my view this behavior has nothing to do with the way how you include mq4 or dll files.

Root cause is the OrderSend function that returns number that is already an id that has already been assigned to another trade (either your someone's else trade).

Either it is sent by server or there is some issue inside client trade context.
This can occur likely during high communication load (either terminal.exe or the broker's server) or when markets move fast
(EA has got lot of ticks to process) or both.

1. Line 2: EURUSD EA tries several times OrderSend new "buy stop" trade and [Trade context is busy]
2. Lines 1 and 3 : USDJPY EA - independent on EURUSD EA - is about to OrderSend new "sell stop" trade and is successful because it gets line 3:
* BUT it caught trade number that should have belonged to EURUSD EA; it should have been short however it gets long. The message actually explains it.
3. Line 4: 4 secs later - terminal finally gets its trade for EURUSD EA
4. Line 5: But USDJPY EA is faster and successfuly - based on logic of the EA - repairs trade params
5. Line 6: EURUSD EA is informed that it got its trade... since now both EAs fight each against other and OrderModify the same trade
6. Lines 7-9: Other EA instances still obtain the same trade number from OrderSend (until I closed it manually in terminal.exe)


So my simple resolution was to catch this condition (Symbol() != OrderSymbol()) and report misbehavior + call a compensation function (not shown here).

assert( StringFind(OrderSymbol(),Symbol(),0) != -1,
"grinderOne: detected EA is working on trade #" + getContractId(idx) + " with irrelevant OrderSymbol()=" + OrderSymbol());

void assert(bool condition, string message) { if (!condition) log("ASSERT: " + message); }
void log(string message) { Print(message); }

 

kungfxp7a:

So my simple resolution was to catch this condition (Symbol() != OrderSymbol()) and report misbehavior

So this means you have actually had the very same error in your own EA and definitely found that it happens in an otherwise correct OrderSend() call and is definitely an MT4 bug? Can you intentionally reproduce the error? Or are you also only speculating?


@MetaQuotes: It would be nice if one of you would please spend 60 seconds time to just look into your source code and give us a hint which conditions exactly trigger this strange undocumented log entry.

Reason: