Обсуждение статьи "Работа с СУБД MySQL из MQL5 (MQL4)"

 

Опубликована статья Работа с СУБД MySQL из MQL5 (MQL4):

Статья посвящена разработке интерфейса между MQL и СУБД MySQL. В ней рассматриваются существующие на данный момент практические решения и предлагается более удобный вариант исполнения библиотеки для работы с СУБД. В статье дано подробное описание функций, структуры интерфейса, приведены примеры и описаны некоторые тонкости при работе с MySQL. В плане программного решения, к статье прикреплены архивы с динамическими библиотеками, документацией и примерами-скриптами для языков MQL4 и MQL5.

Проблема взаимодействия MQL с базами данных уже давно поднималась и актуальна по сей день. С использованием СУБД, возможности платформы MetaTrader значительно расширяются: хранение и анализ истории котировок, копирование сделок с одной торговой платформы на другую, трансляция котировок/сделок в режиме реального времени, выполнение громоздких аналитических вычислений на стороне сервера и/или по расписанию, мониторинг и удаленное управление счетом с использованием Web-технологий.

Так или иначе, попытки подружить MQL и MySQL предпринимались и решения регулярно выкладывались в CodeBase.

К примеру "MySQL оболочка - библиотека для MetaTrader 4" - это тот проект, с которого многие начинали вести свою разработку с какими-либо дополнениями. На мой взгляд, из неудобств данного решения - это выделение специальных массивов для получения данных из БД.

Проект "MySQL logger 1 - эксперт для MetaTrader4" является узкоспециализированным, он не использует обертку для обращения к стандартной библиотеке libmysql.dll. Поэтому с MetaTrader4 Build 600+ он уже работать не будет, так как произошла замена символьных типов char на wchar_t, да и использование типа int вместо указателя на структуру TMYSQL вносит так называемые memory leaks в проект (выделенную память невозможно контролировать/освободить).

Еще один проект, который обращает на себя внимание, это "EAX_Mysql - MySQL library - библиотека для MetaTrader 5". Выполнен достаточно грамотно и на хорошем уровне. Перечень недоработок, о которых говорит сам автор, накладывает некоторые ограничения в его использовании.

Для тех, кто сталкивался с необходимостью использования СУБД в своих MQL-проектах всегда стоит выбор - либо написать "что-то свое" и знать каждый винтик, либо использовать/адаптировать какое-либо стороннее решение, а также научиться им пользоваться и "выловить" все "грабли", мешающие работе своего проекта.

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

Более того, встречались и абсурдные решения, например: DML/DDL операции (вставка/изменение/удаление данных, создание/удаление объектов БД) производились с использованием стандартной libmysql.dll, а выборка данных (SELECT) производилась фактически HTTP запросом (с использованием inet.dll) к PHP скрипту, расположенному на Web-сервере на стороне MySQL сервера. Именно в PHP скрипте были прописаны SQL запросы.

Иными словами, чтобы запустить данный проект, необходимо было иметь в наличии настроенными и запущенными: MySQL-сервер, Apache/IIS Web-сервер, PHP/ASP-скрипты на стороне сервера... Достаточно большое количество технологий в связке. Разумеется, в каких-то условиях это может быть приемлемо, но когда стоит задача всего лишь выборки данных из БД - это нонсенс. К тому же сопровождение такого громоздкого решения будет отнимать много времени.

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

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

В основу интерфейса MQL <-> MySql, о котором далее пойдет речь, был положен типичный подход, который используется в Oracle PL/SQL, MS SQL T-SQL, AdoDB - работа с курсорами. Данный интерфейс был разработан с точки зрения удобства программирования и сопровождения, плюс минимум компонентов. Реализован он виде DLL-обертки к стандартной библиотеке libmysql.dll и набора интерфейсных функций в виде .mqh файла.


1. Интерфейс MQL <-> MySQL

