Libraries: IsNewBar

 

IsNewBar:

СIsNewBar class allows to determine the moment of a bar change. Usually IsNewBar() function is used for such things instead of a class. But such a function contains a static variable, and therefore we cannot use several calls of this function. To be able to reuse such function repeatedly in Expert Advisor's code, it would be much easier to make it a class member. In this case that has been accomplished using IsNewBar.mqh.

Author: Nikolay Kositsin

 
I am not a pro, but I think this code is wrong. The Recount variable is always true. Therefore, each tick will be treated as a new bar. Why is this variable there at all? Why call CopyClose? Are the posted codes checked for correct operation at all? If I am wrong, please correct and explain.
 
lordlev:
I am not a pro, but I think this code is wrong. The Recount variable is always true. Therefore, each tick will be treated as a new bar. Why is this variable there at all? Why call CopyClose? Are the posted codes checked for correct operation at all? If I am wrong, please correct and explain.
I have double-checked everything again and found a mistake. In the attached file itself there is no assignment of Recount to false, but in the example code everything is correct.
 
lordlev:
I rechecked everything again and found an error. In the attached file itself there is no assignment of Recount to false, but in the example code everything is correct.
Well, it can be fixed!
 

Maybe I'm wrong, but I think this is the right way to do it.

if(TNew>m_TOld)

Otherwise it will be inaccurate during paging (history editing).

Could you explain what this is and why this check is inserted?

if(...  && TNew)

I don't understand it. When is this condition true, when is it false? Thank you

 
Prival:

Can you explain what this is and why this check is inserted?

I don't understand it. When is this condition true and when is it false? Thank you

Imho, it checks that TNew is not equal to m_TOld and at the same time is not equal to zero ( i.e. D'1970.01.01.01 00:00:00:00')....

The second condition, also imho, checks that the function

datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));

has returned something different from zero...

Now I ran the script with this function - it returned me exactly 0. Maybe because of the weekend.

 
Prival:

Can you explain what this is and why this check is inserted?

I don't understand it. When is this condition true and when is it false? Thank you.

The check for zero is necessary to avoid getting the beginning of a new bar (no matter how much time has passed since its opening) at the start and the first check of the condition.
 
Prival:

Maybe I'm wrong, but I think this is the right way to do it.

Otherwise there will be inaccuracy of work during paging (history editing).

Could you explain what it is and why this check is inserted?

I don't understand it. When is this condition true, when is it false? Thank you.

I think it would be more logical to do it as a precaution.

if(TNew>m_TOld && TNew)

although TNew will still be zero when the history is swapped. A zero can get into the TNew variable at any time, so you should check for zero all the time.

 
Automated-Trading:

IsNewBar:

Author: Nikolay Kositsin

There is a little bug in your class (as in most of the functions I saw the code). First time you call you method IsNewBar, it always return true, irrespective of the existence of a real new bar.

But such a function contains a static variable, and therefore we cannot use several calls of this function.

One can also use a two dimensional array to keep last bar open time.

 
I made a alternative version of CIsNewBar, without any static variable. I just used the Tick.time_msc to do a idempotent function:


class CIsNewBar{
private:
   long checkedMs;
   datetime lastBarOpenedAt;
   bool lastValue;
   CTickUtils tickUtils;
public:
   CIsNewBar(){}
   ~CIsNewBar(){}

   bool isNewBar(){
      MqlTick tick;
      SymbolInfoTick(_Symbol, tick);
      long tickMs = tick.time_msc;

      
      if(checkedMs >= tickMs){ //already processed this function on this tick?
         return lastValue;     //so, return the buffered value
      }

      datetime time[1];
      CopyTime(_Symbol, _Period, 0, 1, time);


      if(lastBarOpenedAt != time[0]){
         lastBarOpenedAt = time[0];
         lastValue = true;
      } else {
         lastValue = false;
      }

      checkedMs = tickMs;
      return lastValue;
   }
 

I think this is a speedy lightweight class that fixes the above mentioned problems.

This version:

  • won't give a false alert on the first time the .isNewBar() function is called. 
  • eliminates the constant re-instantiation of new variables each time the function is called without using static variables, which speeds up execution. 
  • returns true only one time per bar.
  • has a lightweight memory footprint. 
class CIsNewBar{
        private:
                datetime lastBarOpenedAt;
                datetime time[1];
        public:
                CIsNewBar(){CopyTime(_Symbol, _Period, 0, 1, time);lastBarOpenedAt = time[0];}
                ~CIsNewBar(){}
                bool isNewBar(){
                        CopyTime(_Symbol, _Period, 0, 1, time);
                        if(lastBarOpenedAt < time[0]){
                                lastBarOpenedAt = time[0];
                                return(true);
                                }
                        else { return(false);}
                        }
        };

To implement the class:

CIsNewBar someName;

void OnTick(){
        if(someName.isNewBar()){
                /// Call new bar event handler or
                /// Do work for new bar. 
                }
        }
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
Predefined Macro Substitutions - Named Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5