Особенности языка mql5, тонкости и приёмы работы - страница 104

 
Andrey Khatimlianskii:

Сколько инструментов в обзоре рынка?

61.

 
fxsaber:

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

 

Вопрос по построению индикаторов

#property indicator_chart_window

#property indicator_buffers 12

#property indicator_plots   6

#property indicator_type1   DRAW_COLOR_LINE

#property indicator_type2   DRAW_COLOR_LINE

#property indicator_type3   DRAW_COLOR_LINE

#property indicator_type4   DRAW_COLOR_LINE

#property indicator_type5   DRAW_COLOR_LINE

#property indicator_type6   DRAW_COLOR_LINE 


SetIndexBuffer(0,upper_line,INDICATOR_DATA);

   SetIndexBuffer(1,upper_line_color,INDICATOR_COLOR_INDEX);


   PlotIndexSetString(0,PLOT_LABEL,"Upper Line");

   PlotIndexSetInteger(0,PLOT_LINE_STYLE,UpperStyle);

   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,UpperWidth);

   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,UpperTrendUp);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,UpperTrendDw);

// ==========

   SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   SetIndexBuffer(3,awera_line_color,INDICATOR_COLOR_INDEX);


   PlotIndexSetString(1,PLOT_LABEL,"Average Line");

   PlotIndexSetInteger(1,PLOT_LINE_STYLE,AverageStyle);

   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,AverageWidth);

   PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,AverageTrendUp);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,AverageTrendDw);

// ==========

   SetIndexBuffer(4,lower_line,INDICATOR_DATA);

   SetIndexBuffer(5,lower_line_color,INDICATOR_COLOR_INDEX);


   PlotIndexSetString(2,PLOT_LABEL,"Lower Line");

   PlotIndexSetInteger(2,PLOT_LINE_STYLE,LowerStyle);

   PlotIndexSetInteger(2,PLOT_LINE_WIDTH,LowerWidth);

   PlotIndexSetInteger(2,PLOT_COLOR_INDEXES,2);

   PlotIndexSetInteger(2,PLOT_LINE_COLOR,0,LowerTrendUp);

   PlotIndexSetInteger(2,PLOT_LINE_COLOR,1,LowerTrendDw);

Сколько можно использовать цветовых буферов?

Как связываются друг с другом буферы?

#property indicator_buffers 12    // Обьявили всего 12 буферов

#property indicator_plots   6     // Графических построений

Правильно я понимаю что указав indicator_type с 1 по 6 индикатор будет понимать что цветную линии нужно рисовать для 6 графических построений ?

#property indicator_type1   DRAW_COLOR_LINE

#property indicator_type2   DRAW_COLOR_LINE

#property indicator_type3   DRAW_COLOR_LINE

#property indicator_type4   DRAW_COLOR_LINE

#property indicator_type5   DRAW_COLOR_LINE

#property indicator_type6   DRAW_COLOR_LINE


// =====

   SetIndexBuffer(0,upper_line,INDICATOR_DATA);   // Первый буфер для данных

   SetIndexBuffer(1,upper_line_color,INDICATOR_COLOR_INDEX); // Второй буфер для данных цветов


   PlotIndexSetString(0,PLOT_LABEL,"Upper Line"); // Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_STYLE,UpperStyle);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,UpperWidth);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,UpperTrendUp);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,UpperTrendDw);// Меняем свойства первого буфера


   SetIndexBuffer(2,awera_line,INDICATOR_DATA); // Третий буфер

   SetIndexBuffer(3,awera_line_color,INDICATOR_COLOR_INDEX); // Четвертый буфер цветов 


   PlotIndexSetString(1,PLOT_LABEL,"Average Line");  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_STYLE,AverageStyle);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,AverageWidth);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,AverageTrendUp);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,AverageTrendDw);  // Меняем свойства буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

 
Vladimir Pastushak:

Вопрос по построению индикаторов

#property indicator_chart_window

#property indicator_buffers 12

#property indicator_plots   6

#property indicator_type1   DRAW_COLOR_LINE

#property indicator_type2   DRAW_COLOR_LINE

#property indicator_type3   DRAW_COLOR_LINE

#property indicator_type4   DRAW_COLOR_LINE

#property indicator_type5   DRAW_COLOR_LINE

#property indicator_type6   DRAW_COLOR_LINE 


SetIndexBuffer(0,upper_line,INDICATOR_DATA);

   SetIndexBuffer(1,upper_line_color,INDICATOR_COLOR_INDEX);


   PlotIndexSetString(0,PLOT_LABEL,"Upper Line");

   PlotIndexSetInteger(0,PLOT_LINE_STYLE,UpperStyle);

   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,UpperWidth);

   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,UpperTrendUp);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,UpperTrendDw);

