if(openorder!=1)opentradecommand;
This code works in back testing and most of the time forward testing but every now and then an extra trade will still be placed on the currency pair despite the check in the code below that SHOULD be preventing this. Trades do have different magic number but I do NOT reference them here as I only want 1 trade per pair so I was assuming the orders symbol check would achieve this (limit one order on the pair), am I missing something?
No, just the one EA with several different entry criteria, all checking for an open order on the pair using the code above. Another solution I had was:
void LimitOpenOrdersBuy() { int count = 0; for (int i=OrdersTotal()-1; i >= 0; i--) if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol()) { count++; } } else { Print("OrderSend() error - ", ErrorDescription(GetLastError())); } if (count < OpenOrdersLimit) { BuyOrderType(); } }
It should work, except you have a race condition. EA1 checks total finds it zero, EA2 checks total finds it zero. Both EAs open an order.
You need a mutex around the check and open.
input string GV_Mutex = "Mutex"; //+------------------------------------------------------------------+ //| Trade context semaphore. | //+------------------------------------------------------------------+ class Mutex{ Public: void Mutex() : mName(GV_Mutex), mLocked(false){ Lock();} void Mutex(const string& aName) : mName(aName), mLocked(false){ Lock();} void ~Mutex(){ Release();} void Lock(void){ if(mLocked) return int startWaitingTime = 0; if(!GlobalVariableTemp(mName){ // Attempt to create && _LastError != ERR_GLOBAL_VARIABLES_PROCESSING) DisableTrading( StringFormat("Mutex: GVSet('%s') Failed: %i",s, _LastError) ); return;} while(true){ if(!IsTradeContextBusy() && GlobalVariableSetOnCondition(mName, 0, 1) ){ if(startWaitingTime != 0){ Comment(WindowExpertName(),": ", VERSION); WindowRedraw(); SetNeedToRefresh(); // I slept } RefreshIf(); // RefreshRates if slept or previous OrderSend/Modify SetNeedToRefresh(); // Assume will do a OrderSend/Modify/Close. mLocked = true; return; } if(IsStopped() ){ Alert("Mutex: The expert was terminated by the user!"); return; } if(startWaitingTime == 0) startWaitingTime = GetTickCount(); // Remember start time. else{ int delay = GetTickCount() - startWaitingTime; #define MUTEX_TIMEOUT_MSEC 60000 // Trade context busy maximum delay if(delay > MUTEX_TIMEOUT_MSEC){ // Abort. DisableTrading(StringFormat("Wait time (%i sec) exceeded!", MUTEX_TIMEOUT_MSEC / 1000) ); return; } Comment(WindowExpertName(), ": ", "Wait until another expert finishes trading... ", delay / 1000.); WindowRedraw(); } Sleep(1000); } // while //NOT REACHED } // Lock void Release(void){ if(mLocked){ if(!GlobalVariableSet(mName, 0) ) Alert("Mutex: GlobalVariableSet('%s',!LOCK): Error #", mName, _LastError); mLocked=false; } } void IsLocked(void) const{return mLocked; } Private: string mName; bool mLocked; }; // Mutex void DisableTrading(string msg){ string tradingDisabled = msg+" Trading disabled."; CloseAllOrders(); Alert(tradingDisabled); Comment(tradingDisabled); ExpertRemove(); } //////////////////////////////////// { Mutex m; IfOrderDoesNotExistBuy(); }Not compiled, not tested.
It can be that in case there is a kind of reconnection(?) OrdersTotal() will give you 0 is not yet set correctly - just my guess.
gangsta1: Thank you although from my experience I understand that a MUTEX is required if the trades are open at the EXACT same time.
| There is no EXACT over a network. Both EAs will start at the
EXACT same time because a new tick was received. Both server
requests will be sent milliseconds apart. It can take tens of seconds to open an order on the server (minutes during news.) The reply and update to total will be seconds later when the tickets are returned. |
gangsta1: Do you mean that if mt4 disconnects and reconnects that the orders total can be reset? | I doubt that. What ever it has locally is still there and would eventually be updated on reconnect. Network timeout (a disconnect) takes a minute before the terminal even knows. |
I guess (!) that if you hear disconnect and reconnect (in case you have enabled theses sound events) mt4 knows about it.
And I know that if in case the terminal (re-) loads its server information it takes a while despite OnTick() starts and might create wrong results - that why I return as long e.g. OrdersHistoryTotal() is still 0:
... void OnTick(){ ... if (!isInit) { if ( OrdersHistoryTotal()==0 ) return; isInit = true; } ...
But as I don't know anything about mt4's server it's only guessing than knowing :(
Another problem is that I don't know much about what is changed and not changed in case you just recompile your EA!
The 'extern-' ('input-') variables stay the same even though you might have changed them in the EA-mq4 files, but what about the static, global variables, and ...
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
This code works in back testing and most of the time forward testing but every now and then an extra trade will still be placed on the currency pair despite the check in the code below that SHOULD be preventing this. Trades do have different magic number but I do NOT reference them here as I only want 1 trade per pair so I was assuming the orders symbol check would achieve this (limit one order on the pair), am I missing something?