Советы профессионального программиста (Часть I): Хранение, отладка и компиляция кодов. Работа с проектами и логами
Содержание
- Введение
- Храните свой код в отдельных подкаталогах
- Один код на несколько терминалов
- Использование системы контроля версий
- Используйте для отладки кода отдельный терминал на демо счете
- Компилируйте сразу все файлы кода
- Использование системы управления проектами и задачами
- Селекция логов
- Подсветка логов
- Контекстный поиск
- Заключение
Введение
Храните свой код в отдельных подкаталогах
Программные файлы терминала находятся в каталоге MQL5. Данный каталог является так называемой «песочницей». Доступ наружу закрыт. И это правильно. Хотя если подключить свой DLL, то, наверное, можно залезть куда угодно.
Для примера, структура проекта Cayman:
- /Experts/Cayman/ - эксперт
- /Files/Cayman/ - файлы данных (настройки, параметры)
- /Include/Cayman/ - библиотека классов (функций)
- /Scripts/Cayman/ - основные (боевые) скрипты
- /Scripts/CaymanDev/ - скрипты разработчика (для отладки)
Основные преимущества такого размещения:
- Контекстный поиск только в файлах проекта с помощью TotalCommander
- Контроль версий с помощью Git (следить только за файлами проекта, остальное игнорировать)
- Упрощается копирование в другой терминал (демо -> реал – выпуск релиза)
Один код на несколько терминалов
Одним из признаков хорошего тона в программировании, является отсутствия дублей кода. Если одни и те же строки кода у вас встречаются в нескольких местах, то смело "заворачивайте" его в функцию. То же самое касается и файлов MQL5 - текст программного файла должен быть в одном экземпляре. Решается это с помощью символической ссылки на каталог MQL5.
Пусть каталог проектов находится в D:\Project, а каталог данных терминала находится в C:\Users\Pro\AppData\Roaming\MetaQuotes\Terminal\9EB2973C469D24060397BB5158EA73A5
- Закрываем терминал
- Переходим в каталог данных
- Перемещаем каталог MQL5 в каталог проектов
- Находясь в каталоге данных, запускаем cmd и вводим команду
mklink /D MQL5 D:\Project\MQL5 - Запускаем терминал
Терминал даже не заметит, что «песочница» (программные файлы) переехала в D:\Project\MQL5.
Основное преимущество такого размещения - все личные проекты в одном каталоге (D:\Project).
Использование системы контроля версий
У профи даже не возникнет вопроса, зачем это нужно. Без нее никак, особенно в командной разработке. Вопрос только в выборе конкретной системы. Де-факто это Git.
Основные преимущества Git:
- Локальный репозиторий. Можно экспериментировать (ветвиться). Одним кликом переключаться на любую ветку (версию).
- Удобный графический интерфейс (TortoiseGit). Рулим мышкой.
- Бесплатный облачный репозиторий для личных проектов (Bitbucket). Не боимся за поломку компьютера (жесткого диска)
- История изменений файлов с возможностью восстановления или просмотра старых версий (удобно смотреть в Bitbucket)
Не буду приводить подробные инструкции по установке и настройке, но расскажу о некоторых особенностях. Устанавливаем Git (для работы через командную строку) и TortoiseGit (для работы мышкой). В каталог D:\Project\MQL5 создаем файл .gitignore со следующим содержимым
# исключаем файлы *.ex4 *.ex5 *.dat log.txt # исключаем каталоги полностью Images Indicators Libraries Logs Presets Profiles Services "Shared Projects" Levels Params # исключаем внутренности каталогов Experts/* Files/* Include/* Scripts/* # кроме подкаталогов !Experts/Cayman !Files/Cayman !Include/Cayman !Scripts/Cayman !Scripts/CaymanDev
Данный файл позволит отслеживать версии только программных файлов (*.mq?) проекта. Создаем локальный репозиторий в каталоге MQL5. Добавляем файлы и делаем первый комит (фиксируем версию). Локальный репозиторий готов. Работаем над кодом и почаще комитим с кратким описанием изменений. В дальнейшем это облегчит просмотр и поиск в истории.
Для подключения к облачному репозиторию, сначала нужно создать аккаунт и репозиторий на Bitbucket. Имя репозитория логично установить, как у проекта. В моем случае – CaymanMQL5, поскольку есть еще CaymanMQL4. Импортируем локальный репозиторий в облачный. Облачный репозиторий готов. Основные действия через TortoiseGit (TG):
- Работаем с кодом (одна задача – один комит)
- Проверяем изменения (TG/Check for modifications…)
- Добавляем новые файлы (Add)
- Удаляем не нужные (missing) файлы (Delete)
- Комитим в локальный репозиторий (Commit)
- Пушим в облачный репозиторий (Push)
Используйте для отладки кода отдельный терминал на демо счете
Цель – на реале последняя рабочая версия кода (только файлы *.ex? без *.mq?). На демо - код в процессе отладки. Для копирования демо -> реал можно использовать командный файл:
@echo off setlocal set PROJECT=Cayman set SOURCE=d:\Project\MQL5 set TARGET=c:\Users\Pro\AppData\Roaming\MetaQuotes\Terminal\2E8DC23981084565FA3E19C061F586B2\MQL5 set PARAMS=/MIR /NJH /NJS rem MIR - MIRror a directory tree and delete dest files/folders that no longer exist in source rem NJH - No Job Header rem NJS - No Job Summary echo Copy *.ex? // Source to Production echo Source = %SOURCE% echo Production = %TARGET% robocopy %SOURCE%\Experts\%PROJECT% %TARGET%\Experts\%PROJECT% *.ex? %PARAMS% robocopy %SOURCE%\Scripts\%PROJECT% %TARGET%\Scripts\%PROJECT% *.ex? %PARAMS% rem Copy all files except AppSettings.txt, [Levels], [Params] robocopy %SOURCE%\Files\%PROJECT% %TARGET%\Files\%PROJECT% *.* %PARAMS% /XF AppSettings.txt /XD Levels Params robocopy %SOURCE%\Scripts\Cayman %TARGET%\Scripts\Cayman *.ex? /NJH /NJS robocopy %SOURCE%\Scripts\CaymanDev %TARGET%\Scripts\CaymanDev *.ex? /NJH /NJS echo. endlocal pause
Компилируйте сразу все файлы кода
Цель – согласованность кода. Чтобы не получилось, например, изменили параметры функции. Эксперт компилируется, но остался скрипт использующий старый вариант функции. При этом, этот скрипт (откомпилированный ранее) - рабочий, но выполняет не то что надо. Для пакетной компиляции можно использовать командный файл:
@echo off setlocal set METAEDITOR="C:\Program Files\RoboForex - MetaTrader 5\metaeditor64.exe" set CAYMAN=d:\Project\MQL5\Scripts\Cayman set CAYMAN_DEV=d:\Project\MQL5\Scripts\CaymanDev echo METAEDITOR=%METAEDITOR% echo CAYMAN=%CAYMAN% echo CAYMAN_DEV=%CAYMAN_DEV% echo. echo Wait compile... D: cd %CAYMAN% echo %CAYMAN% for %%F in (*.mq?) do ( %METAEDITOR% /compile:%%F /log type %%~dpnF.log ) del *.log cd %CAYMAN_DEV% echo %CAYMAN_DEV% for %%F in (*.mq?) do ( %METAEDITOR% /compile:%%F /log type %%~dpnF.log ) del *.log endlocal echo. pause
Использование системы управления проектами и задачами
Такие системы, в обязательном порядке, используются в командной разработке, а также полезны и для личных проектов. Систем и методологий управления проектами много. Я остановился на ZenKit. Он бесплатен для небольших команд. Очень удобная доска Канбан.
Раньше у меня было несколько досок Канбан (одна на каждый проект). Недостаток нескольких досок – не видно общей картины. Потом я решил, в качестве этапа(стадии) разработки добавить проект. И стало намного легче управлять задачами. Например, на моей канбан доске 5 стадий (этапов) разработки:
- Легенда – назначение проектов, ссылки и инструкции. Записи не перемещаются в другие этапы. Всегда видно общее назначение доски и доступны ссылки на полезные ресурсы.
- Cayman – проекты на MQL5, MQL4
- Website – проект личного сайта
- Принято – задача в работе
- Готово – задача исполнена
Процесс работы с доской простой и наглядный. Появляется интересная идея, решение или ошибка в программе. Кратко формулирую ее и добавляю на доску, в соответствующий проект. Можно добавлять картинки и файлы. Выбираю задачу, перетаскиваю ее в стадию "Принято". Работаю, тестирую и перетаскиваю ее в стадию "Готово".
По количеству задач в проектах, сразу видно, где «пробка, затык,…». Стараюсь брать в разработку задачи из «перегруженных» проектов. Цель – выровнять проекты по количеству задач. В командной разработке есть еще этап "Тестирование", но для меня (одиночки) это не актуально.
Селекция логов
Как известно, все выводы функций Print, пишутся в лог Терминала MQL5\Logs\yyyyMMdd.log. При этом все символы (инструменты) вперемешку. Для выборки логов по заданному символу я использую следующий командный файл:
echo off if "%2"=="" goto Help find /I "%2" < %1 > "%~n1-%2.log" goto Exit :Help echo. echo Filter log-file echo findLog.cmd logFile text echo Example echo findLog.cmd 20200515.log gbpjpy echo Result echo 20200515-gbpjpy.log echo. pause :Exit
Подсветка логов
В режиме отладки у меня много информации пишется в лог. Анализировать ее в запущенном Терминале – проблематично. Поэтому делаю так:
- Очищаю лог на вкладе Инструменты/Эксперты
- Провоцирую вывод в лог
- Копирую все строки в файл log.txt
- Спокойно анализирую этот файл в Notepad++ (NPP) с подсветкой
У NPP есть несколько вариантов подсветки текста
- Двойной клик по слову - сразу выделит их во всем тексте
- Поиск/Пометить выделенное/Использовать стиль – подкрасит текст во всем документе
- Использовать пользовательский синтаксис с подсветкой определенных лексем
Контекстный поиск
Для контекстного поиска текста использую файловый менеджер TotalCommander. Основными преимуществами такого выбора являются:
- Поиск только по файлам проекта ("левые" файлы в результаты поиска не попадают)
- Возможность использовать в поиске регулярные выражения
Заключение
Это моя первая статья. Планирую продолжить серию. Расскажу об удачных решениях с подробным обоснованием. Приглашаю всех желающих поделиться своими опытом и находками при обсуждении статьи.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Именно так и делаю. Все новые файлы сразу сохраняю в UTF-8
как это делается?
У меня AkelPad. Открываю фал - Сохранить как - UTF-8.
После этого MetaEditor сам кодировку не меняет.
У меня AkelPad. Открываю фал - Сохранить как - UTF-8.
После этого MetaEditor сам кодировку не меняет.
У меня AkelPad. Открываю фал - Сохранить как - UTF-8.
После этого MetaEditor сам кодировку не меняет.
Так ведь это и в самом metaeditore можно делать. Открываю файл - Сохранить как - UTF-8
Так ведь это и в самом metaeditore можно делать. Открываю файл - Сохранить как - UTF-8
Спасибо! Может, эта ф-я недавно появилась в ME?