For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()" - page 3

 
Nikolai Semko #:

what  bug ?

My inference  was only based on what you said my code was a lot more complicated.

Especially since you haven't initialized the object. This clearly indicates that you are not friends with classes.

Did you understand what I meant in this comment https://www.mql5.com/en/forum/429994/page2#comment_41227896 ?

It seemed like a bug to me when it returns true when one changes the timeframe but the bar is not new... or is it supposed to do that?

For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()"
For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()"
  • 2022.08.04
  • www.mql5.com
I think the below code for IsNewBarOnTimeframes() might be useful for anyone who wishes to monitor the end of a bar from any time frame whatsoever...
 
R4tna C #:

Did you understand what I meant in this comment https://www.mql5.com/en/forum/429994/page2#comment_41227896 ?

It seemed like a bug to me when it returns true when one changes the timeframe but the bar is not new... or is it supposed to do that?

I answered you here that it was not a bug, but your mistake.

Forum on trading, automated trading systems and testing trading strategies

For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()"

Nikolai Semko, 2022.08.04 20:45

This is because you are declaring an instance of the class, but you are initializing it:

CIsNewBar            objDetector;

should be like this:

CIsNewBar            objDetector();

or like this:

CIsNewBar            objDetector(PERIOD_M5, "EURUSD");

or like this:

CIsNewBar            objDetector(PERIOD_M5);

 
Nikolai Semko #:

I answered you here that it was not a bug, but your mistake.


It seems you think it is not appropriate to instantiate an object the way I did it, but if you read the MQL guides, you will see it is standard practice - examples below.

I usually follow these MQL examples as I am still learning this platform and rely on what the experts advise. I never had any problems instantiating in this manner, before I encountered your code that is..

If your code needs something specific to work right, you should put that in the comments/documentation or write better code which is not fallible in this manner.


https://www.mql5.com/en/articles/351



The Basics of Object-Oriented Programming
The Basics of Object-Oriented Programming
  • www.mql5.com
You don't need to know what are polymorphism, encapsulation, etc. all about in to use object-oriented programming (OOP)... you may simply use these features. This article covers the basics of OOP with hands-on examples.
 
R4tna C #:

It seems you think it is not appropriate to instantiate an object the way I did it, but if you read the MQL guides, you will see it is standard practice - examples below.

I usually follow these MQL examples as I am still learning this platform and rely on what the experts advise. I never had any problems instantiating in this manner, before I encountered your code that is..

If your code needs something specific to work right, you should put that in the comments/documentation or write better code which is not fallible in this manner.


https://www.mql5.com/en/articles/351



Oh yes, indeed. I beg your pardon. It's just that I program in parallel in many languages. And as a rule, the behavior of such declarations of a class variable is precisely such that it equals NULL.

But I do not reproduce this bug, which you write about.

Please try to run my code and see if this bug will be reproduced?

For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()" - How to fix the problem of a new bar on timeframes
For those who would find it useful: Behold the universal "IsNewBarOnTimeframes()" - How to fix the problem of a new bar on timeframes
  • 2022.08.04
  • www.mql5.com
The first isnewbarontimeframes() i posted above does not have such issue. Here is the test code: i did not see such a problem when switching timeframes. If you leave it running and switch timeframes you get a true result even when the bar is not new
 
Nikolai Semko #:

Oh yes, indeed. I beg your pardon. It's just that I program in parallel in many languages. And as a rule, the behavior of such declarations of a class variable is precisely such that it equals NUUL.

But I do not reproduce this bug, which you write about.

Please try to run my code and see if this bug will be reproduced?

I get what you are saying, I have to use many languages too.

I will have try those alternatives you suggested tomorrow - I have no doubt they will work as designed, just so happens my way of implementing was different from yours and produced some unexpected results.

If you want to see the behaviour I experienced, here is the simple test script I used - just run it and change the time frames and you should see what I saw

//+------------------------------------------------------------------+
//|                                       429994-NewBarDetection.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CIsNewBar
  {
private:
   datetime          last_bar_time_open;
   ENUM_TIMEFRAMES   tf;
   string            symbol;
public:
                     CIsNewBar(ENUM_TIMEFRAMES _tf = 0, string _symbol = NULL)
     {
      symbol = _symbol;
      tf = _tf;
      last_bar_time_open = iTime(symbol, tf, 0);
     };
                    ~CIsNewBar() {};
   bool              IsNewBar()
     {
      datetime cur_bar_time_open = iTime(symbol, tf, 0);
      bool result = cur_bar_time_open != last_bar_time_open;
      last_bar_time_open = cur_bar_time_open;
      return result;
     }
  };

