Обсуждение статьи "Рецепты MQL5 - Разработка мультивалютного индикатора для анализа расхождения цен"

 

Опубликована статья Рецепты MQL5 - Разработка мультивалютного индикатора для анализа расхождения цен:

В этой статье рассмотрим разработку мультивалютного индикатора для анализа расхождения цен за указанный период времени. Многие основные моменты уже рассматривались в предыдущей статье по программированию мультивалютных индикаторов "Разработка мультивалютного индикатора волатильности на MQL5". Поэтому на этот раз будем останавливаться только на новых функциях и тех функциях, которые претерпели сильные изменения. Если Вы впервые рассматриваете тему программирования мультивалютных индикаторов, то рекомендуется в первую очередь прочитать предыдущую статью.

Недельный таймфрейм в режиме "Вертикальная линия"

В этой статье мы рассмотрим следующие вопросы:

  • изменение свойств графика;
  • обработка событий CHARTEVENT_OBJECT_DRAG (перетаскивание графического объекта) и CHARTEVENT_CHART_CHANGE (изменение размеров графика или изменение свойств графика через диалог свойств);
  • отрисовка индикаторных буферов более, чем одним цветом;
  • определение максимумов и минимумов в индикаторных буферах в зоне видимости для установки максимума/минимума графика;
  • инверсия ряда.

Автор: Anatoli Kazharski

 

Это просто опечатка или так и должно быть?

Сколько не пробовал, но все функции из "отряда Copy" ноль никогда не возвращали, только -1 или >0.

//+------------------------------------------------------------------+
//| Проверяет количество доступных данных у всех символов            |
//+------------------------------------------------------------------+
bool CheckAvailableData()
  {
   int attempts=100;
   
//---
   for(int s=0; s<SYMBOLS_COUNT; s++)
     {
      //--- Если такой символ есть
      if(symbol_names[s]!=empty_symbol)
        {
datetime time[];                    // Массив для проверки количества баров
   int      total_period_bars   =0;    // Количество баров текущего периода
   datetime terminal_first_date =NULL; // Первая дата имеющихся данных текущего периода в терминале
         //--- Получим первую дату данных текущего периода в терминале
         terminal_first_date=(datetime)SeriesInfoInteger(symbol_names[s],Period(),SERIES_TERMINAL_FIRSTDATE);
         //--- Получим количество доступных баров от указанной даты
         total_period_bars=Bars(symbol_names[s],Period(),terminal_first_date,TimeCurrent());
         //--- Проверим готовность данных баров
         for(int i=0; i<attempts; i++)
           {
            //--- Скопируем указанное количество данных
            if(CopyTime(symbol_names[s],Period(),0,total_period_bars,time))
              {
               //--- Если скопировалось нужное количество, остановим цикл
               if(ArraySize(time)>=total_period_bars)
                  break;
              }
           }
         //--- Если скопировано меньше данных значит нужно совершить еще одну попытку
         if(ArraySize(time)==0 || ArraySize(time)<total_period_bars)
           {
            msg_last=msg_prepare_data;
            ShowCanvasMessage(msg_prepare_data);
            OC_prev_calculated=0;
            return(false);
           }
        }
     }
//--- Если в режиме вертикальной линии для начальной точки расхождения цен, выходим
   if(StartPriceDivergence==VERTICAL_LINE)
      return(true);
   else
     {
      datetime time[];                    // Массив для проверки количества баров
      int      total_period_bars   =0;    // Количество баров текущего периода
      datetime terminal_first_date =NULL; // Первая дата имеющихся данных текущего периода в терминале
      //--- Получим первую дату данных текущего периода в терминале
      for(int i=0; i<attempts; i++)
         if((terminal_first_date=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_FIRSTDATE))>0)
            break;
      //--- Получим количество доступных баров от указанной даты
      for(int i=0; i<attempts; i++)
         if((total_period_bars=(int)SeriesInfoInteger(Symbol(),timeframe_start_point,SERIES_BARS_COUNT))>0)
            break;
      //--- Проверим готовность данных баров
      for(int i=0; i<attempts; i++)
         //--- Скопируем указанное количество данных
         if(CopyTime(Symbol(),timeframe_start_point,
            terminal_first_date+PeriodSeconds(timeframe_start_point),TimeCurrent(),time)>0)
            break;
      //--- Если скопировано меньше данных, значит нужно совершить еще одну попытку
      if(ArraySize(time)<=0 || total_period_bars<=0)
        {
         msg_last=msg_prepare_data;
         ShowCanvasMessage(msg_prepare_data);
         OC_prev_calculated=0;
         return(false);
        }
     }
//---
   return(true);
  }
 
Fleder:

Это просто опечатка или так и должно быть?

Сколько не пробовал, но все функции из "отряда Copy" ноль никогда не возвращали, только -1 или >0.

Вообще нужно делать >0. Но в этом случае последующие проверки позволяют этого не делать. 
 
tol64:
Вообще нужно делать >0. Но в этом случае последующие проверки позволяют этого не делать. 

Но ведь это выражение всегда будет истинно:

if(CopyTime(symbol_names[s],Period(),0,total_period_bars,time))
 
Fleder:

Но ведь это выражение всегда будет истинно:

Да там можно вообще if убрать. В этом случае это некритично.
 
tol64:
Да там можно вообще if убрать. В этом случае это некритично.
Ну, я так и подумал :-)
 

А вообще загрузка исторических данных по символу происходит совсем не так, как написано в справке.

По факту получается так:

если из mql5 программы произойдёт запрос данных какой-нибудь таймсерии с помощью, например, функции CopyTime

и этих данных не окажется в терминале (ещё не загружены), то терминал будет качать эти данные с сервера не в затребованном количестве (в примере справки - это 100 баров),

а столько,  сколько баров нужной таймсерии позволяет "разместить" в ОЗУ параметр "Max bars in chart" .

Достаточно запросить всего один бар старшего периода, скажем PERIOD_ W1, как будет загружена ВСЯ история с сервера.

 
Fleder:

А вообще загрузка исторических данных по символу происходит совсем не так, как написано в справке.

По факту получается так:

если из mql5 программы произойдёт запрос данных какой-нибудь таймсерии с помощью, например, функции CopyTime

и этих данных не окажется в терминале (ещё не загружены), то терминал будет качать эти данные с сервера не в затребованном количестве (в примере справки - это 100 баров),

а столько,  сколько баров нужной таймсерии позволяет "разместить" в ОЗУ параметр "Max bars in chart" .

Достаточно запросить всего один бар старшего периода, скажем PERIOD_ W1, как будет загружена ВСЯ история с сервера.

В справке может быть написано, всё что угодно. Вы же вольны делать всё так, как считаете нужным. ;)

Пример из справки рассматривал в другой статье: Как подготовить котировки MetaTrader 5 для других программ >>> 

 
tol64:

В справке может быть написано, всё что угодно. Вы же вольны делать всё так, как считаете нужным. ;)

Пример из справки рассматривал в другой статье: Как подготовить котировки MetaTrader 5 для других программ >>> 

Так я и сделал. Просто увидел в Вашем коде расчёт оставшихся "незагруженных баров"  с сервера.

И подумал - терминалу всё равно, качает сколь надо для формирования. 

 

В конце своей статьи Вы написали: "Этот индикатор можно неограниченно развивать в лучшую сторону".

На мой взгляд, созерцание  расхождения цен для человеческого глаза мало полезно. Человек - не робот!

А вот для робота - это интересная тема.

Вами было предложено несколько вариантов отрисовки:

1. от линии.

2. "день".

Я в настоящее время работаю над чем-то похожим, только в режиме "неделя".

 
Fleder:

В конце своей статьи Вы написали: "Этот индикатор можно неограниченно развивать в лучшую сторону".

На мой взгляд, созерцание  расхождения цен для человеческого глаза мало полезно. Человек - не робот!

А вот для робота - это интересная тема.

Вами было предложено несколько вариантов отрисовки:

1. от линии.

2. "день".

Я в настоящее время работаю над чем-то похожим, только в режиме "неделя".

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

Да, человек не робот, но иногда, чтобы родилась идея, нужно посмотреть на предмет изучения как-то иначе. ;) 

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