You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ZeroMQ从Metatrader 5获取实时报价至Python变量?

Great to hear you’ve already got the basic request-reply flow working with ZeroMQ and the mql-zmq library! Let’s walk through how to extend that setup to pull real-time bid/ask prices (and other quote data) from MT5 into your Python variables.

Step 1: Update the MT5 MQL5 Script to Handle Price Requests

First, we’ll modify the MT5 side to listen for symbol-specific requests and return the corresponding bid/ask prices. This replaces your "Hello World" logic with quote-fetching functionality.

//+------------------------------------------------------------------+
//|                                                  MT5_ZMQ_Quotes.mq5 |
//+------------------------------------------------------------------+
#include <zmq/zmq.mqh>

input string ZMQ_LISTEN_ADDRESS = "tcp://*:5555"; // Match this with your Python client

void OnStart()
{
    void *zmq_context = zmq_ctx_new();
    void *responder_socket = zmq_socket(zmq_context, ZMQ_REP);
    
    // Bind the socket to the specified address
    int bind_result = zmq_bind(responder_socket, ZMQ_LISTEN_ADDRESS);
    if(bind_result != 0)
    {
        Print("Failed to bind ZMQ socket: ", zmq_strerror(errno));
        return;
    }
    Print("MT5 Quote Server running on ", ZMQ_LISTEN_ADDRESS);

    // Keep running until the script is stopped in MT5
    while(!IsStopped())
    {
        // Receive the symbol request from Python
        char request_buffer[256];
        int bytes_received = zmq_recv(responder_socket, request_buffer, sizeof(request_buffer), 0);
        if(bytes_received == -1)
        {
            Print("ZMQ receive error: ", zmq_strerror(errno));
            continue;
        }
        request_buffer[bytes_received] = '\0'; // Ensure valid string termination
        string target_symbol = string(request_buffer);

        // Validate the symbol exists in MT5
        if(!SymbolSelect(target_symbol, true))
        {
            string error_response = "Error: Symbol '" + target_symbol + "' not found in MT5";
            zmq_send(responder_socket, error_response, StringLen(error_response), 0);
            continue;
        }

        // Fetch bid and ask prices (add SYMBOL_LAST for closing price if needed)
        double bid_price = SymbolInfoDouble(target_symbol, SYMBOL_BID);
        double ask_price = SymbolInfoDouble(target_symbol, SYMBOL_ASK);

        // Package data into JSON for easy Python parsing
        string quote_response = StringFormat(
            "{\"symbol\":\"%s\", \"bid\":%.5f, \"ask\":%.5f}", 
            target_symbol, bid_price, ask_price
        );
        zmq_send(responder_socket, quote_response, StringLen(quote_response), 0);

        Print("Sent quote for ", target_symbol, ": Bid=", bid_price, ", Ask=", ask_price);
        Sleep(100); // Prevent excessive loop frequency
    }

    // Cleanup resources when stopped
    zmq_close(responder_socket);
    zmq_ctx_destroy(zmq_context);
}
  • Key Details:
    • SymbolSelect(target_symbol, true) ensures the symbol is loaded in MT5 (critical for fetching valid prices).
    • We use JSON to serialize the response because it’s straightforward to parse in Python.
    • The script runs continuously until you manually stop it in MT5 (look for the running script icon in the bottom-right corner).

Step 2: Python Client Code to Request and Parse Quotes

Now, write a Python script to send symbol requests to MT5 and convert the response into usable variables.

import zmq
import json

def fetch_mt5_quote(target_symbol):
    # Initialize ZMQ context and request socket
    zmq_context = zmq.Context()
    client_socket = zmq_context.socket(zmq.REQ)
    client_socket.connect("tcp://localhost:5555") # Match MT5's listen address

    # Send the symbol request
    client_socket.send_string(target_symbol)

    # Receive and parse the response
    raw_response = client_socket.recv_string()
    client_socket.close()
    zmq_context.term()

    try:
        quote_data = json.loads(raw_response)
        return quote_data
    except json.JSONDecodeError:
        # Handle error messages from MT5
        return {"error": raw_response}

# Test the function with your target symbols
if __name__ == "__main__":
    ibm_quote = fetch_mt5_quote("IBM")
    print("IBM Quote:", ibm_quote)
    # Extract individual variables if needed
    if "bid" in ibm_quote:
        ibm_bid = ibm_quote["bid"]
        ibm_ask = ibm_quote["ask"]
        print(f"IBM Bid: {ibm_bid}, Ask: {ibm_ask}")

    goog_quote = fetch_mt5_quote("GOOG")
    print("GOOG Quote:", goog_quote)
  • Key Details:
    • The zmq.REQ socket pairs perfectly with MT5’s ZMQ_REP socket for request-reply communication.
    • We parse the JSON response into a dictionary, making it easy to access bid, ask, and symbol as Python variables.
    • Error handling catches cases where MT5 returns a non-JSON error message (like an invalid symbol).

Step 3: Real-Time Quote Updates (Optional)

If you want continuous real-time updates instead of one-off requests, switch to a publish-subscribe (PUB/SUB) pattern:

MT5 Publisher Script

//+------------------------------------------------------------------+
//|                                                  MT5_ZMQ_PubQuotes.mq5 |
//+------------------------------------------------------------------+
#include <zmq/zmq.mqh>

input string ZMQ_PUB_ADDRESS = "tcp://*:5556";
input string PUBLISH_SYMBOL = "IBM";
input int UPDATE_INTERVAL_MS = 1000; // Update every 1 second

void OnStart()
{
    void *zmq_context = zmq_ctx_new();
    void *publisher_socket = zmq_socket(zmq_context, ZMQ_PUB);
    
    int bind_result = zmq_bind(publisher_socket, ZMQ_PUB_ADDRESS);
    if(bind_result != 0)
    {
        Print("Failed to bind PUB socket: ", zmq_strerror(errno));
        return;
    }
    Print("MT5 Quote Publisher running on ", ZMQ_PUB_ADDRESS);

    while(!IsStopped())
    {
        if(!SymbolSelect(PUBLISH_SYMBOL, true))
        {
            Print("Symbol ", PUBLISH_SYMBOL, " not found");
            Sleep(UPDATE_INTERVAL_MS);
            continue;
        }

        double bid = SymbolInfoDouble(PUBLISH_SYMBOL, SYMBOL_BID);
        double ask = SymbolInfoDouble(PUBLISH_SYMBOL, SYMBOL_ASK);
        string publish_msg = StringFormat(
            "{\"symbol\":\"%s\", \"bid\":%.5f, \"ask\":%.5f}",
            PUBLISH_SYMBOL, bid, ask
        );

        zmq_send(publisher_socket, publish_msg, StringLen(publish_msg), 0);
        Print("Published: ", publish_msg);
        Sleep(UPDATE_INTERVAL_MS);
    }

    zmq_close(publisher_socket);
    zmq_ctx_destroy(zmq_context);
}

Python Subscriber Script

import zmq
import json

def subscribe_to_real_time_quotes():
    zmq_context = zmq.Context()
    subscriber_socket = zmq_context.socket(zmq.SUB)
    subscriber_socket.connect("tcp://localhost:5556")
    subscriber_socket.setsockopt_string(zmq.SUBSCRIBE, "") # Subscribe to all messages

    print("Listening for real-time MT5 quotes...")
    while True:
        raw_msg = subscriber_socket.recv_string()
        quote_data = json.loads(raw_msg)
        print(f"Real-Time Update: {quote_data['symbol']} | Bid: {quote_data['bid']} | Ask: {quote_data['ask']}")

if __name__ == "__main__":
    subscribe_to_real_time_quotes()

Critical Notes

  • Symbol Names: Ensure the symbol you request matches exactly what’s in your MT5 instance (e.g., IBM vs. IBMUSD — check the MT5 Market Watch window).
  • Firewall/Network: Make sure port 5555 (or 5556 for pub/sub) is open on your machine so Python can connect to MT5.
  • MT5 Script State: The MT5 script must be running (execute it in MT5) for Python to receive any responses.

内容的提问来源于stack exchange,提问作者Safrinha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:40:14