Изучение стандартной библиотеки MQL5 (Часть 8): Ведение журнала сделок гибридной системы с помощью CFileTxt
Содержание:
- Введение
- Концепция и преимущества
- Обзор стандартной библиотеки
- Реализация
- Тестирование и результаты
- Заключение
- Вложения
Введение
Добро пожаловать в часть 8 нашей серии, посвященной освоению стандартной библиотеки MQL5 на практике, в реальных проектах. Основываясь на интерактивной визуальной системе управления позициями, разработанной в предыдущей части — с графическими метками на графике, нарисованными с помощью CCanvas, и кликабельными кнопками закрытия — мы добавляем слой хранения данных профессионального уровня: пользовательский CSV-журнал сделок.
MetaTrader 5 предоставляет отличную встроенную историю сделок, которая точно записывает детали выполнения и исходы. Для гибридных систем, сочетающих автоматизированную логику стратегии с человеческим дискреционным вмешательством, осуществляемым через сам советник, нам часто требуется дополнительный уровень контекста, адаптированный к нашим конкретным аналитическим потребностям. В этом пользовательском журнале явно регистрируется инициатор решения для каждого записанного события — независимо от того, было ли действие инициировано алгоритмом ("ALGO") или кликом пользователя в интерактивном интерфейсе ("HUMAN").
Фиксируя этот источник решения наряду со стандартными данными (время, тикет, символ, действие и полученная прибыль), мы создаем переносимый структурированный набор данных, который позволяет точно соотносить результаты с источником решения. Проект представляет собой углубленное исследование компонента Files/FileTxt.mqh, демонстрируя надежные операции с файлами, методы обеспечения целостности данных и аккуратные схемы интеграции, дополняющие встроенные возможности платформы.
Полный советник сочетает в себе логику пересечения скользящих средних, динамическую визуализацию canvas, взаимодействие на основе хитбоксов и журналирование с фиксацией источника решения — в результате получается зрелый гибридный инструмент, который не только совершает сделки, но и документирует процесс принятия решений для уточнения на основе фактических данных.
Концепция и преимущества
Встроенная вкладка Account History и отчеты тестера стратегий в MetaTrader 5 являются надежными и достаточными для учета, регуляторных задач и общей оценки результатов. Они корректно различают каналы выполнения и предоставляют полную хронологическую запись сделок и позиций.
Однако при активной разработке и мониторинге гибридных систем в реальном времени нам часто требуются дополнительные журнальные записи, позволяющие ответить на ключевые для доработки вопросы. Основные метаданные, на которые мы ориентируемся, — это инициатор решения: алгоритмические сигналы против ручных вмешательств трейдера через обработчик событий EA и торговые классы библиотеки. Такая явная маркировка позволяет нам однозначно разделить и сравнить истинный вклад каждого компонента.
Пользовательский CSV-журнал предоставляет ряд конкретных преимуществ,
- Явная атрибуция источника действия — ручные закрытия сделок по кликам на графике регистрируются как "HUMAN", а записи, обусловленные стратегией, — как "ALGO". Такое разделение невозможно обеспечить надежным образом только с помощью встроенной истории в интерактивных гибридных системах.
- Универсальная переносимость — CSV-файлы мгновенно открываются в Excel, Google Sheets, LibreOffice или любом текстовом редакторе. Не требуется каких-либо процедур экспорта или платформенно-специфических форматов.
- Встроенная структура для анализа — заранее заданные столбцы позволяют немедленно фильтровать данные, создавать сводные таблицы и выполнять вычисления без этапов очистки или преобразования.
- Расширяемость — добавление новых столбцов (например, значений индикаторов при входе, текущей просадки, показателя волатильности или пользовательских заметок) требует лишь незначительных изменений в вызове функции логирования.
- Надежная диагностика — журнал служит точной временной шкалой решений системы, что значительно упрощает восстановление событий во время отладки или ретроспективный анализ, чем полагаться исключительно на вывод вкладки Experts.
- Устойчивость к сбоям — стратегическое использование функции Flush() гарантирует физическую запись каждой записи на диск, защищая целостность данных в случае сбоев терминала или отключения питания.
- Связь с внешними инструментами — CSV-файл можно напрямую использовать в Python (Pandas, Matplotlib), R или импортировать в базы данных, что позволяет проводить расширенный статистический анализ, разделение кривых эквити или машинное обучение на основе паттернов принятия решений.
Все эти преимущества в совокупности поддерживают рабочий процесс профессиональной разработки, где решения основываются на чистых, достоверных данных, а не на смешанных агрегатах.
Обзор стандартной библиотеки
Разбираемся с CFileTxt
Класс CFileTxt — это компактный, но функциональный инструмент для работы с текстовыми файлами в рамках стандартной библиотеки. Он предоставляет высокоуровневый интерфейс, который скрывает низкоуровневую работу с файловыми хэндлами, предлагая при этом удобства, характерные для работы с CSV-файлами.
Ключевые методы и паттерны, которые мы используем:
- Open() — объединяет флаги записи, CSV-режима и совместного чтения; в более общем случае этот метод также может использоваться с указанием кодировки и расположения файла.
- Size() — быстро определяет, является ли файл новым (ноль байтов), поэтому заголовок записывается только один раз.
- WriteString() — эффективно добавляет текст; учитывает правила заключения полей CSV в кавычки, если установлен флаг.
- Flush() — краеугольный камень надежности — принудительно выполняет немедленную фиксацию на диске после критических операций записи.
- Seek() — перемещает указатель в конец для корректного добавления.
- Close() — освобождает ресурсы (вызывается автоматически в деструкторе).
Эти методы обеспечивают обработку файлов профессионального качества с минимальным количеством кода. Этот же класс одинаково ценен для сохранения файлов конфигурации советника, экспорта пользовательских отчетов, сохранения параметров оптимизации или реализации простой файловой сигнализации между скриптами.
Реализация
В этом разделе мы продолжаем развивать интерактивную торговую систему, созданную в Части 7. Наша цель — расширить ее функциональность за счет интеграции нового модуля: постоянно сохраняемого журнала сделок. Это не отдельный скрипт, а логическое развитие нашей существующей работы. Теперь мы перейдем к практическому процессу разработки, показав, как интегрировать возможность ведения журнала файлов из библиотеки Files/FileTxt.mqh в структуру нашего работающего советника. Основное внимание уделяется активной интеграции — тому, как мы берем нашу существующую визуальную и стратегическую логику и подключаем ее к новому слою данных для создания полного, самоописывающегося приложения.
Шаг 1: Расширение нашего инструментария с помощью новой библиотеки
Первым шагом в добавлении новой функциональности является включение необходимого модуля стандартной библиотеки. Мы добавляем операции с файлами в проект, который уже использует библиотеки canvas и trade, поэтому мы просто расширяем список директив #include в верхней части нашего существующего кода.
Код:
//--- 1. INCLUDES (Extending the list from Part 7) #include <Canvas\Canvas.mqh> // For drawing custom graphics (from Part 7) #include <Trade\PositionInfo.mqh> // For reading trade details (from Part 7) #include <Trade\Trade.mqh> // For executing trades (from Part 7) #include <Indicators\Trend.mqh> // For Moving Averages (from Part 7) #include <Files\FileTxt.mqh> // NEW: This adds the CFileTxt class for file operations.
С помощью этой единственной строки мы оснащаем нашу программу всеми необходимыми методами для создания, записи и управления текстовыми файлами. Класс CFileTxt становится новым инструментом в нашей мастерской, готовым к использованию вместе с нашими инструментами CCanvas и CTrade.
Шаг 2: Разработка класса CTradeJournal как нового компонента
Далее мы проектируем новый класс для управления всеми аспектами логирования. Мы разрабатываем его как самодостаточный компонент, который можно легко интегрировать в нашу основную программу. Его цель — скрыть сложность операций с файлами за простым интерфейсом.
Код:
//--- 3. THE JOURNAL CLASS (A new component we are adding) class CTradeJournal { private: CFileTxt m_file; // This is our handle to the physical file on disk. string m_filename; string m_sep; // Field separator for CSV format. public: // Constructor: Initializes the object's default state. CTradeJournal() : m_sep(",") {} // The initialization function we will call from OnInit(). bool Init(string filename) { m_filename = filename; // We define flags to control how the file is opened. int flags = FILE_WRITE|FILE_CSV|FILE_SHARE_READ; ResetLastError(); // Here, we attempt to open the file. If it fails, we report the error. if(m_file.Open(filename, flags) == INVALID_HANDLE) { Print("Journal Init Failed. Error: ", GetLastError()); return false; } // If the file is new, we write the column headers to define our data structure. if(m_file.Size() == 0) { string header = "Time,Ticket,Symbol,Action,Source,Profit\n"; m_file.WriteString(header); m_file.Flush(); // Immediately save the headers to disk. } // Move to the end of the file so all new logs are appended. m_file.Seek(0, SEEK_END); return true; }
В этом методе Init мы реализуем несколько лучших практик. Использование FILE_SHARE_READ позволяет другим программам просматривать лог-файл во время записи в него. Вызов GetLastError() предоставляет нам конкретную диагностическую информацию, если файл не может быть открыт, что крайне важно для отладки. Метод Flush() гарантирует, что заголовок физически записывается в хранилище, а не просто хранится в памяти.
Шаг 3: Написание основного метода логирования
Теперь мы создаем ядро класса: метод, который будет вызываться из любой точки нашей торговой системы для записи события. Его дизайн ориентирован на простоту для вызывающей стороны и надежность выполнения.
Код:
// This is the public method our main code will call to save an entry. void Log(ulong ticket, string action, string source, double profit) { // We construct a single, formatted CSV line from the input parameters. string line = StringFormat("%s,%d,%s,%s,%s,%.2f\n", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), ticket, _Symbol, action, source, // The key differentiator: "ALGO" or "HUMAN" profit); // We write the line and then force it to disk. m_file.WriteString(line); m_file.Flush(); // This ensures the data survives a terminal crash. // We also print to the Experts tab for immediate developer feedback. Print("Journal: ", action, " | Ticket: ", ticket, " | Source: ", source); }
Метод логирования — это место, где наши проектные замыслы воплощаются в код. Параметр source — это критически важная часть данных, которые мы добавляем в нашу систему; именно так мы выполняем требование различать автоматизированные и ручные действия. Использование Flush() после каждой записи — это преднамеренный компромисс, жертвующий ничтожно малой частью производительности ради абсолютной целостности данных — непреложного требования для торгового журнала.
Шаг 4: Интеграция нового компонента в существующую систему
После создания класса журнала мы интегрируем его в наш существующий советник. Это включает в себя добавление глобального экземпляра и его инициализацию вместе с другими нашими объектами.
Код:
//--- 4. GLOBAL OBJECTS (Adding to the existing list from Part 7) CCanvas ExtCanvas; // Existing object for visuals CPositionInfo ExtPosition; // Existing object for position data CTrade ExtTrade; // Existing object for trade execution CTradeJournal ExtJournal; // NEW: Our journaling object // Inside our existing OnInit() function: int OnInit() { // ... (Existing code to create indicators and canvas remains unchanged) ... // NEW INITIALIZATION: We start the journaling system. if(!ExtJournal.Init("HybridJournal.csv")) { return INIT_FAILED; // If logging fails, we fail the whole EA load. } return INIT_SUCCEEDED; }
Это чистая, модульная интеграция. Журнал становится полноценной подсистемой наравне с остальными компонентами. Рассматривая инициализацию как критически важную (вызов OnInit() завершится неудачей, если она не запустится), мы гарантируем, что система либо будет работать полностью, либо не будет работать вообще, избегая сценария, когда сделки совершаются без журналирования.
Шаг 5: Подключение логирования к торговым событиям
Последний и самый важный шаг — это добавление точек журналирования в существующую торговую логику. Мы вставляем вызовы логирования именно в те моменты, когда происходят значимые действия.
Сначала мы модифицируем нашу существующую алгоритмическую логику входа из Части 7.
Код:
// This is inside our existing CheckStrategy() function. // After a successful trade execution, we now add a logging call. if(ExtTrade.Buy(0.10, _Symbol, ask, sl, tp, "MA_Cross_Buy")) { // NEW LINE: We log this as an algorithmic entry. ExtJournal.Log(ExtTrade.ResultOrder(), "ENTRY_BUY", "ALGO", 0.0);
Во-вторых, мы улучшаем существующий обработчик OnChartEvent из Части 7, чтобы логировать совершенные вручную закрытия:
// Inside our existing OnChartEvent() function, where we handle bubble clicks. if(ExtPosition.SelectByTicket(ExtHitboxes[i].ticket)) { double final_profit = ExtPosition.Profit(); // Get profit before closing ExtTrade.PositionClose(ExtHitboxes[i].ticket); // Existing close command // NEW LINE: We log this as a human-triggered closure with the final profit. ExtJournal.Log(ExtHitboxes[i].ticket, "CLOSE_MANUAL", "HUMAN", final_profit); }
Эти вставки — кульминация нашей работы. Это минимальные, целенаправленные изменения, создающие максимальную ценность. Передавая соответствующую строковую метку источника в каждом контексте, мы гарантируем, что каждая запись в лог-файле будет помечена своим источником. Класс CTradeJournal, а следовательно, и библиотека CFileTxt, теперь служит единым регистратором для двух различных режимов работы нашей гибридной торговой системы.
То, что мы сделали, — классический пример итеративной разработки программного обеспечения. Мы начали с визуального торгового интерфейса (Часть 7) и теперь дополнили его слоем хранения данных (Часть 8). Модуль логирования не существует в вакууме; это зависимая подсистема, которая получает входные данные от успешной работы модулей canvas, выполнения сделок и информации о позициях. Следуя этому процессу включения библиотеки, проектирования класса, создания его глобального экземпляра и вызова его методов в стратегических точках, мы успешно обеспечили нашей торговой системе постоянную память, достигнув основной цели — различения алгоритмических и ручных действий в надежном, анализируемом формате.
Тестирование и результаты
После компиляции кода и подготовки советника тестирование проходит в несколько взаимодополняющих этапов. Вместе они проверяют обе части системы: логику алгоритмической торговли и журналирования, а также управляемые пользователем интерактивные компоненты. Разделение этих аспектов является преднамеренным и отражает то, как сама система различает автоматизированные и ручные действия.
Этап 1: Быстрая проверка с помощью тестера стратегий (алгоритмический путь)
Самый быстрый способ проверить основной механизм логирования — это использовать тестер стратегий MetaTrader 5. В этой среде советник обрабатывает исторические данные о ценах, а стратегия пересечения скользящих средних автоматически исполняет сделки. Вы можете включить визуальный режим, если хотите наблюдать за движением цены, но он не обязателен для проверки поведения логирования.
Важно понимать ограничения этого этапа. Ручное закрытие позиций с помощью пузырьков на графике нельзя проверить в стандартном бэктестинге, поскольку визуальный интерфейс и обработчик OnChartEvent() не активны. Поэтому этот этап сосредоточен исключительно на проверке алгоритмического выполнения и ведения журнала.
Для проведения теста запустите советник в тестере стратегий на период, содержащий несколько сигналов пересечения скользящих средних. Во время выполнения теста следите за вкладкой Experts в окне Strategy Tester. Для каждой сделки, выполненной стратегией, вы должны видеть сообщения следующего вида:
“Journal Entry Saved: ENTRY_BUY by ALGO.”
Эти сообщения подтверждают, что события алгоритмической торговли корректно регистрируются и передаются в журнал.
После завершения теста найдите сгенерированный CSV-файл в стандартном каталоге терминала:
<Terminal Data Path>\MQL5\Files\HybridJournal.csv
Открытие этого файла подтверждает, что все алгоритмические сделки зарегистрированы и последовательно помечены источником ALGO. Такой подход позволяет провести стресс-тестирование логики логирования для множества сделок в контролируемой и воспроизводимой среде, не дожидаясь реальных рыночных условий. Он также четко изолирует проверку алгоритма от любой логики ручного взаимодействия.

