Questions from Beginners MQL5 MT5 MetaTrader 5 - page 729

 
Artyom Trishkin:
Somehow (solution from @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);
}
//+------------------------------------------------------------------+
Someone wrote somewhere that in selected line you should do this: if (time>=last_bar) res=0;

I haven't checked it, to be honest - I don't get it all the time. Check it and write the result, please.
I wrote it. And it's logical, because if time coincides with opening time of the current bar, its index will also be 0. Yes, pure fxsaber solution will work with errors.
 
Alexey Kozitsyn:
I don't know if my solution is "easier", but try this one: https://www.mql5.com/ru/forum/160945#comment_4053382

Is there no standard function in the language and everyone has to build their own bike and then measure their performance?

It seems that I found all except this one, but after looking at different solutions, it is obvious that they are "who can do what".

 
Vitaly Muzichenko:

Is there no standard function in the language and everyone has to build their own bicycle and then measure their performance?

I seem to have found all but this one, but after looking at the different solutions, it looks like they're all "who can do what".

There is no standard one. You provided a variant from the article https://www.mql5.com/ru/articles/81. The "crutch" is also described there.
Переход с MQL4 на MQL5
Переход с MQL4 на MQL5
  • 2010.05.11
  • Sergey Pavlov
  • www.mql5.com
Данная статья, построенная в форме справочника по функциям MQL4, призвана помочь переходу с MQL4 на MQL5. Для каждой функции языка MQL4 приведено описание и представлен способ ее реализации на MQL5, что позволит вам значительно ускорить перевод своих программ с MQL4 на MQL5. Для удобства функции разбиты на группы, как в документации по MQL4.
 

One last question. Today in the codebase I saw a code from a "master", so it uses this:

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


Just yesterday I wrote a similar one, but I wrote it this way:

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;


After what I've seen today, I somehow began to doubt the correctness of my decision.

Question: Which option is better, because I'm just learning?

 
Vitaly Muzichenko:

One last question. Today in the codebase I saw a code from a "master", so it uses this:

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


Just yesterday I wrote a similar thing, but I wrote it this way:

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;


After what I saw today, I somehow began to doubt the correctness of my decision.

Question: Which variant is better, because I'm just learning?

In this case your implementation should work faster - as there are fewer calls to copy - you copy three values at once instead of one.

Although no one is stopping you from converting code to get one value at a time:

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

into code for getting multiple values at once. I'm just lazy :)

 
Vladimir Karputov:

In this case your implementation should work faster - as there are fewer copy calls - you copy three values at once instead of one at a time.

Although no one is stopping you from converting the code to get one value at a time:

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

into code for getting multiple values at once. I'm just lazy :)

Thanks for the reply!

So, it's better to apply solution, which I posted? There is enough one check, there will be no errors?

 
Vitaly Muzichenko:

Thanks for the reply!

So, is it better to apply the solution I posted? One check is enough there, there will be no errors?

CopyRates needs at least two checks:

  1. error check (if ... <0)
  2. check if the function returned the right amount (what if you asked for three, and returned only two?)
Also very desirable: check prices for rubbish (it's possible that it may return "0" instead of price)

 
Vitaly Muzichenko:

Thanks for the reply!

So, is it better to apply the solution I posted? One check is enough there, there will be no errors?

Your solution is not optimal either, because you initialize a bunch of variables with values from the array you've already got. The question is: why? When only an array may be used? Name it Bars and you'll be happy:

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

Your solution is not optimal either, because you initialise a bunch of variables with values from an already derived array. The question is: why? When only an array may be used? Just call it Bars and you'll be happy:

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

You call itBars and the compiler gives you a slap on the wrist. Have you checked this construct or just assumed that it should work, or am I doing something wrong?

 
Vitaly Muzichenko:

Called itBars, the compiler is scolded as hell. Have you tested this design, or just assumed it should work?

bars[]
Reason: