Видеоуроки по программированию на MQL5 - страница 8

 

MQL5 Приемы и примеры. Оптимизация временных ограничений


MQL5 Приемы и примеры. Оптимизация временных ограничений

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

Стоит начать с того, что переменные типа string никак не подходят для подобных целей, а ведь именно с их помощью мы на прошлом занятии указывали нашему тестовому эксперту, когда ему торговать, а когда нет. Так что начнем с того, что изменим тип двух наших переменных, а также их значение по умолчанию. Теперь переменные у нас будут типа int, а вместо строковых констант их значения будут выглядеть так: 800, 1200, 1015 и т.д.

Если продолжить аналогию, то 800 будет соответствовать полуночи, а 2359 - 23 часам 59 минутам. То есть мы задаем время в формате целого числа, у которого два порядка слева соответствуют часам, а два порядка справа - минутам. Можно конечно добавить еще два порядка справа и учитывать в них даже секунды, но как по мне, это уже перебор.

К сожалению, при установке робота на график все это выглядит не так красиво, как его код, если крайний слева порядок равен нулю. Этот ноль нам не покажут, однако при вводе самого значения все в порядке, поскольку ничего с этим мы сделать не можем. Но об этом позже, а сейчас перегрузим нашу функцию allowItTime для работы с формальными параметрами другого типа. Ничего менять в уже написанном коде пока что не нужно, а вот что нужно обязательно - так это привести типы int к типу datetime.

Точнее, не совсем так, прямое приведение типов datetime к int средствами MQL5 возможно, но результат заранее будет бесполезен, так что нужен какой-то другой механизм. И этот механизм уже определен у нас и реализован функционал приведения строки определенного формата к типу datetime.

Таким образом, наша функция allowItTime станет своего рода посредником между типами int и datetime. Остается только привести наши числа типа int к строке строго определенного формата. Задача на самом деле решается довольно просто, но само решение сравнительно объемное. Так что давайте приступать.

Сначала объявляем переменную типа int и называем ее aux. Присваиваем этой переменной результат операции деления параметра startTime на 100, с обязательным явным приведением к типу int. Теперь нужно убедиться в том, что полученное значение корректно в контексте решаемой задачи. Поскольку число часов в сутках не может быть меньше нуля и больше 23, функция должна проверить значение переменной aux на соответствие обоим ограничениям.

Если значение aux меньше нуля, присваиваем переменной aux значение 0. Если значение aux больше 23, присваиваем переменной aux значение 23. С часами разобрались, теперь беремся за минуты.

Объявляем переменную типа int с именем minutes. Присваиваем ей на сей раз остаток от деления параметра startTime на 100. И снова у итогового значения есть ограничения на максимальное и минимальное значение. Тут все по аналогии с часами - 100 и 59. И финальный шаг формирования строки.

Объявляем переменную типа string с именем startTimeStr и присваиваем ей результат нехитрой операции. Рассмотрим эту операцию подробнее. Сначала вызывается функция IntegerToString. Эта функция приводит целое число, передаваемое ей как аргумент, в виду строки. Эту строку она и возвращает.

В данном случае мы передаем в эту функцию значение переменной aux, а затем, прибавляем к полученному результату символ ":", и к уже полученной строке прибавляем значение, которое вернет еще раз вызванная функция IntegerToString, в которую на этот раз передаем значение переменной minutes.

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

Первое, что нужно сделать, это изменить идентификаторы переменных, передаваемых в функцию string. Вместо "a" и "b" используем более понятные имена startTime и endTime.

Во-вторых, в финале функции else if уже не нужен. Достаточно простого else, который вернет files в случае, если ни одно из условий не сработало.

Теперь давайте добавим еще одну функцию для контроля пользовательского ввода. Назовем ее checkTime. Она будет принимать два параметра типа int, отвечающих за начало и конец временного ограничения соответственно.

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

Кстати, чуть не забыл, эту проверку нужно без изменений перевести в ранее написанную функцию allowItTime. Потому что функция checkTime будет вызываться только один раз в функции init, а функция allowItTime с формальными параметрами типа int будет вызываться на протяжении всей работы программы и она тоже должна уметь корректно отрабатывать этот паттерн входящих настроек.

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

Там же, в наших переменных, есть границы, выход за которые не имеет логического смысла. Потому в то время в сутках не бывает меньше нуля и в нашем случае больше 23 часов 50 минут. Файлы в формате ISHOP2 1359, так как переменная endTime тип беззнаковый, то проблема меньше нуля отпадает сама собой. А вот на превышение значения 2359 нужно проверить каждую переменную по отдельности с соответствующими ограничениями.

И, напоследок, если ни одно из четырех условий не вернуло истину, значит с нашими переменными все в порядке. Следовательно, наша функция должна вернуть истину самостоятельно.

Готово! Теперь применим новую функцию в OnInit(). Как уже было сказано ранее, сделаем это в функции OnInit(), если функция init возвращает мне истину, прерываем дальнейшее выполнение программы, поскольку в нашем примере всего два набора временных ограничений, одно из которых задано типами string. Более ничего не требуется, внутри функции allowItTime предусмотрены все нужные выводы на экран.

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

Если вам было интересно и познавательно, ставьте лайк, чтобы не пропустить другие не менее интересные видео. Подписывайтесь на канал и нажимайте на колокол, чтобы получать уведомления о новых видео. Комментарии открыты для вопросов и мнений. Не забывайте про канал в Telegram и резервный канал на YouTube. Все ссылки находятся в описании под видео. Там же вы найдете ссылку на предыдущее видео из серии о временных ограничениях, а также исходники всего написанного и возможность поддержать автора канала материально. До новых встреч, всем пока!

MQL5 Приемы и примеры. Оптимизация временных ограничений
MQL5 Приемы и примеры. Оптимизация временных ограничений
  • 2022.08.03
  • www.youtube.com
Продолжаем осваивать типовые, и не очень, приемы программирования на MQL5. Этот видео-урок продолжает тему организации тайм-менеджмента работы ваших программ...