индикаторов.
Соответственно в индикаторе будем вызывать эти переписанные функции.
Включим этот переписанный индикатор в фитнес функцию.
И запустим скрипт.
Глубина истории увеличится, но при этом существенно увеличится и время оптимизации — на порядок, при том же самом результате на 1000 барах.
Поэтому для самооптимизации советника будем использовать первый вариант индикатора с глубиной истории в 1000 бар.
С помощью мастера MQL5 сгенерируем код советника на основе сигналов MA и MACD и добавим в него самооптимизацию параметров Signal_MA_Weight и Signal_MACD_Weight с использованием приведенной выше фитнес функции.
Здесь в функции OnTick при превышении порога просадки баланса вызывается функция UGA генетического алгоритма, которая оптимизирует веса сигналов.
И в фитнес функцию перед копированием буферов индикатора добавим вызов Sleep для того, чтобы индикатор успел рассчитаться.
При тестировании советника на паре EURUSD на часах без самооптимизации получаем следующий результат.
С включенной самооптимизацией советника при тестировании получаем следующий результат.
Как мы можем видеть, матожидание прибыли существенно выросло.
Использование библиотечных классов и функций
В функции OnTick советника, для того чтобы торговать только при появлении нового бара на графике символа, мы использовали структуру данных datetime, локальную статическую переменную и функцию CopyTime, для того чтобы отслеживать время открытия бара.
Тоже самое можно сделать с помощью функции iTime.
Здесь мы также используем структуру данных datetime и локальную статическую переменную.
Но вместо функции CopyTime, мы используем функцию iTime для получения времени открытия бара.
Теперь, для открытия позиции, мы использовали структуру MqlTradeRequest и функцию OrderSend.
Тоже самое можно сделать с помощью классов CTrade и CPositionInfo.
Здесь мы с помощью метода Buy класса CTrade открываем длинную позицию с указанным объемом, на текущем символе, по цене, которая возвращается функцией Ask, с нулевым стоплоссом и тейкпрофитом.
Затем мы получаем тикет сделки с помощью метода ResultDeal, и фиксируем позицию CPositionInfo с помощью метода SelectByTicket.
Затем мы вычисляем стоплосс и тейкпрофит на основе входных параметров, и модифицируем открытую позицию с помощью метода PositionModify класса CTrade.
Здесь показаны используемые функции, которые возвращают цену предложения на покупку от брокера, и округляют цену до указанной точности.
Используя методы классов CTrade и CPositionInfo можно также реализовать трейлинг позиций на покупку и продажу.
И еще раз о тестировании роботов
Любой робот, который вы создадите, будет иметь входные параметры своей работы, которые нужно будет оптимизировать для конкретной валютной пары.
Причем оптимизацию параметров робота придется проводить периодически, подстраивая их под текущее поведение рынка.
Невозможно создать универсального робота, который бы выдавал одинаковые результаты для любого символа и для любого периода времени.
Для оптимизации параметров робота, его нужно протестировать на истории цен, которую терминал загружает с сервера брокера и сохраняет в папке BasesDefaultHistory.
Данные истории цен закачиваются с торгового сервера по запросу терминала в виде минутных баров.
Однако вот какое дело, если вы установите терминалы от разных брокеров, вы обнаружите, что каждый брокер будет предоставлять свою историю цен.
И один и тот же робот будет иметь разные оптимизированные параметры для разных брокеров.
Универсальных оптимизированных параметров робота вы не получите.
Более того, один и тот же робот с одними и теми же параметрами будет по-разному торговать на терминалах разных брокеров.
Если же сравнить торговлю робота в реальном времени на терминале брокера с последующим тестированием этого же робота на том же промежутке времени, результаты будут совпадать.
Так что брокер со своей историей не химичит.
При чувствительности результатов работы робота к оптимизации параметров робота, возникает вопрос, как же настроить робота, чтобы он обеспечил прибыльную торговлю на реальном рынке?
Тот, кто найдет ответ на этот вопрос, будет сказочно богат.
Один из способов оптимизации — выбрать участок истории, который, как вам кажется, будет похож на движение цены в будущем, и провести оптимизацию робота на этом временном отрезке ценовой истории.
Для автоматизированной торговли с использованием робота, сначала нужно не кодировать, а создать и сформировать для себя философию рынка и торговли на нем.
Сначала нужно разобраться в движущих силах и механизмах рынка.
Только после этого, на основе своей философии, можно выбрать стратегию торговли и реализовать ее в коде советника.
В качестве демонстрации я покажу работу торгового робота, созданного по такой технологии.
Любой советник требует периодической настройки своих параметров.
Значения параметров советника по сути отражают настроение на рынке.
И так как настроение на рынке периодически меняется, необходимо перенастраивать советник.
Настройка советника производится с помощью тестера стратегий терминала.
Так как в тестере стратегий могут устанавливаться разные режимы задержек и тиков, необходимо исследовать работу сервера брокера, чтобы понять, какому режиму тестера соответствует работа сервера.
Исследовать сервер брокера можно следующим образом.
Можно запустить торговать свой советник, а затем по прошествии определенного периода времени тестировать советник на этом периоде времени, меняя параметры тестера таким образом, чтобы тестирование максимально совпало с реальной торговлей.
Здесь, в нашем примере, мы настраиваем свой советник каждую неделю на периоде прошедшей недели и запускаем торговать таким образом настроенный советник в течение следующей недели.
Как мы видим, наш советник стабильно выдает прибыль.
Однако в период отсутствия тренда, в период высокой волатильности, как показано на 4-х часовом графике, прибыльный советник будет выдавать убыток.
Признаком приближения такого периода может служить снижение прибыльности советника.
В такие периоды лучше не торговать.