Шрифт:
SetIndexBuffer (2,ExtFastMaBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer (3,ExtSlowMaBuffer, INDICATOR_CALCULATIONS);
И в эти массивы производится копирование буфера индикатора Moving Average на основе его хэндлов:
if (CopyBuffer (ExtFastMaHandle,0,0,to_copy, ExtFastMaBuffer) <=0)
{
Print («Getting fast EMA is failed! Error», GetLastError );
return (0);
}
if (CopyBuffer (ExtSlowMaHandle,0,0,to_copy, ExtSlowMaBuffer) <=0)
{
Print («Getting slow SMA is failed! Error», GetLastError );
return (0);
}
Если убрать привязку массивов ExtFastMaBuffer [] и ExtSlowMaBuffer [] к буферам индикатора, тогда клиентский терминал выдаст ошибку:
Происходит это потому, что при загрузке индикатора значение to_copy равно размеру ценовой истории, а дальше to_copy=1 и производится частичное копирование в массивы ExtFastMaBuffer [] и ExtSlowMaBuffer [], при этом их размеры становятся равны 1.
В этом случае применением функции ArrayResize проблему не решить, так как функция CopyBuffer все равно будет уменьшать размер массива до 1.
Можно конечно использовать еще один массив-посредник, в который копировать один элемент. И уже из этого массива-посредника производить копирование в промежуточный массив, но проще всего, конечно, просто привязать промежуточный массив к буферу индикатора.
Функции OnInit , OnDeinit , OnCalculate
Как уже говорилось, функции OnInit , OnDeinit , OnCalculate вызываются клиентским терминалом при наступлении определенных событий.
Функция 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;