English 中文 Español Deutsch 日本語 Português
preview
Как подключить MetaTrader 5 к PostgreSQL

Как подключить MetaTrader 5 к PostgreSQL

MetaTrader 5Интеграция | 22 мая 2023, 13:45
871 0
Jocimar Lopes
Jocimar Lopes

Введение

Разработка программного обеспечения сильно изменилась за последние десять лет. Мы увидели популяризацию облачных вычислений. Такие сокращения, как IASS, PASS и SAAS, теперь являются ключевыми инструментами, которые необходимо учитывать в любом проекте по разработке программного обеспечения. Все стало проще как для конечного пользователя, так и для разработчика.

Команда MetaQuotes знала об этих изменениях, и с 2014 года у нас есть собственный WebRequest для MetaTrader 5.

Одной из областей, которая изменилась больше всего, является управление базами данных. Решения, которые раньше были сложными или даже "странными" с практической точки зрения, стали не только выполнимыми, но и предпочтительным решением для многих вариантов использования. Это касается и доступа к базам данным через REST API.

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

В статье анализируются пять стандартных вариантов подключения базы данных Postgres к MetaTrader 5, их требования, плюсы и минусы. Также мы настроим среду разработки, установим базу данных Postgres как удаленную, подключимся к ней, добавим и получим данные, которые будут использоваться сценарием MQL5 или советником.

Эта настройка среды разработки и соответствующие процедуры могут быть легко воспроизведены любой СУБД, поскольку REST API представляет собой уровень абстракции между системой БД и клиентским кодом.


MetaTrader 5 и базы данных

В MetaTrader 5 уже есть функции, которые могут вам понадобиться для работы с базами данных и функции, которые вам могут понадобиться для подключения к базе данных через сеть.

Платформа обеспечивает нативную интеграцию с SQLite с 2020 года. Вы можете использовать функции базы данных для взаимодействия с ней из кода. Кроме того, вы можете взаимодействовать со своими базами данных через специальный графический интерфейс в MetaEditor, что позволяет легко создавать и редактировать таблицы, а также выполнять операции CRUD (создание, чтение, обновление, удаление) без необходимости в дополнительном программном обеспечении.

Это значительно улучшило взаимодействие с конечным пользователем и дополнило арсенал разработчиков MQL5.

Среди десятков доступных СУБД, многие из которых имеют лицензии с открытым исходным кодом, SQLite, похоже, был наиболее разумным выбором разработчиков MetaTrader 5. Несмотря на то, что это полнофункциональная база данных SQL с многостолбцовыми индексами, триггерами, представлениями, ACID-транзакциями, полнотекстовым поиском, агрегатными функциями и т. д., она при этом остается легкой, основанной на файлах, масштабируемой и не требующей обслуживания. Как указано на ее веб-сайте, "наиболее вероятно, активно используется более одного триллиона (1e12) баз данных SQLite".

Несмотря на свои впечатляющие функции, SQLite по своей конструкции ограничен одним пользователем и не предназначен для одновременного доступа в веб-развертываниях. Большое количество сообщений на форумах и статей на сайте MQL5 о том, как подключить MetaTrader 5 к MySQL, показывает, что существует потребность в более надежном решении для других случаев использования.

Эта статья посвящена настройке среды разработки для этих вариантов использования с применением Postgres.

Почему Postgres?

Я выбрал Postgres в первую очередь потому, что другая популярная альтернатива с открытым исходным кодом, MySQL, уже подробно здесь рассматривалась.

Во-вторых, Postgres — это мультиплатформенный проект с открытым исходным кодом, подробной документацией и хорошей поддержкой. Он популярен - в Интернете можно найти множество примеров кода, руководств и учебных пособий. Имеется множество облачных провайдеров, доступных для любых потребностей и бюджетов.

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

И, конечно же, я выбрал Postgres, потому что доверяю ему. Я пользуюсь Postgres в различных проектах уже более десяти лет.

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


Четыре способа взаимодействия с Postgres из MQL5

На мой взгляд, есть четыре основных подхода к вызову Postgres из MQL5:

  1. специальная библиотека/драйвер MQL5
  2. .dll из клиентского интерфейса C++
  3. через драйвер .NET Npgsql
  4. REST API

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


1. Специальная библиотека/драйвер MQL5

Библиотеки еще не существует. Ее разработка потребует от опытного MQL5-разработчика многих часов кропотливой работы. Это будет недешево. Мы также должны учитывать расходы на техническое обслуживание. Postgres - зрелый проект, но он ни в коем случае не статичен. Это активно развивающийся проект с регулярными релизами, некоторые из которых (а возможно, и многие) потребуют обновлений клиентского кода.

Например, на момент написания статьи последняя версия Postgres (15) требует, чтобы обычным пользователям базы данных были предоставлены некоторые привилегии в "общедоступной схеме" ("public schema"). В предыдущих версиях этого требования не было. Вероятно, некоторые базы кодов потребуют технического обслуживания.

Преимущество заказа разработки специального драйвера MQL5 для Postgres заключается в том, что, если им поделиться, он может быть полезен многим пользователям MQL5. Недостаток очевиден - затраты времени и денег.

С чего начать, если вы выбрали этот путь:

Общий поиск по запросу MySQL в разделе "Статьи" на этом сайте даст кое-какие полезные результаты.

Клиентская библиотека C++ с открытым исходным кодом libpqxx

Официальная клиентская библиотека C для Postgres libpq


2. .dll из клиентского интерфейса C++

Это поддерживаемая извне официальная библиотека C++, libpqxx, построенная поверх поддерживаемой внутри официальной библиотеки C, libpq, поставляемой с дистрибутивом Postgres.

Лично я никогда не пользовался ей. Всё, что я могу сказать, это то, что она существует уже давно и, кажется, находится в хорошем состоянии. Недостатком этого метода является то, что MQL5 Market не поддерживает DLL. Если это не проблема для вашего проекта и вы уверенно работаете с .dll из MetaTrader, это решение может быть для вас.

С чего начать, если вы выбрали этот путь:

Клиентская библиотека C++ с открытым исходным кодом libpqxx


3. через драйвер .NET Npgsql

С 2018 года в MetaTrader 5 есть нативная поддержка библиотек .NET с "умным" импортом функций. С выходом билда 1930 .NET-библиотеки можно использовать без написания специальных оберток — MetaEditor всё делает сам. 