// ==========

   SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   SetIndexBuffer(3,awera_line_color,INDICATOR_COLOR_INDEX);


   PlotIndexSetString(1,PLOT_LABEL,"Average Line");

   PlotIndexSetInteger(1,PLOT_LINE_STYLE,AverageStyle);

   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,AverageWidth);

   PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,AverageTrendUp);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,AverageTrendDw);

// ==========

   SetIndexBuffer(4,lower_line,INDICATOR_DATA);

   SetIndexBuffer(5,lower_line_color,INDICATOR_COLOR_INDEX);


   PlotIndexSetString(2,PLOT_LABEL,"Lower Line");

   PlotIndexSetInteger(2,PLOT_LINE_STYLE,LowerStyle);

   PlotIndexSetInteger(2,PLOT_LINE_WIDTH,LowerWidth);

   PlotIndexSetInteger(2,PLOT_COLOR_INDEXES,2);

   PlotIndexSetInteger(2,PLOT_LINE_COLOR,0,LowerTrendUp);

   PlotIndexSetInteger(2,PLOT_LINE_COLOR,1,LowerTrendDw);

Сколько можно использовать цветовых буферов?

Как связываются друг с другом буферы?

#property indicator_buffers 12    // Обьявили всего 12 буферов

#property indicator_plots   6     // Графических построений

Правильно я понимаю что указав indicator_type с 1 по 6 индикатор будет понимать что цветную линии нужно рисовать для 6 графических построений ?

#property indicator_type1   DRAW_COLOR_LINE

#property indicator_type2   DRAW_COLOR_LINE

#property indicator_type3   DRAW_COLOR_LINE

#property indicator_type4   DRAW_COLOR_LINE

#property indicator_type5   DRAW_COLOR_LINE

#property indicator_type6   DRAW_COLOR_LINE


// =====

   SetIndexBuffer(0,upper_line,INDICATOR_DATA);   // Первый буфер для данных

   SetIndexBuffer(1,upper_line_color,INDICATOR_COLOR_INDEX); // Второй буфер для данных цветов


   PlotIndexSetString(0,PLOT_LABEL,"Upper Line"); // Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_STYLE,UpperStyle);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,UpperWidth);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,UpperTrendUp);// Меняем свойства первого буфера

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,UpperTrendDw);// Меняем свойства первого буфера


   SetIndexBuffer(2,awera_line,INDICATOR_DATA); // Третий буфер

   SetIndexBuffer(3,awera_line_color,INDICATOR_COLOR_INDEX); // Четвертый буфер цветов 


   PlotIndexSetString(1,PLOT_LABEL,"Average Line");  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_STYLE,AverageStyle);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,AverageWidth);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_COLOR_INDEXES,2);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,0,AverageTrendUp);  // Меняем свойства  буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

   PlotIndexSetInteger(1,PLOT_LINE_COLOR,1,AverageTrendDw);  // Меняем свойства буфера  для SetIndexBuffer(2,awera_line,INDICATOR_DATA);

Лучше создайте отдельную ветку для своего вопроса. Эта ветка про особенности, обсуждений тут не должно быть.

Чтобы лучше понять принцип построения, реализуйте функционал инкрементно. Построили одну линию - проверили работоспособность, добавили следующую.

У каждой графической серии (в данном случае цветной линии) может быть только один буфер цвета. Каждый буфер может содержать множество цветов.

 
Andrey Khatimlianskii:

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

Ошибки исчезли, а проблемы с очередью событий — нет. Через несколько часов работы терминал начинает загружать ЦП на 95%. И что-то мне подсказывает, что тики пропускаются.

2018.10.11 23:56:54.069 Terminal        MetaTrader 5 x64 build 1907 started (MetaQuotes Software Corp.)
2018.10.11 23:56:54.139 Terminal        Windows 8.1 (build 9600) x64, IE 11, UAC, Intel Core i5-3570  @ 3.40GHz, Memory: 11580 / 16346 Mb, Disk: 401 / 499 Gb, GMT+2

@Slava, что-то менялось в ChartEvent-ах в 19хх билдах? У вас проблема воспроизводится?

 
Andrey Khatimlianskii:

Ошибки исчезли, а проблемы с очередью событий — нет. Через несколько часов работы терминал начинает загружать ЦП на 95%. И что-то мне подсказывает, что тики пропускаются.

@Slava, что-то менялось в ChartEvent-ах в 19хх билдах? У вас проблема воспроизводится?

Вот так выглядит мониторинг ресурсов через 15 часов работы терминала (минимальная частота отправки события шпионом — 500 мс):

Хотя несколько часов после запуска загрузка процессора близка к 0.

 
Andrey Khatimlianskii:

Вот так выглядит мониторинг ресурсов через 15 часов работы терминала (минимальная частота отправки события шпионом — 500 мс):

Хотя несколько часов после запуска загрузка процессора близка к 0.

Билд 1908 — без изменений.

 

Возможность замены операторов структур базового типа позволяет в некоторых ситуациях проявлять гибкость.

