- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5. Издание 2-е, исправленное и дополненное - Тимур Машнин
Шрифт:
Интервал:
Закладка:
Вернемся к полной версии функции OnCalculate ().
Как правило, код функции OnCalculate () проектируется таким образом, чтобы при загрузке индикатора и первом вызове функции OnCalculate (), буфера индикатора были рассчитаны на основе всей загруженной ценовой истории, а при последующем поступлении нового тика и вызове функции OnCalculate (), рассчитывалось бы только одно новое значение, которое добавляется в конец массива буфера индикатора.
Но в начале кода функции OnCalculate () нужно конечно проверить, достаточный ли размер ценовой истории был загружен при загрузке индикатора.
Для этого проверяется значение переменной rates_total — размер входных таймсерий.
Как правило, в качестве порогового значения для rates_total принимается значение периода индикатора, например для индикатора ADX, это rates_total <ExtADXPeriod.
Если же в расчете буфера индикатора участвует хэндл другого индикатора, тогда проверяется количество рассчитанных данных для запрашиваемого индикатора.
С помощью функции BarsCalculated, которая принимает в качестве аргумента хэндл индикатора.
После проверки первоначальной загруженной истории для расчетов, вычисляется размер данных, которые необходимо рассчитать в этом вызове функции OnCalculate ().
В качестве примера, разберем блок кода функции OnCalculate, который приводится в справочнике, в разделе Технические индикаторы.
Здесь переменная 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 это реализовано следующим образом.
Опять же, судя по справочнику, здесь будет работать только код:
to_copy=rates_total-prev_calculated;
if (prev_calculated> 0) to_copy++;
Т.е. при загрузке индикатора to_copy=rates_total, а затем to_copy=1.
После вычисления размера данных, которые необходимо рассчитать в вызове функции OnCalculate (), производится их вычисление и заполнение ими буферов индикатора.
Если индикатор рассчитывается на основе хэндла другого индикатора, тогда производится копирование из буферов используемого индикатора в динамические массивы данного индикатора.
Вот как это реализовано в справочнике в примере к функции iADX, где используется индикатор ADX.
Здесь ind_handle — это хэндл индикатора ADX, второй параметр — индекс буфера используемого индикатора, из которого производится копирование, третий параметр — стартовая позиция, откуда начинается копирование.
Здесь мы помним, что копирование идет от конца к началу, и поэтому нулевая стартовая позиция — это самые свежие данные.
Четвертый параметр — это наш размер данных, которые необходимо рассчитать в вызове функции OnCalculate (), и последний параметр — это обычно динамический массив, привязанный к буферу индикатора, куда производится копирование.
Тут есть вопрос, как связать второй параметр функции CopyBuffer с индексом буфера используемого индикатора.
Это определяется вызовом функции SetIndexBuffer в используемом индикаторе.
Например, для индикатора ADX.
Здесь нулевой индекс связан с буфером самого индикатора ADX, 1 индекс связан с буфером индикатора направленности +DI, 2 индекс связан с буфером индикатора направленности — DI.
Таким образом, для связывания второго параметра функции CopyBuffer с индексом буфера используемого индикатора, нужно знать код используемого индикатора.
Также для заполнения буфера индикатора значениями, может использоваться цикл, например, цикл for.
Как это можно увидеть в коде индикаторов папки Examples редактора MetaEditor.
Здесь start — это стартовая позиция, с которой начинается заполнение буфера индикатора.
При значении prev_calculated=0, значение start это, как правило, 0, при значении prev_calculated= rates_total, значение start=prev_calculated-1.
Если же перед реализацией цикла с помощью функции ArraySetAsSeries поменять порядок доступа к массивам буферов индикатора и цен, тогда цикл примет следующий вид:
Где start=rates_total-1, если prev_calculated=0, и start=0, если prev_calculated= rates_total.
Пример создания индикатора
В качестве примера рассмотрим создание индикатора, который будет реализовывать форекс стратегию «Impulse keeper» (Ловец импульсов) и показывать на графике сигналы на покупку и продажу.
В данной стратегии применяются четыре индикатора:
— Экспоненциальная скользящая средняя с периодом 34 для цены High.
— Экспоненциальная скользящая средняя с периодом 34 для цены Low.
— Экспоненциальная скользящая средняя с периодом 125 для цены Close.
Parabolic SAR.
Сигналы на покупку и продажу в данной стратегии описываются следующим образом.
Сигнал на покупку: зеленая свеча закрывается выше EMA34 High и EMA34 Low, зеленая свеча выше EMA125 и Parabolic SAR.
Сигнал на продажу: красная свеча закрывается ниже EMA34 Low и EMA34 High, красная свеча ниже EMA125 и Parabolic SAR.
Давайте, реализуем эту стратегию в коде, который будет отображать на графике стрелки вверх и вниз сигналов на покупку и продажу.
Откроем MQL5 редактор и в меню Файл выберем Создать.
В диалоговом окне мастер MQL выберем Пользовательский индикатор и нажмем кнопку Далее.
Введем имя индикатора Impulse keeper, имя автора и ссылку и нажмем два
