Why Does This Code Work?

 

'New_Experts' obtains its value from 'Quantity', which obtains its value from 'Experts'...

So how can 'New_Experts' and 'Experts' ever have a different value, therefore allowing the condition 'if (Experts!=New_Experts)' to return true?

//--------------------------------------------------------------------
int    Experts;                                 // Amount of EAs
double Depo=10000.0,                            // Set deposit
       Persent=30,                              // Set percentage     
       Money;                                   // Desired money
string Quantity="GV_Quantity";                  // GV name
//--------------------------------------------------------------------
int init()                                      // Special funct. init()
  {
   Experts=GlobalVariableGet(Quantity);         // Getting current value
   Experts=Experts+1;                           // Amount of EAs
   GlobalVariableSet(Quantity, Experts);        // New value
   Money=Depo*Persent/100/Experts;                // Money for EAs
   Alert("For EA in window ", Symbol()," allocated ",Money);
   return;                                      // Exit init()
  }
//--------------------------------------------------------------------
int start()                                     // Special funct. start()
  {
   int New_Experts= GlobalVariableGet(Quantity);// New amount of EAs
   if (Experts!=New_Experts)                    // If changed
     {
      Experts=New_Experts;                      // Now current
      Money=Depo*Persent/100/Experts;             // New money value 
      Alert("New value for EA ",Symbol(),": ",Money);
     }
   /*
   ...
   Here the main EA code should be indicated.
   The value of the variable Money is used in it.
   ...
   */
   return;                                      // Exit start()
  }
//--------------------------------------------------------------------
int deinit()                                    // Special funct. deinit()
  {
   if (Experts ==1)                             // If one EA..
      GlobalVariableDel(Quantity);              //..delete GV
   else                                         // Otherwise..
      GlobalVariableSet(Quantity, Experts-1);   //..diminish by 1
   Alert("EA detached from window ",Symbol());  // Alert about detachment
   return;                                      // Exit deinit()
  }
//--------------------------------------------------------------------
 
Quantity is a Global Variable. It can be changed by other Programs running in the same MT4 Terminal.
 
Laszlo Tormasi:
Quantity is a Global Variable. It can be changed by other Programs running in the same MT4 Terminal.

I understand that. When the EA is attached to a separate window, the init() function runs again so the value of 'Experts' and 'Quantity' will be altered. But after the programs have been initialized, the start function does all the work and the only line in the start function before the test condition of the 'if' statement is:

int New_Experts= GlobalVariableGet(Quantity)

So 'New_Experts' gets the value of 'Quantity' (which would be equivalent to 2 after the EA has been attached to 2 separate windows) and the value of 'Quantity' is determined by the lines:

   Experts=Experts+1;                           // Amount of EAs
   GlobalVariableSet(Quantity, Experts);        // New value

in the second initialization.
Using alerts, I can tell that eventually the value of 'New_Experts' increases to 2 in the start() function, whilst the value of 'Experts' remains at 1, but: how is it possible for the value of 'New_Experts' to differ from the value of 'Experts' if the line:

GlobalVariableSet(Quantity, Experts);

sets the value for 'Quantity', which then gives its value to 'New_Experts' in the line:

int New_Experts= GlobalVariableGet(Quantity);
 

As this screenshot illustrates, 'New_Experts' increases to 2 directly after the intialization of the the EA onto the second chart window has completed, but 'Experts' retains the value of 1 in the following alert, despite the fact that the value of 'New_Experts' is dependant upon on the value of 'Experts' due to the lines:

GlobalVariableSet(Quantity, Experts); 
int New_Experts= GlobalVariableGet(Quantity);
 
koranged:

As this screenshot illustrates, 'New_Experts' increases to 2 directly after the intialization of the the EA onto the second chart window has completed, but 'Experts' retains the value of 1 in the following alert, despite the fact that the value of 'New_Experts' is dependant upon on the value of 'Experts' due to the lines:

check the location of your Alert() statement in relation to that if statement in the start(), if the Alert() for New_Expert and Expert is before the if statement it will be updated on the next tick..

 
Lakshan Perera:

check the location of your Alert() statement in relation to that if statement in the start(), if the Alert() for New_Expert and Expert is before the if statement it will be updated on the next tick..


//--------------------------------------------------------------------
int    Experts;                                 // Êîëè÷. ýêñïåðòîâ
double Depo=10000.0,                            // Çàäàííûé äåïîçèò
       Persent=30,                              // Çàäàííûé ïðîöåíò     
       Money;                                   // Èñêîìûå ñðåäñòâà
