Changing extern variables

 

Hi all,

if you have the following program

extern int var=0;

OnInit()
 {
 }

OnTick()
 {
  if(var==1)
   {
    <do something>;
    var=0;
   }
 }

If during operation of the EA the value of 'var' is changed to '1' on the chart, the <do something> routine is executed and the 'var' value is set back to '0', preventing the routine to be executed again when the next tick arrives. However, when there is a platform restart, a compile or a simple Chart change, the value of 'var' is set back to 1 and the routine is executed  once again.

Work around is to also manually set the value of 'var' back to '0' on the chart, but that a little cumbersome and easy to forget. using UNINITIALIZEREASON() = REASON_CHARTCHANGE is likely possible, but i was wondering if there maybe is a more elegant solution?

 

It sounds like you want to set a Global Variable.

Global Variables are stored on file so you can read the value upon program launch, period change, or any event that would cause the value of a variable to be lost when your program is deinitialized.

One thing to note is that it only accepts values of double type, so you will have to be sure that the value you're storing can be typecast into a double (in your case, it can).

https://docs.mql4.com/globals

Global variables of the client terminal should not be mixed up with variables declared in the global scope of the mql4 program.

Global variables are kept in the client terminal for 4 weeks since the last access, then they will be deleted automatically. An access to a global variable is not only setting of a new value, but reading of the global variable value, as well.

Global variables of the client terminal are accessible simultaneously from all mql4 programs launched in the client terminal.


Function

Action

GlobalVariableCheck

Checks the existence of a global variable with the specified name

GlobalVariableTime

Returns time of the last accessing the global variable

GlobalVariableDel

Deletes a global variable

GlobalVariableGet

Returns the value of a global variable

GlobalVariableName

Returns the name of a global variable by its ordinal number in the list of global variables

GlobalVariableSet

Sets the new value to a global variable

GlobalVariablesFlush

Forcibly saves contents of all global variables to a disk

GlobalVariableTemp

Sets the new value to a global variable, that exists only in the current session of the terminal

GlobalVariableSetOnCondition

Sets the new value of the existing global variable by condition

GlobalVariablesDeleteAll

Deletes global variables with the specified prefix in their names

GlobalVariablesTotal

Returns the total number of global variables

Global Variables of the Terminal - MQL4 Reference
Global Variables of the Terminal - MQL4 Reference
  • docs.mql4.com
Global Variables of the Terminal - MQL4 Reference
 
Route206:
extern int var=0;

OnInit()
 {
 }

OnTick()
 {
  if(var==1)
   {
    <do something>;
    var=0;
   }
 }


Aside from my post above, if it's absolutely necessary for the user of the EA to be able to set the value of the var variable (as alluded to by extern modifier). you might have to plan for that. In MT4, you can read the _UninitReason and see if it's REASON_PARAMETERSCHANGE. This solution doesn't work in MT5, though. Another solution is to check for REASON_PARAMTERSCHANGE when OnDeinit is called and create a Global Variable. From there, inside OnInit, check if that Global Variable exists, run whatever code is necessary, and delete the Global Variable afterwards.

However, if the user has no use in setting the value of the var variable, then remove the extern modifier and you can avoid that hassle altogether.

 
Route206:

Hi all,

if you have the following program

If during operation of the EA the value of 'var' is changed to '1' on the chart, the <do something> routine is executed and the 'var' value is set back to '0', preventing the routine to be executed again when the next tick arrives. However, when there is a platform restart, a compile or a simple Chart change, the value of 'var' is set back to 1 and the routine is executed  once again.

Work around is to also manually set the value of 'var' back to '0' on the chart, but that a little cumbersome and easy to forget. using UNINITIALIZEREASON() = REASON_CHARTCHANGE is likely possible, but i was wondering if there maybe is a more elegant solution?

extern int var=0;

OnInit()
 {
var=0;
 }

OnTick()
 {
  if(var==1)
   {
    <do something>;
    var=0;
   }
 }
 
Alexander Martinez #:

It sounds like you want to set a Global Variable.

Global Variables are stored on file so you can read the value upon program launch, period change, or any event that would cause the value of a variable to be lost when your program is deinitialized.

One thing to note is that it only accepts values of double type, so you will have to be sure that the value you're storing can be typecast into a double (in your case, it can).

https://docs.mql4.com/globals

I'm afraid that is not the elegant solution i'm looking for.  I need to set execute simple routines when EA is running, using GlobalVariables and Doubles is not that.
Maybe i should consider buttons...

 
Daniel Cioca #:


OnInit()
 {
var=0;
 }

Is not doing it. The moment you do this, the 'var' parameter is set to '0' before routine is executed. After all: OnInit() is called when changing 'var' during EA operation, which is causing the problem.

 
Route206 #:


Is not doing it. The moment you do this, the 'var' parameter is set to '0' before routine is executed. After all: OnInit() is called when changing 'var' during EA operation, which is causing the problem.

No..OnInit() is only running one time when the program starts ...  when you switch the timeframe, program restarts, therefore OnInit() is called again, your variable from the Global Area will be initialized again to "0" in the OnInit() function. 


The Init event is generated immediately after an Expert Advisor or an indicator is downloaded; The OnInit() function is used for initialization.

 

Or even better


Client Terminal Events

Init

Immediately after the client terminal loads a program (an Expert Advisor or custom indicator) and starts the process of initialization of global variables, the Init event will be sent, which will be processed by OnInit() event handler, if there is such. This event is also generated after a financial instrument and/or chart timeframe is changed, after a program is recompiled in MetaEditor, after input parameters are changed from the setup window of an Expert Advisor or a custom indicator. An Expert Advisor is also initialized after the account is changed.

 
Daniel Cioca #:

No..OnInit() is only running one time when the program starts ...  when you switch the timeframe, program restarts, therefore OnInit() is called again, your variable from the Global Area will be initialized again to "0" in the OnInit() function. 

..which is the problem. I need it to stay '1' for the OnTick() to find it and execture the routine.

 
Route206 #:

..which is the problem. I need it to stay '1' for the OnTick() to find it and execture the routine.

When the program starts, OnInit starts, intialize your var to "0" then OnTick starts, first tick will set your var to "1"then your routine will start. After your routine starts and executes, your var will be set to "0"again, and everything starts over. It will not remain "1". This is what your code does. Is switching back var to "0 "after one routine. And it is correct like this, to reset your variable to "0" once parameters change and maybe your condition to set your variable to "1" are not true anymore.


If you want your var to stay "1" until you switch otherwise, then you should use GlobalVariableSet() as indicated by Alexander Martinez

Changing extern variables
Changing extern variables
  • 2022.04.15
  • www.mql5.com
Hi all, if you have the following program If during operation of the EA the value of 'var' is changed to '1' on the chart, the
 
Daniel Cioca #:

When the program starts, OnInit starts, intialize your var to "0" then OnTick starts, first tick will set your var to "1"then your routine will start. After your routine starts and executes, your var will be set to "0"again, and everything starts over. It will not remain "1". This is what your code does. 

No.
First tick does not change it. It is a variable of the 'extern' sort that will be changed manually on the chart.