Рис. 1. Быстрый тест в тестере стратегий
Этап 2: Тестирование в реальном времени или визуальное тестирование (интегрированная система)
После проверки алгоритмического пути переходите к тестированию полностью интегрированной системы на графике в реальном времени или в среде визуального тестирования.
Для начала скомпилируйте файл Part8_HybridJournal.mq5 в MetaEditor и прикрепите советник к графику, например, EURUSD, на практическом таймфрейме, таком как M5 или H1. Убедитесь, что график работает в обычных реальных условиях или режиме визуального тестирования, а не в режиме бэктестинга только для оптимизации.
Сразу после прикрепления проверьте вкладку Experts. Вы должны увидеть подтверждающие сообщения о том, что canvas создан, а файл журнала инициализирован или открыт. Если возникают ошибки прав доступа к файлу, убедитесь, что терминал имеет права на запись в каталог MQL5\Files. Успешная инициализация подтверждает, что объект CTradeJournal успешно выполнил свою процедуру Init() и подготовил CSV-файл для записи.
Затем дайте стратегии работать до тех пор, пока не произойдет пересечение скользящих средних. Когда быстрая скользящая средняя пересекает медленную снизу вверх, советник автоматически выполняет ордер Buy. Успешное выполнение подтверждается тремя совпадающими сигналами: на вкладке Trade появляется новая позиция, на графике в точке входа отображается визуальный пузырь с информацией о тикете и прибыли, а на вкладке Experts выводится сообщение, подтверждающее действие "ENTRY_BUY action by ALGO".
Это подтверждает полную интеграцию алгоритмического пути выполнения и системы логирования в реальных условиях.
Для проверки пути ручного взаимодействия найдите красную кнопку “X” на пузырьке сделки и нажмите на нее один раз. Позиция должна немедленно закрыться, пузырь должен исчезнуть с графика, а на вкладке Experts должно отобразиться сообщение, подтверждающее действие "CLOSE_MANUAL action by HUMAN".
Эта последовательность подтверждает, что событие возникло в результате взаимодействия с пользователем, прошло через обработчик OnChartEvent(), прошло через интерфейсы позиций и сделок и было корректно записано в журнал с тегом источника "HUMAN". Окончательная прибыль или убыток фиксируются перед закрытием, обеспечивая точность исторических записей.
Этап 3: Проверка журнала и извлечение информации
Окончательное подтверждение корректной работы находится в CSV-файле, расположенном по адресу:
<Terminal Data Path>\MQL5\Files\HybridJournal.csv

Рис. 2. Навигация по папкам терминала
Открытие этого файла в электронной таблице показывает структурированную запись, содержащую время, тикет, символ, действие, источник и прибыль. Вы должны увидеть алгоритмические записи с тегом "ALGO" и ручные закрытия с тегом "HUMAN". Каждая строка немедленно записывается на диск, обеспечивая сохранение данных даже в случае неожиданных сбоев.
С этого момента журнал становится чем-то большим, чем просто инструментом проверки. Простая фильтрация позволяет анализировать алгоритмическую и ручную производительность отдельно, рассчитывая такие показатели, как количество сделок, общая прибыль или средняя доходность. Более сложный анализ можно провести, импортировав CSV-файл во внешние инструменты, что позволит построить отдельные кривые эквити, оценить риски или провести поведенческий анализ ручных вмешательств.
В совокупности этот процесс тестирования демонстрирует полный и дисциплинированный рабочий процесс. Тестер стратегий обеспечивает быструю и воспроизводимую проверку алгоритмического логирования, а тестирование в реальном времени или визуальное тестирование подтверждают взаимодействие и интеграцию. В результате получается прозрачная и проверяемая система, которая заменяет логику “черного ящика” анализом, основанным на данных, что позволяет реализовать главную цель: четко разделять и оценивать торговые решения, принимаемые алгоритмом и человеком.