string Quantity="GV_Quantity";                  // Èìÿ GV-ïåðåìåííîé
//--------------------------------------------------------------------
int init()                                      // Ñïåö. ôóíêöèÿ init
  {
   Experts=GlobalVariableGet(Quantity);         // Ïîëó÷èì òåê. çíà÷.
   Experts=Experts+1;                           // Êîëè÷. ýêñïåðòîâ
   GlobalVariableSet(Quantity, Experts);  
   Alert("Quantity = ", GlobalVariableGet(Quantity));
   Alert("Experts =", Experts);                 // after 2nd initialization Experts = 2
   Money=Depo*Persent/100/Experts;              // Ñðåäñòâà äëÿ ýêñï.
   Alert("For EA in window ", Symbol()," allocated ",Money); 
   return;                                      // Âûõîä èç init()
  }
//--------------------------------------------------------------------
int start()                                     // Ñïåö. ôóíêöèÿ start
  {
   Alert("Experts =", Experts);
   int New_Experts= GlobalVariableGet(Quantity);
   Alert("New_Experts = ", New_Experts); 
   Alert("Experts =", Experts);                 // After 2nd iteration of start(), Experts = 1
   if (Experts!=New_Experts)                    // Åñëè èçìåíèëîñü
     {
      Experts=New_Experts;                      // Òåïåðü òåêóù. òàêîå
      Money=Depo*Persent/100/Experts;           // Íîâîå çíà÷. ñðåäñòâ 
      Alert("New value for EA ",Symbol(),": ",Money);
     }
   /*
   ...
   Çäåñü äîëåí áûòü óêàçàí îñíîâíîé êîä ýêñïåðòà,
   â êîòîðîì èñïîëüçóåòñÿ çíà÷åíèå ïåðåìåííîé Money
   ...
   */
   return;                                      // Âûõîä èç start()
  }
//--------------------------------------------------------------------
int deinit()                                    // Ñïåö. ô-èÿ deinit
  {
  Alert("Deinit happened");
  if (Experts ==1)                             // Åñëè ýêñïåðò îäèí..
      GlobalVariableDel(Quantity);              //..óäàëÿåì GV-ïåðåìåí
   else                                         // À èíà÷å..
      GlobalVariableSet(Quantity, Experts-1);   //..óìåíüøàåì íà 1
   Alert("EA detached from window ",Symbol()); // Ñîîáù. î âûãðóçêå
   return;                                      // Âûõîä èç deinit()
  }
//--------------------------------------------------------------------

I have set the alerts up as indicated above. The alerts for 'New_Expert' and 'Expert' are prior to the 'if' statement, are you suggesting this means that the value of 'Experts' is therefore not updated until the next tick?


 
Lakshan Perera:

check the location of your Alert() statement in relation to that if statement in the start(), if the Alert() for New_Expert and Expert is before the if statement it will be updated on the next tick..

And the problem is that the value of 'Experts' is alerted as 2 from the initialization function, but then in the start function it is alerted as 1, despite the fact that no altering of the 'Experts' variables value has occurred in the start function... I fail to understand this.

 
koranged:

And the problem is that the value of 'Experts' is alerted as 2 from the initialization function, but then in the start function it is alerted as 1, despite the fact that no altering of the 'Experts' variables value has occurred in the start function... I fail to understand this.

Hello,

first of all, you have put Alert() all around, duplicating the same message each time; so first, you may do a clean up up there.

Second, the code works ok, you have mixed things up and lost track. For example, in the second image, EURAUD initializes "Quantity" to 1, as well as "Experts".

Then on USDCHF, you set Experts to 1, increment and you get Experts and Quantity (for USDCHF) to 2, as in the lower arrow.

Back on EURAUD, Quantity, which is a Global Variable is 2, as expected, but Experts remains 1, as expected. Why's that? Experts is a variable local to the EA, so it has the value from OnInit() in EURAUD.

Maybe you are confusing global variables with "Global Variables of the Terminal"? I doubt so but anyway. And a couple of remarks:

a) You are using the old style of MQL4, how bout using the current events, like OnTick()?

b) You should not rely on an assumption on the order that OnInit() and Start() are executed. OnInit() may not happen first
 
koranged:


I have set the alerts up as indicated above. The alerts for 'New_Expert' and 'Expert' are prior to the 'if' statement, are you suggesting this means that the value of 'Experts' is therefore not updated until the next tick?


Not until next tick, it is because you are calling Alert() before the variable is updated that's why, if you call the Alert() for the Expert variable, after the if statement it will have the updated value, and you can see the correct value from Alerts() (on the same tick) because inside the if statement is where the variable update is happening..

//--------------------------------------------------------------------
int    Experts;                                 // Êîëè÷. ýêñïåðòîâ
double Depo=10000.0,                            // Çàäàííûé äåïîçèò
       Persent=30,                              // Çàäàííûé ïðîöåíò     
       Money;                                   // Èñêîìûå ñðåäñòâà
