- Основные характеристики индикаторов
- Главное событие индикаторов: OnCalculate
- Два типа индикаторов: для главного и отдельного окна
- Настройка количества буферов и графических построений
- Назначение массива в качестве буфера: SetIndexBuffer
- Настройка графических построений: PlotIndexSetInteger
- Правила сопоставления буферов и диаграмм
- Применение директив для настройки графических построений
- Установка названий для графических построений
- Визуализация пропусков данных (пустых элементов)
- Индикаторы с собственным подокном: размер и уровни
- Общие свойства индикаторов: заголовок и точность значений
- Поэлементное раскрашивание диаграмм
- Пропуск отрисовки на начальных барах
- Ожидание данных и управление видимостью (DRAW_NONE)
- Мультивалютные и мультитаймфреймовые индикаторы
- Отслеживание формирования баров
- Тестирование индикаторов
- Ограничения и преимущества индикаторов
- Создание заготовки индикатора в Мастере MQL
Индикаторы с собственным подокном: размер и уровни
До сих пор мы ограничивались индикаторами, работающими в основном окне графика, то есть они имели директиву #property indicator_chart_window. Настало время изучить индикаторы, размещаемые в собственном подконе, под графиком котировок. Напомним, что их следует описывать с директивой #property indicator_separate_window.
Все, что мы изучили ранее, применимо и к индикатором в подокне, включая описание и привязку буферов, настройку типов и стилей рисования, применения как полной, так и сокращенной формы OnCalculate, на выбор. Однако они имеют и некоторые особенности, дополнительные настройки.
Поскольку подокно имеет собственную шкалу значений, MQL5 позволяет задать для него максимальную и минимальную величины (пользователи могут задавать подобные ограничения в диалоге настройки индикатора, на закладке Шкала). Программно это делается с помощью функции IndicatorSetDouble со следующим прототипом.
bool IndicatorSetDouble(ENUM_CUSTOMIND_PROPERTY_DOUBLE property, double value)
bool IndicatorSetDouble(ENUM_CUSTOMIND_PROPERTY_DOUBLE property, int modifier,
double value)
Функция задает для индикатора значение свойства типа double. Две формы потребовались потому, что некоторые свойства могут существовать во множественном числе, в частности горизонтальные уровни (о них речь пойдет чуть ниже). Доступные свойства собраны в перечислении ENUM_CUSTOMIND_PROPERTY_DOUBLE.
Идентификатор |
Описание |
---|---|
INDICATOR_MINIMUM |
Минимум по вертикальной оси |
INDICATOR_MAXIMUM |
Максимум по вертикальной оси |
INDICATOR_LEVELVALUE |
Значение горизонтального уровня (номер задается в параметре modifier) |
Фиксированный диапазон шкалы применяется во многих осцилляторных индикаторах, например, WPR. Далее мы покажем с ним пример, охватывающий все функции (свойства) из данного раздела.
В случае успешного выполнения функция возвращает true, в противном случае false.
Кроме управления шкалой индикаторы в подокне могут иметь, как мы уже поняли, горизонтальные уровни. Чтобы задать их количество и атрибуты применяется другая функция IndicatorSetInteger. Пользователь может выполнить аналогичные действия в диалоге настройки индикатора на закладке Уровни.
bool IndicatorSetInteger(ENUM_CUSTOMIND_PROPERTY_INTEGER property, int value)
bool IndicatorSetInteger(ENUM_CUSTOMIND_PROPERTY_INTEGER property, int modifier,
int value)
Функция также имеет две формы и позволяет задать для индикатора значение свойства типа int или эквивалентного ему (например, color или перечисление). Доступные свойства собраны в перечислении ENUM_CUSTOMIND_PROPERTY_INTEGER. Помимо свойств, связанных с уровнями, в нем присутствует свойство INDICATOR_DIGITS, являющее общим для индикаторов любых типов: его мы рассмотрим в следующем разделе.
Идентификатор |
Описание |
---|---|
INDICATOR_DIGITS |
Точность отображения значений индикатора (знаки после десятичной точки) |
INDICATOR_HEIGHT |
Фиксированная высота собственного окна индикатора в пикселях (команда препроцессора #property indicator_height) |
INDICATOR_LEVELS |
Количество горизонтальных уровней в окне индикатора |
INDICATOR_LEVELCOLOR |
Цвет линии уровня (имеет тип color, параметр modifier задает номер уровня) |
INDICATOR_LEVELSTYLE |
Стиль линии уровня (имеет тип ENUM_LINE_STYLE, параметр modifier задает номер уровня) |
INDICATOR_LEVELWIDTH |
Толщина линии уровня (1-5) (параметр modifier задает номер уровня) |
Уровни могут иметь текстовые метки. Для их назначения следует использовать функцию IndicatorSetString.
bool IndicatorSetString(ENUM_CUSTOMIND_PROPERTY_STRING property, string value)
bool IndicatorSetString(ENUM_CUSTOMIND_PROPERTY_STRING property, int modifier,
string value)
Перечисление ENUM_CUSTOMIND_PROPERTY_STRING содержит список строковых свойств индикаторов. Здесь особо следует отметить другое свойство, не относящееся к уровням, — INDICATOR_SHORTNAME: оно также является общим для всех индикаторов и будет рассмотрено в следующем разделе.
Идентификатор |
Описание |
---|---|
INDICATOR_SHORTNAME |
Публичный заголовок индикатора |
INDICATOR_LEVELTEXT |
Описание уровня (номер указывается в modifier) |
Все упомянутые функции для числовых типов int и double дублируются специальными директивами (ниже приведена сводная таблица).
Директивы для |
Функции-аналоги |
Тип |
Описание |
---|---|---|---|
indicator_levelN |
IndicatorSetDouble( |
double |
Значение для горизонтального уровня номер N на вертикальной оси |
indicator_levelcolor |
IndicatorSetInteger( |
color |
Цвет горизонтальных уровней (разный цвет по номеру можно задать только с помощью функции) |
indicator_levelwidth |
IndicatorSetInteger( |
int |
Толщина линий горизонтальных уровней в пикселях (разную толщину по номеру можно задать только с помощью функции) |
indicator_levelstyle |
IndicatorSetInteger( |
ENUM |
Стили линий горизонтальных уровней (разные стили по номеру можно задать только с помощью функции) |
indicator_minimum |
IndicatorSetDouble( |
double |
Фиксированное минимальное значение, нижнее ограничение шкалы по вертикальной оси |
indicator_maximum |
IndicatorSetDouble( |
double |
Фиксированное максимальное значение, верхнее ограничение шкалы по вертикальной оси |
Обратите внимание, что нумерация экземпляров свойств (модификаторов) при использовании директив #property начинается с 1 (единицы), в то время как функции используют нумерацию с 0 (нуля).
Внимательный читатель заметит, что для некоторых свойств не существует директив. К их числу относятся INDICATOR_LEVELTEXT, INDICATOR_SHORTNAME, INDICATOR_DIGITS. Предполагается, что данные свойства должны заполняться динамически из MQL-кода, в зависимости от входных переменных и графика, на котором размещен индикатор. INDICATOR_LEVELS задается опосредованно, за счет указания нескольких директив для уровней.
Наконец, отличительной чертой индикаторов в подокне является то, что программа может "заморозить" вертикальный размер своего окна.
Директива для |
Функция-аналог |
Описание |
---|---|---|
indicator_height |
IndicatorSetInteger( |
Фиксированная высота подокна индикатора в пикселях (пользователь не сможет изменить высоту) |
Фиксированная высота подокна обычно применяется только для управляющих панелей с элементами управления (кнопками, флагами, полями ввода), реализованными с помощью графических объектов.
Для функций установки свойств, к сожалению, не предусмотрено обратных (IndicatorGetInteger, IndicatorGetDouble, IndicatorGetString). Среди прочего это не позволяет, например, узнать количество и значения горизонтальных уровней, если их сменил пользователь.
В качестве примера работы с фиксированной шкалой и уровнями рассмотрим индикатор IndWPR.mq5. В нем воспользуемся стандартным алгоритмом WPR: на заданном количестве прошедших баров (период WPR) найдем максимумы H и минимумы L цены (то есть её размах). Затем вычислим отношение разницы текущей цены C и минимума L, C - L (или разницы -(H - C), со знаком минус) ко всему размаху, и приведем всё в диапазон от 0 до -100. Вот каноническая формула расчета WPR:
R% = (-(H – C) / (H – L)) * 100 |
В начале исходного кода добавим несколько директив. Помимо свойства расположения индикатора в собственном окне установим шкалу значений от 0 до -100.
#property indicator_separate_window
|
Для хранения значений и отображения достаточного одного буфера и одной линейной диаграммы.
#property indicator_buffers 1
|
В индикаторе WPR принято выделять два уровня: -20 и -80, как границы областей перекупленности и перепроданности, соответственно. Создадим для них пару горизонтальных линий.
#property indicator_level1 -20.0
|
Единственная входная переменная позволяет задать период расчета WPR.
input int WPRPeriod = 14; // Period |
Массив для буфера описывается на глобальном уровне и регистрируется в OnInit.
double WPRBuffer[];
|
Обработчик OnInit описан с типом void, что неявным образом подразумевает успешную инициализацию. Вместе с тем, если задан период меньше 1, это не позволит делать расчет, в связи с чем выдается предупреждение пользователю.
Для упрощения заголовка функции OnCalculate для индикаторов был подготовлен заголовочный файл IndCommon.mqh с двумя макросами, описывающими стандартные списки параметров обеих форм обработчика события.
#define ON_CALCULATE_STD_FULL_PARAM_LIST \
|
Теперь мы можем применять в этом и других индикаторах сжатое определение OnCalculate (при условии, что нас устраивают предложенные названия параметров в макросах).
#include <MQL5Book/IndCommon.mqh>
|
В начале OnCalculate делается проверка на возможность расчета при текущих величинах WPRPeriod и rates_total. Если данных недостаточно или период слишком маленький, возвращаем 0, из-за чего окно индикатора останется пустым.
Далее заполняем первые несколько баров, для которых невозможно посчитать WPR заданного периода, пустым значением.
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
|
Наконец, запускаем рабочий цикл с расчетом по формуле WPR и складываем результаты в буфер. Обратите внимание, что последний бар обновляется на каждом тике: это достигается за счет того, что цикл начинается с prev_calculated - 1.
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
|
Для поиска индексов максимальных high и минимальных low применяются функции ArrayMaximum и ArrayMinimum.
Посмотрим, как индикатор выглядит в собственном окне.
Индикатор WPR
В следующих разделах продолжим улучшать данный индикатор, постепенно задействуя другие общеупотребительные свойства.