Analogue to iBarShift - page 3

 
Vasiliy Pushkaryov:

Here's the script.

It just hangs. Forcibly removing it from the chart gets the result.

So I tried it, that's why I recommended it to you. But since you used it and it suits you, I won't change my mind.

I'm sorry, Vassili. I misunderstood you. Just read your post quickly as I was driving. I thought it was about the last parameter, where I have32000000000, it turns out you meant the t parameter. Yes, indeed - it is the only case where the result is different from the original MQL4 iBarShift(). However it is very strange to try to use this function to get the number of bars ( or bar index) from the current time point, i.e.TimeCurrent(), when it is clear that the bar is zero. In general, it is strange that the functionBars() atTimeCurrent() produces 0, and not 1. Formally it is a bug of developers, although it depends. But something cannot hang because of using the standard Bars() function, especially since the script checkedPrint(), i.e. everything is OK.
Understand, Vasily, I don't want to belittle other implementations of iBarShift analog, I just personally use exactly this construction(Bars(NULL,0,t,32000000000)-1;), because it's the fastest. And this construction is used not as a substitute for iBarShift, but simply as a function of finding an index of a bar at a specified time, and I don't understand what you mean by universality. And I don't think it's reasonable to use all of the above functions because of the higher time cost. (Remember the Dosya powder commercials). The thing is, using this function very often happens in large cycles, which significantly increases program runtime, and I'm terribly greedy for runtime. I've done experiments in calculating the runtime of various functions (and not only me, see previous post) and this option is definitely the fastest. Even this variant, which is positioned as the fastest, is the same, but the(Bars(NULL,0,t,32000000000)-1;) construct is even simpler. Of course, it's up to everyone what to use.

In any case, thank you for your substantive remark.

 
Nikolai Semko:

But it is very strange to try to use this function to receive the number of bars (or the index of a bar) from the current moment, i.e.TimeCurrent(), when it is already clear that the bar is zero. It is strange that theBars() function gives 0 instead of 1 atTimeCurrent().

TimeCurrent() was just a special case I had at hand.

I now read this note to the Bars() function more carefully:

"When requesting the number of bars in a given date range , only those bars whose opening time falls within that range are taken into account. For example, if the current day of the week is Saturday, when requesting the number of weekly bars with start_time=lastTuesday and stop_time=lastFriday, the function returns 0 because the opening time of the weekly timeframe always falls on Sunday and no weekly bar falls into the specified range".

Since TimeCurrent() is almost all time later than the opening time of the current bar, so the Bars() function returns 0. So, if we pass the time corresponding to 02:05 on the hourly timeframe as the start_time parameter, and we want the bar that started at 2 o'clock to be validated, then we must get the bar open time (02:00:00) through CopyTime() . Otherwise, function Bars() will ignore this bar.

I.e., if the time is 3:30, I understand that in the hourly TF, the time 2:05 refers to the bar with index 1. None of the functions on the 2nd page will return this index. With this correction Renat Akhtyamov's function returned what I expected.

int iBarShift2(string symbol, ENUM_TIMEFRAMES timeframe, datetime time)
{
  datetime tm0[1], tm1[1];      
  CopyTime(symbol, timeframe, 0, 1, tm0);             // время открытия 0-го бара
  CopyTime(symbol, timeframe, time, 1, tm1);          // время открытия бара, в который попадает указанный time

  return Bars(symbol, timeframe, tm0[0], tm1[0])-1;
}

I'm attaching a script, with 4 options for index lookup functions, which I used as a test.

Files:
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

TheTimeCurrent() is just a special case encountered.

I now read this note to the Bars() function more carefully:

"When requesting the number of bars in a given date range , only those bars whose opening time falls within that range are taken into account. For example, if the current day of the week is Saturday, when requesting the number of weekly bars with start_time=lastTuesday and stop_time=lastFriday, the function returns 0 because the opening time of the weekly timeframe always falls on Sunday and no weekly bar falls into the specified range".

Since TimeCurrent() is almost all time later than the opening time of the current bar, so the Bars() function returns 0. So, if we pass the time corresponding to 02:05 on the hourly timeframe as the start_time parameter and want the bar that started at 2 o'clock to be validated, then we must obtain the bar opening time (02:00:00) through CopyTime() . Otherwise, function Bars() will ignore this bar.

I.e., if the time is now 3:30, I understand that in hourly timeframe, 2:05 refers to the bar with index 1. This index will not be returned by any function of the 2nd page. With this correction Renat Akhtyamov's function returned what I expected.

I'm attaching a script, with 4 options for index lookup functions, which I used as a test.

Of course I need to pass the bar time. I forgot to specify.
 
I don't understand why this function does not yet exist in SB
 
transcendreamer:
I don't understand why this function is still not available in the SB

Tried all variants, the most correct is from Alain Verleyen.
(tested on a complex indicator with a lot of objects)
 
Taras Slobodyanik:

Tried all variants, the most correct is from Alain Verleyen.
(tested on complex indicator with lots of objects)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • votes: 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

In my opinion, the use of theSeriesInfoInteger function is redundant, because it is not free.

Was:

int iBarShift3( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, const bool Exact = false )
{
  static int Res = -1;
  static string LastSymb = NULL;
  static ENUM_TIMEFRAMES LastTimeFrame = 0;
  static datetime LastTime = 0;
  static bool LastExact = false;

  time -= time % ::PeriodSeconds(TimeFrame);

  if ((time != LastTime) || (Symb != LastSymb) || (TimeFrame != LastTimeFrame) || (Exact != LastExact))
  {
    datetime LastBar;

     if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
     {
        if (time > LastBar)
          Res = 0;
        else
        {
          const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);

          if (Shift > 0)
            Res = Shift - 1;
        }
      }

    LastTime = time;
    LastSymb = Symb;
    LastTimeFrame = TimeFrame;
    LastExact = Exact;
  }

  return(Res);
}

Became:

int iBarShift3(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,const bool Exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static bool LastExact=false;
   static int PerSec=::PeriodSeconds(LastTimeFrame);
   
   if (LastTimeFrame!=TimeFrame) PerSec=::PeriodSeconds(TimeFrame);
   time-=time%PerSec;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame) || (Exact!=LastExact))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
      LastExact=Exact;
     }

   return(Res);
  }

The speed gain is about one and a half times.

And it seems to be the fastest option. True, last parameterExact is fake, and it can be removed. But in my opinion it is not necessary. Personally I've never encountered tasks where we neededExact= true.

But if somebody needs it, he can't do without CopyTime and it's better to use@Alain Verleyen' svariant.

SZY: I've bypassed superfluous calls to functionPeriodSeconds, if TF has not changed since the last call. The gain is weak, though - a few percent, but still.

And one more remark: Construction

time-=time%PerSec;
will not work correctly with PERIOD_W1 and PERIOD_MN1 because it starts on 1 January 1970, which is not a Monday, but a Thursday. And each month has a different number of seconds.
 
Nikolai Semko:

In my opinion, the use of theSeriesInfoInteger function is redundant, because it is not free.

Was:

Became:

The speed gain is about one and a half times.

And it seems to be the fastest option. True, the lastExact parameter is fake. But if you ask me, you don't need it.

Or am I wrong?

SZY: I have also bypassed superfluous calls toPeriodSeconds function, if TF has not changed since the last call. The gain is really slight - a few percent, but still.

I don't understand how clever this code is, that's why I want to ask you a question. Will the code work if the chart is not full day?

 
Aleksey Vyazmikin:

How abstruse the code is, it's not clear to me, so I'll ask. Will the code work if the chart is not full day?

I don't understand the essence of the question. Put it in a different way.

The chart is always not a full day, except for the first second of the day.

What timeframe are we talking about? A day?

And what prevents you from checking?

The code is not mine, I just simplified it and made it faster.

In my previous message I made an addition aboutPERIOD_W1 and PERIOD_MN1.

All the algorithms before, including @Alain Verleyen's, have abnormal situations.

You can create a full analogue of iBarShift MQL4, but the code will be quite cumbersome, and I don't see any sense in it.

 
Nikolai Semko:

I don't understand the point of the question. Put it in a different way.

The chart is always not a full day, except for the first second of the day.

What TF are we talking about? A day?

And what prevents you from checking?

The code is not mine, I just simplified it and made it faster.

In my previous message I made an addition aboutPERIOD_W1 and PERIOD_MN1.

All the algorithms before, including @Alain Verleyen's, have abnormal situations.

You can create a full analogue of iBarShift MQL4, but the code will be very cumbersome, and I don't see the point in that.

I haven't tested it because one has to know for sure if the code will work for a certain situation, otherwise it's not correct to blame someone else if he/she made a mistake.

I'm talking about situations like this: suppose we have 14 hours in a day (or less, if there were no quotes every hour), I have an M1 chart and I need to know the shift of a bar on M15 for the previous day. I.e. will everything work correctly if I get 45 minutes in an hour or 14 hours in a day, or any other time/switching drops?