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

Изменить размер шрифта:

Рассмотрим другую реализацию вычисления размера данных, которые необходимо рассчитать в вызове функции OnCalculate ().

Для индикатора MACD это реализовано следующим образом:

// – - we can copy not all data

int to_copy;

if (prev_calculated> rates_total || prev_calculated <0) to_copy=rates_total;

else

{

to_copy=rates_total-prev_calculated;

if (prev_calculated> 0) to_copy++;

}

Опять же, судя по справочнику, здесь будет работать только код:

to_copy=rates_total-prev_calculated;

if (prev_calculated> 0) to_copy++;

Т.е. при загрузке индикатора to_copy=rates_total, а затем to_copy=1.

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

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

Вот как это реализовано для используемого индикатора ADX:

// – - заполняем часть массива ADXBuffer значениями из индикаторного буфера под индексом 0

if (CopyBuffer (ind_handle,0,0,amount, adx_values) <0)

{

// – - если копирование не удалось, сообщим код ошибки

PrintFormat («Не удалось скопировать данные из индикатора iADX, код ошибки %d», GetLastError ());

// – - завершим с нулевым результатом – это означает, что индикатор будет считаться нерассчитанным

return (false);

}

// – - заполняем часть массива DI_plusBuffer значениями из индикаторного буфера под индексом 1

if (CopyBuffer (ind_handle,1,0,amount, DIplus_values) <0)

{

// – - если копирование не удалось, сообщим код ошибки

PrintFormat («Не удалось скопировать данные из индикатора iADX, код ошибки %d», GetLastError ());

// – - завершим с нулевым результатом – это означает, что индикатор будет считаться нерассчитанным

return (false);

}

// – - заполняем часть массива DI_plusBuffer значениями из индикаторного буфера под индексом 2

if (CopyBuffer (ind_handle,2,0,amount, DIminus_values) <0)

{

// – - если копирование не удалось, сообщим код ошибки

PrintFormat («Не удалось скопировать данные из индикатора iADX, код ошибки %d», GetLastError ());

// – - завершим с нулевым результатом – это означает, что индикатор будет считаться нерассчитанным

return (false);

}

Здесь ind_handle – это хэндл индикатора ADX, второй параметр – индекс буфера используемого индикатора, из которого производится копирование, третий параметр – стартовая позиция, откуда начинается копирование. Здесь мы помним, что копирование идет от конца к началу, и поэтому нулевая стартовая позиция – это самые свежие данные. Четвертый параметр – это наш размер данных, которые необходимо рассчитать в вызове функции OnCalculate (), и последний параметр – это обычно динамический массив, привязанный к буферу индикатора, куда производится копирование.

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

Это определяется вызовом функции SetIndexBuffer в используемом индикаторе. Например, для индикатора ADX:

SetIndexBuffer (0,ExtADXBuffer);

SetIndexBuffer (1,ExtPDIBuffer);

SetIndexBuffer (2,ExtNDIBuffer);

Отсюда нулевой индекс связан с буфером самого индикатора ADX, 1 индекс связан с буфером индикатора направленности +DI, 2 индекс связан с буфером индикатора направленности —DI.

Таким образом, для связывания второго параметра функции CopyBuffer с индексом буфера используемого индикатора, нужно знать код используемого индикатора.

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

for (int i=start; i 

{

}

Здесь start – это стартовая позиция, с которой начинается заполнение буфера индикатора.

При значении prev_calculated=0, значение start это, как правило, 0, при значении prev_calculated= rates_total, зачение start=prev_calculated-1.

Если же перед реализацией цикла с помощью функции ArraySetAsSeries поменять порядок доступа к массивам буферов индикатора и цен, тогда цикл примет вид:

for (int i=start; i> =0;i – ) {

}

Где start=rates_total-1, если prev_calculated=0, и start=0, если prev_calculated= rates_total.

Пример создания индикатора

В качестве примера рассмотрим создание индикатора, который будет реализовывать форекс стратегию «Impulse keeper» (Ловец импульсов) и показывать на графике сигналы на покупку и продажу.

В данной стратегии применяются четыре индикатора:

Экспоненциальная скользящая средняя с периодом 34 для цены High.

Экспоненциальная скользящая средняя с периодом 34 для цены Low.

Экспоненциальная скользящая средняя с периодом 125 для цены Close.

Parabolic SAR.

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

Сигналы на покупку и продажу в данной стратегии описываются следующим образом.

Сигнал на покупку: зеленая свеча закрывается выше EMA34 High и EMA34 Low, зеленая свеча выше EMA125 и Parabolic SAR.

Сигнал на продажу: красная свеча закрывается ниже EMA34 Low и EMA34 High, красная свеча ниже EMA125 и Parabolic SAR.

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

Откроем MQL5 редактор и в меню File выберем New. В диалоговом окне MQL Wizard выберем Custom Indicator и нажмем кнопку Далее. Введем имя индикатора Impulse keeper, имя автора и ссылку и нажмем два раза Далее, а затем Готово.

В результате мы получим код индикатора с пустыми функциями OnInit и OnCalculate.

Создание индикатора начнем с определения его свойств.

Количество буферов индикатора определим 8.

2 буфера – данные и цвет, для сигналов на покупку. 2 буфера – данные и цвет, для сигналов на продажу. И 4 буфера промежуточных вычислений для скопированных данных из индикаторов EMA34 Low, EMA34 High, EMA125 и Parabolic SAR:

#property indicator_buffers 8

Определим число графических построений – 2, одно построение для сигналов на покупку и другое построение для сигналов на продажу:

#property indicator_plots 2

Определим цвет и тип для обоих графических построений:

#property indicator_color1 clrGreen, clrBlack

#property indicator_type1 DRAW_COLOR_ARROW

#property indicator_color2 clrRed, clrBlack

#property indicator_type2 DRAW_COLOR_ARROW

Далее определим массивы буферов индикатора и хэндлы используемых индикаторов:

double IKBuyBuffer [];

double ColorIKBuyBuffer [];

double IKSellBuffer [];

double ColorIKSellBuffer [];

double EMA34HBuffer [];

double EMA34LBuffer [];

double EMA125Buffer [];

double PSARBuffer [];

int EMA34HHandle;

int EMA34LHandle;

int EMA125Handle;

int PSARHandle;

В функции OnInit () для первого графического построения определим тип стрелки – стрелка вверх, пустое значение и сдвиг:

int OnInit ()

{

PlotIndexSetInteger (0,PLOT_ARROW,233);

PlotIndexSetDouble (0,PLOT_EMPTY_VALUE,0);

PlotIndexSetInteger (0,PLOT_ARROW_SHIFT, -10);

Для второго графического построения определим тип стрелки – стрелка вниз, пустое значение и сдвиг:

PlotIndexSetInteger (1,PLOT_ARROW,234);

Оригинальный текст книги читать онлайн бесплатно в онлайн-библиотеке Knigger.com