CIsNewBar            objDetector;
bool                 detector;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {

      PrintFormat("TimeCurrent = %s [detector.detectnewBar = objDetector.IsNewBar()]",
                  TimeToString(TimeCurrent(), TIME_SECONDS)
                 );

      detector = objDetector.IsNewBar();
     

   if(detector)
     {
      PrintFormat("TimeCurrent = %s - New bar Detected", TimeToString(TimeCurrent(), TIME_SECONDS));
     }


   Sleep(1 * 1000);
  }
//+------------------------------------------------------------------+
 
R4tna C #:

I get what you are saying, I have to use many languages too.

I will have try those alternatives you suggested tomorrow - I have no doubt they will work as designed, just so happens my way of implementing was different from yours and produced some unexpected results.

If you want to see the behaviour I experienced, here is the simple test script I used - just run it and change the time frames and you should see what I saw

Yes, I've understood the problem. Thank you!

This happened only in EA and only with TimeFrame = PERIOD_CURRENT (0), because variables, including class instances, are not re-initialized in EA when the timeframe is changed. Therefore, when TimeFrame = 0 (PERIOD_CURRENT), when changing the TimeFrame of the chart, the internal parameter tf must be changed to the current TimeFrame.

I fixed this issue. Now this class and test EA look like this:

#property strict

//+------------------------------------------------------------------+
class CIsNewBar
  {
private:
   datetime          last_bar_time_open;
   ENUM_TIMEFRAMES   tf, tf2;
   string            symbol;
public:
                     CIsNewBar(ENUM_TIMEFRAMES _tf = 0, string _symbol = NULL)
     {
      symbol = _symbol;
      if(symbol == NULL)
         symbol = _Symbol;
      tf = _tf;
      if(tf == 0)
         tf2 = (ENUM_TIMEFRAMES)_Period;
      last_bar_time_open = iTime(symbol, tf, 0);
     };
   bool              IsNewBar()
     {
      if(tf==0 && tf2 != _Period)    // if the TimeFrame was switched with mode = PERIOD_CURRENT
        {
         tf2 =(ENUM_TIMEFRAMES)_Period;
         last_bar_time_open = iTime(symbol, tf, 0);
         return false;
        }
      datetime cur_bar_time_open = iTime(symbol, tf, 0);
      bool result = cur_bar_time_open > last_bar_time_open;
      last_bar_time_open = cur_bar_time_open;
      return result;
     }
   void              PrintInfo()
     {
      Print("New Bar " + EnumToString(tf) +" in " + symbol);
     }
  };

//+------------------------------------------------------------------+
CIsNewBar m1_eur();
CIsNewBar *new_bar[6];
//+------------------------------------------------------------------+
int OnInit()
  {
   new_bar[0] = new CIsNewBar(PERIOD_M1);
   new_bar[1] = new CIsNewBar(PERIOD_M1, "EURUSD");
   new_bar[2] = new CIsNewBar(PERIOD_M1, "USDJPY");
   new_bar[3] = new CIsNewBar(PERIOD_M5, "GBPUSD");
   new_bar[4] = new CIsNewBar(PERIOD_M15, "USDJPY");
   new_bar[5] = new CIsNewBar();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   for(int i = 0; i<6; i++)
      delete new_bar[i];
  }
//+------------------------------------------------------------------+
void OnTick()
  {

   if(m1_eur.IsNewBar()) m1_eur.PrintInfo();
   for(int i = 0; i<6; i++)
      if(new_bar[i].IsNewBar()) new_bar[i].PrintInfo();
  }
//+------------------------------------------------------------------+

this code works in MT5 too
Files:
 
Nikolai Semko #:

Yes, I've understood the problem. Thank you!

This happened only in EA and only with TimeFrame = PERIOD_CURRENT (0), because variables, including class instances, are not re-initialized in EA when the timeframe is changed. Therefore, when TimeFrame = 0 (PERIOD_CURRENT), when changing the TimeFrame of the chart, the internal parameter tf must be changed to the current TimeFrame.

I fixed this issue. Now this class and test EA look like this:


this code works in MT5 too

Looks good - I ran it on M1 & M5 and all fine!