Стили индикаторов в примерах

В клиентский терминал MetaTrader 5 встроено 38 технических индикаторов, которые можно использовать в программах MQL5 с помощью соответствующих функций. Но главное достоинство языка MQL5 – возможность создавать свои собственные пользовательские индикаторы, которые потом можно использовать в советниках для получения значений или просто накладывать на ценовые графики для проведения технического анализа.

Все множество индикаторов можно получить на основе нескольких базовых стилей рисования, называемых  графическими построениями. Под построением понимается способ отображения данных, которые индикатор рассчитывает, хранит и выдает по запросу. Всего таких базовых построений семь:

  1. линия,
  2. секция (отрезок),
  3. гистограмма,
  4. стрелка (символ),
  5. закрашиваемая область (канал с заливкой),
  6. бары,
  7. японские свечи.

Каждое построение требует для своего отображения от одного до пяти массивов типа double, в которых хранятся значения индикатора. Эти массивы для удобства работы индикатора связываются с индикаторными буферами. Количество буферов в индикаторе необходимо объявить заранее с помощью директивы компилятора, пример:

#property indicator_buffers 3 // количество буферов
#property indicator_plots   2 // количество графических построений

Количество буферов в индикаторе всегда больше или равно количеству построений в индикаторе.

Так как каждое базовое графическое построение может иметь цветовые вариации или специфику отображения, то реальное количество построений в языке MQL5 составляет 18:

Построение

Описание

Буферов значений

Буферов цвета

DRAW_NONE

На графике визуально не отображается, но значения соответствующего буфера можно посмотреть в "Окне данных"

1

-

DRAW_LINE

Строится линия по значениям соответствующего буфера  (пустые значения в буфере нежелательны)

1

-

DRAW_SECTION

Рисуется отрезками между значениями соответствующего буфера (обычно пустых значений много)

1

-

DRAW_HISTOGRAM

Рисуется гистограммой от нулевой линии до значений соответствующего буфера (допускаются пустые значения)

1

-

DRAW_HISTOGRAM2

Рисуется гистограммой на двух индикаторных буферах (допускаются пустые значения)

2

-

DRAW_ARROW

Отображается символами  (допускаются пустые значения)

1

-

DRAW_ZIGZAG

Похож на стиль DRAW_SECTION, но в отличие от него может строить вертикальные отрезки на одном баре

2

-

DRAW_FILLING

Цветовая заливка между двумя линиями. В "Окне данных" показываются 2 значения соответствующих буферов

2

-

DRAW_BARS

Отображение на графике в виде баров. В "Окне данных" показываются 4 значения соответствующих буферов

4

-

DRAW_CANDLES

Отображение в виде японских свечей. В "Окне данных" показываются 4 значения соответствующих буферов

4

-

DRAW_COLOR_LINE

Линия, для которой можно чередовать цвет как на разных барах, так и сменить ее цвет в любой момент времени

1

1

DRAW_COLOR_SECTION

Похож на стиль DRAW_SECTION, но цвет каждой секции можно задавать индивидуально, можно задавать цвет динамически

1

1

DRAW_COLOR_HISTOGRAM

Похож на стиль DRAW_HISTOGRAM, но каждая полоска может иметь свой цвет, можно задавать цвет динамически

1

1

DRAW_COLOR_HISTOGRAM2

Похож на DRAW_HISTOGRAM2,  но каждая полоска может иметь свой цвет, цвет можно задавать динамически

2

1

DRAW_COLOR_ARROW

Похож на стиль DRAW_ARROW, но каждый символ может иметь свой цвет. Цвет можно менять динамически

1

1

DRAW_COLOR_ZIGZAG

Стиль DRAW_ZIGZAG с возможностями индивидуальной раскраски секций и динамической смены цвета

2

1

DRAW_COLOR_BARS

Стиль DRAW_BARS с возможностями индивидуальной раскраски баров и динамической смены цвета

4

1

DRAW_COLOR_CANDLES

Стиль DRAW_CANDLES с возможностями индивидуальной раскраски свечей и динамической смены цвета

4

1

 

Разница между индикаторным буфером и массивом

В каждом индикаторе необходимо объявить на глобальном уровне один или более массивов типа double, который затем должен быть использован в качестве индикаторного буфера с помощью функции SetIndexBuffer(). Для рисования графических построений индикатора используются только значения из индикаторных буферов, какие-либо другие массивы для этого использовать нельзя. Кроме того, значения буферов показываются в "Окне данных".

