Основные характеристики индикаторов

Индикатор реализует некий расчетный алгоритм, применяемый по барам к заданной исходной таймсерии или нескольким таймсериям. Все такие временные ряды являются собственными массивами (см. функцию ArrayIsSeries) терминала: он сам распределяет под них память и добавляет новые элементы по мере формирования новых баров. Среди таких массивов основополагающую роль играют, разумеется, массивы с котировками символов на разных таймфреймах: их терминал также заполняет сам. Однако запущенные индикаторы способны существенно расширить набор таймсерий, доступных для анализа.

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

Точкой входа в расчетную часть индикатора является функция OnCalculate — обработчик одноименного события. В разделе Обзор функций обработки событий мы уже упоминали данную функцию: одного её наличия в исходном коде достаточно, чтобы MQL-программа стала восприниматься терминалом как индикатор. Функция OnCalculate будет подробно описана в следующем разделе. В частности, главной особенностью OnCalculate является наличие двух разных форм. Программисту требуется определиться с выбором в пользу одного или другого варианта в самом начале проектирования индикатора, потому что это определяет назначение и возможные сценарии использования.

Функция OnCalculate является не единственной отличительной чертой индикатора. Кроме неё исключительно для индикаторов предназначена группа специальных директив препроцессора #property — мы рассмотрим их поэтапно в нескольких соответствующих разделах этой Главы. Напомним, что ранее мы встречались с некоторыми Общими свойствами программ, и такие директивы, разумеется, тоже применимы к индикаторам.

Как известно пользователям MetaTrader 5, в каждый индикатор заложен способ отображения его графических построений (таймсерий): либо в главном окне, в котором выводятся котировки, либо в отдельной панели (подокне). Такая панель создается в нижней части окна при набрасывании на график конкретного индикатора (или группы индикаторов), если он спроектирован для работы в подокне. Например, стандартный индикатор Moving Average (MA) рисуется вместе с котировками, а Williams Percent Range (WPR) — в отдельном подокне.

С точки зрения разработчика это означает, что следует изначально определить, будет ли индикатор предназначен для показа на главном окне или в подокне, потому что совместить эти два режима нельзя. Более того, эта характеристика, так же как и количество индикаторных буферов могут задаваться лишь однажды с помощью директив #property (см. разделы Два типа индикаторов и Настройка количества буферов и графических построений), и изменить их затем с помощью вызовов функций MQL5 API не удастся — таких функций просто не предусмотрено. В отличие от этих неизменяемых атрибутов, большинство прочих свойств индикаторов может динамически подстраиваться специальными функциями. Таким образом, по мере изучения технических аспектов программирования индикаторов, мы сможем установить соответствия между свойствами #property и функциями MQL5.

Также в индикаторах обычно реализуются обработчики OnInit и OnDeinit (см. раздел Опорные события индикаторов и советников). OnInit особенно важен для назначения массивов, которые будут выполнять роль индикаторных буферов, то есть аккумулировать результаты промежуточных и окончательных расчетов, видимых пользователю и доступных другим программам, таким как советники.

Индикатор относится к числу интерактивных MQL-программ, которые способны, при необходимости, работать с событиями таймера (OnTimer) и изменениями графика (OnChartEvent), производимыми пользователем или другими программами. Эти технические возможности являются опциональными для индикаторов и основываются на очереди событий графика, а потому будут рассмотрены отдельно, в главе, посвященной графикам.