How to prevent the EA to fully initialize?

 

Hi there, I'm having trouble with my EA while live testing.

I've placed an EA on a demo account for live testing. The thing is that I had to change a couple of things in it while the EA was working and when I compiled it the EA ignored the existing data. For ie I had 5 pending orders and 5 was the limit, but after recompiling the EA, it ignored the first 5 pending orders and sent another 5 for a new total of 10. How can I force the EA to do a proper check after recompiling and thus not starting from anew? This is also important since if you have to restart your computer, you want the EA to continue working properly as if you never shut it down.

Thanks in advance.

 

1. Have a look at Returns the code of the uninitialization reason for the experts, custom indicators, and scripts. The returned values can be ones of Uninitialize reason codes. This function can also be called in function init() to analyze the reasons for deinitialization of the previour launch

2. Think about 'remembering' your current trading status. Why? IF EA restarts due to say a recompile THEN all previous runtime state information is lost.

Having recompiled your EA, it naturally had no 'memory' of what it was doing before compile, yes?

3. You need to know why EA's init() has been entered, yes?

In init() you can do this by calling UniitializeReason() - below I offer you example which you could play around with.

//------------------------------------------------------------------------------
//-
string _UninitializeReason (int& iCode)
{ /***********************
    
    COMMENT:
        return: (functionValue)reason string && (callerIntLoc)reason code
    */
    string s;
    iCode = UninitializeReason();
    switch(iCode)
    {
        case 0:                        s = "REASON_SELF_INITIATED_EXIT"; break;
        case REASON_REMOVE:            s = "REASON_REMOVE"; break;
        case REASON_RECOMPILE:         s = "REASON_RECOMPILE"; break;
        case REASON_CHARTCHANGE:       s = "REASON_CHARTCHANGE"; break;
        case REASON_CHARTCLOSE:        s = "REASON_CHARTCLOSE"; break;
        case REASON_PARAMETERS:        s = "REASON_PARAMETERS"; break;
        case REASON_ACCOUNT:           s = "REASON_ACCOUNT"; break;
        default:
            s = "unexplainedReason!";
            iCode = ERROR;
            break;
    }
    return(s);
}//_UninitializeReason

4. How does this help you if recompile?

Well, there are many ways to approach the 'remembering' of current runtime EA state:

a. When you recompile the EA, the currently running version is closed down, yes?

This means that it's deinit() will be called - remember - afaik, this will happen even if EA is deciding to not exit start() any time soon ;), as Client Terminal will forcedly shutdown EA after ~2.5s and as part of this process - I would assume the 'normal' shutdown sequence would be followed - ie, deinit() called after start() exits either by itself or forced. See MetaEditor docs, info in there and also mql4 book too...

So, in deinit() call made to Unit...Reason() and reason is recompile - so you must dump/save/remember the current EA runtime state, yes?

b. Having 'remembered'..., the recompiled EA is started up and init() will be first EA called, yes?

So, it calls Unit...Reason() and sees the recompile reason code. It can now restore the previously 'remembered' EA runtime state, ok?

Now, when start() gets called after init() exits, the EA 'should' ;), carry on as per normal, yes? ie, since 5 pending then EA will just do whatever ....

5. 'remembering' data can be achieved by: Terminal Global Variables, Disk Files, or... by just using one semaphore to flag that EA must pickup where it was so rudely interrupted at recompile time :)

6. data to remember is totally under your control and if lots of data then disk file is best and actually, disk files are simple to use anyway... so I generally use - is design thingy yes?

7. semaphore: basic idea here is that Client Terminal has it's Trading Pools, yes?

All historical and current market order info resides in these pools... so - given all the Trading Functions - which can return info stored in these pools, you could use OrdersTotal() and inspect pools contents to see what orders this EA initiated, yes?

Think magic number unique to this EA - then it will only look at /OrderSelect() pool entries with it's magic number, yes?

8. Ok, that's where semaphore can be used, is just a Client Terminal GlobalVariable which... deinit() can create and give it a value, yes?

init() of new version always 'first thing' sees if this GlobalVariable exists. (that in itself - the 'existence' bit, could be enough to tell EA that must deal with a recompile/brandNewNoMemoryRestart ) all depends on design - if need more meaning in the GlobalVariable then can have various values or even be bit-mapped to allow a doubleValue's worth of bits to play with....

9. I probably repeat self here - but anyway, main idea is that firstly the 'about to be restarted/recompiled EA' must in either deinit(oldEA) OR IN init(newVerEA) see the reason as to 'why' !

The 'seeing' perspective is either from the about to be stopped old EA or the just started new EA - again, where you decide to 'see' and what you decide to do with this knowledge is up to your design, yes?

secondly you must decide how gonna remember etc. and finally how you gonna reinstate previous EA runtime state IF you so desire...

please shout if I make more unclear... I think have habit of that - LOL

edit.1

forgot to say, that IF use semaphore AND is based purely on it's existence|not THEN init() having 'seen' would then GlobalVariableDel() because it has served it's 'one shot' purpose...

 

Thanks a lot ukt, I´ll try to send a file with the elemental data to be read after recompiling or reopening.

I´ve never used this approach but it is a legitime one, thanks again.

Reason: