Disallowing multiple EA instances in one terminal - page 3

 
jjc:

You make a good point, given that Fromin explicitly limits his/her requirements to "in one MT4 terminal at once".

The file-locking route has the disadvantages of complexity and requiring "Allow DLL imports" to be turned on. However, it also has three small advantages:

* If MT4 crashes or an EA/script shuts down in a disorderly fashion, a global-variable lock will remain in place and have to be manually removed. The file-based lock can be done in a way which is automatically freed when MT4 terminates.

* The file-based method is more future-proof; it offers the possibility of extending the locking beyond the single MT4 instance.

* I'm not 100% sure that MT4 synchronises access to global variables. If you have two EAs starting at exactly the same time, e.g. because MT4 is starting up with EAs already in place on its charts, then it may be possible for both EAs to think that the lock is free because e.g. they both call GlobalVariableCheck() before either of them then goes on to acquire a lock by calling GlobalVariableSet(). Or, depending on how you code it, two simultaneous calls to GlobalVariableSet() might both return 0.

I am running a strategy on with five EAs on five different pairs simultaneously. Is it possible to prevent to EAs from to simulataneously call the global variable?
 
Fromin:
can anyone think of a way to disallow the user to run more than 1 instance of the same EA in one MT4 terminal at once (not only 2 forward testing instances, but also forward testing + backtesting)?
I would use this approach.
#include <WinUser32.mqh>       
datetime EAstart;
int init(){
    EAstart = TimeCurrent(); 
}
int start(){
    datetime prevStart = GetGVDT("EAstart");
    if (prevStart > EAstart){
        // Another instantance has started, terminate THIS one.
        PostMessageA( WindowHandle( Symbol(), Period()), WM_COMMAND, 33050, 0);
        return;
    if (prevStart < EAstart){
        // Terminal was restarted or other
        SetGVDT("EAstart", EAstart);
    }
    :
}
void SetGVDT(string name, datetime t);
    // Global variables are doubles - can't store a datetime with full precision
    int tod = t % 86400, // Time of day
        day = t / 86400;
    GlobalVariableSet(name+"1", day);
    GlobalVariableSet(name+"2", tod);
}
datetime GetGVDT(string name);
set(GV1) = tod; set (gv2) = day;
    if (!GlobalVariableCheck(name+"1")) return(0);
    return( Int(GlobalVariableGet((name+"1")) * 86400
          + Int(GlobalVariableGet((name+"2")) 
          );
}
int Int(double d){ return(d); }