Интеграция MQL5 с Python через сокеты для TensorFlow моделей

Интеграция MQL5 с Python через сокеты для TensorFlow моделей MQL4 / MQL5 (MetaTrader)
Пошаговое руководство по интеграции советника MQL5 с Python через TCP-сокеты для передачи котировок в реальном времени в нейросеть TensorFlow.
Суть: Создание прямого TCP-соединения между советником MQL5 и Python-сервером без использования сторонних DLL. Это позволяет передавать котировки в реальном времени с минимальной задержкой для инференса в нейросети TensorFlow и возвращать торговые сигналы обратно в терминал MetaTrader 5.

Исходный код

В современной алгоритмической торговле интеграция торговых терминалов с библиотеками машинного обучения является стандартом де-факто. В отличие от архитектуры с использованием ZeroMQ, описанной в нашей статье MetaTrader 5 и Python: Передача данных через ZeroMQ (ZMQ) сокеты, прямое использование системных TCP-сокетов в MQL5 позволяет обойтись без подключения внешних библиотек (DLL), что повышает безопасность и упрощает перенос советника на другие торговые терминалы.

Ниже представлен код советника на MQL5, который инициализирует TCP-клиент, подключается к локальному Python-серверу и отправляет структуру тика в формате JSON при каждом обновлении цены.

//+------------------------------------------------------------------+
//|                                               SocketClientEA.mq5 |
//|                                  Copyright 2024, Quant Developer |
//+------------------------------------------------------------------+
#property property_strict
#property description "EA for sending quotes to Python via TCP Socket"

input string   InpServerIP   = "127.0.0.1"; // IP Address
input int      InpServerPort = 9090;        // Port

int socket_handle = INVALID_HANDLE;

int OnInit()
{
   socket_handle = SocketCreate();
   if(socket_handle == INVALID_HANDLE)
   {
      Print("Ошибка создания сокета: ", GetLastError());
      return(INIT_FAILED);
   }
   
   if(!SocketConnect(socket_handle, InpServerIP, InpServerPort, 5000))
   {
      Print("Ошибка подключения к серверу: ", GetLastError());
      return(INIT_FAILED);
   }
   
   Print("Успешное подключение к Python серверу.");
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   if(socket_handle != INVALID_HANDLE)
   {
      SocketClose(socket_handle);
      Print("Сокет закрыт.");
   }
}

void OnTick()
{
   if(socket_handle == INVALID_HANDLE) return;

   MqlTick last_tick;
   if(!SymbolInfoTick(_Symbol, last_tick)) return;

   string json_data = StringFormat("{\"symbol\":\"%s\",\"time\":%lld,\"bid\":%f,\"ask\":%f,\"volume\":%lld}",
      _Symbol, last_tick.time, last_tick.bid, last_tick.ask, last_tick.volume);

   uchar data[];
   StringToCharArray(json_data, data, 0, WHOLE_ARRAY, CP_UTF8);
   
   int bytes_sent = SocketSend(socket_handle, data, ArraySize(data));
   if(bytes_sent < 0)
   {
      Print("Ошибка отправки данных: ", GetLastError());
   }
}

На стороне Python мы запускаем TCP-сервер, который принимает входящее соединение, парсит JSON-пакеты и передает полученные фичи в модель TensorFlow для получения предсказания.

import socket
import json
import numpy as np
import tensorflow as tf

# Создаем простую модель TensorFlow для демонстрации инференса
# В реальном сценарии загрузите вашу предобученную модель: model = tf.keras.models.load_model('path')
model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(4,)),
    tf.keras.layers.Dense(8, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

HOST = '127.0.0.1'
PORT = 9090

def start_server():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        s.listen()
        print(f"Сервер запущен на {HOST}:{PORT}. Ожидание подключения...")
        conn, addr = s.accept()
        with conn:
            print(f"Подключено клиентом: {addr}")
            buffer = ""
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                buffer += data.decode('utf-8')
                
                try:
                    while "}" in buffer:
                        end_idx = buffer.index("}") + 1
                        packet = buffer[:end_idx]
                        buffer = buffer[end_idx:]
                        
                        payload = json.loads(packet)
                        print(f"Получены данные: {payload}")
                        
                        # Подготовка фичей для TensorFlow (например: bid, ask, volume, spread)
                        bid = payload['bid']
                        ask = payload['ask']
                        vol = payload['volume']
                        spread = ask - bid
                        
                        features = np.array([[bid, ask, vol, spread]], dtype=np.float32)
                        prediction = model.predict(features, verbose=0)
                        print(f"Прогноз модели: {prediction[0][0]:.4f}")
                        
                except Exception as e:
                    pass

if __name__ == "__main__":
    start_server()

Разбор параметров

  • InpServerIP: IP-адрес хоста, на котором запущен Python-скрипт. Для локального тестирования используется 127.0.0.1.
  • InpServerPort: Порт TCP-сервера. Должен совпадать в настройках советника и Python-скрипта.
  • SocketCreate: Встроенная функция MQL5 для создания системного сокета.
  • SocketConnect: Функция для установки соединения с сервером с возможностью задания таймаута.
  • SocketSend: Отправляет массив байт в сокет. Мы конвертируем JSON-строку в массив uchar с помощью StringToCharArray.

Как запустить

1. Разрешите веб-запросы в терминале MetaTrader 5: перейдите в Сервис -> Настройки -> Советники и добавьте http://127.0.0.1 (или IP вашего сервера) в список разрешенных URL.

2. Запустите Python-скрипт. Он инициализирует модель TensorFlow и начнет прослушивание порта 9090.

3. Скомпилируйте и запустите советник на любом графике в MT5. Вкладка "Эксперты" подтвердит успешное подключение.

После получения сигнала от модели TensorFlow, советник может совершать сделки. Для контроля рисков вам может потребоваться MQL5: Массовое изменение Stop Loss и Take Profit по Magic Number, а для анализа качества исполнения ордеров пригодится MQL5: Скрипт для сбора статистики проскальзываний Market ордеров.

Оцените статью
FinFluct