Индикаторный буфер должен быть динамическим и не требует указания размера – размер массива, использованного в качестве индикаторного буфера, устанавливается исполняющей подсистемой терминала автоматически.

Направление индексации после связывания массива с индикаторным буфером по умолчанию устанавливается как в обычных массивах, но при необходимости можно применить функцию ArraySetAsSeries() для изменения способа доступа к элементам массива. По умолчанию индикаторный буфер используется для хранения данных, предназначенных для отрисовки (INDICATOR_DATA).

Если для расчетов значений индикатора требуется проводить промежуточные вычисления и хранить для каждого бара вспомогательное значение, то при связывании такой массив можно объявить в качестве расчетного буфера ( INDICATOR_CALCULATIONS). Можно использовать для промежуточных значений и обычный массив, но в этом случае программист должен самостоятельно управлять размером такого массива.

Некоторые построения позволяют задавать для каждого бара цвет отображения. Для хранения информации о цвете используются цветовые буфера (INDICATOR_COLOR_INDEX). Цвет представлен целочисленным типом color, но все индикаторные буфера должны иметь тип double. Значения цветовых и вспомогательных (INDICATOR_CALCULATIONS) буферов нельзя получить с помощью функции CopyBuffer().

Количество индикаторных буферов должно быть указано директивой компилятора #property indicator_buffers количество_буферов:

#property indicator_buffers 3  //  индикатор имеет 3 буфера

Максимально допустимое количество буферов в одном индикаторе - 512.

 

Соответствие индикаторных буферов и графических построений

Каждое графическое построение базируется на одном или более индикаторных буферах. Так, для отображения простых японских свечей требуется четыре значения - цены Open, High, Low и Close. Соответственно, для отображения индикатора в виде японских свечей необходимо объявить 4 индикаторных буфера и 4 массива типа double под них. Например:

//--- в индикаторе четыре индикаторных буфера
#property indicator_buffers 4
//--- в индикаторе одно графическое построение
#property indicator_plots   1
//--- графическое построение под номером 1 будет отображаться японскими свечами
#property indicator_type1   DRAW_CANDLES
//--- японские свечи будут рисоваться цветом clrDodgerBlue
#property indicator_color1  clrDodgerBlue
//--- 4 массива под индикаторные буферы
double OBuffer[];
double HBuffer[];
double LBuffer[];
double CBuffer[];

 

Графические построения автоматически используют индикаторные буферы в соответствии с номером построения. Номера построения начинаются с единицы, номера буферов начинаются с нуля. Если первое построение требует 4 индикаторных буфера, то для отрисовки будут использованы 4 первых индикаторных буфера. Эти четыре буфера должны быть связаны функцией SetIndexBuffer() с соответствующими массивами с правильной индексацией.

//--- связывание массивов с индикаторными буферами
   SetIndexBuffer(0,OBuffer,INDICATOR_DATA);  // первый буфер соответствует нулевому индексу
   SetIndexBuffer(1,HBuffer,INDICATOR_DATA);  // второй буфер соответствует индексу 1
   SetIndexBuffer(2,LBuffer,INDICATOR_DATA);  // третий буфер  соответствует индексу 2
   SetIndexBuffer(3,CBuffer,INDICATOR_DATA);  // четвертый буфер  соответствует индексу 3

При отрисовке японских свечей индикатор будет использовать именно первые четыре буфера, потому что построение "японские свечи" было объявлено под первым номером.

Изменим немного пример, добавим построение в виде простой линии - DRAW_LINE.  Пусть теперь линия будет иметь номер 1, а японские свечи будут под номером 2. Количество буферов и количество построений увеличилось.

//--- в индикаторе 5 индикаторных буферов
#property indicator_buffers 5
//--- в индикаторе 2 графических построения
#property indicator_plots   2
//--- графическое построение под номером 1 будет отображаться линией
#property indicator_type1   DRAW_LINE
//--- линия будет рисоваться цветом clrDodgerRed
#property indicator_color1  clrDodgerRed
//--- графическое построение под номером 2 будет отображаться японскими свечами
#property indicator_type2   DRAW_CANDLES
//--- японские свечи будут рисоваться цветом clrDodgerBlue
#property indicator_color2  clrDodgerBlue
//--- 5 массивов под индикаторные буферы
double LineBuffer[];
double OBuffer[];
double HBuffer[];
double LBuffer[];
double CBuffer[];

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

   SetIndexBuffer(0,LineBuffer,INDICATOR_DATA);  // первый буфер соответствует индексу 0
