Can somebody explain me how this little piece of code works?

 

Hey guys,

I know it sounds silly but this piece of code I use in almost every indicator is a riddle for me. It works perfect but I don't understand what I am doing there.

The purpose of this code is that something should only be executed once a minute even if timeframes are changed. 

I know it's all about the boolean variable 'a' but like I said before, I have no idea why it works, although I read the code at least 1000 times.

So if anyone could explain me what exactly the variable 'a' does, I would be very thankful.

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---

   static bool a=true;
   static datetime m1Time0;
   if (m1Time0!=iTime(_Symbol, PERIOD_M1, 0)) {
      m1Time0=iTime(_Symbol, PERIOD_M1, 0);
      if (!a) {
      
         //--- here starts the code which is only executed once a minute
         //--- even if the timeframes are changed
         
         Print("Code executed at "+TimeToString(TimeCurrent()));
         
         /---
      }
      else a=false;
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

With every tick the variable 'a' is set to true, so how can it become false when it's always set to true at the beginning?

 
It's not "set to true at the beginning." It is a static variable, it is set to true when the indicator is loaded and retains it's value between calls.
 
whroeder1:
It's not "set to true at the beginning." It is a static variable, it is set to true when the indicator is loaded and retains it's value between calls.

Ok, but I still don’t understand how this whole structure works. I remember that I saw it in one of your postings and adjusted it to my needs.

So you say that variable ‚a‘ is not set to true with every execution of OnCalculate()? I don’t get this in my mind. And if so where is it set to true? The execution of the code requires the variable to be false. But all the other remaining ticks of the minute it must be true because it’s not executed...

I think this logic is absolutely clear and easy for you but I’m totally stuck here. I don’t understand the smallest piece of this logic... :(

 
Marcus Riemenschneider: a‘ is not set to true with every execution of OnCalculate()?  ... And if so where is it set to true?
  1. Correct. If you want it initialized every execution, drop the static.

  2. What part of "it is set to true when the indicator is loaded" was unclear?
    Your code
     Equivalent
    int OnCalculate(...){
       static bool a=true;
    bool a; // global is same as static.
    int OnInit(){ a = true; ...} // Initialized on load
    int OnCalculate(...){
 
Marcus Riemenschneider:

Hey guys,

I know it sounds silly but this piece of code I use in almost every indicator is a riddle for me. It works perfect but I don't understand what I am doing there.

The purpose of this code is that something should only be executed once a minute even if timeframes are changed. 

I know it's all about the boolean variable 'a' but like I said before, I have no idea why it works, although I read the code at least 1000 times.

So if anyone could explain me what exactly the variable 'a' does, I would be very thankful.

With every tick the variable 'a' is set to true, so how can it become false when it's always set to true at the beginning?

//+------------------------------------------------------------------+
//|                                                          ddd.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
int prevtime;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(Time[0] == prevtime)  return(0);
        prevtime = Time[0];
    Alert(" Time ",Time[0]);
// Your Code
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
whroeder1:
  1. Correct. If you want it initialized every execution, drop the static.

  2. What part of "it is set to true when the indicator is loaded" was unclear?
    Your code
     Equivalent

That equivalent example helped a lot. I think I got the logic now! Thank you!!

I forgot that changing the timeframe also causes the indicator to load. 
 
Mehmet Bastem:

This is already a part of my code. If you change the timeframe you will always get an alert. I wanted to avoid exactly that. Therefore the use of the Boolean variable a. 

 
Mehmet Bastem: everything is already in your indicator. Why use Time[], if there is a time[]
#property strict
#property indicator_chart_window

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   #ifdef __MQL5__
     datetime Time[];
     CopyTime(_Symbol, 0, 0, 1, Time);
   #endif
     if( !ArrayGetAsSeries(time) )
          ArraySetAsSeries(time, true);
     Comment("Time: ", Time[0],
             "\n",
             "time: ", time[0]);
     
     return(rates_total);
}


Event Handling Functions
--> OnCalculate

 
Konstantin Nikitin Why use Time[], if you have &time[]

Because in MT4

  1. You don't have to pass it down to other functions.
  2. You don't have to declare it as series or not.
  3. A lot of existing code already use it.
Reason: