И всё-таки есть ли полный аналог функции iBarShift для MT5 или как его заменить?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Sergey Efimenko
42423
Sergey Efimenko  

Поиск по статьям и форуму дал несколько вариантов, но все они имеют одну проблему. После нажатия на кнопку "обновить" контекстного меню графика, все значения смещаются вперёд. На скринах пример.

  после обновить -> 

Andrey F. Zelinsky
35833
Andrey F. Zelinsky  

Буквально с первых дней развития MT5 была написана весьма полезная статья: https://www.mql5.com/ru/articles/81 -- в ней показаны аналоги всех функций MQL4 и как их в MQL5 корректно заменить

Переход с MQL4 на MQL5
Переход с MQL4 на MQL5
  • 2010.05.11
  • Sergey Pavlov
  • www.mql5.com
Данная статья, построенная в форме справочника по функциям MQL4, призвана помочь переходу с MQL4 на MQL5. Для каждой функции языка MQL4 приведено описание и представлен способ ее реализации на MQL5, что позволит вам значительно ускорить перевод своих программ с MQL4 на MQL5. Для удобства функции разбиты на группы, как в документации по MQL4.
Sergey Efimenko
42423
Sergey Efimenko  
Andrey F. Zelinsky:

Буквально с первых дней развития MT5 была написана весьма полезная статья: https://www.mql5.com/ru/articles/81 -- в ней показаны аналоги всех функций MQL4 и как их в MQL5 корректно заменить

Я в курсе об этой статье, но как уже писал выше, всё что тут (на сайте) можно явно найти не работает в описанной ситуации.

Собственно вот код используемого аналога, результаты ошибок заменил на 0 вместо -1, мне так нужно:

int iBarShift(datetime time,bool exact=false) { datetime LastBar;
   if(!SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE,LastBar)) { datetime opentimelastbar[1]; if(CopyTime(_Symbol,_Period,0,1,opentimelastbar)==1) LastBar=opentimelastbar[0]; else return(0); }
   if(time>LastBar) return(0);
   int shift=Bars(_Symbol,_Period,time,LastBar); datetime checkcandle[1];
   if(CopyTime(_Symbol,_Period,time,1,checkcandle)==1) {
      if(checkcandle[0]==time) return(shift-1); else if(exact && time>checkcandle[0]+PeriodSeconds(_Period)) return(0); else return(shift);}
return(0); }
Ihor Herasko
21045
Ihor Herasko  

Как-то fxsaber показал замечательное решение, которое уже встроено в МТ5. Это использование перегрузки функции Bars(). Чтобы найти индекс бара по времени, достаточно знать время открытия бара с индексом 1:

datetime timeOfFirstBar = ....; // Получить через CopyTime или другими способами
datetime knownTime = ...; // Известное время, для которого требуется найти индекс бара
int barIndex = Bars(Symbol(), Period(), knownTime, timeOfFirstBar);

Единственное, что требуется учесть, так это тот факт, что knownTime должно попадать четко на время открытия бара (или быть чуть "правее" него). Иначе результат будет на 1 меньше.
 

Sergey Efimenko
42423
Sergey Efimenko  
Ihor Herasko:

Как-то fxsaber показал замечательное решение, которое уже встроено в МТ5. Это использование перегрузки функции Bars(). Чтобы найти индекс бара по времени, достаточно знать время открытия бара с индексом 1:

datetime timeOfFirstBar = ....; // Получить через CopyTime или другими способами
datetime knownTime = ...; // Известное время, для которого требуется найти индекс бара
int barIndex = Bars(Symbol(), Period(), knownTime, timeOfFirstBar);

Единственное, что требуется учесть, так это тот факт, что knownTime должно попадать четко на время открытия бара (или быть чуть "правее" него). Иначе результат будет на 1 меньше.
 

Спасибо, этот вариант я видел среди форумных тем, как раз пробую...
Ihor Herasko
21045
Ihor Herasko  
Ihor Herasko:

Как-то fxsaber показал замечательное решение, которое уже встроено в МТ5. Это использование перегрузки функции Bars(). Чтобы найти индекс бара по времени, достаточно знать время открытия бара с индексом 1:

datetime timeOfFirstBar = ....; // Получить через CopyTime или другими способами
datetime knownTime = ...; // Известное время, для которого требуется найти индекс бара
int barIndex = Bars(Symbol(), Period(), knownTime, timeOfFirstBar);

Единственное, что требуется учесть, так это тот факт, что knownTime должно попадать четко на время открытия бара (или быть чуть "правее" него). Иначе результат будет на 1 меньше.
 

