Analogue to iBarShift - page 4

 
Nikolai Semko:

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

Was:

Became:

A speed gain of about 1.5 times.

2% gain. Note.

will not work correctly with PERIOD_W1 and PERIOD_MN1, because it is counted from January 1, 1970, and it is Thursday, not Monday. And each month has a different number of seconds.

This needs to be added to the PeriodSeconds documentation.

 
Aleksey Vyazmikin:

I haven't checked it - because I need to know for sure if the code will work or not for a specific situation, because it's not correct to blame someone else if you have made a mistake yourself.

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?

I personally think it is appropriate to use such a feature:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }

But it should be noted that it's not a full analogue of MQL4iBarShift function at least due to the fact that it doesn't haveExact parameter

Otherwise it is identical.

I am pasting a simple MQL4 script that shows the full identity of the standard function with this one.

If values from the standardiBarShift function and my function are not equal, then Print. It didn't print anything for me.

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime t=TimeCurrent()+1000;
   const ENUM_TIMEFRAMES tf[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
   while(!IsStopped())
     {
      for(int i=0; i<9;i++)
        {
         int i1=iBarShift(NULL,tf[i],t);
         int i2=iBarShift2(NULL,tf[i],t);
         if(i1!=i2) Print(EnumToString(tf[i]),"   ",TimeToString(t),"   ",i1,"   ",i2);
        }
      t-=10;
      Comment(TimeToString(t));
     }

  }
//+------------------------------------------------------------------+
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
 
fxsaber:

2% win rate. Note.

What, really?

I was too lazy to put GetMicrosecondCount(), so I trusted profiling.

 
Nikolai Semko:

Really?

I was too lazy to set GetMicrosecondCount(), so I trusted profiling.

Profiling is about something else. 2% is the maximum gain you can get.

250 million calls in the Tester on my machine gives a saving of 1 second.

Definitely your option is the best! But I can't even imagine why in MT5 you need to work with bars.

 
fxsaber:

But I have no idea why in MT5 I need to work with bars.

I use it when I control the mouse. For example here.

 
Nikolai Semko:

I use this when controlling the mouse. Here, for example.

Yeah, that's what I don't understand.

 
fxsaber:

Yes, that's what I don't understand.

And I don't understand the misunderstanding ))

For example, I have a channel, one of the characteristics of which is the start time (left edge). And I need to build this channel on different TFs. Well, what other alternative do I have but to find the bar number in a new TF?

I have a lot of other things.

For example, when I combine all TFs into one with a logarithmic scale. This is a very cool topic. Can't do without the iBarShift analogue here either

 
Nikolai Semko:

I personally think it is reasonable to use such a function:

But it should be noted that it's not a full analogue of the standard MQL4iBarShift function, at least because it doesn't have theExact parameter

Otherwise it is identical.

I am pasting a simple MQL4 script that shows the full identity of the standard function with this one.

If values from the standardiBarShift function and my function are not equal, then Print. I have not printed anything.

No, it didn't because of Comment().

If you remove it, there is a mismatch by 1, but I don't think it's a mistake, because in fact the new bar is defined in two algorithms with a shift by half a bar. My version of new bar detection seems more logical to me than the standard one.

 
Nikolai Semko:

And I don't understand the misunderstanding ))

I don't understand the point of using bars. CopyRates etc.

 

Why is the script so slow?

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:20:49.300 Scripts script BS (Si Splice,H4) loaded successfully

2018.03.30 09:21:20.209 Scripts script BS (Si Splice,H4) removed

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs

input ENUM_TIMEFRAMES TF=PERIOD_D1;
input int Bar=3;
input int calcN=1;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("1 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("1 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }



   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift2(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("2 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("2 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }
   return;

  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+  
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+   
int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
   if(index < 0) return(-1);
   datetime Arr[];
   if(CopyTime(symbol,tf,index,1,Arr)>0)
      return(Arr[0]);
   else return(-1);
  }
//+------------------------------------------------------------------+