Статьи по MQL4
Своя статистика (команда #include)

Своя статистика (команда #include)


например, forex

Люди считают, что без особого труда можно делать кучу денег. Они считают, что вы можете делать 100% в год, ограничиваясь крошечными исследованиями по выходным. Это смешно.
Монро Траут. Глава «Лучшая прибыль при минимальном риске» (Джек Д. Швагер «Новые маги рынка»)


После прогона советника на исторических данных тестер в МТ4 позволяет сохранить отчет о результатах тестирования в формате html, с включением графика Баланса и Эквити, а также списком проведенных торговых операций. Список содержит дату и время открытия и закрытия каждой позиции, объем, тип (покупка или продажа) и результат (прибыль или убыток) каждой операции. Кроме того, в отчете приводятся разнообразные рассчитанные параметры для оценки результатов тестирования эксперта. Для лучшего понимания работы экспертов рекомендуется прочитать статьи на сайте разработчиков:
  1. Особенности написания экспертов
  2. Strategy Tester: режимы моделирования при тестировании
  3. Особенности и ограничения тестирования в MetaTrader 4
  4. Что означают цифры в отчёте тестирования эксперта


Список торговых операций со вкладки «Результаты» можно скопировать в Microsoft Excel и провести дополнительный анализ(провести самостоятельный расчет своих показателей). Но даже и в этом случае у нас будет не полная статистика, к тому же невозможно предусмотреть в тестере варианты на все случаи жизни. Для примера, нам необходимо получать информацию о поле «Комментарий» в ордерах, время жизни позиции (между открытием и закрытием) в минутах.

Также выведем прибыль в пунктах и в валюте депозита из расчета на 0.1 лот (для устранения влияния Money Management). На всякий случай будем также выводить час и день недели открытия/закрытия ордеров. Дополнительно будем различать ордера закрытые по стопу, по тейк-профиту и по рынку. Как видите, список получился достаточно большой.

Где нам проводить обработку истории ордеров? Конечно же в той процедуре, которая выполняется самой последней, то есть в функции deinit(). После бектеста советника имеется история сделок, которую мы можем обработать в цикле. Используем для полигона наш советника RandomTrade4. Создадим два массива double trades[] и cancells[] (для отмененных ордеров), в которые будем записывать атрибуты каждого ордера. В массив string commentsTrades[] будем записывать строковые значения.

 
 


Я не стал заполнять массив отмененных ордеров, для них все аналогично:

 
 


Пояснения требуются только для использования функции StringSubstr(). Дело в том, что к комментарию ордера при закрытии по стопу тестер или торговый сервер добавляет «[sl]» , а при закрытии по тейк-профиту добавляется «[tp]». Если у вас был ордер с комментарием «проба», то при закрытии по стопу комментарий превратится в «проба[sl]». Таким образом в commentsTrades[cnt][0] записывается первоначальный комментарий, в индекс [1] пишем «[sl]», «[tp]» или «»(пустую строку), если ордер был закрыт по рынку. В индекс [2] пишем тип ордера – «buy» или «sell». Измененный эксперт назовем RandomTrade+Statistika.mq4. В массиве trades[] не обрабатываются индексы 9, 10 и 12. Они могут понадобиться нам в будущем.

Теперь осталось решить – что мы будем анализировать. Наш советник хоть и не несет особой смысловой нагрузки, но попробуем и из него выжать по максимуму. Обычно пишут советник по сигналам некоего индикатора и стараются его каким-либо образом улучшить (путем оптимизации) для увеличения прибыли при торговле на истории. Попробуем пойти обратным путем – через массив случайных сделок увидеть закономерность в показаниях индикатора. Возьмем классический индикатор MACD(12,26,9) и будем записывать в комментарий ордера единицу, если значение главной линии выше нуля, и минус один в противном случае.

 
 


Компилируем код советника, прогоняем на EIUUSD H1 с параметром StDev=50 и открываем в Excel csv-файл. Мы попробуем найти закономерность – связь между значением MACD и направлением позиции. После сортировки по типу «buy» и полю «Comment»=-1 видим, что эти сделки нам принесли прибыль в размере $1266.

 
 


Проверяем обратную ситуацию, ставим «Comment»=1 – получаем убыток $200.

 
 


Меняем тип ордера на «sell» и «Comment» на 1. Получаем опять убыток, но небольшой - $250.

 
 


Интересно, последний год с лишним (на этом интервале шло тестирование) идет падение EURUSD, а покупки при условии StopLoss=50 и TakeProfit=150 пунктов являются прибыльными. Может быть мы случайно выявили некую закономерность в поведении этой валютной пары? Чтобы проверить это, мы немного изменим алгоритм нашего советника. Время открытия позиций будет по-прежнему случайным, а направление открытия мы зададим жестко. Если MACD выше нуля – продаем, если ниже – покупаем. Вот такая простая контртрендовая система. Назовем этот вариант RandomTtade+Statistika2.mq4 .

 
 


Проверим наше предположение, сделаем оптимизацию, если она покажет, что случайные сделки при таких параметрах в среднем прибыльны – значит мы на правильном пути. Параметры оптимизации:
  1. Balk – от 1 до 100 с шагом 1 (100 проходов для каждой комбинации значащих параметров)
  2. TP_K – от 1 до 3.
  3. StDev – от 10 до 100 с шагом 5.


Оптимизация заняла чуть меньше двух часов, «Результаты оптимизации» я скопировал и сохранил в файле Excel.

 
 


Но самое главное, на «Графике оптимизации» мы видим, что есть целая серия прибыльных сделок при StDev=65 и TP_K=2. Лучшие результаты получены не при StDev=50, но и не очень далеко от этого значения.

 
 


Самое интересное, что если TakeProfit больше стопа в 3 раза (TP_K=3) – прибыль становится меньше. Это еще одна неожиданность. Устанавливаем оптимальные параметры и прогоняем разок в бектесте. Смотрим график:

 
 


Делаем еще прогон, опять смотрим:

 
 


Еще разок, опять видим прибыль:

 
 


«Отчет» тестера для одного из прогонов в виде html-файла прилагается.

 
 


Неужели все так просто? Даже не верится. Внимательно просматриваем сделки и замечаем, что после закрытия одной сделки тут же открывается другая. Каким-то образом при таком изменении кода мы потеряли главное достоинство нашего эксперта – случайность сделок. Или нет? Сделаем простую проверку, сначала прогоним в тестере нашего эксперта с оптимальными параметрами в режиме LongOnly (Только покупки),

 
 


а затем в режиме ShortOnly (Только продажи):

 
 


Нас учили: от перестановки мест слагаемых сумма не меняется. А тут не только нет прибыли, но и количество сделок не совпадает – отдельные покупки и продажи дали примерно по 300 сделок, всего около 600, а в режиме Long&Short мы имели примерно 400 сделок. С большой долей уверенности мы можем констатировать, что была произведена скрытая подгонка советника. Чтобы это опровергнуть, вам как минимум необходимо изменить код таким образом, чтобы появилась случайная пауза между сделками, как максимум – научить эксперта различать направление уже открытой позиции.

Возможно, нам понадобится проводить такой же анализ для других советников. В этом случае мы можем в функцию deinit() нового эксперта вставлять кусок кода из этого советника. Но есть и другой путь – использование директивы #include. Директива #include(включить, добавить) имеет силу только при компиляции кода. Когда компилятор встречает эту команду, то он пытается найти указанный файл в папке "C:Program FilesMetaTrader 4expertsinclude" и вставить весь код из этого файла в код советника.

Покажем это на примере. Весь код в блоке deinit() сначала вынесем в отдельную функцию HistoryCalculate(). В блоке deinit() теперь присутствует только вызов этой функции:

 
 


Сохраняем это вариант под именем RandonTrade+Statistika3.mq4. Если компиляция проходит успешно – переходим к созданию заголовочного файла Statistika.mqh. Запускаем «Мастера по созданию советника», выбираем тип «Заголовочный файл»:

 
 


Задаем имя файла, имя автора и линк (ссылку):

 
 


Получили шаблон заголовочного файла, который содержит примеры вызова динамической библиотеки dll, скомпилированного файла mq4 – ex4 и просто определения константы(#define).

 
 


Копируем определение нашей функции HistoryCalculate(), при этом не забываем перенести объявления переменных StatBars и stat_FileHandle, а также имени файла статистики TradesFileName:

 
 


В нашем же советнике функцию HistoryCalculate() и переменные StatBars, stat_FileHandle, TradesFileName удаляем, добавляем строчку #include :

 
 


Сохраняем советника с именем RandonTrade+Statistika4.mq4 и заголовочный файл. Удобство этого подхода в том, что если вы отладили некий код, который хотели бы использовать многократно в своих разработках, то впоследствии легко добавляете его в свой новый код на стадии компиляции. Поэтому, если впоследствии вам будет необходимо изменить код заголовочного файла (*.mqh), то вы не должны забывать о необходимости перекомпиляции всех программ, использующих этот файл.

Напоследок вставим в файл Statistika.mqh определение ненужной функции Placebo(), вызывать которую мы не будем.

 
 


Сохраняем файл и компилируем заново наш советник. Получаем сообщение:

 
 


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


Перейти к статье «Техника скользящего стопа».
 
+7 (495) 710-76-76
8 (800) 200-01-31
по России бесплатно

закрыть

Вход в личный кабинет

Для счета alpari.classic введите номер счета (буква и 4 цифры) и пароль в ЛК.

Для счетов alpari.micro и alpari.partner введите логин и пароль в МТ.

Зарегистрироваться!Забыли пароль?

 
Rambler's Top100