Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5

Тимур Машнин

Создание пользовательских индикаторов и советников для торговой платформы MetaTrader 5 с использованием языка программирования MQL5.

Оглавление

Функция OnInit ()

Функция OnInit () вызывается сразу после загрузки индикатора и соответственно используется для его инициализации.

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

Давайте разберем некоторые из этих пунктов более подробно.

Как уже было показано, привязка массивов к буферам индикатора осуществляется с помощью функции SetIndexBuffer:

bool SetIndexBuffer (

int index, // индекс буфера

double buffer [], // массив

ENUM_INDEXBUFFER_TYPE data_type // что будем хранить

);

Где data_type может быть INDICATOR_DATA (данные индикатора для отрисовки, по умолчанию, можно не указывать), INDICATOR_COLOR_INDEX (цвет индикатора), INDICATOR_CALCULATIONS (буфер промежуточных расчетов индикатора).

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

Каждый индекс массива типа INDICATOR_COLOR_INDEX соответствует индексу массива типа INDICATOR_DATA, а значение индекса массива типа INDICATOR_COLOR_INDEX определяет цвет отображения индекса массива типа INDICATOR_DATA.

Значение индекса массива типа INDICATOR_COLOR_INDEX, при его установке, берется из свойства #property indicator_colorN как индекс цвета в строке.

Индекс буфера типа INDICATOR_COLOR_INDEX должен следовать за индексом буфера типа INDICATOR_DATA.

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

bool ArraySetAsSeries (

const void& array [], // массив по ссылке

bool flag // true означает обратный порядок индексации

);

При применении функции ArraySetAsSeries физическое хранение данных массива не меняется, в памяти массив, как и прежде, хранится в порядке от первого значения до последнего значения.

Функция ArraySetAsSeries меняет лишь программный доступ к элементам массива — от последнего элемента массива к первому элементу массива.

В функции OnInit () также может осуществляться проверка входных параметров на корректность, так как пользователь может ввести все, что угодно.

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

Например, для индикатора ADX это выглядит так:

// — — check for input parameters

if (InpPeriodADX> =100 InpPeriodADX <=0)

{

ExtADXPeriod=14;

printf («Incorrect value for input variable Period_ADX=%d. Indicator will use value=%d for calculations.», InpPeriodADX, ExtADXPeriod);

}

else ExtADXPeriod=InpPeriodADX;

здесь ExtADXPeriod — глобальная переменная, а InpPeriodADX — входной параметр.

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

При этом такой символ может определяться пользователем.

В функции OnInit () также полезно проверить этот входной параметр на корректность.

Пусть определен входной параметр:

input string symbol=""; // символ

Объявим глобальную переменную:

string name=symbol;

В функции OnInit () произведем проверку:

// — — удалим пробелы слева и справа

StringTrimRight (name);

StringTrimLeft (name);

// — — если после этого длина строки name нулевая

if (StringLen (name) ==0)

{

// — — возьмем символ с графика, на котором запущен индикатор

name=_Symbol;

}

Программная установка свойств индикатора осуществляется с помощью функций IndicatorSetDouble, IndicatorSetInteger, IndicatorSetString, PlotIndexSetDouble, PlotIndexSetInteger, PlotIndexSetString.

Функция IndicatorSetDouble позволяет программным способом определять такие свойства индикатора как indicator_minimum, indicator_maximum и indicator_levelN, например:

IndicatorSetDouble (INDICATOR_LEVELVALUE, 0, 50)

является аналогом:

property indicator_level1 50

Функция IndicatorSetInteger позволяет программным способом определять такие свойства индикатора как indicator_height, indicator_levelcolor, indicator_levelwidth, indicator_levelstyle.

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

Свойства индикатора:

//#property indicator_level1 30

//#property indicator_level2 70

//#property indicator_levelcolor Red

//#property indicator_levelstyle STYLE_SOLID

//#property indicator_levelwidth 1

Заменяем на код:

IndicatorSetInteger (INDICATOR_LEVELS,2);

IndicatorSetDouble (INDICATOR_LEVELVALUE,0,30);

IndicatorSetDouble (INDICATOR_LEVELVALUE,1,70);

IndicatorSetInteger (INDICATOR_LEVELCOLOR,0,0xff0);

IndicatorSetInteger (INDICATOR_LEVELCOLOR,1,0xff0);

IndicatorSetInteger (INDICATOR_LEVELSTYLE,0,STYLE_SOLID);

IndicatorSetInteger (INDICATOR_LEVELSTYLE,1,STYLE_SOLID);

IndicatorSetInteger (INDICATOR_LEVELWIDTH,0,1);

IndicatorSetInteger (INDICATOR_LEVELWIDTH,1,1);

Функция IndicatorSetInteger также позволяет определить точность индикатора, например:

IndicatorSetInteger (INDICATOR_DIGITS,2);

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

Для функции IndicatorSetString нет соответствующих ей свойств индикатора.

С помощью функции IndicatorSetString можно определить короткое наименование индикатора, например для индикатора MACD:

IndicatorSetString (INDICATOR_SHORTNAME,«MACD (»+string (InpFastEMA) +»,»+string (InpSlowEMA) +»,»+string (InpSignalSMA) +»)»);

Соответственно имя индикатора будет отображаться в окне индикатора как:

Кроме того, функция IndicatorSetString позволяет установить подписи к уровням индикатора, например для индикатора RSI:

IndicatorSetString (INDICATOR_LEVELTEXT, 0,«Oversold»);

IndicatorSetString (INDICATOR_LEVELTEXT, 1,«Overbought»)

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

Диаграмма индикатора рисуется от одного непустого значения до другого непустого значения индикаторного буфера, пустые значения пропускаются. Чтобы указать, какое значение следует считать «пустым», необходимо определить это значение в свойстве PLOT_EMPTY_VALUE. Например, если индикатор должен рисоваться по ненулевым значениям, то нужно задать нулевое значение в качестве пустого значения буфера индикатора:

PlotIndexSetDouble (индекс_построения, PLOT_EMPTY_VALUE,0);

Функция PlotIndexSetInteger позволяет программным способом, динамически, задавать такие свойства диаграммы индикатора, как код стрелки для стиля DRAW_ARROW, смещение стрелок по вертикали для стиля DRAW_ARROW, количество начальных баров без отрисовки и значений в DataWindow, тип графического построения, признак отображения значений построения в окне DataWindow, сдвиг графического построения индикатора по оси времени в барах, стиль линии отрисовки, толщина линии отрисовки, количество цветов, индекс буфера, содержащего цвет отрисовки.

Давайте разберем каждое из этих свойств по порядку на примере индикатора Custom Moving Average.

Изменим свойство indicator_type1 индикатора Custom Moving Average:

#property indicator_type1 DRAW_ARROW

В функции OnInit () добавим вызов функции PlotIndexSetInteger, определяя различный код стрелки для стиля DRAW_ARROW:

PlotIndexSetInteger (0,PLOT_ARROW,2);

PlotIndexSetInteger (0,PLOT_ARROW,3);

PlotIndexSetInteger (0,PLOT_ARROW,4);

PlotIndexSetInteger (0,PLOT_ARROW,5);

PlotIndexSetInteger (0,PLOT_ARROW,6);

PlotIndexSetInteger (0,PLOT_ARROW,7);

PlotIndexSetInteger (0,PLOT_ARROW,8);

PlotIndexSetInteger (0,PLOT_ARROW,11);

PlotIndexSetInteger (0,PLOT_ARROW,12);

PlotIndexSetInteger (0,PLOT_ARROW,14);

PlotIndexSetInteger (0,PLOT_ARROW,15);

И так далее. Я думаю, этого будет достаточно для демонстрации этой опции.

В функции OnInit () добавим вызов функции PlotIndexSetInteger, определяя смещение стрелок по вертикали для стиля DRAW_ARROW:

PlotIndexSetInteger (0,PLOT_ARROW_SHIFT,0);

PlotIndexSetInteger (0,PLOT_ARROW_SHIFT,100)

В результате диаграмма индикатора сдвинулась вниз.

В индикаторе Custom Moving Average для определения количества начальных баров без отрисовки и значений в DataWindow используется вызов функции PlotIndexSetInteger:

PlotIndexSetInteger (0,PLOT_DRAW_BEGIN, InpMAPeriod);

где InpMAPeriod — период скользящей средней.

Идентификатор свойства PLOT_DRAW_TYPE функции PlotIndexSetInteger позволяет программным способом задать свойство индикатора indicator_typeN, например:

PlotIndexSetInteger (0, PLOT_DRAW_TYPE, DRAW_ARROW);

Причем, если одновременно задано свойство indicator_typeN и сделан вызов функции PlotIndexSetInteger с идентификатором PLOT_DRAW_TYPE — действовать будет тип диаграммы, заданный функцией PlotIndexSetInteger.

Убрать отображение текущих значений диаграммы индикатора в окне DataWindow при наведении курсора мышки можно с помощью вызова функции PlotIndexSetInteger с идентификатором PLOT_SHOW_DATA:

PlotIndexSetInteger (0, PLOT_SHOW_DATA, false);

В индикаторе Custom Moving Average для определения сдвига графического построения индикатора по оси времени в барах используется вызов функции PlotIndexSetInteger:

PlotIndexSetInteger (0,PLOT_SHIFT, InpMAShift);

При InpMAShift=0:

При InpMAShift=10:

Такой сдвиг делается для имитации предсказательности индикатора.

Идентификатор свойства PLOT_LINE_STYLE функции PlotIndexSetInteger позволяет программным способом задать свойство индикатора indicator_styleN, стиль линии отрисовки, например:

PlotIndexSetInteger (0, PLOT_LINE_STYLE, STYLE_DASHDOT);

Идентификатор свойства PLOT_LINE_WIDTH функции PlotIndexSetInteger позволяет программным способом задать свойство индикатора indicator_widthN, толщину линии отрисовки, например:

PlotIndexSetInteger (0, PLOT_LINE_WIDTH, 2);

Программным способом задать свойство индикатора indicator_colorN позволяет вызов функции PlotIndexSetInteger с идентификаторами PLOT_COLOR_INDEXES и PLOT_LINE_COLOR, например:

#property indicator_color1 clrGreen, clrRed

Или

PlotIndexSetInteger (0,PLOT_COLOR_INDEXES,2);

PlotIndexSetInteger (0,PLOT_LINE_COLOR,0,clrGreen);

PlotIndexSetInteger (0,PLOT_LINE_COLOR,1,clrRed);

Функция PlotIndexSetString позволяет программным способом задать свойство индикатора indicator_labelN. Например, для индикатора MACD это будет выглядеть следующим образом:

#property indicator_label1 «MACD»

#property indicator_label2 «Signal»

Или

PlotIndexSetString (0, PLOT_LABEL, «MACD»);

PlotIndexSetString (1, PLOT_LABEL, «Signal»);

Рассмотренные выше функции программной установки свойств индикатора можно конечно вызывать и в функции обратного вызова OnCalculate, но глубокого смысла в этом нет, так как они не могут быть применены только к части диаграммы индикатора — они применяются сразу ко всей диаграмме индикатора. Поэтому для экономии ресурсов лучше всего вызывать эти функции в функции обратного вызова OnInit ().

Смотрите также

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