//--- связывание массивов с индикаторными буферами под японские свечи
   SetIndexBuffer(1,OBuffer,INDICATOR_DATA);     // второй буфер соответствует индексу 1
   SetIndexBuffer(2,HBuffer,INDICATOR_DATA);     // третий буфер соответствует индексу 2
   SetIndexBuffer(3,LBuffer,INDICATOR_DATA);     // четвертый буфер  соответствует индексу 3
   SetIndexBuffer(4,CBuffer,INDICATOR_DATA);     // пятый буфер  соответствует индексу 4 

Количество буферов и графических построений можно задавать только с помощью директив компилятора, динамическое изменение этих свойств с помощью функций невозможно.

 

Цветовые версии стилей

Как можно увидеть в таблице, стили делятся на две группы. Первая группа — это стили, у которых в названии нет слова COLOR, назовем эти стили базовыми:

  • DRAW_LINE
  • DRAW_SECTION
  • DRAW_HISTOGRAM
  • DRAW_HISTOGRAM2
  • DRAW_ARROW
  • DRAW_ZIGZAG
  • DRAW_FILLING
  • DRAW_BARS
  • DRAW_CANDLES

Вторая группа стилей содержит в названии слово COLOR, назовем их цветовыми версиями:

  • DRAW_COLOR_LINE
  • DRAW_COLOR_SECTION
  • DRAW_COLOR_HISTOGRAM
  • DRAW_COLOR_HISTOGRAM2
  • DRAW_COLOR_ARROW
  • DRAW_COLOR_ZIGZAG
  • DRAW_COLOR_BARS
  • DRAW_COLOR_CANDLES

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

Для того чтобы задавать цвет построения на каждом баре, в цветовые версии стилей был добавлен дополнительный специальный буфер для хранения индекса цвета. Эти индексы указывают на номер цвета в специальном массиве, содержащем заранее определенный набор цветов. Размер массива цветов – 64. Это означает, что каждая цветовая версия стиля позволяет раскрасить графическое построение 64-мя различными цвета.

Набор и количество цветов в специальном массиве цветов можно задавать директивой компилятора #property indicator_color, где через запятую указываются все необходимые цвета. Например, такая запись в индикаторе:

//--- зададим 8 цветов для раскраски свечей (они хранятся в специальном массиве)
#property indicator_color1  clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange

Здесь указано, что для графического построения номер 1 заданы 8 цветов, которые будут помещены в специальный массив. Далее в программе мы будем указывать не сам цвет, которым будет отображаться графическое построение, а только его индекс. Если мы хотим задать для бара красный цвет, то для этого необходимо установить в цветовом буфере индекс красного цвета из массива. Красный цвет задан в директиве первым первым, ему соответствует индекс номер 0.

  //--- зададим цвет свечи clrRed
  col_buffer[buffer_index]=0;

Набор цветов для раскрашивания не является раз и навсегда заданным, его можно менять динамически с помощью функции PlotIndexSetInteger(). Пример:

      //--- установим цвет для каждого индекса как свойство PLOT_LINE_COLOR
      PlotIndexSetInteger(0,                    //  номер графического стиля
                          PLOT_LINE_COLOR,      //  идентификатор свойства
                          plot_color_ind,       //  индекс цвета, куда запишем цвет
                          color_array[i]);      //  новый цвет

 

Свойства индикатора и графических построений

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

 

Начало отрисовки индикатора на графике

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

В таких случаях либо нет возможности рассчитать значения индикатора на N самых первых барах, либо эти значения не предназначены для отображения на графике и являются только вспомогательными для расчета последующих значений. Чтобы отказаться от визуализации индикатора на первых N барах истории, следует установить свойству   PLOT_DRAW_BEGIN значение N для соответствующего графического построения:

//--- связывание массивов с индикаторными буферами под японские свечи
PlotIndexSetInteger(номер_графического_построения,PLOT_DRAW_BEGIN,N);

Здесь:

  • номер_графического_построения – значение от нуля до indicator_plots-1 (нумерация графических построений начинается с нуля).
  • N – количество первых в истории баров, на которых индикатор не должен отображаться на графике.