string Quantity="GV_Quantity";                  // Èìÿ GV-ïåðåìåííîé
//--------------------------------------------------------------------
int init()                                      // Ñïåö. ôóíêöèÿ init
  {
   Experts=GlobalVariableGet(Quantity);         // Ïîëó÷èì òåê. çíà÷.
   Experts=Experts+1;                           // Êîëè÷. ýêñïåðòîâ
   GlobalVariableSet(Quantity, Experts);  
   Alert("Quantity = ", GlobalVariableGet(Quantity));
   Alert("Experts =", Experts);                 // after 2nd initialization Experts = 2
   Money=Depo*Persent/100/Experts;              // Ñðåäñòâà äëÿ ýêñï.
   Alert("For EA in window ", Symbol()," allocated ",Money); 
   return;                                      // Âûõîä èç init()
  }
//--------------------------------------------------------------------
int start()                                     // Ñïåö. ôóíêöèÿ start
  {
   Alert("Before update, Experts =", Experts); // has not updated yet
   int New_Experts= GlobalVariableGet(Quantity);
   Alert("New_Experts = ", New_Experts);        
   Alert("Experts =", Experts);         // hasn't updated yet               
   if (Experts!=New_Experts)                    
     {
      Experts=New_Experts;              //Now Only it updated                  
      Money=Depo*Persent/100/Experts;           
      Alert("New value for EA ",Symbol(),": ",Money);
     }
   Alert("After update, Experts =", Experts);
   /*
   ...
   Çäåñü äîëåí áûòü óêàçàí îñíîâíîé êîä ýêñïåðòà,
   â êîòîðîì èñïîëüçóåòñÿ çíà÷åíèå ïåðåìåííîé Money
   ...
   */
   return;                                      // Âûõîä èç start()
  }
//--------------------------------------------------------------------
int deinit()                                    // Ñïåö. ô-èÿ deinit
  {
  Alert("Deinit happened");
  if (Experts ==1)                             // Åñëè ýêñïåðò îäèí..
      GlobalVariableDel(Quantity);              //..óäàëÿåì GV-ïåðåìåí
   else                                         // À èíà÷å..
      GlobalVariableSet(Quantity, Experts-1);   //..óìåíüøàåì íà 1
   Alert("EA detached from window ",Symbol()); // Ñîîáù. î âûãðóçêå
   return;                                      // Âûõîä èç deinit()
  }
//--------------------------------------------------------------------
 
Lakshan Perera:

Not until next tick, it is because you are calling Alert() before the variable is updated that's why, if you call the Alert() for the Expert variable, after the if statement it will have the updated value, and you can see the correct value from Alerts() (on the same tick) because inside the if statement is where the variable update is happening..

Okay thanks Lakshan.

 
Demos Stogios:

Hello,

first of all, you have put Alert() all around, duplicating the same message each time; so first, you may do a clean up up there.

Second, the code works ok, you have mixed things up and lost track. For example, in the second image, EURAUD initializes "Quantity" to 1, as well as "Experts".

Then on USDCHF, you set Experts to 1, increment and you get Experts and Quantity (for USDCHF) to 2, as in the lower arrow.

Back on EURAUD, Quantity, which is a Global Variable is 2, as expected, but Experts remains 1, as expected. Why's that? Experts is a variable local to the EA, so it has the value from OnInit() in EURAUD.

Maybe you are confusing global variables with "Global Variables of the Terminal"? I doubt so but anyway. And a couple of remarks:

a) You are using the old style of MQL4, how bout using the current events, like OnTick()?

b) You should not rely on an assumption on the order that OnInit() and Start() are executed. OnInit() may not happen first

Hi Demos,

The reason I have put multiple alerts for the same message is so that I can track the values of 'Experts' and 'New_Experts' after each operation to understand where exactly the values are changing. 

Also as I mentioned at the top, this isn't a program that I have coded, it is an example from the manual/tutorial, so that is probably why the current events are absent. I am just trying to gain a working understanding of the examples used in the documentation before moving on to the next step.

This example relates to 'Global Variables of the Client Terminal' not just 'global variables'.

When you say "Experts is a variable local to the EA", does this mean that 'Experts' will not update its value after initialization of the second pair, because the start() function can only see the value of 'Experts' on the first pair, due to the fact that 'Experts' is not a Global Variable of the Client Terminal?

So if I am following correctly, this means that 'Experts' is local to just the one program rather than all programs as a Global Variable of the Client Terminal would be, whereas 'Quantity' is a Global Variable of the Client Terminal, and its value can therefore be updated by other programs, i.e. when the EA is attached to the second window, the value of 'Quantity' (and therefore 'New_Experts') will be 2, but as 'Experts' is a variable local to just this program, it is not aware that the EA has been attached to the second window and therefore its value remains as 1, until the 'if' statement changes that?

Is this correct or at least along the right lines?

Thanks for your help.