__stdcall и отключенным декорированием имен (extern 'C'). В MQL5 импорт осуществляется через директиву #import 'Имя.dll', где массивы передаются по ссылке как указатели на непрерывные блоки памяти. Это позволяет использовать OpenMP, AVX-инструкции и сторонние математические библиотеки для кратного ускорения расчетов.При разработке сложных торговых систем на платформе MetaTrader 5 разработчики часто сталкиваются с ограничениями производительности MQL5. При работе со сложными структурами данных, такими как в статье MQL5: Индикатор тепловой карты корреляции валютных пар с многомерными массивами, вычисления на стороне MQL5 могут стать узким горлышком. Перенос расчетов в C++ решает эту проблему.
Аналогично, тяжелые адаптивные алгоритмы фильтрации, подобные тем, что описаны в Реализации адаптивного скользящего среднего Кауфмана (KAMA) в MQL4, при оптимизации на миллионах тиков требуют максимальной производительности процессора, которую может дать только оптимизированный C++ код с поддержкой векторных инструкций (AVX/SSE).
Если для ваших задач машинного обучения C++ кажется избыточным, рассмотрите альтернативный вариант: Интеграция MQL5 с Python через сокеты для TensorFlow моделей. Однако для низкозадержечных (low-latency) расчетов связка MQL5 + C++ DLL остается непревзойденным стандартом.
Исходный код
Ниже представлен исходный код библиотеки на C++ (компилируется в DLL) и скрипта на MQL5, который вызывает экспортируемую функцию для параллельного вычисления математического ряда на массиве данных.
Код C++ (файл MyMathLib.cpp):
#define WIN32_LEAN_AND_MEAN
#include
#include
#include
// Обязательно используем extern "C" для предотвращения декорирования (mangling) имен функций
// и __stdcall — стандартное соглашение о вызовах для MQL5
extern "C" __declspec(dllexport) void __stdcall ParallelVectorMath(
const double* inputArray,
double* outputArray,
const int size,
const double multiplier
)
{
// Распараллеливание цикла с помощью OpenMP для ускорения расчетов
#pragma omp parallel for
for (int i = 0; i < size; ++i)
{
// Имитация тяжелых тригонометрических расчетов
double temp = std::sin(inputArray[i]) * std::cos(inputArray[i]);
outputArray[i] = std::exp(temp) * multiplier;
}
} Код MQL5 (файл CallDllExample.mq5):
#property strict
#property description "Пример вызова функций из внешней C++ DLL"
// Импортируем функцию из DLL. Файл должен лежать в MQL5\Libraries\
#import "MyMathLib.dll"
void ParallelVectorMath(const double &inputArray[], double &outputArray[], const int size, const double multiplier);
#import
void OnStart()
{
const int arraySize = 1000000;
double inputs[];
double outputs[];
ArrayResize(inputs, arraySize);
ArrayResize(outputs, arraySize);
// Заполнение тестовыми данными
for(int i = 0; i < arraySize; i++)
{
inputs[i] = i * 0.0001;
}
Print("Начало расчета в C++ DLL...");
uint startTicks = GetTickCount();
// Вызов функции из DLL. Массивы передаются по ссылке
ParallelVectorMath(inputs, outputs, arraySize, 2.5);
uint endTicks = GetTickCount();
PrintFormat("Расчет завершен за %d мс. Результат [0]: %f, [999999]: %f",
(endTicks - startTicks), outputs[0], outputs[arraySize - 1]);
} Разбор параметров
const double* inputArray(в C++) /const double &inputArray[](в MQL5): Входной массив данных. В MQL5 массивы простых типов передаются по ссылке. В C++ они принимаются как обычные указатели на первый элемент непрерывного блока памяти.double* outputArray(в C++) /double &outputArray[](в MQL5): Выходной массив, куда C++ запишет результаты вычислений. Память под него должна быть заранее выделена на стороне MQL5 с помощью функцииArrayResize.const int size: Размер массивов. Необходим для безопасного итерирования внутри C++ кода, так как чистый указатель не хранит информацию о размере выделенной памяти.const double multiplier: Скалярный коэффициент для демонстрации передачи обычных переменных по значению.
Как запустить
Для успешного запуска выполните следующие шаги:
1. Создайте проект динамической библиотеки (DLL) в Microsoft Visual Studio. Скопируйте код MyMathLib.cpp в проект.
2. В настройках проекта Visual Studio (Свойства -> C/C++ -> Язык) включите поддержку OpenMP (/openmp) для параллельных вычислений.
3. Скомпилируйте проект в конфигурации Release x64 (MetaTrader 5 работает исключительно в 64-битной среде).
4. Скопируйте полученный файл MyMathLib.dll из папки сборки в директорию терминала [Каталог данных]\MQL5\Libraries\.
5. В MetaEditor создайте новый скрипт, вставьте код CallDllExample.mq5 и скомпилируйте его.
6. В настройках терминала MetaTrader 5 (Сервис -> Настройки -> Советники) обязательно установите галочку 'Разрешить импорт DLL', иначе терминал заблокирует вызов внешних функций из соображений безопасности.
7. Накиньте скрипт на любой график и контролируйте вывод результатов во вкладке 'Эксперты'.




