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

 
Karputov Vladimir:
В индикаторе или в советнике/скрипте?
В индикаторе.
 

Yuri Evseenkov:

fromme2you:

Еще вопрос: как напрячь разработчика МТ4 и среды исполнения MQL кода, чтобы он(они) приложил ум и руки в развитии языка для обработки исключений, такие как в моем примере или сходные по смыслу?


Обращатся в сервесдеск, создать тему/опрос на форуме.

Не так давно МТ4 вообще хоронили. Сейчас тренд если не развернулся , то по крайней мере в последнее время платформу и язык стали значительно модернизировать.

См. сегодняшний пост Рената:

Renat Fatkhullin:

...

развитие МТ4 остановлено и для него будут только фиксы с косметикой.

 
Alex:

Здравствуйте. Не могли бы знающие люди подсказать в какую сторону решить данную задачу. Нужно найти цены открытия баров в определенное время, например в 01:00, анализируя  к примеру 50 последних баров. Не знаю каким образом подойти лучше к задаче на mql5.


То ли через вычисление текущей даты+добавление к ней времени требуемого, и далее уже плюсовать сутками,  этот способ работал на mql4.

На mql5 я так понял есть специальные структуры с выводом времени, но почему то не получается через них.

Заранее спасибо за ответ.

Буду очень благодарен , если кто-нибудь накидает кусочек кода для понимания направления  размышления.
Alex:
В индикаторе.

Здесь, для того, чтобы Вы потом лучше понимали, советую для начала посмотреть нумерацию баров. То есть нужно сначала точно понять, как в MQL5 индикаторе нумеруется самый правый бар.

Для этого в индикаторе, в 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);
  }
//+------------------------------------------------------------------+

Этот код выдаст такой результат:

Нумерация в массивах индикатора MQL5, по умолчанию

То есть по умолчанию в массивах индикатора MQL5 самый правый бар имеет индекс равный "rates_total-1".

 

Возвращаясь к Вашему вопросу - необходимо взять последние 50 баров и пройтись по ним. Причём анализировать время открытия бара (массив time[]), если время бара равно заданному, то запомнить индекс этого бара. Потом по этому индексу получить из массива open[] цену открытия.

 

Это выглядит примерно так:

//+------------------------------------------------------------------+
//|                                                         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:

Здесь, для того, чтобы Вы потом лучше понимали, советую для начала посмотреть нумерацию баров. То есть нужно сначала точно понять, как в MQL5 индикаторе нумеруется самый правый бар.

Для этого в индикаторе, в OnCalculate, поставьте такой вывод комментария:

Этот код выдаст такой результат:


То есть по умолчанию в массивах индикатора MQL5 самый правый бар имеет индекс равный "rates_total-1".

 

Возвращаясь к Вашему вопросу - необходимо взять последние 50 баров и пройтись по ним. Причём анализировать время открытия бара (массив time[]), если время бара равно заданному, то запомнить индекс этого бара. Потом по этому индексу получить из массива open[] цену открытия.

 

Это выглядит примерно так:

Karputov Vladimir,огромная Вам благодарность. Буду разбираться. В mql5 вроде сделали более гибко доступ к тайм сериям, но как то усложнилось все по моему для программистов "Любителей-новичков". :))
 
Alex:
Karputov Vladimir,огромная Вам благодарность. Буду разбираться. В mql5 вроде сделали более гибко доступ к тайм сериям, но как то усложнилось все по моему для программистов "Любителей-новичков". :))
 Дело привычки. Потом поймёте, что всё структурировано, легко и правильно.
 
Karputov Vladimir:
 Дело привычки. Потом поймёте, что всё структурировано, легко и правильно.

Еще такой вопрос. Параметры

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


Я так понял отвечают за пару на которую наложен индикатор. И вытащить при помощи них ту же информацию о другой валютной паре нельзя?  То есть более универсальное решение получается сделать такие же массивы OCHL только через функции Copy...?
 
Alex:

Еще такой вопрос. Параметры

Я так понял отвечают за пару на которую наложен индикатор. И вытащить при помощи них ту же информацию о другой валютной паре нельзя?  То есть более универсальное решение получается сделать такие же массивы OCHL только через функции Copy...?
При доступе к чужим символам есть нюансы, которые нужно понимать и знать: Организация доступа к данным. Другими словами, если Вы запрашиваете данные таймсерий чужого символа - сначала нужно удостовериться, что эти данные подготовлены и существуют. Только так можно будет быть уверенным в корректности запрошенных данных с чужого символа.
 
Karputov Vladimir:
При доступе к чужим символам есть нюансы, которые нужно понимать и знать: Организация доступа к данным. Другими словами, если Вы запрашиваете данные таймсерий чужого символа - сначала нужно удостовериться, что эти данные подготовлены и существуют. Только так можно будет быть уверенным в корректности запрошенных данных с чужого символа.

Понял. Спасибо.

Еще вопрос Вы в функции Print() всегда переводите значения в тип string. С какой целью это делается? Без перевода типы int,double и т.д точно так же отображаются в Print().

 
Alex:

Понял. Спасибо.

Еще вопрос Вы в функции Print() всегда переводите значения в тип string. С какой целью это делается? Без перевода типы int,double и т.д точно так же отображаются в Print().

То как  число храниться в памяти компьютера и то как оно выводится - это две большие разницы. Тем более для чисел с плавающей точкой всегда лучше ограничивать количество знаков после запятой. 

Поэтому стараюсь всегда правильно форматировать вывод чисел через принт - использовать IntegerToString и DoubleToString

 
Karputov Vladimir:

То как  число храниться в памяти компьютера и то как оно выводится - это две большие разницы. Тем более для чисел с плавающей точкой всегда лучше ограничивать количество знаков после запятой. 

Поэтому стараюсь всегда правильно форматировать вывод чисел через принт - использовать IntegerToString и DoubleToString

Благодарю за ответы  и терпение.


Владимир, я наверное уже замучил Вас:) Но что то очень тяжко идет движение по основам основ. Попробовал сделать тестовую задачу с функциями Copy... Индикатор не рисуется, хотя в Printe числа есть... Ничего не понимаю.


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