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

Книгу можно купить на ЛитРес.
Всего за 490 руб. Купить полную версию
Шрифт
Фон

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 ())

//  - для расчета добавилось не более одного бара

values_to_copy= (rates_total-prev_calculated) +1;

}


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

bars_calculated=calculated;

//  - вернем значение prev_calculated для следующего вызова

return (rates_total);

}

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

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

Таким образом, при загрузке индикатора prev_calculated=0, а при каждом следующем поступлении нового тика prev_calculated= rates_total.

Переменная prev_calculated также обнуляется терминалом, если вдруг изменилось значение переменной rates_total.

Переменная bars_calculated  предыдущее количество рассчитанных данных для запрашиваемого индикатора, на основе которого рассчитывается данный индикатор.

Таким образом, первая проверка здесь:

prev_calculated==0  индикатор только что загрузился или изменилась ценовая история.

calculated!=bars_calculated  изменилось количество рассчитанных данных для запрашиваемого индикатора.

rates_total> prev_calculated+1  необходимо рассчитать индикатор для двух или более баров (значит, что-то изменилось в истории).

Последнее условие вступает в противоречие с утверждением справочника:

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

Если изменилась история, тогда сработает проверка prev_calculated==0 и проверка последнего условия будет излишней.

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

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

values_to_copy= (rates_total-prev_calculated) +1;

Опять же, тут есть излишний код, так как, судя по справочнику, переменная prev_calculated может принимать значение либо 0, либо rates_total.

Поэтому, values_to_copy=1.

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

Рассмотрим другую реализацию вычисления размера данных, которые необходимо рассчитать в вызове функции 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 ());

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

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке

Скачать книгу

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

fb2.zip txt txt.zip rtf.zip a4.pdf a6.pdf mobi.prc epub ios.epub fb3