Отладка в mql. Улучшить дебаг с помощью mql_debug

28 февраля 2021 г. 22:54

Зачастую при написании кода mql в среде разработки MetaEditor не хватает отладчика (дебаггера), который мог бы не только следить за переменными, но и вычислять выражения. К сожалению, в MetaEditor такого нет. Например, в коде:

int OnInit(){
    double a = MathPow(2, 1) + MathAbs(-10)/2;

    for (int i=0, len=OrdersTotal(); i < len; i++)
        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() == OP_BUY)
           OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 70);
}

поставив точку останова, например, на 2-ой, мы не можем посмотреть в дебаггере отдельно, чему равно MathPow(2, 1) или MathAbs(-10)/2. Только если мы пошагово перейдём на следующую строчку, мы сможем узнать в дебаггере, чему равно a. Такая же ситуация и со строчкой OrderClose - мы не сможем узнать в отладчике текущий результат выражения OrderTicket(), OrderLots() или MarketInfo(OrderSymbol(), MODE_BID)

Чтобы хоть как-то узнать, например, чему равно MathPow(2, 1), можно использовать команду Print и смотреть результат выражения в журнале терминала. Или выносить выражения в отдельную переменную и просматривать результат в дебаггере:

int OnInit(){
    Print(MathPow(2, 1));
    double my_debug = MathAbs(-10)/2;
    double a = MathPow(2, 1) + MathAbs(-10)/2;
}

Недостаток такого подхода в том, что при использовании Print неудобно просматривать значение выражения: всё-таки хочется видеть в одном месте и код, и вычисленные значения. При создании дополнительных переменных, требуется писать много букв: объявлять тип данных и придумывать имя переменной - это долго.

Для облегчения работы с отладкой программного кода на mql я написал библиотеку mql_debug, который умеет записывать результат вычисления выражений в файл или журнал терминала. При этом показывается, в каком файле, в какой функции и на какой строчке кода был вызван дебаг выражения. Библиотека доступна на гитхабе:
https://github.com/vivazzi/mql_debug

Установка mql_debug

Скачайте библиотеку и скопируйте папку mql_debug/Include/debug в <TERMINAL DIR>/MQL(4/5)/Include.

Использование

Добавьте #include <debug/debug.mqh> и используйте функцию _d:

#include <debug/debug.mqh>

int OnInit(){
    _d(MathPow(2, 1) + MathAbs(-10) / 2);
    _d(StringFormat("Length of 1234567890 = %d", StringLen("1234567890")));
}

Скомпилируйте и запустите своего эксперта в терминале, прикрепив на какое-нибудь окно торговой пары. Результат дебага будет записан в файл <TERMINAL DIR>/Files/debug/<ACCOUNT NUMBER>/debug.txt:

MyExpert.mq4: int OnInit(), line 3:
    MathPow(2,1)+MathAbs(-10)/2 :: 7
MyExpert.mq4: int OnInit(), line 4:
    StringFormat(Length of 1234567890 = %d,StringLen(1234567890)) :: Length of 1234567890 = 10

Как видите, в лог файле отображается информация:

  • Файл, функция и номер линии, на которой был вызван дебаг _d,
  • Отслеживаемое выражение и его результат после знаков ::

Также вы можете использовать _d любой вложенности:

_d(_d(MathPow(2, 1)) + _d(MathAbs(-10) / 2));

Результат выполнения кода:

TestDebug.mq4: int OnInit(), line 3:
    MathPow(2,1) :: 2
TestDebug.mq4: int OnInit(), line 3:
    MathAbs(-10)/2 :: 5
TestDebug.mq4: int OnInit(), line 3:
    MathPow(2,1)+MathAbs(-10)/2 :: 7

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

После выполнения нескольких функций _d можно поменять имя лог файла командой _d_set_log_path(). Таким образом будет несколько файлов с отслеживаемыми данными:

#include <debug/debug.mqh>

int OnInit(){
    _d(MathPow(2, 1));
    _d_set_log_path("example_debug.txt");
    _d(MathAbs(-10));
}

В результате создадутся 2 дебаг файла:

1. <TERMINAL DIR>/Files/debug/<ACCOUNT NUMBER>/debug.txt:
TestDebug.mq4: int OnInit(), line 3:
    MathPow(2,1) :: 2

2. <TERMINAL DIR>/Files/example_debug.txt:
TestDebug.mq4: int OnInit(), line 3:
    MathAbs(-10) :: 10

Если во время выполнения кода нужно очистить файл, то используйте метод _d_clear():

#include <debug/debug.mqh>

int OnInit(){
    _d(MathPow(2, 1));
    _d_clear();
    _d(MathAbs(-10));
}

При вызове _d и _dp вы используете объект Дебага по умолчанию. Для использования нескольких дебагов создайте свои объекты дебага и используйте соответствующие функции d и dp с указанием вашего объекта:

Debug d_1("debug_1.txt");
d(d_1, MathPow(4, 1));
dp(d_1, MathPow(4, 2));

Debug d_2("debug_2.txt");
d(d_2, MathPow(4, 1));
dp(d_2, MathPow(4, 2));

Для изменения лог файла используйте d_set_log_path(d_object, log_path), а для очищения файла используйте d_clear(d_object).

Сохранение дебага в журнал терминала

Для сохранения результатов дебага в журнал терминала, то используйте _dp():

#include <debug/debug.mqh>

int OnInit(){
    _dp(MathPow(2, 3));
}

Выведет в журнал:

2021.02.28 13:50:25.956 MyExpert EURUSD,H1: MyExpert.mq4: int OnInit(), line 43: MathPow(2,3) :: 8

В README.md пакета на гитхабе вы можете найти более полную и актуальную документацию mql_debug:
https://github.com/vivazzi/mql_debug

Оцените статью

0 из 5 (всего 0 оценок)

captcha
Поля, отмеченные звёздочкой ( * ) , являются обязательными.

Спасибо за ваш отзыв!

После нажатия кнопки "Отправить" ваше сообщение будет доставлено мне на почту.

Автор статьи

Мальцев Артём

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

Права на использование материала, расположенного на этой странице https://vivazzi.pro/it/debug-mql/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор статьи: Мальцев Артём
Ссылка на статью: <a href="https://vivazzi.pro/it/debug-mql/">https://vivazzi.pro/it/debug-mql/</a>

Подробнее: Правила использования сайта

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

Вы можете оставить комментарий как незарегистрированный пользователь.

Но зарегистрировавшись, вы сможете:

  • получать оповещения об ответах
  • просматривать свои комментарии
  • иметь возможность использовать все функции разработанных сервисов

Для комментрирования от своего имени, войдите или зарегистрируйтесь обычным способом или через социальные сети:

Отправить

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте

Выберите валюту для отображения денежных единиц