В качестве примера, ниже один из приемов для кастомной сортировки массива структур

// Основная структура
struct A
{
  int a;
  int b;
  
  // Правило сортировки
  bool operator > ( const A& Value ) const 
  {
    return(this.a > Value.a);
  }
};

// Вспомогательная структура для изменения правила сортировки
struct B : A
{
  // Перегрузка правила сортировки
  bool operator > ( const A& Value ) const 
  {
    return(this.b > Value.b);
  }
};

// Простая сортировка
template <typename T1, typename T2> // T2 - по какому правилу сортируем
void Sort( T1 &Array[] )
{
  const int Size = ArraySize(Array);
  
  for (int i = 0; i < Size - 1; i++)
  {
    T2 Min = Array[i];
    int Pos = i;
    
    for (int j = i + 1; j < Size; j++)
      if (Min > Array[j])
      {
        Min = Array[j];
        Pos = j;        
      }
      
    if (Pos != i)
    {
      Array[Pos] = Array[i];
      Array[i] = Min;
    }
  }
}

void OnStart()
{
  A Array[3] = {{2, 2}, {3,1}, {1, 3}};
  
  ArrayPrint(Array);
  
  // Сортировка по правилу A
  Sort<A, A>(Array); 
  ArrayPrint(Array);
  
  // Сортировка по правилу B
  Sort<A, B>(Array);  
  ArrayPrint(Array);
}


Результат

    [a] [b]
[0]   2   2
[1]   3   1
[2]   1   3
    [a] [b]
[0]   1   3
[1]   2   2
[2]   3   1
    [a] [b]
[0]   3   1
[1]   2   2
[2]   1   3


Наверное, древний велосипед.

 
fxsaber:

Возможность замены операторов структур базового типа позволяет в некоторых ситуациях проявлять гибкость.

есть несколько моментов. в mql оператор <  обязательно должен быть методом класса\структуры.

это значит, что его нельзя задать для встроенных структур. ну или для неизменяемых.

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

UPD: пишу везде оператор < потому что перегружают обычно его а не >, это не строго, но общепринято
 
TheXpert:

есть несколько моментов. в mql оператор <  обязательно должен быть методом класса\структуры.

это значит, что его нельзя задать для встроенных структур. ну или для неизменяемых.

// Вспомогательная структура для изменения правила сортировки
struct MQLTICK_BID : MqlTick
{
  // Сортировка по времени
  bool operator <( const MqlTick& Value ) const 
  {
    return(this.bid < Value.bid);
  }
};

// Простая сортировка
template <typename T1, typename T2> // T2 - по какому правилу сортируем
void Sort( T1 &Array[] )
{
  const int Size = ArraySize(Array);
  
  for (int i = 0; i < Size - 1; i++)
  {
    T2 Min = Array[i];
    int Pos = i;
    
    for (int j = i + 1; j < Size; j++)
      if (Min < Array[j])
      {
        Min = Array[j];
        Pos = j;        
      }
      
    if (Pos != i)
    {
      Array[Pos] = Array[i];
      Array[i] = Min;
    }
  }
}

void OnStart()
{
  MqlTick Ticks[];
  
  CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 5);
  
  ArrayPrint(Ticks);
  
  // Сортировка по правилу MQLTICK_BID
  Sort<MqlTick, MQLTICK_BID>(Ticks); 
  ArrayPrint(Ticks);
}


Результат

                 [time]   [bid]   [ask]  [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2018.10.11 23:59:55 1.09115 1.09354 0.00000        0 1539302395303       6       0.00000
[1] 2018.10.11 23:59:56 1.09132 1.09348 0.00000        0 1539302396037       6       0.00000
[2] 2018.10.11 23:59:56 1.09131 1.09353 0.00000        0 1539302396302       6       0.00000
[3] 2018.10.11 23:59:59 1.09135 1.09354 0.00000        0 1539302399458       6       0.00000
[4] 2018.10.11 23:59:59 1.09139 1.09378 1.09260        0 1539302399989      14       0.00000
                 [time]   [bid]   [ask]  [last] [volume]    [time_msc] [flags] [volume_real]
[0] 2018.10.11 23:59:59 1.09139 1.09378 1.09260        0 1539302399989      14       0.00000
[1] 2018.10.11 23:59:59 1.09135 1.09354 0.00000        0 1539302399458       6       0.00000
[2] 2018.10.11 23:59:56 1.09132 1.09348 0.00000        0 1539302396037       6       0.00000
[3] 2018.10.11 23:59:56 1.09131 1.09353 0.00000        0 1539302396302       6       0.00000
[4] 2018.10.11 23:59:55 1.09115 1.09354 0.00000        0 1539302395303       6       0.00000


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

Если использовать typedef, то тогда нужно определять функцию сортировки не только для структур, но и для стандартных числовых типов. Или я не понял, о чем речь.