如何使用 ZeroMQ 将 MQL4/5 中的消息从 MetaTrader 终端发送到 python?



我只想从 MetaTrader 终端发送一条消息,使用它的 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中这样做要小,如果在某些CustomIndicatorMQL4/5 代码中运行,则会发生最坏的副作用。


在零MQ端:

无论如何,REQ/REP内置可扩展形式通信原型模式是最糟糕的选择,就像在以前的许多帖子中一样,已经解释了这个内置是多么脆弱,并且它很容易陷入一个基本上无法挽救的相互死锁并置,所以最好重新阅读这些帖子,并在进入生产级服务设计和实现之前尽量避免这种风险。

始终在 MQL4/5 和 Python 端设置socket.setsockopt( zmq.LINGER, 0 )。没有例外,没有借口。

在MQL4/5 和 Python 端使用socket.setsockopt( zmq.COMPLETE, 1 )进行设置也是非常值得推荐的。


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

由于 MQL4/5 终端 MQL4/5 代码执行生态系统和 ZeroMQ API v.X.Y.Z DLL-库之间有几个活动绑定可用于 MQL4/5#import-ed 中介,因此 ATM 无法详细介绍。在使用 API v2.1.11 之后(我已经修改了.MQH-文件以解决游戏中引入的#import-ed 接口不兼容与New-MQL4.56789更改的游戏 - 因为string实际上不再是string和其他一些(并看到了其他绑定,直到 ZeroMQ API v.4.2.+,有一些差异需要详细了解, 如果超越一个只是">Helloworld"的例子。

然而,Context()实例启动应该配备适当的设置/参数,并且在测试时,您的代码应该定期获取所有返回代码 + 以编程方式处理所有异常(至少将它们Print()到日志中以便使用FILELINE进一步调试(。

还可以使用#import-ed 函数int aZmqERROR = zmq_errno();,无论您的疑问在哪里可能出现,以便知道在调用发生之前/之后没有与 ZeroMQ 错误状态相关,或者确切地知道 ZeroMQ 信令来自其内部层,这可能会阻止 API 调用提供预期的功能状态/结果。 MQL4/5 端string Zmq::errorMessage( int error )已准备好就观察任何此类 ZeroMQ 端错误标志的一些更人性化的提示提供建议。


最后但同样重要的:

还要检查本地主机 FireWall 配置,TCPport# == 9999是否确实可以免费使用,或者防火墙安全策略的管理禁令是否确实阻止了任何尝试成功使用此端口#。

在公开验证之前,最好显式终止每个Context()实例,并采取适当的谨慎措施(在显式.close()所有本地创建的 ZeroMQ-Socket()-实例之后(。在早期的 API 版本中可能会发生令人讨厌的事情,因此最好在所有较新的 API 版本中进行系统和防御,即使示例或发布的代码没有系统地做到这一点。

相关内容

最新更新