– перед переинициализацией в связи со сменой символа или периода графика, к которому прикреплена mql5-программа;
– перед переинициализацией в связи со сменой входных параметров;
– перед выгрузкой mql5-программы.
Так как функция OnDeinit вызывается при деинициализации, то ее основное предназначение, это освобождение занимаемых ресурсов.
Под освобождением занимаемых ресурсов для индикатора подразумевается очищение графика символа от дополнительных графических объектов.
То есть помимо диаграммы индикатора, мы можем присоединять к графику символа различные объекты – линии, графические фигуры треугольник, прямоугольник и эллипс, знаки, подписи и др. Об этом мы поговорим позже.
Соответственно при деинициализации индикатора было бы неплохо все это убрать с графика символа.
Первым делом здесь используется функция Comment, которая выводит комментарий, определенный пользователем, в левый верхний угол графика:
void Comment (
argument, // первое значение
…// последующие значения
);
Для очистки от комментариев используются пустые комментарии:
Comment (»»);
Далее используется функция ObjectDelete, которая удаляет объект с указанным именем с указанного графика:
bool ObjectDelete (
long chart_id, // chart identifier
string name // object name
);
Позже мы продемонстрируем применение этих функций.
Функция OnCalculate
Функция OnCalculate вызывается клиентским терминалом при поступлении нового тика по символу, для которого рассчитывается индикатор.
Хотя функция OnCalculate имеет два вида – для индикатора, который может быть рассчитан на основе только одной из ценовых таймсерий:
int OnCalculate (const int rates_total, // размер массива price []
const int prev_calculated, // обработано баров на предыдущем вызове
const int begin, // откуда начинаются значимые данные
const double& price [] // массив для расчета
);
и для индикатора, который рассчитывается с использованием нескольких ценовых таймсерий:
int OnCalculate (const int rates_total, // размер входных таймсерий
const int prev_calculated, // обработано баров на предыдущем вызове
const datetime& time [], // Time
const double& open [], // Open
const double& high [], // High
const double& low [], // Low
const double& close [], // Close
const long& tick_volume [], // Tick Volume
const long& volume [], // Real Volume
const int& spread [] // Spread
);
Здесь мы будем пользоваться полной версией функции OnCalculate как наиболее гибкой и предоставляющей наибольшие возможности.
Единственное, что мы должны отметить об усеченной функции OnCalculate , это то, что она имеет опцию использования в качестве массива price [] рассчитанного буфера другого индикатора.
Продемонстрируем это на примере индикатора MACD и индикатора Custom Moving Average, который использует как раз усеченную функцию OnCalculate .
Присоединим сначала индикатор MACD к графику символа, а затем перетащим индикатор MA в окно индикатора MACD:
Затем опять перетащим индикатор Custom Moving Average в окно индикатора MACD, при этом снова откроется окно параметров индикатора Custom Moving Average:
В списке выбора, что использовать в качестве массива price [], будут пункты First Indicator’s Data и Previous Indicator’s Data.
Здесь пункт First Indicator’s Data означает, что в качестве массива price [] будет использоваться массив ExtMacdBuffer буфера индикатора MACD, а пункт Previous Indicator’s Data означает, что в качестве массива price [] будет использоваться массив ExtLineBuffer буфера индикатора MA.
Если в функцию OnCalculate индикатора Custom Moving Average добавить:
Print («begin», begin);
То при выборе First Indicator’s Data будет выводиться:
А при выборе Previous Indicator’s Data будет выводиться:
В первом случае, begin=0, так как для буфера ExtMacdBuffer индикатора MACD функция PlotIndexSetInteger с параметром PLOT_DRAW_BEGIN не вызывается. А во втором случае, begin=12, так как для буфера ExtLineBuffer индикатора MA вызывается функция PlotIndexSetInteger:
PlotIndexSetInteger (0,PLOT_DRAW_BEGIN, InpMAPeriod-1+begin);
Тут говорится о том, что массив буфера ExtLineBuffer индикатора MA заполняется, начиная с InpMAPeriod-1 бара, соответственно значение переменной begin функции OnCalculate индикатора Custom Moving Average будет также равно InpMAPeriod-1.
Вернемся к полной версии функции OnCalculate .
Как правило, код функции OnCalculate проектируется таким образом, чтобы при загрузке индикатора и первом вызове функции OnCalculate , буфера индикатора были рассчитаны на основе всей загруженной ценовой истории, а при последующем поступлении нового тика и вызове функции OnCalculate , рассчитывалось бы только одно новое значение, которое добавляется в конец массива буфера индикатора.
Но в начале кода функции OnCalculate нужно конечно проверить, достаточный ли размер ценовой истории был загружен при загрузке индикатора.
Для этого проверяется значение переменной rates_total – размер входных таймсерий.
Как правило, в качестве порогового значения для rates_total принимается значение периода индикатора, например для индикатора ADX:
// – - checking for bars count