如何使用ZeroMQ从MetaTrader终端向python发送MQL4/5中的消息? [英] How to send a message in MQL4/5 from MetaTrader Terminal to python using ZeroMQ?

查看:434
本文介绍了如何使用ZeroMQ从MetaTrader终端向python发送MQL4/5中的消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想从MetaTrader Terminal发送一条消息,使用它的MQL4/5到Python,这是一个简单的客户端服务器,其中MQL4/5是发送的客户端,而python是接收这些消息的服务器两个正在与ZeroMQ同步.

Python端代码就是这个,我确信这部分工作正常:

    import zmq
    import time


    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://127.0.0.1:9999")

    print("Server Started")
    while True:
        message = socket.recv()              # Wait for next request from client
        print("Received request: ", message)
        time.sleep (1)
        socket.send_string("World")

MQL4/5的一面是这样:

   Context context( "helloworld" );
   Socket socket( context, ZMQ_REQ );

   Print( "Connecting to hello world server…" );
   socket.connect( "tcp://127.0.0.1:9999" );

   while ( True )
   {
      ZmqMsg request( "Hello" );
      socket.send( request );

      ZmqMsg reply;
      socket.recv( reply );           // Get the reply.

      Sleep( 1000 );
   }

似乎MQL4/5没有发送任何东西.
你能说出什么问题吗?

解决方案

您能说出这是怎么回事吗?

从MQL4/5端开始的几件事:

MetaTrader终端可以用几种完全不同的代码执行模式来操作已编译的MQL4/5语言.

如果在 Script 中尝试过此方法,则与在 ExpertAdvisor 中使用此方法相比,基本损失较小,如果这样做会产生最严重的副作用.以某些 CustomIndicator -MQL4/5类型代码运行.


在ZeroMQ端:

无论如何, REQ/REP 内置可伸缩形式化通信原型模式是最坏的选择,因为在以前的许多文章中,已经解释了该内置的脆弱程度,以及它很容易陷入原则上无法挽回的相互僵局并置,因此最好在进入生产级服务设计和实现之前重新阅读这些文章并尝试避免这种风险.

始终在MQL4/5和Python方面分别设置 socket.setsockopt( zmq.LINGER, 0 ) 两者.没有例外,没有借口.

在MQL4/5和Python方面同时使用 socket.setsockopt( zmq.COMPLETE, 1 ) 两者的设置也建议不要这样做.


MQL4/5的ZeroMQ语言特定的绑定:

由于在MetaTrader终端MQL4/5代码执行生态系统和ZeroMQ API vXYZ DLL库之间存在用于MQL4/5 #import -ed中介的多个活动绑定自动取款机进入更多细节.使用API​​ v2.1.11(我修改了 .MQH -文件以解决 New 引入游戏的 #import -ed接口不兼容问题. em>- MQL4.56789 更改了游戏-因为 string 实际上不再是 string 和其他一些),并且看到了其他绑定,直到ZeroMQ API v.4.2.+为止,如果不仅仅只是一个" Helloworld "-示例,还有一些细节需要详细了解.

但是, Context() 实例启动应配备适当的设置/参数,并且在测试时,您的代码应例行获取所有返回代码+以编程方式处理所有异常(至少 Print() 记录到日志中,以使用 FILE LINE )进行进一步调试.

还可以使用 #import -ed函数 int aZmqERROR = zmq_errno(); ,在您可能会出现疑问的任何地方,以便知道在/之前没有与ZeroMQ错误相关的状态在发生调用之后,或者确切地从内部层知道什么是ZeroMQ信令,这可能阻止了API调用传递预期的功能状态/结果. MQL4/5端的 string Zmq::errorMessage( int error ) 准备就观察这些此类ZeroMQ端错误标志的一些更易理解的提示提供建议.


最后,但并非最不重要:

还检查localhost FireWall配置,是否实际上可以免费使用TCP port# == 9999 ,或者对FireWall安全策略的管理禁令确实阻止了任何尝试的成功进行,并且使用此端口号.