Рис. 3. Содержимое файла HybridJournal.csv при тестировании в реальном времени.
На рис. 3 выше показан фрагмент CSV-файла, сгенерированного после тестирования в реальном времени. Как видно, большинство сделок были закрыты вручную в целях тестирования, поскольку для формирования автоматических условий выхода в условиях реального рынка потребовалось больше времени.
Заключение
В этом обсуждении серии мы успешно закрыли критический разрыв между выполнением и анализом. Усовершенствовав нашу предыдущую работу с помощью системы аудируемого журналирования, мы превратили простой торговый инструмент в механизм подотчетности, гарантирующий, что каждое решение будет четко связано с его источником. Это различие имеет решающее значение; оно помогает нам собирать важные данные для выборочного анализа производительности системы.
С технической точки зрения, этот проект демонстрирует, как компонент заголовка библиотеки CFileTxt обеспечивает сохранение данных профессионального уровня с минимальными усилиями. Используя стандартную библиотеку, мы избегаем сложности и уязвимости управления низкоуровневыми файловыми хэндлами и вместо этого сосредотачиваемся на логике приложения. В результате получается гибридный советник, который является надежным, интерактивным и самодокументирующимся, генерируя структурированные данные, поддерживающие дисциплинированный анализ и долгосрочную разработку. Он также доказывает важный момент: такие функции, как централизованное логирование и вывод CSV-файлов в формате Excel, доступны не только институциональным платформам, но и любому частному трейдеру-разработчику, корректно использующему библиотеку.
Ценность этой работы выходит далеко за рамки этого единственного советника. Представленные здесь паттерны проектирования намеренно являются повторно используемыми. Класс CTradeJournal представляет собой самодостаточный модуль, который может быть интегрирован в будущие проекты для немедленного повышения трассируемости и прозрачности событий. Отсюда вы можете расширить журнал дополнительными полями, поэкспериментировать с альтернативными форматами вывода или изучить более глубокую интеграцию, например, хранение данных в базе данных с использованием других компонентов стандартной библиотеки. Каждый последующий шаг основывается на том же фундаменте ясности и подотчетности, заложенном в этой части.
Вложения
| Имя исходного файла | Тип | Версия | Описание: |
|---|---|---|---|
| Part8_HybridJournal | Советник | 1.00 | Полный гибридный советник, интегрирующий взаимодействие с canvas и журналирование в CSV-файлах фиксацией источника решения. |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/21045
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Неопределённость как модель (Часть 8): Обобщение МНК
Возможности Мастера MQL5, которые вам нужно знать (Часть 89): Использование побитовой векторизации с перцептронными классификаторами
Нейросети в трейдинге: Долговременная память торговых сценариев (Окончание)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования