Исходный код
В современной алгоритмической торговле интеграция торговых терминалов с библиотеками машинного обучения является стандартом де-факто. В отличие от архитектуры с использованием 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 ордеров.