在公开验证之前,最好明确并适当地终止每个 Context() 实例(在明确 .close() -ed所有本地创建的ZeroMQ- <实例.在较早的API版本中可能会发生令人讨厌的事情,因此,即使示例或已发布的代码没有系统地做到这一点,在所有较新的API版本中最好还是系统化和防御性的.

I just want to send a message from MetaTrader Terminal, using it`s MQL4/5 to Python, just a simple client server, in which MQL4/5 is a client that sends, and python is a server who receives and these two are syncing with ZeroMQ.

The Python side code is this which I am sure this part is working fine:

    import zmq
    import time


    context = zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://127.0.0.1:9999")

    print("Server Started")
    while True:
        message = socket.recv()              # Wait for next request from client
        print("Received request: ", message)
        time.sleep (1)
        socket.send_string("World")

the MQL4/5 side is this:

   Context context( "helloworld" );
   Socket socket( context, ZMQ_REQ );

   Print( "Connecting to hello world server…" );
   socket.connect( "tcp://127.0.0.1:9999" );

   while ( True )
   {
      ZmqMsg request( "Hello" );
      socket.send( request );

      ZmqMsg reply;
      socket.recv( reply );           // Get the reply.

      Sleep( 1000 );
   }

it seems like MQL4/5 doesn't send anything.
Can you say what is wrong with it?

解决方案

Can you say what is wrong with it?

A few things to start with on MQL4/5-side :

MetaTrader Terminal can operate the compiled MQL4/5 language in several, quite different code-execution modes.

If this was tried in Script, the damages are less cardinal than if this would be in ExpertAdvisor and worst side-effects would happen if this was run in some CustomIndicator -type-of-MQL4/5-code.


On ZeroMQ-side :

In any case, REQ/REP Built-in Scalable Formal Communication Archetype pattern is a worst case choice, as in many previous posts, there has been explained how fragile this built-in was and that it can easily fall into a principally un-salvageable mutual dead-lock juxtaposition, so better re-read these posts and try to avoid this risk before going into production-grade service desing and implementation.

Always setup socket.setsockopt( zmq.LINGER, 0 ), both on MQL4/5 and Python sides. No exceptions, no excuse.

A setup with socket.setsockopt( zmq.COMPLETE, 1 ), both on MQL4/5 and Python sides is also more than adviseable.


ZeroMQ language-specific bindings for MQL4/5 :

As there are several active bindings available for MQL4/5 #import-ed mediations between MetaTrader Terminal MQL4/5 code-execution ecosystem and the ZeroMQ API v.X.Y.Z DLL-library, there is not possible ATM to go into more details. Having used API v2.1.11 ( I had modified the .MQH-file for solving #import-ed interface incompatibilities introduced into the game with New-MQL4.56789 changed game - as string actually stopped being a string and some others ) and having seen other bindings, up to the ZeroMQ API v.4.2.+, there are differences to know about in detail, if going beyond a just "Helloworld"-example.

Yet, Context() instance initiation ought be equipped with appropriate settings / parameters and when testing, your code should routinely acquire all return-codes + handle all exceptions programmatically ( at least Print() them into log for further debugging with FILE and LINE ).

Also use #import-ed function int aZmqERROR = zmq_errno();, wherever your doubts may spring out, so as to know there was no ZeroMQ error state related right before / after a call took place, or to know exactly what was ZeroMQ signalling from its internal layers, that may have prevented an API call to deliver an expected functional state / result. An MQL4/5-side string Zmq::errorMessage( int error ) is ready to advice on some more human readable hints on observing any such ZeroMQ-side error-flag.


Last, but not least :

also check the localhost FireWall-configuration, if the TCP port# == 9999 was actually free to be used, or if the administrative bans on the FireWall security policies did actually prevent any attempt from successfully going and use this port#.

Until validated in public, better terminate each Context()-instance explicitly and with due care ( after having explicitly .close()-ed all locally created ZeroMQ-Socket()-instances. Nasty things could have happended in the earlier API versions, so better be systematic and defensive in all newer API-versions, even if examples or posted code does not do this systematically.

这篇关于如何使用ZeroMQ从MetaTrader终端向python发送MQL4/5中的消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