Analogue to iBarShift - page 14

 
fxsaber:

Then I don't understand why Bars thinks that 18:00:01 belongs to M1-bar 18:01 and not 18:00.

And the logic here is the same as the fact that my daughter is now on her second birthday, even though she only turned one a week ago. Or today is 09.04.2018, although 01 Jan 00 was 2017 years, 3 months and 8 days ago .

By the way, TimeCurrent needs to be replaced with SYMBOL_TIME.

Thanks! I really didn't know about such an identifier.

 

By the way, when I tested the correctness of the iBars algorithm by comparing it to the Bars reference in MQL4, trying different variants at random, I found a bug in Bars:

Print(Bars(_Symbol,PERIOD_MN1,D'2005.08.31 00:00:00',D'2005.08.31 23:00:00')); // 1  должен быть 0, т.к. временной диапазон находиться внутри одного бара.
Print(Bars(_Symbol,PERIOD_MN1,D'2006.08.31 00:00:00',D'2006.08.31 23:00:00')); // 0

There is no such a bug in MQL5.

Of course it is not significant, since it only appears in TF = MN1, at dates 30 and 31, stop_time = 23 and only before 2005 :)))

Here is the script for MQL4 that catches it, and iBars turned out to be more reference than native Bars.

Files:
TestiBars.mq4  10 kb
 
fxsaber:


By the way, TimeCurrent should be replaced by SYMBOL_TIME.

No, you don't.
It won't add correctness, because TimeCurrent() is universal for all symbols, because it returns the last arrival time of the quote for all symbols, not the current one.

At the same time, SymbolInfoInteger(symbol_name,SYMBOL_TIME) is very slow compared to TimeCurrent(), and this time is needed at each call of iBars

 

For those who are interested.

Edited version of iBars (similar to built-in Bars, only without glitches and faster).

Fixed some bugs.

If you have noticed that your MQL5 code hangs for 10-20 seconds all of a sudden and has the Bars function, which can return 0, then I strongly recommend replacing it with this version.
It will work faster and without hangs.

int iBars(string symbol_name,ENUM_TIMEFRAMES  timeframe,datetime start_time,datetime stop_time)
  {
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static datetime LastTime0=0;
   static int PerSec=0;
   static int PreBars=0;
   static datetime LastBAR=0;
   static datetime LastTimeCur=0;
   datetime TimeCur;
   if(stop_time<start_time) {TimeCur=stop_time; stop_time=start_time; start_time=TimeCur; }
   TimeCur=TimeCurrent();
   if(LastTimeFrame!=timeframe) if(timeframe==PERIOD_MN1) PerSec=2419200; else PerSec=::PeriodSeconds(timeframe);
   if(timeframe<PERIOD_W1) TimeCur-=TimeCur%PerSec;
   if(start_time>TimeCur) {LastSymb=NULL; return(0);}
   if(LastTimeFrame!=timeframe || LastSymb!=symbol_name || ((TimeCur-LastBAR)>0 && TimeCur!=LastTimeCur))
      LastBAR=(datetime)SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE);

   LastTimeCur=TimeCur;
   if(PerSec==0) return(0);
   if(start_time>LastBAR)
     {LastTimeFrame=timeframe; LastSymb=symbol_name; return(0);}

   datetime tS,tF=0;
   bool check=true;
   if(timeframe<PERIOD_W1) tS=start_time-(start_time-1)%PerSec-1;
   else if(timeframe==PERIOD_W1) tS=start_time-(start_time-259201)%PerSec-1;
   else
     {
      PerSec=2678400;
      MqlDateTime dt;
      TimeToStruct(start_time-1,dt);
      tS=dt.year*12+dt.mon;
     }
   if(stop_time<=LastBAR)
     {
      if(timeframe<PERIOD_W1) tF=stop_time-(stop_time)%PerSec;
      else if(timeframe==PERIOD_W1) tF=stop_time-(stop_time-259200)%PerSec;
      else
        {
         MqlDateTime dt0;
         TimeToStruct(stop_time,dt0);
         tF=dt0.year*12+dt0.mon;
        }
      if(tS==tF) {PreBars=0; check=false;}
     }
   if((LastTimeFrame!=timeframe || LastSymb!=symbol_name || tS!=LastTime || tF!=LastTime0) && check)
      PreBars=Bars(symbol_name,timeframe,start_time,stop_time);
   LastTime=tS; LastTime0=(datetime)tF;
   LastTimeFrame=timeframe;
   LastSymb=symbol_name;
   return(PreBars);
  }
 
Nikolai Semko:

Edited version of iBars(similar to the built-in Bars, only without glitches and faster).

Fixed some bugs.

Built-in Bars() is overloaded:

1. int Bars(const string symbol_name,ENUM_TIMEFRAMES timeframe)
2. int Bars(const string symbol_name,ENUM_TIMEFRAMES timeframe,datetime start_time,datetime stop_time)

You only have one call form.

 
Artyom Trishkin:

The built-in Bars() is overloaded:

You only have one form to call.

if you need a short form, it's fine to use the built-in one. There are hardly any glitches there.

 
Nikolai Semko:

No, it is not necessary.
It will not add correctness, because TimeCurrent() is universal for all symbols, because it returns the last arrival time of quotation for all symbols, not the current one.

SymbolInfoInteger(symbol_name,SYMBOL_TIME) is very slow compared to TimeCurrent(), and this time is needed every time iBars is called

Cotypes can go for all characters except the one of interest.

Ok, looked at the new source. Saw that edits, that were discussed, have not been made. I'm out.

 
Why don't the developers do it themselves?
 
It would be much more convenient for users to call one function and get a synchronised (time-aligned) array of rows across several instruments
 
By the way, about the Bars() function. This may be the cause of the clincher.
Reason: