UninitializeReason() REASON_CHARTCHANGE Problem

 

Why is symbol change and timeframe change both bunched up in REASON_CHARTCHANGE? One may require a lot of extra processing time and the other typically should not. Please create new constants to distinguish the two.


Regards,

JT

 
skatt:

Why is symbol change and timeframe change both bunched up in REASON_CHARTCHANGE? One may require a lot of extra processing time and the other typically should not. Please create new constants to distinguish the two.

Global (or static) variables in the EA are preserved across deinits and inits which happen as a result of REASON_CHARTCHANGE. Therefore, you can distinguish what's changed using something like this:


string glbCacheSymbol;

int glbCachePeriod;


int init()

{

   if (glbCacheSymbol != Symbol() && glbCachePeriod != Period()) {

      // A complete change, or (re-)load

   } else if (glbCacheSymbol != Symbol()) {

      // Symbol has changed but timeframe hasn't

   } else {

      // Period has changed but symbol hasn't

   }

   

   // Cache initial or new period and symbol in memory for the EA

   glbCacheSymbol = Symbol();

   glbCachePeriod = Period();


   etc.

}


int deinit()

{

   etc.

}


int start()

{

   etc.

}

 
I would like to know the reason for deinitialization at deinit(), before a new init() is called. That does not appear to be possible.
 
skatt #:
I would like to know the reason for deinitialization at deinit(), before a new init() is called. That does not appear to be possible.

I understand that 14 years passed, but maybe other people are still looking for a solution to this issue.

The solution is rather simple. You can treat OnDeinit() and OnInit() as a single function when reason = REASON_CHARTCHANGE.

This is the case because nothing executes between OnDeinit() and OnInit() in EAs for REASON_CHARTCHANGE.

It executes continuously - when OnDeinit() ends, OnInit() begins. So, everything you want to get done in OnDeinit() for REASON_CHARTCHANGE, you can put at the top of OnInit(). And there, you can analyze whether it was a timeframe change or a symbol change.

Like this:

int DeinitializationReason = -1;
string OldSymbol = "";

int OnInit()
{
    if (DeinitializationReason == REASON_CHARTCHANGE)
    {
        if (OldSymbol != _Symbol)
        {
            // Symbol change...
        }
        else
        {
            // Timeframe change...
        }
    }

    // Normal initialization stuff...

    return INIT_SUCCEEDED;
}

void OnDeinit(const int reason)
{
    DeinitializationReason = reason;
    OldSymbol = _Symbol;

    if (reason != REASON_CHARTCHANGE)
    {
        // Normal deinitialization stuff...
    }
    else
    {
        // Defer deinitialization to OnInit().
    }
}
This will only work in expert advisors. It won't work in indicators.