Взаимодействие между терминалом MetaTrader (посредством MQL-программ) реализуется с помощью:

Схема взаимодействия MQL с MySQL

Автор: Eugeniy Lugovoy

 
DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);

а не создаст ли это большую нагрузку при вызове на каждый тик???

не логичнее ли подключение у базе сделать в init и затем использовать уже для доступа идентификатор ? 

 
DKeN:

а не создаст ли это большую нагрузку при вызове на каждый тик???

не логичнее ли подключение у базе сделать в init и затем использовать уже для доступа идентификатор ? 

Приветствую. Для Expert Advisors и Indicators соединение с БД выполняется как раз в функции инициализации. В статье нет рекомендаций по поводу установки соединения с БД на каждом тике. Приведены лишь примеры скриптов, а у скриптов, сами понимаете, нет инициализации.
 

Евгений, спасибо за статью. Интересный материал по СУБД.

Есть такая проблема.

У меня MetaTrader5, x64, 975 build.

При запуске скрипта "MySQL-001" получаю ошибку:

RL      1       12:41:22.443    MySQL-001       'C:\Program Files\MetaTrader5\MQL5\libraries\MQLMySQL.dll' is not 64-bit version
PG      1       12:41:22.474    MySQL-001 (AUDCAD.e,M1) Cannot load 'C:\Program Files\MetaTrader5\MQL5\libraries\MQLMySQL.dll'
DK      2       12:41:23.677    MySQL-001 (AUDCAD.e,M1) Cannot call 'cMySqlVersion', '..\libraries\MQLMySQL.dll' is not loaded
ID      2       12:41:23.677    MySQL-001 (AUDCAD.e,M1) unresolved import function call

Причина в том, как понимаю, система пытается загрузить 64-битную библиотеку...

 
denkir:

Евгений, спасибо за статью. Интересный материал по СУБД.

Есть такая проблема.

У меня MetaTrader5, x64, 975 build.

При запуске скрипта "MySQL-001" получаю ошибку:

Причина в том, как понимаю, система пытается загрузить 64-битную библиотеку...

Да, проект скомпилирован для x32, так как в основном работаю с 32-битными терминалами. Проблему понял, в ближайшие дни скомпилирую и проверю под MT5 x64. 

Спасибо за замечание. 

 

Версия библиотеки для Metatrader 5 - x64

- Проект MQLMySQL.DLL перекомпилирован под x64 (исходники не корректировались).

- Стандартная LibMySQL.DLL взята из последнего стабильного дистрибутива MySQL v5.6.21 x64

Собственно говоря, для тех кто пытался запустить проект под MT5 x64, можно заменить лишь содержимое директории MQL5\Libraries. Исходный код MQL программ править или рекомпилировать не нужно.

Еще раз спасибо Денису (denkir) за замечание, совсем забыл я про пользователей x64.

Файлы:
 

Прочёл и прослезился. Ничего против автора не имею. Надеюсь, он адекватно относится к критике. Так вот:

1. Зачем писать обёртку в виде еще одной DLL, если и без неё всё прекрасно работает? Язык MQL уже не на той стадии развития чтобы писать такие костыли которые нередко превращаются в грабли.

2. Почему в результате всей этой работы не написан класс в котором есть всё необходимое, и который устраняет недочеты предшественников, на которые ссылается автор?

3. Особо хочу отметить вот это:

string SQL;
SQL = "INSERT INTO EURUSD(Ask,Bid) VALUES (1.3601,1.3632);";
SQL = SQL + "INSERT INTO EURUSD(Ask,Bid) VALUES (1.3621,1.3643);";
SQL = SQL + "INSERT INTO EURUSD(Ask,Bid) VALUES (1.3605,1.3629);";

Вообще-то все делается куда проще:

string SQL="INSERT INTO EURUSD(Ask,Bid) VALUES (1.3601,1.3632),(1.3621,1.3643),(1.3605,1.3629);";

В общем статья написана в стиле "Смотрите, что я умею!" вместо "Смотрите и учитесь как это нужно делать".

 
avoitenko:

Прочёл и прослезился. Ничего против автора не имею. Надеюсь, он адекватно относится к критике. Так вот:

1. Зачем писать обёртку в виде еще одной DLL, если и без неё всё прекрасно работает? Язык MQL уже не на той стадии развития чтобы писать такие костыли которые нередко превращаются в грабли.

2. Почему в результате всей этой работы не написан класс в котором есть всё необходимое, и который устраняет недочеты предшественников, на которые ссылается автор?

3. Особо хочу отметить вот это:

Вообще-то все делается куда проще:

В общем статья написана в стиле "Смотрите, что я умею!" вместо "Смотрите и учитесь как это нужно делать".

Отвечу по порядку.

Надо сказать что начало проекта было заложено достаточно давно, когда еще язык MQL не был на нынешней стадии развития и в MQL4 отсутствовали не то что классы, структур не было.

А программное решение должно было работать и для MQL4 и для MQL5 с минимальными расходами на переход от MQL4 к MQL5 (при необходимости). Доработки проекта велись до недавнего времени.

Именно поэтому проект не был реализован как класс. Хотите класс? Нет проблем - напишите! Никто Вам не запрещает.

Теперь касательно 3-х INSERT вместо одного. Я написал именно так (и это авторское право) по следующим причинам:

- не нарушается общепринятый стандарт SQL'92, SQL'2000 (ваш вариант - особенности синтаксиса именно MySQL bulk insert);

- начинающему программисту в этой области легче будет прочесть и разобраться;

- демонстрация выполнения именно 3-х инструкций INSERT, а не одной.

Multi statements может включать любые DML/DDL/DCL операции, Ваш пример ограничен операцией INSERT над одной таблицей.

P.S. Статья написана была в стиле "Берите и пользуйтесь".

 

Спасибо за статью! Сколько решений не пробовал везде одно и то же, если Вас не затруднит посмотрите, пожалуйста, на лог, я ничего понять не могу....

MySQL сервер: 

  • Сервер: localhost via TCP/IP
  • Версия сервера: 5.6.10
  • Версия протокола: 10
  • Пользователь: root@localhost
  • MySQL-кодировка: UTF-8 Unicode (utf8) 
  • База InnoDB, UTF8-General-Ci

MT5 build 1035

OS: Win8.1 x64

Файлы:
log_.txt  19 kb
 

Приветствую.

У Вас операционка x64, Вы точно используете DLLки для 64-битной версии?

Они прикреплены в одном из постов обсуждении (mqlmysql_for_mql5_x64.zip 1264 kb)

В статье были библиотеки только для x86 операционных систем.

Кстати, а тестовые примеры из архива отрабатывают ? 

<<чуть позже>>

Смущает эта строка: Tester file added: libraries\MQLMySQL.dll. 89626 bytes loaded 

Оригинальный размер файла x64 MQLMySQL.dll = 89600 байт, а не 89626.

Какой антивирус у Вас? 

 
mat.twg:

Спасибо за статью! Сколько решений не пробовал везде одно и то же, если Вас не затруднит посмотрите, пожалуйста, на лог, я ничего понять не могу....

MySQL сервер: 

  • Сервер: localhost via TCP/IP
  • Версия сервера: 5.6.10
  • Версия протокола: 10
  • Пользователь: root@localhost
  • MySQL-кодировка: UTF-8 Unicode (utf8) 
  • База InnoDB, UTF8-General-Ci

MT5 build 1035

OS: Win8.1 x64

Это ошибка MT5 build 1035, x64. Сервисдеск поставлен в известность и гарантируют исправление в следующем билде.

Проблема заключается в приеме MQL программой строковых значений из динамической библиотеки.

В MT5 build 1035 x32, работает без этой ошибки. 

Причина обращения: