Questions from Beginners MQL5 MT5 MetaTrader 5 - page 602

 
Karputov Vladimir:
In an indicator or in an EA/script?
In an indicator.
 

Yuri Evseenkov:

fromme2you:

Another question: how to stress the developer of MT4 and MQL code execution environment, so that he(they) put mind and hand in developing a language to handle exceptions, such as in my example or similar in meaning?


Contact servesdesk, create a thread/survey on the forum.

It wasn't so long ago that MT4 was buried. They do not have a clear view on the market, they have a clear view on the regulation of the market.

See Renat's post today:

Renat Fatkhullin:

...

MT4 development is stopped and there will be only fixes and cosmetics.

 
Alex:

Hello. Can you please advise how to solve this issue. I need to find the open prices of bars at a certain time, for example at 01:00, by analyzing for example the last 50 bars. I'm not sure how to go about this task in mql5.


Whether by calculating the current date + adding the required time to it and then adding twenty-four hours, this method worked on mql4.

As far as I understood mql5 has special structures with time output, but for some reason I can't use them.

Thanks in advance for the answer.

I would be very grateful if somebody could throw me a bit of code to understand the thinking process.
Alex:
In the indicator.

Here, for better understanding, I advise to first look at the numbering of bars. First we need to understand exactly how the rightmost bar in the MQL5 indicator is numbered.

To do this, put the following comment in the indicator in OnCalculate:

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property  indicator_type1   DRAW_LINE
#property  indicator_color1  Blue
//--- indicator buffers
double Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
//---
   ArrayInitialize(Buffer,1);
//---
   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[])
  {
//---
   Comment("rates_total=",IntegerToString(rates_total),
           ", time[rates_total-1]=",TimeToString(time[rates_total-1],TIME_DATE|TIME_MINUTES|TIME_SECONDS));

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

This code will produce this result:

Numbering in MQL5 indicator arrays, by default

That is, by default the rightmost bar in MQL5 indicator arrays has an index equal to "rates_total-1".

Returning to your question - you need to take the last 50 bars and pass through them. And analyze the open time of the bar (the time[] array), if the bar time is equal to the specified one, remember the index of the bar. Then obtain the open price from the open[] array using this index.

It looks similar to this:

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots   0
//--- input parameters
input datetime time_open=D'01:00';     // время искомого бара
//--- parameters
int open_hour;                         // время искомого бара (часы)
int open_min;                          // время искомого бара (минуты)
bool first_start=false;                // false - значит бары ещё не искались
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MqlDateTime str1;
   TimeToStruct(time_open,str1);
   open_hour=str1.hour;
   open_min=str1.min;
//---
   first_start=false;
//---
   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[])
  {
//---
//Comment("rates_total=",IntegerToString(rates_total),
//        ", time[rates_total-1]=",TimeToString(time[rates_total-1],TIME_DATE|TIME_MINUTES|TIME_SECONDS));
   if(!first_start)
     {
      int index=-1;
      for(int i=rates_total-1;i>rates_total-1-50;i--)
        {
         MqlDateTime str2;
         TimeToStruct(time[i],str2);
         if(str2.hour==open_hour && str2.min==open_min)
           {
            index=i;
            first_start=true;
            Print("Бар ",IntegerToString(i)," имеет время открытия ",TimeToString(time[i],TIME_DATE|TIME_MINUTES|TIME_SECONDS),
                  " и цену открытия ",DoubleToString(open[i],Digits()));
           }
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Karputov Vladimir:

Here, in order for you to better understand later, I advise you to start by looking at the numbering of bars. That is, you should first understand exactly how the rightmost bar in MQL5 indicator is numbered.

To do this, put the following comment in the indicator in OnCalculate:

This code will produce this result:


That is, by default the rightmost bar in MQL5 indicator arrays has an index equal to "rates_total-1".

Returning to your question - you need to take the last 50 bars and pass through them. And analyze the open time of the bar (the time[] array), if the bar time is equal to the specified one, remember the index of the bar. Then retrieve the open price from the open[] array.

It looks approximately like this

Karputov Vladimir, thank you very much. I will take care of it. I think mql5 has more flexible access to timeseries, but it's a bit complicated for "newbie" programmers. :))
 
Alex:
Karputov Vladimir, thank you very much. I really appreciate it. I think mql5 has more flexible access to timeseries, but it's a bit complicated for "newbie" programmers. :))
It's a matter of getting used to it. Then you'll understand that everything is structured, easy and correct.
 
Karputov Vladimir:
It's a matter of habit. Then you will find that everything is structured, easy and correct.

Another question. The parameters

const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])


I think they are responsible for the pair the indicator is applied to. So, it's impossible to obtain the same information about another currency pair? In other words, the more universal solution is to create the same arrays of OCHL only through Copy function...?
 
Alex:

Another question. Parameters

I understand that they are responsible for the pair to which the indicator is applied. And to pull out with their help the same information about another currency pair is impossible? So, the more universal solution is to create the same arrays OCHL only through Copy function...?
When accessing other people's symbols, there are nuances that you need to understand and be aware of:Organisation of data access. In other words, if you request timeseries data of someone else's symbol - you must first make sure that this data is prepared and exists. This is the only way to be sure that the data requested from someone else's symbol is correct.
 
Karputov Vladimir:
When accessing other people's characters, there are nuances that you need to understand and be aware of:Organising data access. In other words, if you request someone else's symbol timeseries data - you must first make sure that this data has been prepared and exists. Only this way you can be sure that the data you request from the alien character is correct.

Got it. Thank you.

Another question does you always convert values into the string type in the Print() function. What is the purpose of doing this? Without translation, the int, double, etc. types are displayed in the Print() function in exactly the same way.

 
Alex:

Got it. Thank you.

Another question do you always convert values to the string type in the Print() function. What is the purpose of doing this? Without translation, the int, double, etc. types are displayed in Print() in exactly the same way.

The way a number is stored in computer memory and the way it is output are two big differences. Especially with floating point numbers, it's always better to limit the number of decimal places.

That's why I always try to format the output correctly - useIntegerToString andDoubleToString.

 
Karputov Vladimir:

The way a number is stored in computer memory and the way it is output are two big differences. Especially with floating point numbers, it's always better to limit the number of decimal places.

That's why I always try to properly format number output usingIntegerToString andDoubleToString.

Thank you for your answers and patience.


Vladimir, I am probably tired of you :) But the progress in the basics is going very slow. I tried to do a test task with Copy function... The indicator isn't drawn, though there are numbers in Printe... I don't understand anything.


