Аналог iBarShift - страница 4

 
Nikolai Semko:

На мой взгляд использование функции SeriesInfoInteger  является излишнем, ведь она весьма не бесплатная.

Было:

Стало:

Выигрыш в скорости где-то в полтора раза.

2% выигрыш. Замечание.

будет отрабатываться некорректно при PERIOD_W1 и PERIOD_MN1, т.к. отсчет ведется с 1 января 1970 года, а это не понедельник, а четверг. И в каждом месяце разное количество секунд.

Это нужно добавить в Документацию PeriodSeconds.

 
Aleksey Vyazmikin:

Не проверял - потому что надо знать точно, будет работать код или нет под конкретную ситуацию, а то пенять на другого не корректно, если сам ошибся.

Я говорю о таких вот ситуациях, допустим у нас в сутках 14 часов(или меньше, если не было котировок каждый час), у меня чарт M1 и мне надо узнать сдвиг бара по M15 в прошлом дне. Т.е. будет ли корректно все работать, если в часе получилось 45 минут или в сутках 14 часов или ещё какие выпады временные/свечные?

Я лично считаю, что целесообразно использовать такую функцию:

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);
  }

Но необходимо отметить, что это не полный аналог штатной функции MQL4 iBarShift  как минимум по причине, что в ней нет  параметра Exact  

В остальном она идентична.

Прикладываю простой скрипт на MQL4, который показывает полную идентичность штатной и данной функции.

Если значения от штатной функции iBarShift и моей функции не равны, тогда Print. У меня ничего не напечатало.

//+------------------------------------------------------------------+
//|                                                    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% выигрыш. Замечание.

Что, правда что-ли?

Мне лениво было ставить GetMicrosecondCount(), и я доверился профилированию. 

 
Nikolai Semko:

Что, правда что-ли?

Мне лениво было ставить GetMicrosecondCount(), и я доверился профилированию. 

Профилирование - это о другом. 2% - максимальный выигрышь, который можно получить. 

250 миллионов вызовов в Тестере на моей машине дает экономию в 1 секунду.

Однозначно, Ваш вариант лучший! Но я даже не представляю, зачем в MT5 работать с барами.

 
fxsaber:

 Но я даже не представляю, зачем в MT5 работать с барами.

Я это использую когда управляю мышкой. Например здесь.

 
Nikolai Semko:

Я это использую когда управляю мышкой. Например здесь.

Да, вот этого и не понимаю.

 
fxsaber:

Да, вот этого и не понимаю.

А я не понимаю непонимания ))

Ну вот, например, у меня есть канал, одна из характеристик которого время начала (левая граница). И мне нужно этот канал строить на разных ТФ. Ну какая у меня еще альтернатива, кроме как через время найти в новом ТФ номер бара?

Да и много еще чего.

Например, когда я объединяю всеТФ в один с логарифмической шкалой. Это очень классная тема. Здесь тоже не обойтись без аналога iBarShift

 
Nikolai Semko:

Я лично считаю, что целесообразно использовать такую функцию:

Но необходимо отметить, что это не полный аналог штатной функции MQL4 iBarShift  как минимум по причине, что в ней нет  параметра Exact  

В остальном она идентична.

Прикладываю простой скрипт на MQL4, который показывает полную идентичность штатной и данной функции.

Если значения от штатной функции iBarShift и моей функции не равны, тогда Print. У меня ничего не напечатало.

Нет, не печатало из-за Comment()

Если его убрать, то идет рассогласование на 1, но я не считаю это ошибкой, т.к. по сути определение нового бара происходит в двух алгоритмах со сдвигом на полбара. Мой вариант определения нового бара кажется мне более логичным, чем штатный.

 
Nikolai Semko:

А я не понимаю непонимания ))

Я не понимаю смысл использования баров. CopyRates и т.д.

 

Почему так медленно работает скрипт?

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);
  }
//+------------------------------------------------------------------+