Исходный код
Для минимизации задержек (latency) и исключения проблем с безопасностью (блокировка вызовов внешних библиотек терминалом) мы будем использовать встроенный в MetaTrader 5 движок SQLite. Данный советник перехватывает каждый входящий тик через событие OnTick и мгновенно записывает его в локальную базу данных.
#property copyright "Quant Developer"
#property link "https://finfluct.com"
#property version "1.00"
#property strict
// Входные параметры
input string DB_FileName = "TickData.db"; // Имя файла базы данных
input string DB_TableName = "ticks"; // Имя таблицы
int db_handle = INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
// Открываем или создаем базу данных в общей папке всех терминалов
db_handle = DatabaseOpen(DB_FileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
if(db_handle == INVALID_HANDLE) {
Print("Ошибка открытия БД: ", GetLastError());
return INIT_FAILED;
}
// Создаем таблицу для хранения тиков, если она не существует
string query = "CREATE TABLE IF NOT EXISTS " + DB_TableName + " ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"symbol TEXT,"
"time INT,"
"msec INT,"
"bid REAL,"
"ask REAL,"
"volume REAL"
");";
if(!DatabaseExecute(db_handle, query)) {
Print("Ошибка создания таблицы: ", GetLastError());
DatabaseClose(db_handle);
return INIT_FAILED;
}
// Создаем индекс для оптимизации будущих аналитических выборок
string index_query = "CREATE INDEX IF NOT EXISTS idx_symbol_time ON " + DB_TableName + " (symbol, time);";
if(!DatabaseExecute(db_handle, index_query)) {
Print("Ошибка создания индекса: ", GetLastError());
}
Print("Экспорт тиков успешно запущен. БД: ", DB_FileName);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
if(db_handle != INVALID_HANDLE) {
DatabaseClose(db_handle);
Print("Соединение с БД закрыто.");
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
MqlTick last_tick;
if(SymbolInfoTick(_Symbol, last_tick)) {
// Формируем SQL-запрос на вставку данных
string query = StringFormat(
"INSERT INTO %s (symbol, time, msec, bid, ask, volume) VALUES ('%s', %lld, %d, %f, %f, %f);",
DB_TableName, _Symbol, last_tick.time, last_tick.time_msc % 1000, last_tick.bid, last_tick.ask, (double)last_tick.volume_real
);
if(!DatabaseExecute(db_handle, query)) {
Print("Ошибка записи тика: ", GetLastError());
}
}
} Разбор параметров
DB_FileName: Имя файла базы данных SQLite. Использование флагаDATABASE_OPEN_COMMONсохраняет файл в общую директорию данных всех терминалов MetaTrader 5, что упрощает доступ внешних скриптов (например, на Python).DB_TableName: Имя таблицы, в которую будут записываться поля тика: символ, Unix-время, миллисекунды, цены Bid/Ask и реальный объем.db_handle: Дескриптор соединения с базой данных, возвращаемый функциейDatabaseOpen. Используется для всех последующих транзакций.MqlTick: Встроенная структура MQL5, содержащая наиболее полную информацию о последнем изменении цены, включая время в миллисекундах (time_msc).
Как запустить
1. Откройте MetaEditor в MetaTrader 5 (клавиша F4) и создайте новый советник (Expert Advisor).
2. Скопируйте представленный выше код, вставьте его в редактор и скомпилируйте (клавиша F7).
3. Перетащите скомпилированный советник на график интересующего вас финансового инструмента. С этого момента каждый новый тик будет мгновенно записываться в базу данных.
4. Найти полученный файл базы данных можно в общей папке терминалов по пути: C:\Users\[Имя_Пользователя]\AppData\Roaming\MetaQuotes\Terminal\Common\Files\.
Для построения распределенных систем сбора данных, где требуется централизованное хранилище корпоративного уровня, рекомендуем использовать PostgreSQL. Подробное руководство по такой архитектуре доступно в нашей статье Интеграция MetaTrader 5 с PostgreSQL через libpq.dll в MQL5.
При разработке сложных сеточных роботов, тестируемых на собранной тиковой истории, часто возникает необходимость оптимизации просадок. Ознакомьтесь с готовым решением в материале MQL4: Алгоритм Частичного Закрытия Сетки для Снижения Просадки (Partial Grid Close).
Если вы планируете использовать накопленные тиковые данные для тестирования сложных портфельных стратегий, вам обязательно пригодится статья про Мультивалютное тестирование в MT5: обход ограничений тестера.




