Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5. Издание 2-е, исправленное и дополненное. Тимур Машнин
Чтение книги онлайн.

Читать онлайн книгу Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5. Издание 2-е, исправленное и дополненное - Тимур Машнин страница 5

СКАЧАТЬ представляющие буфера индикатора, используются не для построения диаграмм индикатора, а для промежуточных вычислений.

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

      SetIndexBuffer (3,ExtPDBuffer, INDICATOR_CALCULATIONS);

      SetIndexBuffer (4,ExtNDBuffer, INDICATOR_CALCULATIONS);

      SetIndexBuffer (5,ExtTmpBuffer, INDICATOR_CALCULATIONS);

      Такой массив определяется с помощью третьего параметра INDICATOR_CALCULATIONS.

      Это дает следующее:

      Все дело в частичном заполнении массива.

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

      Рассмотрим это на примере индикатора ADX.

      В редакторе MQL5, в окне Navigator (Навигатор), в разделе Indicators-> Examples выберем и откроем исходный код индикатора ADX.

      В функции OnInit () закомментируем строку:

      // SetIndexBuffer (5,ExtTmpBuffer, INDICATOR_CALCULATIONS);

      Теперь массив ExtTmpBuffer является просто динамическим массивом.

      Откомпилируем код индикатора и присоединим индикатор к графику в терминале MetaTrader 5.

      В результате Терминал выдаст ошибку.

      array out of range

      Это произошло потому, что мы перед заполнением данного массива значениями не указали его размера и не зарезервировали под него память.

      Так что его размер был равен нулю, когда мы попытались в него что-то записать.

      Статическим мы этот массив сделать тоже не можем, т.е. объявить его сразу с указанием размера, так как значения такого промежуточного массива рассчитываются в функции обратного вызова OnCalculate на основе загруженной в функцию OnCalculate истории цен, а именно массивов open [], high [], low [], и close [].

      Но точный размер массивов open [], high [], low [], и close [] неизвестен, он обозначается лишь переменной rates_total.

      Хорошо, но мы можем в функции OnCalculate применить функцию ArrayResize, чтобы установить размер массива:

      ArrayResize (ExtTmpBuffer, rates_total);

      Передав в функцию в качестве аргумента переменную rates_total – количество баров на графике, на котором запущен индикатор.

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

      Но дело в том, что в функции OnCalculate мы сначала рассчитываем индикатор для всей ценовой истории, т.е. для rates_total значений, а затем при поступлении нового тика по символу индикатора, и соответственно вызове функции OnCalculate, мы рассчитываем значение индикатора для этого нового тика по символу и записываем новое значение индикатора в его массив буфера.

      Чтобы это реализовать с промежуточным массивом, нужно внимательно следить за его размером и записывать новое значение в конец массива.

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

      Аналогичная ситуация возникает, когда значения таких промежуточных массивов заполняются СКАЧАТЬ