Alerts, Timeframes and Deinit()

 

Hi All,

I have tried different ways of writing 'Alert' indicators that do NOT keep alerting when you change timeframes - this is very annoying and occurs primarily because any flags that are set to prevent more than one alert are reset by the deinit() function if you change timeframe. The only surefire way I can see to do this is using GlobalVariables as below:

string AlertName = Symbol() + "alert1";

int start()
{ 
    ...set up all indicator values here (MA's, SAR whatever..)
      
    //check for buy trade
    if(.....buy condition met.....then..)
    {
      //first time alert
      if(GlobalVariableGet(AlertName) == 0)
      {
       Alert(...buy alert..);
       GlobalVariableSet(AlertName,1);
      }
    }
      
    //check for sell trade   
    else if(....sell condition met...then..)
    {
     if(GlobalVariableGet(AlertName) == 0) 
       {
        Alert(..sell alert...);
        GlobalVariableSet(AlertName,-1); 
       }
    }
    //if no condition met
    else {GlobalVariableSet(AlertName,0);} 
  }
return(0);
}
This works fine because when I change chart timeframes the GlobalVariable 'AlertName' is unchanged until a new condition is met. For good housekeeping I should delete all GlobalVariables (relating to this indicator) when I remove the indicator from the chart. However, if I put GlobalVariableDel(AlertName) in the deinit() function I will need to reinstate its value in the init() function if I change timeframes which is very inefficient.

 

Please can anyone think of a better design on how to do this? BTW do STATIC variables reset their values when timeframes are changed? (i.e when the deinit() funtion is invoked?).

thanks 

 
sd59:

Hi All,

I have tried different ways of writing 'Alert' indicators that do NOT keep alerting when you change timeframes - this is very annoying and occurs primarily because any flags that are set to prevent more than one alert are reset by the deinit() function if you change timeframe. The only surefire way I can see to do this is using GlobalVariables as below:

This works fine because when I change chart timeframes the GlobalVariable 'AlertName' is unchanged until a new condition is met. For good housekeeping I should delete all GlobalVariables (relating to this indicator) when I remove the indicator from the chart. However, if I put GlobalVariableDel(AlertName) in the deinit() function I will need to reinstate its value in the init() function if I change timeframes which is very inefficient.

 

Please can anyone think of a better design on how to do this? BTW do STATIC variables reset their values when timeframes are changed? (i.e when the deinit() funtion is invoked?).

thanks 

I might have answered my own question but I now know if I put :

If(IsStopped())
{
.
...delete GlobalVariables()
.
}

this deletes them when the indicator is taken off the chart.

I'd still be interested to hear if anyone can do this more efficiently.

thanks 

 
Check trading condition for previous bar and current bar https://www.mql5.com/en/forum/141712
 
sd59:

Hi All,

I have tried different ways of writing 'Alert' indicators that do NOT keep alerting when you change timeframes - this is very annoying and occurs primarily because any flags that are set to prevent more than one alert are reset by the deinit() function if you change timeframe. The only surefire way I can see to do this is using GlobalVariables as below:

This works fine because when I change chart timeframes the GlobalVariable 'AlertName' is unchanged until a new condition is met. For good housekeeping I should delete all GlobalVariables (relating to this indicator) when I remove the indicator from the chart. However, if I put GlobalVariableDel(AlertName) in the deinit() function I will need to reinstate its value in the init() function if I change timeframes which is very inefficient.

 

Please can anyone think of a better design on how to do this? BTW do STATIC variables reset their values when timeframes are changed? (i.e when the deinit() funtion is invoked?).

thanks 

Check the Uninitialize Reason in init()  if it is REASON_CHARTCHANGE  don't reset your flag.
 
BTW do STATIC variables reset their values when timeframes are changed? (i.e when the deinit() funtion is invoked?).

Static and Globaly declared variables are reset ONLY when the EA is reloaded (recompiled on live chart, not tester.)

ALL other reasons, only deinit/init is called. That is the reason you can't use if(c) SL *=10; on externs.

Statics are problematic because you can't reset them on init. I use this pattern:

No reset static
Resetting "static"
type Function(){
   static type staticVar = 0;
   if (staticVar == 0) .
int init(){
   OnInitFunction(); // OnInitFunction2(); ..
   :
}
/////////////////////////////////////////////////////////////
type notStaticVar; void OnInitFunction(){ notStaticVar = 0; }
type Function(){
   if (nonStaticVar == 0) ...
 
sd59: Please can anyone think of a better design on how to do this? BTW do STATIC variables reset their values when timeframes are changed? (i.e when the deinit() funtion is invoked?).

use of global vars (GlobalVariable*()) is possible but cumbersome. to add to the problems it is slow because access to global vars needs to be synchronized by the terminal (at any given time only one thread gets access, other threads have to wait). and what to do if the terminal/EA/indicator crashes. Global vars remain in the terminal and code that follows gets confused/breaks. a better way is in fact to use static variables.

RaptorUK: Check the Uninitialize Reason in init()  if it is REASON_CHARTCHANGE  don't reset your flag.

Raptor, while this sounds good and is the typical/recommended way to solve the problem, it works only for experts. in indicators it leads to what sd59 is facing: after a REASON_CHARTCHANGE everything is gone, the terminal "resets" every flag. aren't we always switching timeframes, all day long, all the time?

in indicators we need to manage static variables in libraries, there they survive REASON_CHARTCHANGE and REASON_PARAMETERCHANGE. something like that:

int counter;

int init() {
   counter = MyLibGetCounter();
}

int deinit() {
   MyLibSetCounter(counter);
}

ps: things related to execution speed are not so important during online trading, there slow code and execution speed is a non-issue (if properly coded even JavaScript is quick enough for online trading). but in Tester execution speed is of utmost importance. synchronization of every access to shared vars/objects can easily double the duration time of a test. this is not only an MQL issue but true for every language.

 
WHRoeder: Statics are always problematic ...
i agree. even more because the life-time of static variables differs not only between experts and indicators but also between the different data types. strings are most strange, for example in Tester a static string array survives between different tests. change of timeframe/symbol doesn't matter, if you don't take care you're still working on old data. string arrays need great care.
 

static string array survives between different tests. change of timeframe/symbol doesn't matter

Of course it doesn't matter, you are NOT reloading the EA. ALL statics keep their values. Data type is irrelevant.

ALL arrays are static wither declared so or not. Array declared at a local level in a function and resized will remain unchanged after the function has completed its operation.

Use the pattern I posted above and reset your sizes on init().

 
WHRoeder:

Of course it doesn't matter, you are NOT reloading the EA. ALL statics keep their values. Data type is irrelevant.

ALL arrays are static wither declared so or not. Array declared at a local level in a function and resized will remain unchanged after the function has completed its operation.

Use the pattern I posted above and reset your sizes on init().

thanks for the replies guys very useful.
Reason: