Español Português
preview
Моделирование рынка: Первые шаги на SQL в MQL5 (I)

Моделирование рынка: Первые шаги на SQL в MQL5 (I)

MetaTrader 5Тестер |
30 1
Daniel Jose
Daniel Jose

Введение

Здравствуйте всем и добро пожаловать в очередную статью о создании системы репликации/моделирования.

В предыдущей статье Моделирование рынка (Часть 24): Первые шаги на SQL (VII) мы завершили то, что я считаю самой базовой основой, необходимой для того, чтобы вы, даже без опыта работы с SQL, могли хотя бы понять, что мы будем делать дальше. Это связано с тем, что мы переходим к новому этапу разработки системы репликации/моделирования и здесь знание SQL будет иметь первостепенное значение для того, чтобы вы могли следить за этой и последующими статьями.

Не беспокойтесь, если вы только начали изучать SQL и опираетесь лишь на знания, полученные в предыдущих статьях. При правильном использовании и понимании данного материала его будет уже достаточно для решения многих действительно необходимых нам задач. На данном первом этапе мое истинное намерение состоит в том, чтобы мы оставались в рамках SQLite, поскольку он уже интегрирован в MetaTrader 5, что значительно облегчает его использование без необходимости прибегать к DLL или даже к сокетам.

Итак, если вы уже используете SQLite в своих программах на MQL5, данная статья ничего нового вам не добавит к тому, что вы уже знаете. Но если вы только начинаете свой путь в этом мире, где использование баз данных должно рассматриваться со всей серьезностью, и вы не знаете, как это реализовать с помощью MQL5, я думаю, лучше всего вам устроиться поудобнее в кресле и внимательно изучить эту статью. Потому что здесь мы разберем, как начать работу с базой данных SQL, используя для этого язык MQL5. Однако мы будем использовать не любую базу данных, а SQLite. И, как вы уже видели в предыдущих статьях, мы можем многое сделать в рамках данной системы. Всё это с минимальными усилиями на языке MQL5.


Создание базы данных SQL с помощью MQL5

Хорошо. Первым делом нужно будет создать базу данных. Как мы уже видели в предыдущих статьях, сделать это довольно просто и не составляет труда. Можно работать непосредственно в MetaEditor, из командной строки или с помощью специальной программы для редактирования SQL-скриптов. Но я хочу, чтобы вы поняли, что нам не обязательно делать это именно так. Можно реализовать это напрямую с помощью программирования, используя для нашей цели тот или иной язык.

Если поискать, то можно найти множество людей, которые объясняют один и тот же процесс разными способами, используя для этого разные языки. Но если присмотреться, то можно заметить, то в сущности всё сводится к SQL. И именно в этот момент события становятся наиболее интересными. Это связано с тем, что, если вы поймете эти принципы, вы сможете перевести что-то, сделанное, например, на JAVA, чтобы реализовать это здесь, на MQL5. Причина в том, что в конечном итоге именно SQL-код будет фактически обрабатывать данные и работать с записями. JAVA будет служить лишь для того, чтобы предоставить более дружелюбный интерфейс для определенного типа пользователей.

Вы встретите такой же подход в VBA, где мы используем Excel для представления данных, которые будут получены напрямую с помощью SQL. Вот почему так важно понимать, как на самом деле работает SQL-код. Потому что в конечном итоге мы будем использовать SQL. Язык, выступающий в качестве поддержки для SQL, будет служить лишь для представления данных, которые нам предоставит SQL.

Понимание того, как всё на самом деле работает, очень поможет вам в дальнейшем. Итак, начнём с самого основного принципа: создания файла базы данных в SQLite с помощью MQL5. Поскольку наша цель — объяснить это максимально наглядно, мы воспользуемся самым простым способом. Другими словами, мы воспользуемся скриптом MQL5. Это связано с тем, что скрипт легче понять и проще протестировать. Первый фрагмент кода, который мы будем использовать, можно увидеть ниже:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Basic script for SQL database written in MQL5"
04. #property version   "1.00"
05. #property script_show_inputs
06. //+------------------------------------------------------------------+
07. input string user01 = "DataBase01";        //FileName
08. //+------------------------------------------------------------------+
09. void OnStart()
10. {
11.     string szFileName = user01 + ".sqlite";
12.     int handleDB;
13.     
14.     if ((handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE)
15.     {
16.         Print("Unable to create or open the file ", szFileName);
17.         return;
18.     }
19.     DatabaseClose(handleDB);
20.     Print("Database file saved successfully..");
21. }
22. //+------------------------------------------------------------------+

Код на языке MQL5

Это простейший код для открытия или создания файла базы данных. Всё это делается с помощью MQL5 и SQLite. Обратите внимание, это очень легко понять. В строке 07 мы позволяем пользователю скрипта указать имя базы данных, которую необходимо создать или открыть. Имейте в виду, что мы не указываем расширение файла для использования, мы его укажем позже. Используемое расширение указано в строке 11. Прошу заметить, что здесь мы используем имя, которое нам сообщит пользователь скрипта, и мы объединим его с другой строкой, которая в данном случае будет расширением имени файла.

Важно отметить, что мы можем использовать любое расширение, но я бы посоветовал вам использовать то, которое указывает на тип используемого файла. Для базы данных SQL чаще всего используется расширение .DB или, в случае SQLite, .sqlite, поскольку мы можем использовать элементы, специфичные для SQLite. Это уже объяснялось в предыдущих статьях. Если у вас возникнут какие-либо сомнения, ознакомьтесь с ними, а также с приведенными в них источниками для лучшего понимания темы.

Итак, поскольку мы будем работать с файлами, нам нужен идентификатор. Он указан в строке 12. Уже в строке 14 мы используем функцию DatabaseOpen, которая входит в состав MQL5, для открытия или даже создания файла базы данных. На этом этапе следует отметить один важный момент. Можно создать файл базы данных в трех разных местах. Всё это выполняется с помощью одной и той же функции DatabaseOpen. Места хранения данных следующие: первое — в оперативной памяти, что означает, что после закрытия базы данных она перестанет существовать. Это очень полезно в определённых ситуациях, но в нашем случае мы его использовать не будем, по крайней мере, пока. Второе местоположение,

как и в третьем случае, будет зависеть от аргументов, переданных функции DatabaseOpen. Прошу заметить, что в приведенном коде мы используем аргументы DATABASE_OPEN_CREATE и DATABASE_OPEN_READWRITE. В результате этого файл базы данных будет создан где-то в папке MQL5\Files. Я говорю "где-то", потому что в указанном пользователем имени может содержаться допустимое имя каталога. И если это произойдёт, нам потребуется перейти в каталог, указанный пользователем. В любом случае, данный каталог будет находиться внутри папки MQL5\Files именно из-за указанных аргументов.

Однако это местоположение может отличаться, если, помимо аргументов, которые мы видели в коде, мы также добавим аргумент DATABASE_OPEN_COMMON. Это изменит папку с MQL5\Files на COMMON\Files. "Однако, где находится папка COMMON, как мне получить к ней доступ?" Подобные сомнения встречаются довольно часто. Итак, уважаемый читатель, если вы не знаете, где находится данная папка, просто перейдите по следующему пути на вашем локальном диске:

C:\Users\<UserName>\AppData\Roaming\MetaQuotes\Terminal

В этом месте вы найдете папку COMMON, а внутри нее — папку Files. Не забудьте заменить имя <UserName> на имя пользователя, вошедшего в систему Windows.

Если создание или доступ к указанному файлу запрещены, в терминале MetaTrader 5 будет выведено сообщение из строки 16. Сразу после этого, в строке 17, скрипт закроется. Но если всё прошло идеально, в строке 19 мы закроем файл базы данных, а в строке 20 выведем в терминал MetaTrader 5 сообщение о том, что всё успешно завершено. В результате вы сможете открыть его в MetaEditor и увидеть нечто похожее на то, что показано на следующем изображении:

На данном этапе мы можем использовать SQL через MetaEditor. Однако мы будем использовать его через MQL5. Тем не менее, можно использовать MetaEditor или даже программы, показанные в предыдущих статьях при объяснении SQL, чтобы проследить за тем, что будет сделано с помощью MQL5. На первых этапах изучения использования SQLite в MQL5 важно иметь возможность отслеживать ход выполнения операций. Для этого очень полезным будет знание основ SQL. Поэтому используйте вспомогательные материалы из предыдущих статей, чтобы ещё больше ускорить процесс обучения. То, что мы будем здесь делать, довольно интересно.

Отлично, теперь, когда мы уже знаем, как создать или открыть файл базы данных SQL, мы можем перейти к следующему этапу. Но прежде позвольте прояснить кое-что, что может вызвать у вас сомнения. Когда говорим, что мы будем открывать файл, получать доступ к данным и добавлять или изменять записи в SQL, я хочу, чтобы вы помнили, что мы будем использовать SQLite. Это связано с тем, что для выполнения тех же действий, которые мы будем делать здесь, но с использованием другой реализации SQL, например, MySQL или SQL Server, способ их выполнения будет немного отличаться. Так что не путайте вещи.

SQL как язык — один. Есть несколько типов реализации, и каждый из них позволяет нам делать больше или меньше вещей. Здесь мы будем работать исключительно с SQLite, по крайней мере, на начальном этапе реализации. В будущем можно передумать, но если это произойдет, мы объясним, как перейти с SQLite на другую реализацию SQL. Однако, вам не стоит бояться изучать SQL, потому что язык SQL всегда будет одним и тем же, независимо от приложения или реализации, которая его использует.


Создание первых таблиц

Как и в случае с объяснением команд SQL, мы сделаем нечто очень похожее. Это нужно для того, чтобы переход от программирования на чистом SQL к SQL, встроенному в другой код, был плавным. В данном случае, код, который будет получать эти команды, — это MQL5. К счастью, разработчики MQL5 проделали отличную работу и сделали всё достаточно простым для понимания и использования. Таким образом, нам действительно нужно будет научиться использовать шесть функций из всех доступных в MQL5 для работы с базами данных. "Но тогда другие функции становятся лишними?" Нет, я этого не говорил. Я сказал, что нужно научиться использовать шесть функций. А зная, как работать с этими шестью функциями, и немного разбираясь в SQL, мы сможем безупречно справиться с любой ситуацией, связанной с ними. По крайней мере, это касается работы с SQLite, который входит в состав MQL5.

Если мы собираемся использовать SQLite через DLL, то способ работы будет немного отличаться. Это связано с тем, что в этом случае мы будем выполнять вызовы напрямую, используя SQLite, включенный в DLL-файл. Итак, если это ваш конкретный случай, я рекомендую изучить документацию по использованию SQLite через DLL, поскольку здесь всё немного отличается от того, что мы рассмотрим.

Давайте теперь посмотрим, какие функции нам нужно будет научиться использовать. Две из них мы уже показали, а именно: DatabaseOpen и DatabaseClose. Но нам также понадобятся функции DatabaseExecute, DatabasePrepare, DatabaseReadBind и DatabaseFinalize. Конечно, умение использовать остальные функции очень поможет во многих ситуациях. Но с помощью этих шести мы теперь можем очень легко построить практически всё что угодно. Разумеется, при условии, что будут хорошие базовые знания в программировании на SQL.

Благодаря тому, о чем мы рассказали в предыдущих статьях, вы, по крайней мере, уже сможете делать некоторые довольно интересные вещи. Кроме того, разумеется, вы сможете делать такие вещи, которые многие не сумели бы сделать так, как это сможете сделать вы. Но, как я и обещал, мы будем делать всё постепенно, чтобы все могли следить за происходящим и понимать, что происходит.

Хорошо. Как вы, возможно, заметили в предыдущих статьях, всё, что мы делаем, так или иначе связано с таблицами, так что начнём с основ данной темы. Таким образом, наш новый скрипт представлен ниже.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Basic script for SQL database written in MQL5"
04. #property version   "1.00"
05. #property script_show_inputs
06. //+------------------------------------------------------------------+
07. input string user01 = "DataBase01";        //FileName
08. //+------------------------------------------------------------------+
09. void OnStart()
10. {
11.     string szFileName = user01 + ".sqlite",
12.              szRequestSQL;
13.     int handleDB;
14.     
15.     if ((handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE)
16.     {
17.         Print("Unable to create or open the file ", szFileName);
18.         return;
19.     }
20.     szRequestSQL = "CREATE TABLE IF NOT EXISTS tb_Symbol(id PRIMARY KEY, symbol NOT NULL UNIQUE);";
21.     if (!DatabaseExecute(handleDB, szRequestSQL))
22.     {
23.         Print("Request execution failed.");
24.         DatabaseClose(handleDB);
25.         return;
26.     }
27.     DatabaseClose(handleDB);
28.     Print("Database file saved successfully.");
29. }
30. //+------------------------------------------------------------------+

Код на языке MQL5

При запуске данного скрипта в MetaTrader 5 мы получим такой результат:

"Ух ты, это здорово. Но как это было сделано?" Просто. Мы всего лишь использовали то, что видели в предыдущих статьях, где мы объясняли SQL. Но здесь мы всё сделали с помощью MQL5. Как? Взяв за основу скрипт, который мы видели в предыдущем разделе, мы добавляем в код всего лишь несколько строк. С одной оговоркой: данный код пока не имеет корректной структуры. Здесь я хочу показать вам, как мы можем сделать то же самое, что видели раньше. Таким образом, мы добавляем строку 12, которая представляет собой строку, принимающую SQL-команду, которую мы хотим выполнить. В строке 20 мы указываем, что это за команда. В данном случае мы попросим SQL создать таблицу с именем tb_Symbol, если она отсутствует в базе данных.

Сразу после этого, используя функцию DatabaseExecute, мы указываем SQLite выполнить SQL-команду. Если данная процедура не удастся, в строке 23 терминала MetaTrader 5 будет выведено сообщение. Поскольку база данных открыта, нам необходимо её закрыть, что и делается в строке 24. В строке 25 мы завершили выполнение скрипта в MetaTrader 5.

Теперь обратите внимание на один момент. При использовании SQLite, который входит в состав MetaTrader 5, любую команду, которую мы хотим отправить в SQLite для выполнения, мы будем делать через DatabaseExecute. Однако это подходит только в тех случаях, когда мы хотим отдавать команды SQL. При выполнении запросов нам также потребуется использовать другие функции. Прошу заметить, как всё складывается, и мы можем разработать то, что нам нужно.

Итак, прежде чем перейти к работе с запросами, давайте сделаем данный MQL5-скрипт немного более универсальным и, следовательно, более подходящим для использования с создаваемой нами базой данных. Поскольку структуру можно изменять, мы можем превратить данный же скрипт в класс. Хотя на данном этапе это может показаться простым, это значительно поможет, поскольку мы сможем сделать код более пригодным для повторного использования и, следовательно, более безопасным и стабильным. Затем тот же самый код, который мы видели раньше, преобразуем в код, показанный ниже, только теперь с использованием классов:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Basic script for SQL database written in MQL5"
04. #property version   "1.00"
05. #property script_show_inputs
06. //+------------------------------------------------------------------+
07. input string user01 = "DataBase01";         //FileName
08. //+------------------------------------------------------------------+
09. class C_DB_SQLite
10. {
11.     private :
12.             int     m_handleDB;
13.     public  :
14. //+------------------------------------------------------------------+
15.             C_DB_SQLite(const string szFileName)
16.                     :m_handleDB(INVALID_HANDLE)
17.                     {
18.                             if ((m_handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE)
19.                             {
20.                                     Print("Unable to create or open the file ", szFileName);
21.                                     return;
22.                             }
23.                     }
24. //+------------------------------------------------------------------+
25.             ~C_DB_SQLite()
26.                     {
27.                             DatabaseClose(m_handleDB);
28.                             Print("Closing Database...");
29.                     }
30. //+------------------------------------------------------------------+
31.             bool Command(const string szRequestSQL)
32.                     {
33.                             bool ret = DatabaseExecute(m_handleDB, szRequestSQL);                           
34.                             Print("Request execution: ", (ret ? "Success" : "Failed"), "...");
35.                             return ret;
36.                     }
37. //+------------------------------------------------------------------+
38. };
39. //+------------------------------------------------------------------+
40. void OnStart()
41. {
42.     C_DB_SQLite *DB;
43.     
44.     DB = new C_DB_SQLite(user01 + ".sqlite");
45.     
46.     (*DB).Command("CREATE TABLE IF NOT EXISTS tb_Symbol(id PRIMARY KEY, symbol NOT NULL UNIQUE);");
47.     
48.     delete DB;      
49. }
50. //+------------------------------------------------------------------+

Код на языке MQL5

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

Например, мы не можем использовать идентификатор, если он не был инициализирован. И, поскольку инициализация выполняется через конструктор класса, мы имеем гарантию того, что всегда будем использовать подходящий идентификатор. Это можно увидеть в строке 33, где мы используем идентификатор для отправки команды в SQL.

А теперь я хочу, чтобы вы обратили внимание на следующий момент: Многие могут посчитать излишним использование или даже создание класса для инкапсуляции системы связи с SQLite, но давайте немного подумаем об этом, и, возможно, это изменит ваше мнение. Можно подумать: "зачем мне создавать класс только для того, чтобы использовать SQLite, включенный в MetaTrader 5? Для этого гораздо проще использовать функции MQL5 напрямую. Тем более что я не собираюсь интенсивно использовать SQL в своих программах". С этой точки зрения я должен с вами согласиться, но давайте рассмотрим это в несколько более широком контексте. MQL5 позволяет нам легко и просто получить доступ к встроенному в MetaTrader 5 SQLite. Хорошо. Но нам не следует ограничиваться этим.

Если мы разрабатываем целый спектр приложений или даже систему, которая использует SQLite, встроенную в MetaTrader 5, и при этом используем исключительно функции MQL5, то в какой-то момент мы окажемся ограничены использованием только и исключительно SQLite из MetaTrader 5. Мы не сможем использовать собственную сборку SQLite в DLL-файле. И что самое ужасное: если в какой-то момент мы решим использовать другую реализацию SQL, будь то MySQL, SQL Server или любую другую, нам придётся много работать, переписывая весь свой код, чтобы учесть необходимые зависимости. Это связано с тем, что MySQL и SQL Server, о которых мы только упоминали, не используют файловую систему, к которой можно получить доступ с помощью MQL5. Мы даже можем использовать MQL5, но для этого нам придётся воспользоваться другим инструментом, применение которого мы уже демонстрировали в этой серии. Речь идёт о сокетах.

Иными словами, для доступа к базам данных, использующим клиент-серверную архитектуру, нам придётся использовать сокеты. Если наша реализация с самого начала была задумана с использованием системы классов, чтобы скрыть детали реализации, то всё, что нам потребуется сделать, — это изменить класс, расширив или адаптировав его так, чтобы он мог обеспечить необходимую поддержку для связи через сокеты. Это значительно упрощает весь процесс разработки. Потому что, если нам потребуется изменить реализацию SQL, заменив SQLite, используемый в MetaTrader 5, на собственную SQLite, скомпилированную в DLL, это будет легко сделать.

То же самое относится и к случаю, когда нам потребуется изменить реализацию. При переходе от SQLite, основанной на файлах, к клиент-серверной SQL, у нас не возникнет больших проблем. Достаточно будет просто изменить принцип работы класса, и остальная часть кода выиграет от этих изменений. Всё просто. Поэтому не стоит недооценивать преимущества разработки приложения с расчетом на то, что в будущем способ его работы может измениться. Помните: технологии со временем меняются. Делать реализацию, которая была бы заблокирована или неразрывно связана с чем-то одним, — не самый лучший выбор.


Понимание некоторых моментов

Перед тем, как продолжить, я хочу показать вам кое-что. Потому что очень важно, чтобы вы это поняли. Давайте сделаем следующее. В предыдущих статьях мы создали взаимосвязь между таблицами для построения реляционной базы данных. Мы объяснили, как это можно сделать, а также преимущества и недостатки такого способа структурирования базы данных по принципу реляционного представления. Но когда мы будем работать с большим количеством SQL-команд через SQLite, встроенный в MetaTrader 5, нам придется принять некоторые меры предосторожности. Или, вернее, нам нужно придумать способ сделать это более безопасно.

То, что мы покажем, заставит нас принять ряд решений в следующей статье. Внимательно изучите приведенный ниже код MQL5:

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Basic script for SQL database written in MQL5"
04. #property version   "1.00"
05. #property script_show_inputs
06. //+------------------------------------------------------------------+
07. input string user01 = "DataBase01";        //FileName
08. //+------------------------------------------------------------------+
09. class C_DB_SQLite
10. {
11.     private    :
12.         int    m_handleDB;
13.     public    :
14. //+------------------------------------------------------------------+
15.         C_DB_SQLite(const string szFileName)
16.             :m_handleDB(INVALID_HANDLE)
17.             {
18.                 if ((m_handleDB = DatabaseOpen(szFileName, DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE)) == INVALID_HANDLE)
19.                 {
20.                     Print("Unable to create or open the file ", szFileName);
21.                     return;
22.                 }
23.             }
24. //+------------------------------------------------------------------+
25.         ~C_DB_SQLite()
26.             {
27.                 DatabaseClose(m_handleDB);
28.                 Print("Closing Database...");
29.             }
30. //+------------------------------------------------------------------+
31.         bool Command(const string szRequestSQL)
32.             {
33.                 bool ret = DatabaseExecute(m_handleDB, szRequestSQL);                
34.                 Print("Request execution: ", (ret ? "Success" : "Failed"), "...");
35.                 return ret;
36.             }
37. //+------------------------------------------------------------------+
38. };
39. //+------------------------------------------------------------------+
40. void OnStart()
41. {
42.     C_DB_SQLite *DB;
43.     
44.     DB = new C_DB_SQLite(user01 + ".sqlite");
45.     
46.     (*DB).Command("PRAGMA FOREIGN_KEYS = ON;");    
47.     (*DB).Command("CREATE TABLE IF NOT EXISTS tb_Symbols"
48.                   "("
49.                     "id PRIMARY KEY,"
50.                     "symbol NOT NULL UNIQUE"
51.                   ");");
52.     (*DB).Command("CREATE TABLE IF NOT EXISTS tb_Quotes"
53.                   "("
54.                     "of_day NOT NULL,"
55.                     "price NOT NULL,"
56.                     "fk_id NOT NULL,"
57.                     "FOREIGN KEY (fk_id) REFERENCES tb_Symbols(id)"
58.                   ");");    
59.     delete DB;
60. }
61. //+------------------------------------------------------------------+

Код на языке MQL5

Обратите внимание на то, как команды расположены в коде MQL5. Это необходимо для выполнения команд SQL. Нередко случается так, что, записывая так много вещей, мы в конечном итоге допускаем какую-нибудь ошибку. Теперь взгляните на приведенный ниже скрипт:

01. PRAGMA FOREIGN_KEYS = ON;
02. 
03. CREATE TABLE IF NOT EXISTS tb_Symbols
04. (
05.     id PRIMARY KEY,
06.     symbol NOT NULL UNIQUE
07. );
08. 
09. CREATE TABLE IF NOT EXISTS tb_Quotes
10. (
11.     of_day NOT NULL,
12.     price NOT NULL,
13.     fk_id NOT NULL,
14.     FOREIGN KEY (fk_id) REFERENCES tb_Symbols(id)
15. );

Код в SQLite

Сравните данный скрипт с предыдущим. Обратите внимание, что хотя последний использует чистый SQL и его синтаксис можно проанализировать в процессе написания, у нас нет такой же возможности, когда мы вставляем строки напрямую в код MQL5. Это позволяет MQL5 обеспечивать корректную работу SQLite, встроенного в MetaTrader 5. То есть, если при написании SQL-кода внутри строки в коде MQL5 мы допустим опечатку, SQL не сможет корректно выполнить наш код. В итоге мы можем свалить всю вину на MQL5 или даже на MetaTrader 5, что было бы большой ошибкой. Однако следует отметить, что в обоих вариантах кода мы создаем базу данных со связанными таблицами. И если по случайности в какой-то момент мы напишем имя таблицы tb_Symbols как tb_Symbol, результат будет совершенно отличаться от показанного на следующем рисунке:

Прошу заметить, что если мы попытаемся увидеть в MetaEditor ту же структуру, что показана на предыдущем рисунке, у нас ничего не получится. Об этом мы уже рассказали в другой статье. Если вам непонятно, что здесь происходит, советую ознакомиться со статьями, где мы объясняли SQL и как получить необходимые программы для более эффективного использования системы SQL.

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

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


Заключительные идеи

В сегодняшней статье мы начнем изучать использование SQL в коде MQL5. Мы рассмотрели, как можно создать базу данных. Или, точнее, как создать файл базы данных в SQLite, используя ресурсы или процедуры, включенные в язык MQL5. Мы также рассмотрели, как создать таблицу, а затем как установить связь между таблицами с помощью первичного и внешнего ключа. Всё это, опять же, с использованием MQL5. Мы увидели, как легко создать код, который в будущем можно будет перенести в другие реализации SQL, используя класс, помогающий скрыть созданную реализацию.

И самое главное: мы убедились, что при использовании SQL в разное время существует риск возникновения проблем. Это связано с тем, что внутри кода MQL5 SQL-код будет помещен внутрь строки (STRING). И тот факт, что это происходит, делает весьма вероятным, что что-то может пойти не так, из-за чего выполнение SQL-кода внутри MQL5 станет проблематичным по причине опечатки. Однако мы можем и будем создавать механизм, который, помимо предоставления нам большей свободы, позволит нам избежать этих проблем, поскольку существуют редакторы, предназначенные для облегчения чтения кода SQL-скрипта.

Итак, в следующей статье мы создадим механизм для облегчения такой переносимости. Многие из тех, кто обладает некоторым опытом, наверняка уже догадываются, о чем идет речь. Но если это не ваш случай, не волнуйтесь, в следующей статье мы рассмотрим, как это сделать. И мы продолжим нашу работу в области SQL, только теперь используя MQL5 в качестве базы для выполнения. Это необходимо для того, чтобы MetaTrader 5 позволил нашей системе репликации/моделирования начать использовать базы данных в своей работе. Так что продолжайте учиться, и увидимся в следующей статье, где всё станет ещё интереснее.

Файл Описание
Experts\Expert Advisor.mq5
Демонстрирует взаимодействие между Chart Trade и советником (для взаимодействия требуется Mouse Study).
Indicators\Chart Trade.mq5 Создает окно для настройки отправляемого ордера (для взаимодействия требуется Mouse Study).
Indicators\Market Replay.mq5 Создает элементы управления для взаимодействия с сервисом репликации/моделирования (для взаимодействия требуется Mouse Study)
Indicators\Mouse Study.mq5 Обеспечивает взаимодействие между графическими элементами управления и пользователем (необходимо как для работы системы репликации/моделирования, так и на реальном рынке).
Services\Market Replay.mq5 Создает и поддерживает сервис репликации/моделирования рынка (главный файл всей системы)
Code VS C++\Servidor.cpp Создает и поддерживает серверный сокет, разработанный на C++ (версия MiniChat)
Code in Python\Server.py Создает и поддерживает сокет в Python для связи между MetaTrader 5 и Excel
Indicators\Mini Chat.mq5 Позволяет реализовать мини-чат через индикатор (для работы требуется использование сервера)
Experts\Mini Chat.mq5 Позволяет реализовать мини-чат с помощью советника (для работы требуется сервер).
Scripts\SQLite.mq5 Демонстрирует использование скрипта SQL с помощью MQL5
Files\Script 01.sql Демонстрирует создание простой таблицы с внешним ключом.
Files\Script 02.sql Показывает добавление значений в таблицу

Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/13062

Прикрепленные файлы |
Anexo.zip (571.71 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (1)
Maxim Kuznetsov
Maxim Kuznetsov | 23 апр. 2026 в 14:52

статья близкая к абсолютному 0.

и есть ощущение что про просто взята статья официального help и размыта AI

PS/ бегло глянул прочии статьи автора - они такие-же, берётся справочник и размывается

Статистический арбитраж на основе коинтегрированных акций (Часть 7): Система оценки 2 Статистический арбитраж на основе коинтегрированных акций (Часть 7): Система оценки 2
В данной статье описываются два дополнительных критерия оценки, используемых при отборе корзин акций для торговли в стратегиях возврата к среднему, а точнее — в статистическом арбитраже на основе коинтеграции. Данная статья дополняет предыдущую публикацию, в которой были представлены показатели ликвидности и силы векторов коинтеграции, а также стратегические критерии — временной интервал и период ретроспективы, — за счет включения показателей стабильности векторов коинтеграции и времени возврата к среднему значению (полупериод). В статье приведены результаты бэктеста с применением новых фильтров с комментариями, а также предоставлены файлы, необходимые для его воспроизведения.
Популяционные алгоритмы оптимизации: строим защиту от читеров Популяционные алгоритмы оптимизации: строим защиту от читеров
Проведён повторный прогон алгоритмов на обновлённых функциях и предложен метод быстрой проверки их «честности». Составной тест объединяет пять разных ландшафтов и исключает выигрыш за счёт геометрии отдельных задач, позволяя быстро оценить реальную поисковую способность алгоритма. Прилагается скрипт для предварительной валидации алгоритмов перед применением к оптимизации торговых стратегий.
Разработка инструментария для анализа Price Action (Часть 34): Построение прогнозных моделей на основе необработанных рыночных данных с помощью усовершенствованного пайплайна загрузки данных Разработка инструментария для анализа Price Action (Часть 34): Построение прогнозных моделей на основе необработанных рыночных данных с помощью усовершенствованного пайплайна загрузки данных
Случалось ли вам пропустить внезапный рыночный всплеск или оказаться застигнутым врасплох, когда такой всплеск происходил? Лучший способ заранее распознавать события в реальном времени – учиться на исторических паттернах. Если вы хотите обучить модель машинного обучения, в этой статье сначала показано, как создать скрипт для MetaTrader 5, который собирает исторические данные и отправляет их в Python для хранения, закладывая основу системы обнаружения всплесков. Читайте дальше, чтобы увидеть каждый шаг на практике.
Разработка инструментария для анализа Price Action (Часть 33): Инструмент на основе теории свечного диапазона Разработка инструментария для анализа Price Action (Часть 33): Инструмент на основе теории свечного диапазона
Улучшите свое понимание рынка с помощью набора инструментов Candle-Range Theory для MetaTrader 5 – полностью нативного решения на MQL5 на основе теории свечного диапазона, которое превращает необработанные ценовые бары в информацию о волатильности в реальном времени. Легковесная библиотека CRangePattern сопоставляет истинный диапазон каждой свечи с адаптивным ATR и классифицирует ее в момент закрытия; затем CRT Indicator отображает эти классификации на графике в виде четких цветовых прямоугольников и стрелок, которые сразу показывают зоны сжатия, резкие пробои и полное поглощение диапазона.