Наши рекомендации:

  1. Главная
  2. Уроки MQL4
  3. 3.2 Пишем советник, торгующий по Стохастику в заданное время

3.2 Пишем советник, торгующий по Стохастику в заданное время

курсы mql

Всем привет. На прошлых уроках мы изучали возможность создания советников по нескольким простым сигналам для открытия ордеров, но что, если нам нужно входить в рынок только в конкретно заданное время? Давайте попробуем добавить данный фильтр в наш код торгового робота. Для разнообразия попробуем использовать индикатор Stochastic как сигнальный. Цель урока языку mql4 — усложнить код с помощью дополнительных плюшек, а также практика, практика и практика. Пройдя все уроки по написанию советников для МТ4 у вас не сможет возникнуть проблемы в создании собственного эксперта по вашей, индивидуальной логике торговли.

Торговая идея будущего советника

Если вы уже приличное время знакомы с рынком Форекс, то возможно вы слышали о такой стратегии торговли, как ночной скальпинг. Также ее называют трейдингом в Азиатскую торговую сессию. Суть системы проста — входить в рынок в ночное время по причине низкой волатильности, когда Европейская и Американские сессии закрыты. Мы будем осуществлять торговлю с 23 часов вечера до 01 часа утра.

Так как наша основная цель это практика, то мы попробуем входить в рынок по сигналу всего одного индикатора — Стохастика. Он прост и уже встроен в терминал MT4. Продажи будут осуществляться в заданное время, когда основная линия индикатора выше отметки 90, т.е. цена в зоне перекупленности. Покупки же, когда линия ниже 10, т.е. индикатор показывает зону перепроданности. Период ТФ установим М15.

курсы mql

Как видите, идея проста и тривиальна по своей логике. Начнем же!

Пишем код MQL4

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

Итак, создаем новый советник. Присоединяем к нему встроенную библиотеку для расшифровки возможных ошибок.

Теперь давайте определимся с внешними переменными, которые вы сможете менять по мере тестирования и оптимизации советника.

  • Основные настройки: торговый лот, проскальзывание, СЛ, ТП, комментарий, магик номер. Также сюда мы добавим фильтр спреда, чтобы учитывать его перед открытием будущих ордеров, ведь в ночное время спред очень часто расширяется.
  • Настройки индикатора. В нашем случае это Stochastic, у которого есть три основных параметра: K Period, D Period и Slowing. Также мы должны задать зоны, по пересечению которых будет появляться положительный сигнал на вход: StohLevel. Мы укажем его для зоны перекупленности, а для перепроданности он будет равен 100-StohLevel, т.е. зеркально. Чем меньше внешних параметров, тем меньше вариантов прогона оптимизации.
  • Настройки времени торговли. Мы должны указать возможный сдвиг по GMT в зависимости от времени брокера. Данный параметр нужен, если вы будете использовать советник у брокеров с разным GMT. Также укажем время начала и окончания торговли в часах и минутах.

В итоге внешние настройки будут иметь вид:

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

Переходим к функциям обработки событий. Функция OnDeinit нам не понадобится, поэтому ее оставляем пустой. В функцию инициализации OnInit мы пропишем умножение наших внешних переменный в пунктах на десять, если котировки брокера содержат 3 (для JPY) и 5 знаков после запятой.

Далее начинаем работу с основной функцией OnTick. Нам нужно определить время начала и окончания торговли в зависимости от текущего торгового дня. Определение происходит 1 раз в день (day_of_year_trade), чтобы не загружать код лишними расчетами. Вначале мы получим время открытия текущего дня, для этого воспользуемся нехитрой формулой перевода текущего времени в дату дня. Далее мы должны прибавить к этому времени значение часа и минут из внешних переменных, не забыв о сдвиге по GMT. Это нужно сделать для определения точного времени начала и окончания нашей торговли. Не забываем о том, что значение времени хранится в секундах, поэтому часы и минуты нужно переводить в секунды.

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

Готово, все ордера советника теперь под надзором советника. Давайте теперь определим, подходит ли конкретно текущее время для торгов нашим советником. Для этого введем пользовательскую функцию IsTime и запишем результат ее расчетов в bool переменную.

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

Соответственно, если текущее время соответствует времени торгов из настроек, то функция вернет значение true, если же нет, то false.

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

Стохастик уже встроен в код Meta Editor, поэтому мы просто воспользуемся функцией iStochastic для получения его данных в переменную Stoh. Функция содержит следующие параметры:

  • Имя символа. Null — текущий.
  • Период. 0 — текущий.
  • Kperiod, Dperiod, slowing — все эти данные берутся из внешних переменных.
  • Метод усреднения. Мы возьмем по классике обычную МАшку — MODE_SMA.
  • Тип цены. Берем цену закрытия Close, т.е. пишем 1.
  • Индекс линии — значение одной из двух линий индикатора. Мы выбираем основную MODE_MAIN.
  • Сдвиг индикатора. Нам нужно сдвинуться на 1 бар назад, поэтому прописываем единицу.
Остается только проверить условия на вход как для покупок, так и для продаж. Напомню, что их три: соответствие времени торговли, отсутствие сделок в том же направлении в рынке и сигнал индикатора.
Открытие ордера будет выполняться уже знакомой нам пользовательской функцией OpenTrade. Единственное отличие в ее коде будет в том, что перед вначале мы будем сравнивать максимально допустимый спред в настройках (если он больше нуля) с текущим значением на рынке. Если текущий спред больше — функция возвращает false и ордер не будет открыт, пока спред не нормализуется. Естественно, при тестировании на котировках брокера вы не получили значение плавающего спреда, данная проверка нужна только для реала или программы TDS.

Остальную часть кода нет смысла объяснять, если будут вопросы — пиши в комментариях.

Осталось добавить блок проверки на ошибки в самом конце функции OnTick:

Все, можно выдохнуть, поставленная задача нами выполнена.

Добавляем в код возможность перевода в безубыток

курсы mql

Немного подумав, я решил, что нужно еще вас загрузить информацией. Давайте предположим, что цена практически подошла к отметке Take Profit, но он еще не был достигнут. Будет очень обидно, если цена развернется и заденет Стоп Лосс. К слову, чувак на картинке выше не использует БУ в своей торговле.

Чтобы ограничить наши возможные убытки, мы введем в код возможность выставления безубытка при достижении цены указанного процента от значения ТП. Т.е. если цена подошла на 80% к ТП — мы переведем СЛ на уровень БУ с указанным отступом. Для этого давайте добавим две внешние переменные — процент БУ и отступ от него:

В функции обработки событий добавляем BE_Step в проверку на количество знаков.

Так как цена постоянно в движении, то проверку на изменение СЛ нужно осуществлять каждый тик. У нас уже есть блок анализа открытых ордеров. К нему же добавим и проверку на БУ.

Осталось прописать саму функцию для перевода СЛ в БУ. Так как ордер уже выделен, то нам будет вполне комфортно работать с его свойствами. Вначале мы узнаем, что за тип ордера перед нами, далее на примере покупок мы уточняем, ниже ли текущий СЛ рассчитанного уровня БУ или нет. Если да, значит он еще не был модифицирован (БУ не активирован). Далее с помощью незамысловатой математики мы высчитаем какой процент до ТП прошла цена, и если он больше или равен заданному в настройках, то нужно активировать БУ. Дополнительной проверкой сравниваем текущий СЛ и рассчитанным, чтобы не дергать сделку в пустую и не получить ошибку, когда они будут одинаковыми. Модифицируем ордер, выставляя ему СЛ равный цене открытия ордера плюс указанный отступ в пунктах. Аналогично и продажи.

Теперь точно все. Остается поставить советник на быструю оптимизацию и посмотреть, какой результат лучше всего себя покажет. Вот, что получилось у меня:

Вполне неплохая картина для советника, написанного за час. Естественно, вы должны понимать, что это не рекомендация для реального счета, полученный прогон не использовал плавающий спред, также это лучший их сотни результатов, да и Стохастик был взят просто как пример для обучения. Вместо него вы можете попробовать применить канальный метод торговли, который очень распространен в ночной торговле, например использовать Bollinger Bands, канал Кельтнера или Дончиана. Простор для творчества огромен.

Заключение

В этом уроке мы значительно усовершенствовали код, изученный ранее и написали советник mql. Научились использовать определенное время для торговли, будь то день, ночь или какая-то отдельная торговая сессия. Познакомились с торговлей в Азиатскую сессию. Импортировали показатели индикатора Стохастик, а также научились переводить ордера в безубыток. Надеюсь вы смогли не уснуть и дочитать этот текст до конца.

На этом все, увидимся в следующих уроках. Всем профитов!

0. Начало работы

Предыдущая запись
3.1 Создаем советник, торгующий по сигналу двух скользящих средних
Следующая запись
3.3 Создаем простой советник с сеткой ордеров по системе Мартингейл

7 комментариев. Оставить новый

  • Ярослав
    07.04.2021 17:33

    Здравствуйте. А как организовать проверку на закрытие ордера по стоплосу (допустим чтобы при закрытии ордера по стопу переменной присваивалось значение true)?

    Ответить
    • Добрый вечер. Только с помощью цикла по закрытым ордерам. Т.е. сохраняем количество закрытых ордеров в переменной глобального уровня и каждый тик сравниваем ее с фактическим значением. Как только появился новый ордер в истории, обновляем значение этой переменной и циклом проходим по последним закрытым ордерам. Если расстояние от цены закрытия до цены открытия более определенного значения (СЛ в пунктах к примеру), значит это наш ордер, мы присваиваем bool переменной статус true.

      Получится что то типа того:

      Ответить
  • Ярослав
    26.05.2021 16:43

    Доброго дня. Не очень понял вот это место
    if (day_of_year_trade != DayOfYear()) {
    datetime _CurrentDate = StrToTime(TimeToStr(TimeCurrent(),TIME_DATE));

    StartTime =_CurrentDate+Start_Trade_Hour*60*60+Start_Trade_Minute*60+GMT_Offset*60*60;
    EndTime = _CurrentDate+End_Trade_Hour*60*60+End_Trade_Minute*60+GMT_Offset*60*60;
    }
    почему переменная day_of_year_trade не перезадаётся каждый день? Ведь если её не перезадавать то каждый тик будет происходить перезадание StartTime и EndTime.

    Ответить
  • Александр
    14.09.2022 22:12

    Добрый день. По уроку 3.2 после установки советник сразу входит в рынок, не дожидаясь заданного времени следующего дня. Подскажите, где можно исправить, чтобы вход в рынок осуществлялся на следующий день в заданное время?

    Ответить
  • Александр
    15.09.2022 20:01

    Здравствуйте. Вопрос по уроку 3.2 снят. Я сам разобрался.

    Ответить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Заполните поле
Заполните поле
Пожалуйста, введите корректный адрес email.
Вы должны согласиться с условиями для продолжения

Меню