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

macpee
888
macpee  
R4tna C #:

I tested it on M1 & M5 and it was fine.

Only observation was that if you switch timeframes on the chart it can return true on the first tick - I had that issue too... small bug but easily fixed

The first IsNewBarOnTimeframes() I posted above does not have such issue. It can work even if you require that multiple timeframes be ended to trade, e.g. M1, M15 and H4 simultaneousely. Only issue might be "Requote error" due to time wasted.

R4tna C
380
R4tna C  
macpee #:

The first IsNewBarOnTimeframes() I posted above does not have such issue. It can work even if you require that multiple timeframes be ended to trade, e.g. M1, M15 and H4 simultaneousely. Only issue might be "Requote error" due to time wasted.

I see - your's is quite elaborate.

My feeling was that it could be done with less code - this was my attempt.

Seems to work unless someone finds a bug...

//+------------------------------------------------------------------+
struct struc_newBarDetector
  {
   datetime             openTime;
   datetime             openTimeNext;
   ENUM_TIMEFRAMES      timeFrame;
   bool                 detectnewBar;
   //+------------------------------------------------------------------+
   bool              detectNewBar()
   //+------------------------------------------------------------------+
     {
      detectnewBar  = false;
      openTime      = iTime(_Symbol, PERIOD_CURRENT, 0);

      if(
         (openTimeNext == 0)               //Init
         || (timeFrame != ChartPeriod())   //Timeframe changed
      )
        {
         timeFrame    = ChartPeriod();
         openTimeNext = openTime + PeriodSeconds(timeFrame);
        }

      if((openTimeNext <= openTime) || (openTimeNext <= TimeCurrent()))
        {
         openTimeNext = openTime + PeriodSeconds(timeFrame);
         detectnewBar   = true;
        }
      return(detectnewBar);
      //+------------------------------------------------------------------+
     } //end = struc_newBarDetector.detectNewBar()
   //+------------------------------------------------------------------+
  }; //end - struc_newBarDetector
//+------------------------------------------------------------------+


Here is the test code:

struc_newBarDetector detector;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {

   detector.detectnewBar = detector.detectNewBar();


   PrintFormat("TimeCurrent = %s [Open Time = %s %s Next Open Time = %s %s]",
               TimeToString(TimeCurrent(), TIME_SECONDS),
               TimeToString(detector.openTime, TIME_DATE), TimeToString(detector.openTime, TIME_SECONDS),
               TimeToString(detector.openTimeNext, TIME_DATE), TimeToString(detector.openTimeNext, TIME_SECONDS)
              );

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


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

I tested it on M1 & M5 and it was fine.

Only observation was that if you switch timeframes on the chart it can return true on the first tick - I had that issue too... small bug but easily fixed

I did not see such a problem when switching timeframes.

I wrote a test indicator using an array of objects. Only in the case of an array class instance via pointers, you must remember to delete these objects.

#property strict
#property indicator_chart_window

//+------------------------------------------------------------------+
class CIsNewBar
  {
private:
   datetime          last_bar_time_open;
   ENUM_TIMEFRAMES   tf;
   string            symbol;
public:        
                     CIsNewBar(ENUM_TIMEFRAMES _tf = 0, string _symbol = NULL)
     {
      symbol = _symbol;
      if(symbol == NULL)
         symbol = _Symbol;
      tf = _tf;
      last_bar_time_open = iTime(symbol, tf, 0);
     };
   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;
     }
   void Print()
     {
      Print("New Bar " + EnumToString(tf) +" in " + symbol);
     }
  };

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
CIsNewBar m1_eur(PERIOD_M5, "EURUSD");
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];
  }
//+------------------------------------------------------------------+
//| 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 (m1_eur.IsNewBar()) m1_eur.Print();
   for(int i = 0; i<6; i++)
     {
      if(new_bar[i].IsNewBar())
         new_bar[i].Print();
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+


It is also necessary to remember that if you use other Symbols, then it is better to poll them in a timer, since you can skip the ticks of another symbol in OnCalculate.
And also you must make sure that this symbol is present in Market Watch.

Files:
R4tna C
380
R4tna C  
Nikolai Semko #:

I did not see such a problem when switching timeframes.

I wrote a test indicator using an array of objects. Only in the case of an array class instance via pointers, you must remember to delete these objects.

It is also necessary to remember that if you use other Symbols, then it is better to poll them in a timer, since you can skip the ticks of another symbol in OnCalculate.

ok - that's a lot more complicated. My test was simple, the same way I tested mine (see below).

If you leave it running and switch timeframes you get a true result even when the bar is not new.

It is a problem I faced in my code (shown above), so I had to put a check in there to prevent it

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

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

   detector.detectnewBar = objDetector.IsNewBar();

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


   Sleep(1 * 1000);
  }


Every time I click a new timeframe it shows new bar detected:


BeeXXI Corporation
10814
R4tna C #:

ok - that's a lot more complicated. My test was simple, the same way I tested mine (see below).

If you leave it running and switch timeframes you get a true result even when the bar is not new.

It is a problem I faced in my code (shown above), so I had to put a check in there to prevent it


Every time I click a new timeframe it shows new bar detected:


The code that I have presented is no more complicated than yours, but more versatile, as it can be used in multi-symbol strategies. Your function cannot be used for different Symbols. Moreover, in the variant presented by me, the performance is higher, since there is no timeframe search.

If you love programming and want to further develop in this direction, but at the same time you are not friends with OOP, then you urgently need to make friends with OOP, because without OOP you will not be able to compete in the future.

William Roeder
28234
William Roeder  
R4tna C #: Really?

Yes, really. The class as only one remembered time.

BeeXXI Corporation
10814
R4tna C #:


Every time I click a new timeframe it shows new bar detected:


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);
R4tna C
380
R4tna C  
Nikolai Semko #:

The code that I have presented is no more complicated than yours, but more versatile, as it can be used in multi-symbol strategies. Your function cannot be used for different Symbols. Moreover, in the variant presented by me, the performance is higher, since there is no timeframe search.

If you love programming and want to further develop in this direction, but at the same time you are not friends with OOP, then you urgently need to make friends with OOP, because without OOP you will not be able to compete in the future.

My code was a quick example - I was thinking of how one could do this with a simple function and the least amount of code, but that does not mean I am not friends with OOP or that it cannot be expanded to handle multi symbol strategies.

If that is your inference because I observed a bug in your implementation, so be it - there are so many other aspects to master beyond OOP to stay competitive, but I guess you know that already... 

BeeXXI Corporation
10814
William Roeder #:

Yes, really. The class as only one remembered time.

?

BeeXXI Corporation
10814
R4tna C #:

My code was a quick example - I was thinking of how one could do this with a simple function and the least amount of code, but that does not mean I am not friends with OOP or that it cannot be expanded to handle multi symbol strategies.

If that is your inference because I observed a bug in your implementation, so be it - there are so many other aspects to master beyond OOP to stay competitive, but I guess you know that already... 

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.