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

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

СКАЧАТЬ соответственно значение переменной begin функции OnCalculate индикатора Custom Moving Average будет также равно InpMAPeriod-1.

      Вернемся к полной версии функции OnCalculate ().

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

      Но в начале кода функции OnCalculate () нужно конечно проверить, достаточный ли размер ценовой истории был загружен при загрузке индикатора.

      Для этого проверяется значение переменной rates_total – размер входных таймсерий.

      Как правило, в качестве порогового значения для rates_total принимается значение периода индикатора, например для индикатора ADX:

      // – - checking for bars count

      if (rates_total <ExtADXPeriod)

      return (0);

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

      // – - узнаем количество рассчитанных значений в индикаторе

      int calculated=BarsCalculated (handle);

      if (calculated <=0)

      {

      PrintFormat («BarsCalculated () вернул %d, код ошибки %d», calculated, GetLastError ());

      return (0);

      }

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

      В качестве примера, разберем блок кода, который приводится в справочнике, в разделе Технические индикаторы:

      int OnCalculate (const int rates_total,

      const int prev_calculated,

      const datetime &time [],

      const double &open [],

      const double &high [],

      const double &low [],

      const double &close [],

      const long &tick_volume [],

      const long &volume [],

      const int &spread [])

      {

      // – - количество копируемых значений из индикатора

      int values_to_copy;

      // – - узнаем количество рассчитанных значений в индикаторе

      int calculated=BarsCalculated (handle);

      if (calculated <=0)

      {

      PrintFormat («BarsCalculated () вернул %d, код ошибки %d», calculated, GetLastError ());

      return (0);

      }

      // – - если это первый запуск вычислений нашего индикатора или изменилось количество значений в индикаторе

      // – - или если необходимо рассчитать индикатор для двух или более баров (значит что-то изменилось в истории)

      if (prev_calculated==0 || calculated!=bars_calculated || rates_total> prev_calculated+1)

      {

      // – - если массив больше, чем значений в индикаторе на паре symbol/period, то копируем не все

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

      if (calculated> rates_total) values_to_copy=rates_total;

      else values_to_copy=calculated;

      }

      else

      {

      // – - значит наш индикатор рассчитывается не в первый раз и с момента последнего вызова OnCalculate ())

      // – СКАЧАТЬ