Все, что вам нужно для использования драйвера .NET Npgsql, — это импортировать саму .dll. Есть некоторые ограничения, о которых вы можете узнать в официальном сообщении (https://www.mql5.com/ru/forum/285631).

С чего начать, если вы выбрали этот путь:

Драйвер Postgres с открытым исходным кодом для .NET


4. REST API

Если вы предпочитаете работать без .dll, этот подход будет наиболее быстрым и дешевым. API можно написать на любом языке, а рабочий прототип можно получить через день или даже несколько часов.

Кроме того, некоторые облачные провайдеры бесплатно предлагают встроенный REST API для Postgres. Все, что вам нужно для начала, — это хорошая среда для разработки вашего MQL5-кода.

С этим подходом ваш MQL5-код может использовать ваши ответы Postgres в формате JSON.

С чего начать, если вы выбрали этот путь:

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


Настройка среды разработки

Какой бы метод вы ни выбрали, вам понадобится среда разработки на машине Windows с работающим сервером Postgres. Есть несколько способов начать работу. Я перечислю три способа - от самого сложного и трудоемкого до самого простого:

  1. компиляция из исходного кода
  2. контейнер Docker
  3. сторонний установщик msi

Всё это хорошие способы установки Postgres в Windows, но, поверьте мне, компиляция из исходного кода в Windows должна быть вашим последним вариантом, если вы, конечно, не хотите проверить себя на стрессоустойчивость в разработке программного обеспечения.

Контейнер Docker - очень хороший вариант, отличающийся надежной и гибкой установкой. Ваш сервер базы данных будет работать на "удаленном" компьютере, а не на "локальном хосте" (см. ниже). Всё довольно просто. Вам просто нужно установить Docker, ввести две-три командные строки, и вы готовы к работе.

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

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

Что такое WSL?

WSL расшифровывается как Windows Subsystem For Linux (подсистема Windows для Linux).

С 2016 года вы можете запускать дистрибутив Linux на машине с Windows в качестве подсистемы. Не беспокойтесь! Ничего взламывать не придется. WSL разработан Microsoft и встроен в Windows. Вам просто нужно включить ее. Как это сделать, увидим ниже.

Почему WSL?

Почему бы просто не установить Postgres на другую машину с Windows, возможно, на виртуальную машину?

Потому что Postgres — это нативная Unix-система, созданная и разработанная в системах *nix. После его установки в Linux, вы получаете простую установку, а также легкое обновление и обслуживание. Вся официальная документация ориентирована на Unix-систему. И большинство примеров кода, фрагментов и общей справки, которые вы можете найти в Интернете, отражают этот факт.

Таким образом, вам будет легко разрабатывать в системе Linux. Именно для этой цели Microsoft разработала WSL.

Установка WSL

Условие из документации Microsoft:

"Вы должны использовать Windows 10 версии 2004 и выше (сборка 19041 и выше) или Windows 11, чтобы использовать приведенные ниже команды. Если вы используете более ранние версии, смотрите страницу о ручной установке".

Если ваша система соответствует этому условию, откройте Power Shell от имени администратора и введите команду ниже, чтобы установить/включить WSL:

wsl –install

команда установки wsl в PowerShell

Эта команда установит Ubuntu на WSL, так как это дистрибутив по умолчанию. 

Перезапустите Windows.

Тут всё просто. При необходимости в официальной документации MS можно найти раздел с наиболее распространенными проблемами установки.

После перезагрузки вы должны увидеть что-то вроде этого. Создайте новое имя пользователя и пароль UNIX.

установка wsl после первой перезагрузки


После установки WSL/Ubuntu пора устанавливать Postgres.

Установка Postgres на WSL

Введите команду ниже.

sudo apt install postgresql postgresql-contrib

Эта команда установит последнюю стабильную версию пакета PostgreSQL, доступную в репозиториях Ubuntu. Он включает в себя сервер, клиент pgsql, удобные бинарные файлы и некоторые утилиты. Это всё, что нужно для старта.

Если вы хотите установить последнюю стабильную версию Postgres (обычно отличающуюся от последней стабильной версии в репозиториях Ubuntu) вы можете включить официальный репозиторий Postgres в список источников вашего менеджера пакетов. Подробную инструкцию можно найти в официальной документации Postgres.

Если всё в порядке, ввод команды

psql --version

должен вернуть установленную версию вашей базы данных Postgres.


Запуск сервера

Введите следующую команду, чтобы запустить сервер.

sudo service postgresql start

По умолчанию новая установка Postgres принимает соединения только с localhost. Давайте изменим это.

Найдите файл конфигурации Postgres.

sudo -u postgres psql -c "SHOW config_file"

файл конфигурации postgres


Отредактируйте файл конфигурации, чтобы принимать подключения за пределами локального хоста. Измените строку listen_addresses.

строка listen_addresses в postgres


Найдите файл конфигурации pg_hba.

sudo -u postgres psql -c "SHOW hba_file"

файл конфигурации pg_hba в postgres


Отредактируйте файл pg_hba.conf, чтобы разрешить аутентификацию по паролю как для IPv4, так и для IPv6.

авторизация по паролю


Теперь войдите в утилиту psql как пользователь Postgres по умолчанию, созданный при установке. Он называется 'postgres'.

sudo -u postgres psql


Создайте обычного пользователя базы данных с привилегией CREATEDB. Пока у нас есть только пользовательский 'postgres', созданный установкой.

Предоставьте все привилегии в общедоступной схеме пользователю mt5_user. В этом нет необходимости, если ваша версия Postgres ниже 15.

CREATE USER mt5_user PASSWORD '123' CREATEDB;

GRANT ALL ON SCHEMA public TO mt5_user;

предоставление всех привилегий пользователю в postgres


Создайте базу данных my_remote_db и предоставьте все права на нее пользователю mt5_user.

GRANT ALL PRIVILEGES ON DATABASE my_remote_db TO mt5_user;

создание базы данных и предоставление всех привилегий


Подключение к Postgres

К настоящему времени у вас должен быть сервер базы данных, работающий на удаленной машине, с IP, отличным от вашего локального хоста Windows, и готовый принимать подключения по сети. Мы можем подключиться через сокет или HTTP. Поскольку мы будем взаимодействовать с REST API, в этом примере мы будем использовать HTTP.

Посмотрим, сможем ли мы подключиться к my_remote_db как mt5_user с паролем 123 на хосте WSL.

Введите следующую команду, чтобы получить имя хоста WSL (IP).

hostname -I

имя хоста команды терминала ubuntu


Проверьте статус сервера Postgres. Если нужно, запустите его. Вы можете использовать следующую команду для запуска, перезапуска или остановки сервера.

sudo service postgresql {status, start, stop}


В терминале MetaTrader 5 перейдите на вкладку "Сервис" > "Настройки" > "Советники" и добавьте IP-адрес хоста WSL в список разрешенных.

Меню настроек терминала MetaTrader 5

Терминал MetaTrader 5 принимает соединения HTTP и HTTPS только на портах 80 и 443 соответственно. Только порты 80 и 443. Учитывайте эту меру предосторожности при разработке своего API. Обычно перед переходом на реальный рабочий сервер сервер разработки прослушивает непривилегированный порт, например 3000 или 5000. Таким образом, чтобы иметь возможность отправлять запросы на IP-адрес, который вы указали в настройках терминала выше, вам необходимо перенаправить трафик, поступающий на порт сервера разработки, на порт 80 для HTTP-запросов и/или 443 для HTTPS-запросов.

Для простоты в файле README прикрепленного Python-приложения вы найдете инструкции о том, как выполнить это перенаправление в WSL.


Запуск демонстрационного приложения

Поскольку эта статья посвящена MQL5, я не буду обсуждать детали реализации API. Вместо этого я сделал демонстрационное приложение, которое вы можете загрузить и установить в виде пакета Python, чтобы протестировать взаимодействие вашего кода MQL5 с API.

Чтобы запустить демонстрационное приложение, вам просто нужно установить Python на WSL. Он уже должен быть там.

Настоятельно рекомендуется создать виртуальную среду Python ('venv') для установки приложения. Это гарантирует, что системная установка Python пройдет без проблем. Поработав с приложением, вы можете просто удалить виртуальную среду.

Вы можете создать виртуальную среду с помощью следующей команды.

python3 -m venv 'venv'


Таким образом, после того, как вы установили демо-приложение, вам необходимо:

  1. запустить WSL
  2. запустить сервер Postgres
  3. запустить демонстрационное приложение
  4. получить из приложения IP-адрес хоста
  5. добавить IP-адрес хоста к разрешенным адресам в терминале

И WSL, и сервер Postgres можно настроить так, чтобы они запускались при запуске Windows.


Вставка данных из MQL5

Давайте попробуем вставить данные. Во-первых, информация о нашем счете. В своем терминале MetaTrader 5 создайте новый скрипт и добавьте следующий код.

//+------------------------------------------------------------------+
//|                                                post_acc_info.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <JAson.mqh> //--- include the JSON library
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- gathering the data - Account Info
   CJAVal data;
   CJAVal acc_info;
//--- doubles
   data["balance"] =          AccountInfoDouble(ACCOUNT_BALANCE);
   data["credit"] =           AccountInfoDouble(ACCOUNT_CREDIT);
   data["profit"] =           AccountInfoDouble(ACCOUNT_PROFIT);
   data["equity"] =           AccountInfoDouble(ACCOUNT_EQUITY);
   data["margin"] =           AccountInfoDouble(ACCOUNT_MARGIN);
   data["margin_free"] =      AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   data["margin_level"] =     AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   data["margin_so_call"] =   AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL);
   data["margin_so_so"] =     AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
//--- integers
   data["login"] =            AccountInfoInteger(ACCOUNT_LOGIN);
   data["leverage"] =         AccountInfoInteger(ACCOUNT_LEVERAGE);
   data["trade_allowed"] =    AccountInfoInteger(ACCOUNT_TRADE_ALLOWED);
   data["ea_allowed"] =       AccountInfoInteger(ACCOUNT_TRADE_EXPERT);
   data["trade_mode"] =       AccountInfoInteger(ACCOUNT_TRADE_MODE);
   data["margin_so_mode"] =   AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
//-- strings
   data["company"] =          AccountInfoString(ACCOUNT_COMPANY);
   data["currency"] =         AccountInfoString(ACCOUNT_CURRENCY);
   data["name"] =             AccountInfoString(ACCOUNT_NAME);
   data["server"] =           AccountInfoString(ACCOUNT_SERVER);
   
//--- fill in the acc_info array with Account Info data
   acc_info["acc_info"].Add(data);
   
//--- WebRequest arguments
   string method = "POST";
   string url = "http://172.22.18.235/accs";
   string headers = "Content-Type: application/json";
   int timeout = 500;
   char post[], result[];
   string result_headers;
   
//--- prepare JSON data to send
   string json = acc_info.Serialize();
   ArrayResize(post, json.Length(), 0);
   StringToCharArray(json, post, 0, StringLen(json), CP_UTF8);
   ResetLastError();
   
//--- send the request
   int res = WebRequest(method, url, headers, timeout, post, result, result_headers);
   if(res == -1)
     {
      Print("Error in WebRequest  =", GetLastError());
      MessageBox("Add " + url + " to allowed URLs on MT5 terminal", "Unknown URL", MB_ICONINFORMATION);     }
   else
     {
      Print("Starting post...");
      
      if(res == 201)// HTTP result code 201 (created)
        {
         Print("posted accs");
        }
     }
  }

Как видно из начала файла, мы используем вспомогательную библиотеку для сериализации/десериализации наших JSON-данных. Она была разработана членом MQL5-сообщества, и вы можете найти библиотеку в его хранилище на GitHub.

Теперь добавим наши сделки из истории MetaTrader 5. Создайте новый скрипт и добавьте следующий код.

//+------------------------------------------------------------------+
//|                                                   post_deals.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <JAson.mqh> //--- include the JSON library
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- gathering the data - Deals
   CJAVal data;
   CJAVal deals;
//--- request trade history
   HistorySelect(0, TimeCurrent());
   int deals_total = HistoryDealsTotal();
//--- iterate over all deals to get data
//--- of each deal from its ticket number
   for(int i = 0; i < deals_total; i++)
     {
      //-- integers
      ulong deal_ticket =   HistoryDealGetTicket(i);
      data["ticket"] =     (int) deal_ticket;
      data["order"] =      (int) HistoryDealGetInteger(deal_ticket, DEAL_ORDER);
      data["position"] =   (int) HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);
      data["time"] =       (int) HistoryDealGetInteger(deal_ticket, DEAL_TIME);
      data["type"] =       (int) HistoryDealGetInteger(deal_ticket, DEAL_TYPE);
      data["entry"] =      (int) HistoryDealGetInteger(deal_ticket, DEAL_ENTRY);
      data["magic"] =      (int) HistoryDealGetInteger(deal_ticket, DEAL_MAGIC);
      data["reason"] =     (int) HistoryDealGetInteger(deal_ticket, DEAL_REASON);
      //--- strings
      data["symbol"] =     (string) HistoryDealGetString(deal_ticket, DEAL_SYMBOL);
      //--- doubles
      data["volume"] =     (double) HistoryDealGetDouble(deal_ticket, DEAL_VOLUME);
      data["price"] =      (double) HistoryDealGetDouble(deal_ticket, DEAL_PRICE);
      data["profit"] =     (double) HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
      data["swap"] =       (double) HistoryDealGetDouble(deal_ticket, DEAL_SWAP);
      data["comission"] =  (double) HistoryDealGetDouble(deal_ticket, DEAL_COMMISSION);
 //--- fill in the deals array with each deal data
      deals["deals"].Add(data);
     }
 //--- WebRequest arguments
   string method = "POST";
   string url = "http://172.22.18.235/deals";
   string headers = "Content-Type: application/json";
   int timeout = 500;
   char post[], result[];
   string result_headers;
   
 //--- prepare JSON data to send
   string json = deals.Serialize();
   ArrayResize(post, json.Length(), 0);
   StringToCharArray(json, post, 0, StringLen(json), CP_UTF8);
   ResetLastError();
//--- send the request
   int res = WebRequest(method, url, headers, timeout, post, result, result_headers);
   
   if(res == -1)
     {
      Print("Error in WebRequest  =", GetLastError());
      MessageBox("Add " + url + " to allowed URLs on MT5 terminal", "Unknown URL", MB_ICONINFORMATION);     }
   else
     {
      Print("Starting post...");
      
      if(res == 201)// HTTP result code 201 (created)
        {
         Print("posted deals");
        }
     }
  }


Запрос данных из MQL5

Теперь давайте запросим наши недавно добавленные данные. В терминале MetaTrader 5 создайте новый скрипт и добавьте следующий код.

//+------------------------------------------------------------------+
//|                                                 get_endpoint.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <JAson.mqh> //--- include the JSON library
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- choose the testing endpoint
   string endpoint = "accs"; // or "deals"
//--- WebRequest arguments
   string method = "GET";
   string url = "http://172.22.18.235/" + endpoint;
   string cookie = NULL, headers;
   int timeout = 500;
   char post[], result[];
   ResetLastError();
//--- send the request
   int res = WebRequest(method, url, cookie, NULL, timeout, post, 0, result, headers);
   if(res == -1)
     {
      Print("Error in WebRequest  =", GetLastError());
      MessageBox("Add " + url + " to allowed URLs on MT5 terminal", "Unknown URL", MB_ICONINFORMATION);
     }
   else
     {
      Print("Starting get...");
      if(res == 200)// HTTP result code 200 (OK)
        {
         PrintFormat("Server headers: %s", headers);
         ResetLastError();
         // save the returned JSON in a file
         string terminal_data_path = TerminalInfoString(TERMINAL_DATA_PATH);
         string subfolder = "TutoPostgres";
         string filename = endpoint + "_fromserver.json";
         int filehandle = FileOpen(subfolder + "\\" + filename, FILE_WRITE | FILE_BIN);
         if(filehandle != INVALID_HANDLE)
           {
            FileWriteArray(filehandle, result, 0, ArraySize(result));
            FileClose(filehandle);
            Print(filename + " created at " + terminal_data_path + "\\" + subfolder);
           }
         else
            Print("File open failed with error ", GetLastError());
        }
      else
         PrintFormat("Request to '%s' failed with error code %d", url, res);
     }
  }

Изменив конечную точку с "accs" на "deals", вы можете запрашивать только что добавленные сделки. Проверьте <Путь терминала MT5>\Files\TutoPostgres. Если все прошло нормально, там должно быть как минимум два файла - accs_fromserver.json и Deals_fromserver.json. 


Использование данных JSON в советниках

Чтобы использовать возвращенные сервером данные JSON, вам необходимо их десериализовать. Это может сделать упомянутая выше библиотека.

Если вы просмотрели файлы JSON, сохраненные после запроса к базе данных с приведенным выше примером кода, вы могли увидеть строку JSON, подобную этой:

[
  {
    "a_balance": "10005.93",
    "a_company": "MetaQuotes Software Corp.",
    "a_credit": "0.0",
    "a_currency": "USD",
    "a_ea_allowed": true,
    "a_equity": "10005.93",
    "a_id": 3,
    "a_leverage": 100,
    "a_login": 66744794,
    "a_margin": "0.0",
    "a_margin_free": "10005.93",
    "a_margin_level": "0.0",
    "a_margin_so_call": "50.0",
    "a_margin_so_mode": "0",
    "a_margin_so_so": "30.0",
    "a_name": "MetaTrader 5 Desktop Demo",
    "a_profit": "0.0",
    "a_server": "MetaQuotes-Demo",
    "a_trade_allowed": true,
    "a_trade_mode": "0"
  },
  {
(...)

Мы будем использовать эти ключи для доступа к десериализованным данным. '0' (ноль) в индексе массива — это доступ к первой возвращенной учетной записи. Если у вас более одного счета, эта конечная точка ("accs") вернет все учетные записи, и вы сможете получить доступ к каждой из них, перебирая массив по этому индексу.

//+------------------------------------------------------------------+
//|                                                 consume_json.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <JAson.mqh> //--- include the JSON library
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- choose the testing endpoint
   string endpoint = "accs"; // or "deals"
//--- WebRequest arguments
   string method = "GET";
   string url = "http://172.22.18.235/" + endpoint;
   string cookie = NULL, headers;
   int timeout = 500;
   char post[], result[];
   ResetLastError();
//--- send the request
   int res = WebRequest(method, url, cookie, NULL, timeout, post, 0, result, headers);
   if(res == -1)
     {
      Print("Error in WebRequest  =", GetLastError());
      MessageBox("Add " + url + " to allowed URLs on MT5 terminal", "Unknown URL", MB_ICONINFORMATION);
     }
   else
     {
      Print("Starting get...");
      if(res == 200)// HTTP result code 200 (OK)
        {
         CJAVal data;
         data.Deserialize(result);
         //--- doubles
         double a_balance =         data[0]["a_balance"].ToDbl();
         double a_credit =          data[0]["a_credit"].ToDbl();
         double a_profit =          data[0]["a_profit"].ToDbl();
         double a_equity =          data[0]["a_equity"].ToDbl();
         double a_margin =          data[0]["a_margin"].ToDbl();
         double a_margin_free =     data[0]["a_margin_free"].ToDbl();
         double a_margin_level =    data[0]["a_margin_level"].ToDbl();
         double a_margin_so_call =  data[0]["a_margin_so_call"].ToDbl();
         double a_margin_so_so =    data[0]["a_margin_so_so"].ToDbl();
         //--- longs
         long a_login =             data[0]["a_login"].ToInt();
         long a_leverage =          data[0]["a_leverage"].ToInt();
         long a_trade_mode =        data[0]["a_trade_mode"].ToInt();
         long a_margin_so_mode =    data[0]["a_margin_so_mode"].ToInt();
         long a_id =                data[0]["a_id"].ToInt(); //--- database generated ID
         //--- strings
         string a_company =         data[0]["a_company"].ToStr();
         string a_currency =        data[0]["a_currency"].ToStr();
         string a_name =            data[0]["a_name"].ToStr();
         string a_server =          data[0]["a_server"].ToStr();
         //--- booleans
         bool a_ea_allowed =        data[0]["a_ea_allowed"].ToBool();
         bool a_trade_allowed =     data[0]["a_trade_allowed"].ToBool();
         //printf("Server headers: %s", headers);
         //--- doubles
         printf("Balance: %d", a_balance);
         printf("Credit: %d", a_credit);
         printf("Profit: %d", a_profit);
         printf("Equity: %d", a_equity);
         printf("Margin: %d", a_margin);
         printf("Margin Free: %d", a_margin_free);
         printf("Margin Level: %d", a_margin_level);
         printf("Margin Call Level: %d", a_margin_so_call);
         printf("Margin Stop Out Level: %d", a_margin_so_so);
         //--- longs
         printf("Login: %d", a_login);
         printf("Leverage: %d", a_leverage);
         printf("Trade Mode: %d", a_trade_mode);
         printf("Margin Stop Out Mode: %d", a_margin_so_mode);
         printf("Database ID: %d", a_id);
         //--- strings
         printf("Company: %s", a_company);
         printf("Currency: %s", a_currency);
         printf("Platform Name: %s", a_name);
         printf("Server: %s", a_server);
         //--- booleans
         printf("Expert Advisor Allowed: %d", a_ea_allowed);
         printf("Trade Allowed: %d", a_trade_allowed);
         Print("Done!");
        }
      else
         PrintFormat("Request to '%s' failed with error code %d", url, res);
     }
  }


SQLite как зеркало Postgres

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

Если вы считаете, что эта функция будет полезна, сообщите мне об этом. Я напишу подробное руководство с примером кода для синхронизации удаленной базой данных Postgres с локальными базами данных SQLite.


Заключение

Мы рассмотрели некоторые доступные в настоящее время методы подключения кода MQL5 к базе данных Postgres. Мы выбрали REST API как жизнеспособную и быструю альтернативу более дорогой разработке специальных драйверов или использованию .dll. Кроме того, мы разработали базовое демонстрационное приложение в качестве примера настройки среды разработки для MQL5/Postgres в подсистеме Windows для Linux.

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

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

Прикрепленные файлы |
Теория категорий в MQL5 (Часть 6): Мономорфные расслоенные произведения и эпиморфные кодекартовы квадраты Теория категорий в MQL5 (Часть 6): Мономорфные расслоенные произведения и эпиморфные кодекартовы квадраты
Теория категорий представляет собой разнообразный и расширяющийся раздел математики, который лишь недавно начал освещаться в MQL5-сообществе. Эта серия статей призвана рассмотреть некоторые из ее концепций для создания открытой библиотеки и дальнейшему использованию этого замечательного раздела в создании торговых стратегий.
Нейросети — это просто (Часть 42): Прокрастинация модели, причины и методы решения Нейросети — это просто (Часть 42): Прокрастинация модели, причины и методы решения
Прокрастинация модели в контексте обучения с подкреплением может быть вызвана несколькими причинами, и решение этой проблемы требует принятия соответствующих мер. В статье рассмотрены некоторые из возможных причин прокрастинации модели и методы их преодоления.
Многослойный перцептрон и алгоритм обратного распространения ошибки (Часть 3): Интеграция с тестером стратегии - Обзор (I) Многослойный перцептрон и алгоритм обратного распространения ошибки (Часть 3): Интеграция с тестером стратегии - Обзор (I)
Многослойный перцептрон - это эволюция простого перцептрона, способного решать нелинейно разделяемые задачи. Вместе с алгоритмом обратного распространения можно эффективно обучить данную нейронную сеть. В третьей части серии статей о многослойном перцептроне и обратном распространении мы посмотрим, как интегрировать эту технику в тестер стратегий. Эта интеграция позволит использовать комплексный анализ данных и принимать лучшие решения для оптимизации торговых стратегий. В данном обзоре мы обсудим преимущества и проблемы применения этой методики.
Реализация фактора Януса в MQL5 Реализация фактора Януса в MQL5
Гэри Андерсон разработал метод анализа рынка, основанный на теории, которую он назвал фактором Януса. Теория описывает набор индикаторов, которые можно использовать для выявления тенденций и оценки рыночного риска. В этой статье мы реализуем эти инструменты в MQL5.