Прошу прощения. Имел в виду чуть "левее" по графику.
Alexey Viktorov
25686
Alexey Viktorov  

Можно пример из документации подправить под свои нужды.


#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot Numeration
#property indicator_label1  "Numeration"
#property indicator_type1   DRAW_LINE
#property indicator_color1  CLR_NONE
//--- indicator buffers
double         NumerationBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,NumerationBuffer,INDICATOR_DATA);
//--- установим индексацию для буфера как в таймсерии
   ArraySetAsSeries(NumerationBuffer,true);
//--- установим точность отборажения в DataWindow
   IndicatorSetInteger(INDICATOR_DIGITS,0);
//--- как будет выглядеть в DataWindow имя индикаторного массива
   PlotIndexSetString(0,PLOT_LABEL,"Bar #");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---  будем хранить время открытия текущего нулевого бара
   static datetime currentBarTimeOpen=0;
//--- перевернем доступ к массиву time[] - сделаем как в таймсерии
   ArraySetAsSeries(time,true);
//--- если время нулевого бара отличается от того, что мы храним
   if(currentBarTimeOpen!=time[0])
     {
     //--- пронумеруем все бары от текущего момента вглубь графика
      for(int i=rates_total-1;i>=0;i--) NumerationBuffer[i]=i;
      currentBarTimeOpen=time[0];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
Документация по MQL5: Операции с массивами / ArraySetAsSeries
Документация по MQL5: Операции с массивами / ArraySetAsSeries
  • www.mql5.com
Операции с массивами / ArraySetAsSeries - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
Artyom Trishkin
Модератор
52250
Artyom Trishkin  

Вот же. От fxsaber:

//+------------------------------------------------------------------+
int GetBarShift(const string symbol_name, const ENUM_TIMEFRAMES timeframe, const datetime time) {
   int res=-1;
   datetime last_bar;
   if(SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE,last_bar)) {
      if(time>last_bar) res=0;
      else {
         const int shift=Bars(symbol_name,timeframe,time,last_bar);
         if(shift>0) res=shift-1;
         }
      }
   return(res);
}
//+------------------------------------------------------------------+
Sergey Efimenko
42423
Sergey Efimenko  
Artyom Trishkin:

Вот же. От fxsaber:

//+------------------------------------------------------------------+
int GetBarShift(const string symbol_name, const ENUM_TIMEFRAMES timeframe, const datetime time) {
   int res=-1;
   datetime last_bar;
   if(SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE,last_bar)) {
      if(time>last_bar) res=0;
      else {
         const int shift=Bars(symbol_name,timeframe,time,last_bar);
         if(shift>0) res=shift-1;
         }
      }
   return(res);
}
//+------------------------------------------------------------------+
У вас нет параметра exact, кроме того данная конструкция напоминает приведённый мною выше кусок текущего кода, который не работает в описанной ситуации.
Sergey Efimenko
42423
Sergey Efimenko  
Alexey Viktorov:

Можно пример из документации подправить под свои нужды.


#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot Numeration
#property indicator_label1  "Numeration"
#property indicator_type1   DRAW_LINE
#property indicator_color1  CLR_NONE
//--- indicator buffers
double         NumerationBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,NumerationBuffer,INDICATOR_DATA);
//--- установим индексацию для буфера как в таймсерии
   ArraySetAsSeries(NumerationBuffer,true);
//--- установим точность отборажения в DataWindow
   IndicatorSetInteger(INDICATOR_DIGITS,0);
//--- как будет выглядеть в DataWindow имя индикаторного массива
   PlotIndexSetString(0,PLOT_LABEL,"Bar #");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---  будем хранить время открытия текущего нулевого бара
   static datetime currentBarTimeOpen=0;
//--- перевернем доступ к массиву time[] - сделаем как в таймсерии
   ArraySetAsSeries(time,true);
//--- если время нулевого бара отличается от того, что мы храним
   if(currentBarTimeOpen!=time[0])
     {
     //--- пронумеруем все бары от текущего момента вглубь графика
      for(int i=rates_total-1;i>=0;i--) NumerationBuffer[i]=i;
      currentBarTimeOpen=time[0];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

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

Alexey Viktorov
25686
Alexey Viktorov  
Sergey Efimenko:

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

А просто не надо не трезвым подходить к компу. Тогда и советов таких будет меньше.

Или чтобы понять нужно тоже нетрезвым читать:))))))))

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий