Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 729

 
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);
}
//+------------------------------------------------------------------+
Тут где-то кто-то писал, что в выделенной строке нужно так сделать: if(time>=last_bar) res=0;

Вот не проверял, если честно - всё время не доходит. Проверите, напишите результат пожалуйста.
Я это написал. И это логично, т.к. если время time совпадает c временем открытия текущего бара, то индекс у него тоже 0. Да, чистое решение fxsaber'a будет работать с ошибками.
 
Alexey Kozitsyn:
Не знаю, насколько мое решение "легче", но попробуйте это: https://www.mql5.com/ru/forum/160945#comment_4053382

А что, нет стандартной функции в языке и нужно каждому строить свой велосипед, а после этого мерятся писпроизводительностью?

Вроде как нашёл все, кроме этой, но после просмотра разных решений видно, что лепят "кто на что гаразд" 

 
Vitaly Muzichenko:

А что, нет стандартной функции в языке и нужно каждому строить свой велосипед, а после этого мерятся писпроизводительностью?

Вроде как нашёл все, кроме этой, но после просмотра разных решений видно, что лепят "кто на что гаразд" 

Стандартной нет. Вы предоставили вариант из статьи https://www.mql5.com/ru/articles/81. Там тоже описан "костыль".
Переход с MQL4 на MQL5
Переход с MQL4 на MQL5
  • 2010.05.11
  • Sergey Pavlov
  • www.mql5.com
Данная статья, построенная в форме справочника по функциям MQL4, призвана помочь переходу с MQL4 на MQL5. Для каждой функции языка MQL4 приведено описание и представлен способ ее реализации на MQL5, что позволит вам значительно ускорить перевод своих программ с MQL4 на MQL5. Для удобства функции разбиты на группы, как в документации по MQL4.
 

Последний вопрос. Сегодня в кодебазе увидел код от "мастера", так вот там используется такое:

   double open_1=iOpen(1);
   double open_2=iOpen(2);
   double high_0=iHigh(0);
   double high_1=iHigh(1);
   double high_2=iHigh(2);
   double high_3=iHigh(3);
   double low_0=iLow(0);
   double low_1=iLow(1);
   double low_2=iLow(2);
   double low_3=iLow(3);
   double close_1=iClose(1);
   double close_2=iClose(2);


 Буквально вчера писал аналогичное, но написал так:

ArraySetAsSeries(Tick,true);
if(CopyRates(dSymbol,0,1,3,Tick)<0) return;
  open1 = Tick[0].open;  open2 = Tick[1].open;  open3 = Tick[2].open;
  high1 = Tick[0].high;  high2 = Tick[1].high;  high3 = Tick[2].high;
  low1  = Tick[0].low;   low2  = Tick[1].low;   low3  = Tick[2].low;
  close1= Tick[0].close; close2= Tick[1].close; close3= Tick[2].close;


После увиденного сегодня, как-то начал сомневаться в правильности своего решения.

Вопрос: Какой вариант лучше, а то Я только учусь? 

 
Vitaly Muzichenko:

Последний вопрос. Сегодня в кодебазе увидел код от "мастера", так вот там используется такое:

   double open_1=iOpen(1);
   double open_2=iOpen(2);
   double high_0=iHigh(0);
   double high_1=iHigh(1);
   double high_2=iHigh(2);
   double high_3=iHigh(3);
   double low_0=iLow(0);
   double low_1=iLow(1);
   double low_2=iLow(2);
   double low_3=iLow(3);
   double close_1=iClose(1);
   double close_2=iClose(2);


 Буквально вчера писал аналогичное, но написал так:

ArraySetAsSeries(Tick,true);
if(CopyRates(dSymbol,0,1,3,Tick)<0) return;
  open1 = Tick[0].open;  open2 = Tick[1].open;  open3 = Tick[2].open;
  high1 = Tick[0].high;  high2 = Tick[1].high;  high3 = Tick[2].high;
  low1  = Tick[0].low;   low2  = Tick[1].low;   low3  = Tick[2].low;
  close1= Tick[0].close; close2= Tick[1].close; close3= Tick[2].close;


После увиденного сегодня, как-то начал сомневаться в правильности своего решения.

Вопрос: Какой вариант лучше, а то Я только учусь? 

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

Хотя и никто не помешает преобразовать код получения за раз одного значения:

//+------------------------------------------------------------------+
//| Get Close for specified bar index                                |
//+------------------------------------------------------------------+
double iClose(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Close[1];
   double close=0;
   int copied=CopyClose(symbol,timeframe,index,1,Close);
   if(copied>0) close=Close[0];
   return(close);
  }

в код получения сразу нескольких значений. Мне просто лень :) 

 
Vladimir Karputov:

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

Хотя и никто не помешает преобразовать код получения за раз одного значения:

//+------------------------------------------------------------------+
//| Get Close for specified bar index                                |
//+------------------------------------------------------------------+
double iClose(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  }

в код получения сразу нескольких значений. Мне просто лень :) 

Спасибо за ответ!

То есть, лучше применять решение, которое  выложил Я? Там достаточно одной проверки, не будет ошибок?

 
Vitaly Muzichenko:

Спасибо за ответ!

То есть, лучше применять решение, которое  выложил Я? Там достаточно одной проверки, не будет ошибок?

Для CopyRates нужно как минимум две проверки:

  1. проверка на ошибку (if ... <0)
  2. проверка, а точно функция вернула нужное количество (вдруг запросили три, а вернула всего два?)
Также очень желательно: проверить цены на наличие мусора (может быть, что в качестве цены может вернуть не цену, а "0")

 
Vitaly Muzichenko:

Спасибо за ответ!

То есть, лучше применять решение, которое  выложил Я? Там достаточно одной проверки, не будет ошибок?

Ваше решение тоже не оптимально, т.к. Вы инициализируете кучу переменных значениями из уже полученного массива. Вопрос: зачем? Когда можно использовать только массив? Назовите его Bars и будет вам счастье:

ArraySetAsSeries(Bars, true);
if(CopyRates(Symbol(), 0, 1, 3, Bars)<0) return;
double value = Bars[0].open;
...
 
Vasiliy Sokolov:

Ваше решение тоже не оптимально, т.к. Вы инициализируете кучу переменных значениями из уже полученного массива. Вопрос: зачем? Когда можно использовать только массив? Назовите его Bars и будет вам счастье:

ArraySetAsSeries(Bars, true);
if(CopyRates(Symbol(), 0, 1, 3, Bars)<0) return;
double value = Bars[0].open;
...

Обозвал Bars, компилятор обругал на чём свет стоит. Вы проверяли эту конструкцию, или просто предположили что должно работать, или Я делаю что-то не так?

 

 

 
Vitaly Muzichenko:

Обозвал Bars, компилятор обругал на чём свет стоит. Вы проверяли эту конструкцию, или просто предположили что должно работать?

 

 

bars[]
Причина обращения: