понедельник, 1 июля 2013 г.

Построение графиков по данным из робота при тестировании в MetaTrader

При отладке торгового робота часто возникает необходимость посмотреть, как робот управляет позицией. В обеих популярных сейчас версиях MetaTrader (4 и 5) для этого есть тестер стратегий с режимом визуализации. В этой заметке расскажу один простой способ расширить возможности тестера так, чтобы можно было вывести на график любой параметр из робота в виде графика. Также это может быть любой параметр счета - например, суммарная позиция или график средств.

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

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

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

В MetaTrader 5 есть возможность вывести индикаторы путем инициализации их прямо из кода, например один раз в OnInit(). Деинициализацию таких индикаторов производить не нужно, иначе они не будут отображены. В четвертой версии терминала такой возможности нет. Достоинство метода - не нужно возиться с шаблоном, недостаток - нельзя изменить стиль линии индикатора, но это можно обойти, немного доработав его так, чтобы стиль линии можно было передавать во входных параметрах.

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

int OnInit()
{
...
    // Вывести индикаторы на график в визуальном режиме тестера
    if (MQLInfoInteger(MQL_VISUAL_MODE))
    {
        // Средства и позиция (+/-лот) в отдельных окнах снизу
        iCustom(_Symbol, PERIOD_CURRENT, "EA-Line-v2", "Equity");
        iCustom(_Symbol, PERIOD_CURRENT, "EA-Line-v2", "Lot");

        // Уровень стопа на основном графике
        iCustom(_Symbol, PERIOD_CURRENT, "EA-Line0-v2", "Stop");
    }

    return(0);
}

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

#property indicator_chart_window    // индикатор в основном окне
#property indicator_separate_window // индикатор в отдельном окне

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

void OnTick()
{
...
    // Запись текущей информации в глобальные переменные
    if (MQLInfoInteger(MQL_VISUAL_MODE))
    {
        GlobalVariableSet("Equity", AccountInfoDouble(ACCOUNT_EQUITY));
        GlobalVariableSet("Lot", totalLot);    // позиция (+/-лот)
        GlobalVariableSet("Stop", stopLevel);  // текущий стоп-лосс
    }
}

Посмотрим, что можно получить с помощью этого нехитрого метода, на примере торгового робота MACD Sample.

Модификация кода эксперта (MQL5/Experts/Examples/MACD/MACD Sample.mq5):

int OnInit()
{
...
    // Вывести индикаторы на график в визуальном режиме тестера
    if (MQLInfoInteger(MQL_VISUAL_MODE))
    {
        // Средства в отдельном окне снизу
        iCustom(_Symbol, PERIOD_CURRENT, "EA-Line-v2", "Equity");
    }

    return(0);
}

void OnTick()
{
...
    // Запись текущей информации в глобальные переменные
    if (MQLInfoInteger(MQL_VISUAL_MODE))
    {
        GlobalVariableSet("Equity", AccountInfoDouble(ACCOUNT_EQUITY));
    }
}

Результат визуального тестирования:


Это простейший пример, по которому можно сказать, что большую часть времени робот простаивает. Если в MetaTrader 5 подобный вывод можно сделать и по графику в результатах тестирования, то в MetaTrader 4 приходится рассматривать сделки, чтобы понять это. В данном случае передача информации из эксперта в индикатор необязательна, так как индикатор может и сам получить текущее значение средств. Но проще иметь пару индикаторов, способных вывести любой параметр, чем готовить для каждого свой.

Более сложный пример - система с пирамидингом.



Что видно здесь:
  • уровень стол-лосса (красный пунктир) неплохо прилегает к цене снизу
  • корректное открытие и закрытие всех ордеров
  • уровень стоп-лосса ниже безубытка (зеленая линия) после второй сделки, что может быть признаком ошибки (обычно стоп после второй сделки ставится на безубыток), но в данном случае это следствие особого трала
  • типовая проблема пирамидинга - последняя сделка всегда убыточна
Визуальное представление может быть намного сложнее - это могут быть гистограммы, свечи, прочие объекты. В пределах одного бара может происходить множество событий, и желательно знать хотя бы границы их результатов. Здесь приведена только основная идея визуального контроля за состоянием торгового робота.

См. также

Комментариев нет:

Отправить комментарий