//+------------------------------------------------------------------+
//|                                                        Bars.mq5 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot UpBar
#property  indicator_label1  "UpBar"
#property  indicator_type1   DRAW_HISTOGRAM
#property  indicator_color1  clrGreen
#property  indicator_style1  STYLE_SOLID
#property  indicator_width1  6
//--- plot DnBar
#property  indicator_label2  "DnBar"
#property  indicator_type2   DRAW_HISTOGRAM
#property  indicator_color2  clrRed
#property  indicator_style2  STYLE_SOLID
#property  indicator_width2  6
//--- input parameters
input int   Histori=30;
input ENUM_TIMEFRAMES TimeFrame=0; 
input string  Simvol="EURUSD";
//--- indicator buffers
double         UpBar[];
double         DnBar[];
double         O_Price[];
double         C_Price[];



  
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UpBar,INDICATOR_DATA);
   SetIndexBuffer(1,UpBar,INDICATOR_DATA);
   SetIndexBuffer(2,O_Price,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,C_Price,INDICATOR_CALCULATIONS);



   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[])
 {
ArraySetAsSeries(O_Price,true);
ArraySetAsSeries(C_Price,true);
CopyOpen(Simvol,TimeFrame,0,Histori,O_Price);
CopyClose(Simvol,TimeFrame,0,Histori,C_Price);

     for (int t=3; t<Histori; t++) 
       {
          UpBar[t]=MathAbs(NormalizeDouble((O_Price[t]-C_Price[t]),Digits()));   
          Print(DoubleToString(UpBar[t],Digits()));
       }

   return(rates_total);
  }
Reason: