如何通过ZeroMQ实现MetaTrader终端MQL4/5向Python发送消息?
Got it, let's build out a fully working client-server setup for your MetaTrader (MQL4/5) + Python + ZeroMQ sync. You already have a solid Python server foundation, so I'll pair that with a tested MQL client and walk through all the key details to get you up and running.
Python ZeroMQ Server (REP Socket)
Your existing code is a great start—here's the full, polished version that handles string messages cleanly and maintains the request-response cycle:
import zmq import time context = zmq.Context() socket = context.socket(zmq.REP) socket.bind("tcp://127.0.0.1:9999") print("Server started, waiting for MQL client messages...") while True: # Wait for incoming message from MQL client message = socket.recv_string() print(f"Received from MQL: {message}") # Add your custom processing logic here (e.g., data analysis, database calls) time.sleep(1) # Simulate work # Send a response back to the MQL client response = f"Server processed: {message}" socket.send_string(response) print(f"Sent response: {response}")
I switched to recv_string() and send_string() instead of raw bytes because it plays nicer with MQL's string-based messaging, making debugging and data transfer smoother. The REP socket type ensures every request gets a response—critical for keeping your MQL and Python code in sync.
MQL4/5 ZeroMQ Client (REQ Socket)
First, you'll need the ZeroMQ MQL binding installed:
- For MQL5: Open MetaEditor, go to
Tools > MetaQuotes Language Market, search for "ZeroMQ", and install the official library. - For MQL4: Download the ZeroMQ library from MetaQuotes' resources and place it in your
MQL4/Librariesfolder.
MQL5 Client Code
//+------------------------------------------------------------------+ //| MQL_ZMQ_Client.mq5 | //| Copyright 2024, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Zmq/Zmq.mqh> ZMQContext context; ZMQSocket socket; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { if(context.Create() != ZMQ_OK) { Print("Failed to create ZMQ context: ", context.LastError()); return INIT_FAILED; } if(socket.Create(context, ZMQ_REQ) != ZMQ_OK) { Print("Failed to create REQ socket: ", socket.LastError()); context.Destroy(); return INIT_FAILED; } if(socket.Connect("tcp://127.0.0.1:9999") != ZMQ_OK) { Print("Failed to connect to server: ", socket.LastError()); socket.Destroy(); context.Destroy(); return INIT_FAILED; } Print("MQL client connected to Python server successfully"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { socket.Disconnect(); socket.Destroy(); context.Destroy(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Example: Send current symbol and bid price to the server on every tick string message = StringFormat("Symbol: %s, Bid: %.5f", _Symbol, SymbolInfoDouble(_Symbol, SYMBOL_BID)); if(socket.Send(message, 0) != ZMQ_OK) { Print("Failed to send message: ", socket.LastError()); return; } Print("Sent to server: ", message); // Wait for response from the Python server string response; if(socket.Recv(response, 0) != ZMQ_OK) { Print("Failed to receive response: ", socket.LastError()); return; } Print("Received from server: ", response); } //+------------------------------------------------------------------+
MQL4 Client Code
Nearly identical to MQL5, with minor syntax adjustments:
//+------------------------------------------------------------------+ //| MQL_ZMQ_Client.mq4 | //| Copyright 2024, MetaQuotes Software Corp. | //| https://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Software Corp." #property link "https://www.mql4.com" #property version "1.00" #include <Zmq/Zmq.mqh> ZMQContext context; ZMQSocket socket; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { if(context.Create() != ZMQ_OK) { Print("Failed to create ZMQ context: ", context.LastError()); return(INIT_FAILED); } if(socket.Create(context, ZMQ_REQ) != ZMQ_OK) { Print("Failed to create REQ socket: ", socket.LastError()); context.Destroy(); return(INIT_FAILED); } if(socket.Connect("tcp://127.0.0.1:9999") != ZMQ_OK) { Print("Failed to connect to server: ", socket.LastError()); socket.Destroy(); context.Destroy(); return(INIT_FAILED); } Print("MQL client connected to Python server"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { socket.Disconnect(); socket.Destroy(); context.Destroy(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { string message = StringFormat("Symbol: %s, Bid: %.5f", Symbol(), Bid); if(socket.Send(message, 0) != ZMQ_OK) { Print("Send error: ", socket.LastError()); return; } Print("Sent: ", message); string response; if(socket.Recv(response, 0) != ZMQ_OK) { Print("Receive error: ", socket.LastError()); return; } Print("Received: ", response); } //+------------------------------------------------------------------+
Key Setup & Troubleshooting Tips
- Socket Pairing: We're using
ZMQ_REP(server) andZMQ_REQ(client) because they enforce a strict request-response pattern—this is ideal for synchronous communication where MQL sends data and waits for Python to process it before moving on. - Network Configuration: The example uses localhost (
127.0.0.1) for testing. If you want to run the server on a remote machine, replace the IP with the server's public address and make sure port 9999 is open in both firewalls. - Error Handling: The code includes basic error checking, but you can expand it to handle timeouts, reconnections, or invalid message formats based on your specific use case.
- Testing Order: Always start the Python server first, then launch the MQL client in MetaTrader—this ensures the client can connect immediately.
内容的提问来源于stack exchange,提问作者Kent Winston




