Git Product home page Git Product logo

mql-zmq's Introduction

mql-zmq

ZMQ binding for the MQL language (both 32bit MT4 and 64bit MT5)

Introduction

This is a complete binding of the ZeroMQ library for the MQL4/5 language provided by MetaTrader4/5.

Traders with programming abilities have always wanted a messaging solution like ZeroMQ, simple and powerful, far better than the PIPE trick as suggested by the official articles. However, bindings for MQL were either outdated or not complete (mostly toy projects and only basic features are implemented). This binding is based on latest 4.2 version of the library, and provides all functionalities as specified in the API documentation.

This binding tries to remain compatible between MQL4/5. Users of both versions can use this binding, with a single set of headers. MQL4 and MQL5 are basically the same in that they are merged in recent versions. The difference is in the runtime environment (MetaTrader5 is 64bit by default, while MetaTrader4 is 32bit). The trading system is also different, but it is no concern of this binding.

Files and Installation

This binding contains three sets of files:

  1. The binding itself is in the Include/Zmq directory. Note that there is a Mql directory in Include, which is part of the mql4-lib. Previous Common.mqh and GlobalHandle.mqh are actually from this library. At release 1.4, this becomes a direct reference, with mql4-lib content copied here verbatim. It is recommended you install the full mql4-lib, as it contains a lot other features. But for those who want to use mql-zmq alone, it is OK to deploy only the small subset included here.

  2. The testing scripts and zmq guide examples are in Scripts directory. The script files are mq4 by default, but you can change the extension to mq5 to use them in MetaTrader5.

  3. Precompiled DLLs of both 64bit (Library/MT5) and 32bit (Library/MT4) ZeroMQ (4.2.0) and libsodium (1.0.11) are provided. Copy the corresponding DLLs to the Library folder of your MetaTrader terminal. If you are using MT5 32bit, use the 32bit version from Library/MT4. The DLLs require that you have the latest Visual C++ runtime (2015).

    Note that if you are using MT5 32bit, you need to comment out the __X64__ macro definition at the top of the Include/Mql/Lang/Native.mqh. I assume MT5 is 64 bit, since their is no way to detect 32 bit by native macros, and to define pointer related values a macro like this is required.

    Note that these DLLs are compiled from official sources, without any modification. You can compile your own if you don't trust these binaries. The libsodium.dll is copied from the official binary release. If you want to support security mechanisms other than curve, or you want to use transports like OpenPGM, you need to compile your own DLL.

    Note for WINE users, if the default binaries do not work for you, you can try the binaries in the Library/VC2010 directory. The new binaries are a little newer (libzmq 4.2.2 and libsodium 1.0.36). They are compiled with Visual C++ 2010 Express SP1 (using the Windows SDK 7.1), and supposed to be more compatible to WINE than the VS2015 version. They depend on VC2010 runtime (msvcr100.dll and msvcp100.dll). I have actually tested the old and the new DLLs on WINE 2.0.3 (Debian Jessie PlayOnLinux 32bit with MetaTrader4 build 1090) and they both work. So it is not guarenteed but it is nice to have an alternative. The new libzmq.dll only runs on vista or newer windows because I turned on the using poll option. This improves performance a little bit. Since MetaTrader4 officially no longer supports Windows XP, I assume this would not be a problem.

About string encoding

MQL strings are Win32 UNICODE strings (basically 2-byte UTF-16). In this binding all strings are converted to utf-8 strings before sending to the dll layer. The ZmqMsg supports a constructor from MQL strings, the default is NOT null-terminated.

Notes on context creation

In the official guide:

You should create and use exactly one context in your process. Technically, the context is the container for all sockets in a single process, and acts as the transport for inproc sockets, which are the fastest way to connect threads in one process. If at runtime a process has two contexts, these are like separate ZeroMQ instances.

In MetaTrader, every Script and Expert Advsior has its own thread, but they all share a process, that is the Terminal. So it is advised to use a single global context on all your MQL programs. The shared parameter of Context is used for sychronization of context creation and destruction. It is better named globally, and in a manner not easily recognized by humans, for example: __3kewducdxhkd__

Usage

You can find a simple test script in Scripts/Test, and you can find examples of the official guide in Scripts/ZeroMQGuideExamples. I intend to translate all examples to this binding, but now only the hello world example is provided. I will gradually add those examples. Of course forking this binding if you are interested and welcome to send pull requests.

Here is a sample from HelloWorldServer.mq4:

#include <Zmq/Zmq.mqh>
//+------------------------------------------------------------------+
//| Hello World server in MQL                                        |
//| Binds REP socket to tcp://*:5555                                 |
//| Expects "Hello" from client, replies with "World"                |
//+------------------------------------------------------------------+
void OnStart()
  {
   Context context("helloworld");
   Socket socket(context,ZMQ_REP);

   socket.bind("tcp://*:5555");

   while(true)
     {
      ZmqMsg request;

      // Wait for next request from client

      // MetaTrader note: this will block the script thread
      // and if you try to terminate this script, MetaTrader
      // will hang (and crash if you force closing it)
      socket.recv(request);
      Print("Receive Hello");

      Sleep(1000);

      ZmqMsg reply("World");
      // Send reply back to client
      socket.send(reply);
     }
  }

TODO

  1. Write more tests.
  2. Add more examples from the official ZMQ guide.
  3. More documentation
  4. High level API for common patterns

Changes

  • 2017-10-28: Released 1.5: Important: API change for Socket.send; Remove PollItem duplicate API (#11); Fix compiler warning (#10) and compile failure (#12); Add RTReq example from ZMQ Guide Chapter 3.
  • 2017-08-18: Released 1.4: Fix ZmqMsg setData bug; Change License to Apache 2.0; Inlcude mql4-lib dependencies directly.
  • 2017-07-18: Released 1.3: Refactored poll support; Add Chapter 2 examples from the official ZMQ guide.
  • 2017-06-08: Released 1.2: Fix GlobalHandle bug; Add rebuild method to ZmqMsg; Complete all examples in ZMQ Guide Chapter 1.
  • 2017-05-26: Released 1.1: add the ability to share a ZMQ context globally in a terminal
  • 2016-12-27: Released 1.0.

Donation

This binding is created in spare time and the author answers questions, solves issues, and intends to maintain the code so that bugs are fixed and the binding is kept up to date with official releases. If you think that the binding is useful to you or your organization, please consider donate to the author for his effort to maintain this binding. Thanks!

paypal

alipay

mql-zmq's People

Contributors

biohazardxxx avatar dingmaotu avatar yerden avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mql-zmq's Issues

Still getting "Cannot load 'libzmq.dll' [126]" error

Hey, sorry to raise the issue again even though it was solved (for some) before.

Even after using all the fixes provided in the previous threads (installing visual C++ 2015 + checking that &key[32] below #define SOCKOPT_CURVE_KEY(KeyType,Macro) is changed to uchar &key[] in SocketOptions.mqh) but I still get the same "Cannot load 'libzmq.dll' [126]" error. Anybody having the same problem or a fix ??

Thanks so much!!

how to clean up zmq binding properly?

deinit is not being called everytime.

the program can subscribe and receive message at first run. after closing the expert and reopen, mt4 held up zmq binding. the program cannot receive messages anymore. need to restart whole metatrader program in order to reuse the same tcp port. sometimes need to reboot to release.

//+------------------------------------------------------------------+
//| HelloWorldServer.mq5 |
//| Copyright 2016, Li Ding |
//| [email protected] |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Li Ding"
#property link "[email protected]"
#property version "1.00"

#include <Zmq/Zmq.mqh>
//+------------------------------------------------------------------+
//| Hello World server in MQL |
//| Binds REP socket to tcp://*:5555 |
//| Expects "Hello" from client, replies with "World" |
//+------------------------------------------------------------------+
//void OnStart()
Context context("helloworld");
Socket socket(context,ZMQ_SUB);
string command_string = "cmd|" + AccountName();
string serstr="tcp://127.0.0.1:16006";

int init()
{

socket.bind(serstr);
socket.subscribe(command_string);

EventSetMillisecondTimer(1);
return 0;
}
//+------------------------------------------------------------------+

int deinit(){
//destroyer(socket);
Alert ("Function deinit() triggered at exit");// Alert
socket.unsubscribe(command_string);
socket.unbind(serstr);
context.shutdown();
return 0;
}

void OnTimer()
{

  ZmqMsg request;

  // Wait for next request from client

  // MetaTrader note: this will block the script thread
  // and if you try to terminate this script, MetaTrader
  // will hang (and crash if you force closing it)
  socket.recv(request);
  Print(request.getData());

  Sleep(1000);

  //ZmqMsg reply("World");
  // Send reply back to client
  //socket.send(reply);

}

Cannot load libzmq.dll [998]

The problem is that, libzmq.dll library can't be loaded into MT5 after metatrader update from 2350 to 2450.
It prints the 998 error code, not 126 as it is common when the environment lacks with vc 2015.

I use MT5 2450 build with WINE environment.
The libzmq.dll is taken from here https://github.com/dingmaotu/mql-zmq/tree/master/Library/MT5.
I also tried with libraries taken from VC2010 directory.
Before MetaTrader update, the library could be loaded, so I think that the problem is not connected with the vc libraries.

problem
Maybe someone has an idea how to solve this issue?

Errors in TestZmq.mq5 execution

Hi!
Thanks for awesome binding.
I try to run in configuration: core i7, Ubuntu 16 x64, Wine x32, MQL5 x32
After installation and module patching TestZmq.mq5 had compiled fine.
But when I try to run it, most of functions work incorrectly

Here is print log:
DH 0 22:49:36.714 TestZmq (EURUSD,H1) >>> Testing capabilities
FO 0 22:49:36.717 TestZmq (EURUSD,H1) 0) Zmq version is [4.2.0]
DD 0 22:49:36.717 TestZmq (EURUSD,H1) 1) Supports ipc:// protocol: [false]
MJ 0 22:49:36.717 TestZmq (EURUSD,H1) 2) Supports pgm:// protocol: [false]
JM 0 22:49:36.717 TestZmq (EURUSD,H1) 3) Supports norm:// protocol: [false]
MF 0 22:49:36.717 TestZmq (EURUSD,H1) 4) Supports tipc:// protocol: [false]
PS 0 22:49:36.717 TestZmq (EURUSD,H1) 5) Supports curve security: [true]
DI 0 22:49:36.717 TestZmq (EURUSD,H1) 6) Supports gssapi security: [false]
FM 0 22:49:36.717 TestZmq (EURUSD,H1) >>> End testing capabilities
CR 0 22:49:36.717 TestZmq (EURUSD,H1) >>> Testing Z85 encoding/decoding
DI 0 22:49:36.717 TestZmq (EURUSD,H1) 1) Original data is: 12345678
PO 0 22:49:36.717 TestZmq (EURUSD,H1) 2) Encrypted value is: f!$Kwh8WxM
GE 0 22:49:36.717 TestZmq (EURUSD,H1) 3) Decoded: 12345678
OO 0 22:49:36.717 TestZmq (EURUSD,H1) 4) Decoded value is equal to original: [true]
RK 0 22:49:36.717 TestZmq (EURUSD,H1) >>> End testing Z85 encoding/decoding
ER 0 22:49:36.717 TestZmq (EURUSD,H1) >>> Testing atomic counters
PF 0 22:49:36.719 TestZmq (EURUSD,H1) 1) Initial value should be 0: [true0]
IG 0 22:49:36.719 TestZmq (EURUSD,H1) 2) Counter set to 5: [false1502567338]
DO 0 22:49:36.719 TestZmq (EURUSD,H1) 3) Increased value should be 6: [false1502567339]
OH 0 22:49:36.719 TestZmq (EURUSD,H1) 4) Decreased value should be 5: [false1502567338]
FH 0 22:49:36.719 TestZmq (EURUSD,H1) >>> End testing atomic counters
NQ 0 22:49:36.719 TestZmq (EURUSD,H1) >>> Testing context
RH 0 22:49:36.720 TestZmq (EURUSD,H1) 1) Default IO threads should be ZMQ_IO_THREADS_DFLT: [false]
EN 0 22:49:36.720 TestZmq (EURUSD,H1) >>> trying to set io threads to 2
OK 0 22:49:36.720 TestZmq (EURUSD,H1) >>> DEBUG: In Context::setIoThreads(Context.mqh:67) [failed to set ZMQ_IO_THREADS]
LJ 0 22:49:36.720 TestZmq (EURUSD,H1) 2) Now IO threads should be 2: [false]
OR 0 22:49:36.720 TestZmq (EURUSD,H1) 3) Socket limit: [-1]
FE 0 22:49:36.720 TestZmq (EURUSD,H1) 4) Max sockets: [-1]
EO 0 22:49:36.720 TestZmq (EURUSD,H1) 5) Max message size: [-1]
MJ 0 22:49:36.720 TestZmq (EURUSD,H1) >>> End testing context
MQ 2 22:49:36.726 TestZmq (EURUSD,H1) Unhandled exception 0x40000015
KI 2 22:49:37.240 TestZmq (EURUSD,H1) 7B43C1D0 8D4C2404 lea ecx, [esp+0x4]
...
then much of assembler lines.

Thanks for help!

Context init bug

新建一个上下文对象用到 makeTemp(string name) {return GlobalVariableTemp(name);}这段代码。
每次调试都要
GlobalVariableDel("helloworld");
Context context("helloworld");
有更好的处理方法么?

No WinUser32.mqh in MT5 x32

Hi!
I use MT5 x32 on Linux under wine and there is no WinUser32.mqh in Include dir
So I have to comment it
eval sed -i "s/#include\ <WinUser32.mqh>/\\/\\//" "$MT_DIR"/MQL5/Include/Mql/Lang/Native.mqh
and then compilation works good.

无法连接互联网ip

如果是内网的话,可以。
如果是外网ip,没法client连接。
不知道哪里设置允许连接外部server

Publish to a certain topic

Hi,

I'm trying to create different topics for different stuff, how can I implement that since the ZmqMsg only accepts a string.

Thanks

HandleManager::destroy() undeclared identifier using MT 5

Returning compilation error using MT5 MetaQuotes/MetaEditor Version5.00 build 2375 31/Mar/2020 into file MQL5\Include\Mql\Lang\GlobalVariable.mqh into lines 228:
if(!m_cs.isValid()) {HandleManager::destroy(m_ref); return;}
and line 233:
HandleManager::destroy(m_ref);
image
(Windows 10/64bits)
The same project does not return compilation error using version MT 5 MetaEditor Version 5.00 build 2363 13/Mar/2020 AND version MT 5 MetaEditor Version 5.00 build 2361 08/MAr/2020

SOCKOPT

I need to set receive time, but I can't get how to properly use SOCKOPT(int, ReceiveTimeout, ZMQ_RCVTIMEO). It's even doesnt compile

Metatrader crashes (but not immediately)

I use mql zmq on MT5 but I also used to use it on MT4 and I think I had this same problem.

After running it for a while (could be 30 minutes, could be many hours) eventually it might crash metatrader.

I have no idea how to debug this.

I use a ZMQ_POLLIN to poll a ZMQ_REQ socket continuously (with a 20ms break in between) in a timer event.

apart from the crashing everything works fine. I don't have any other EAs or scripts running in metatrader.. just the one ZMQ EA.

Can anyone think of what could be causing this? I'm on windows 10.

I’m getting “Resource timeout.. please try again.” error and...

Hi,

I have just installed required server and client.

trades = 10
for _ in range(trades):
    _zmq._DWX_MTX_NEW_TRADE_()

the strange thing is, only second half of my orders are executed. If i set "trades" variable to 20, MT4 will open only 10 orders. If I set 2, only one order will be opened. This may help you to find the problem and possible solution.

I have not changed any default parameters. I have updated EA properties and changed Maximum orders to 10 and maximum lot size to 10.

_verbose is set to True. I can send orders anyway, the problem is totally different here.

I have two more questions

  1. Can I ask how can i reach return values of following line? “tt” is None type and doesn’t return anything. It just prints results to console.

tt = _zmq._DWX_MTX_GET_ALL_OPEN_TRADES_()

  1. How can i get last 400 OHLC data?

SUB收不到消息

我用下面这段代码订阅信息,为什么一直都收不到任何信息呢?
请您帮我看一下错误在哪里,可以吗?或者可否提供一个订阅所有频道的例子?

void OnStart()
{
   Context context;
   Socket socket(context,ZMQ_SUB);
   bool rc = socket.connect("tcp://localhost:5555");
   socket.setSubscribe("");
   ZmqMsg msg;
   socket.recv(msg);
   Alert(msg.getData());
}

socket.mqh里面提到的Context工厂方法指的是哪一个方法?

socket.mqh里面提到:

it is not recommended to use this constructor directly: use Context factory methods instead

我在context.mqh里找不到这个工厂方法。

我对zeromq还不是特别熟悉,我之前只用过pyzmq。这里提到的工厂方法是不是像pyzmq的context.socket(zmq.PUB)?但是不知道在您的mql-zmq这个工厂函数叫什么?

Fails under wine 2.0.3

Apologies if the operation under wine is not something that has been envisaged.

But if it is, having this issue with wine-2.0.3. Testing with TestZmq.mq4. Metatrader 4 build 1090.

Hangs at this point:

Context context;

Log output from wine:
fixme:ntdll:EtwEventRegister ({5eec90ab-c022-44b2-a5dd-fd716a222a15}, 0x9cc27f0, 0x9cd0030, 0x9cd0048) stub.

Log output from MT:

2017.12.15 18:30:51.848 TestZmq EURUSD,H4: >>> Testing context

Appreciate any guidance.

Libraries for MT5

Hello @dingmaotu ,
I 've been using your libraries for binding Mql4 and Python.
I tried to use them for Mql5 however I keep getting errors on ZmqMsg.mqh. I checked the readme, you say MQL4 and MQL5 are basically the same in that they are merged in recent versions. However I can't use Zmq binding library on Mql5. Zmq.mqh can't be used with Mql5 cause ZmqMsg can't be compiled on mql5.

https://imgur.com/a/XOetypp

I have:
Visual C++ runtime (2015).

Error on ZmqMsg.mqh

Hello.
I have been using this MQL-ZMQ library for 2 months, but today I started to get the following error. I tried to download the library again, replacing the old files for the new ones but the bug persists. Any idea how to fix it?

image

image

issue with mt5 dll?

Run on mt4 success, but with same code, it got error after call Socket::send
Access violation at 0x00007FFFACF42640 read to 0x0000000000000613 in 'D:\MT5\AMP3\MQL5\Libraries\libzmq.dll'

mt5: 64bit, 5.0.0.1881

(I had use tool Dependencies to make sure the library used is AMD64 dll)

Cannot load 'libzmq.dll' [126]

Whenever I try and run the below script, I get the error: Cannot load 'libzmq.dll' [126]

The file libzmq.dll is everywhere in my bindings, so it's not that the file does not exist.

Somebody else (maybe) seems to be having a similar issue here: https://www.mql5.com/en/forum/104158

Any ideas???

#include <Zmq/Zmq.mqh>
//+------------------------------------------------------------------+
//| Hello World client in MQL                                        |
//| Connects REQ socket to tcp://localhost:5555                      |
//| Sends "Hello" to server, expects "World" back                    |
//+------------------------------------------------------------------+
void OnInit()
  {
   Comment("Started");
// Prepare our context and socket
   Context context("helloworld");
   Socket socket(context,ZMQ_REQ);

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

// Do 10 requests, waiting each time for a response
   for(int request_nbr=0; request_nbr!=10 && !IsStopped(); request_nbr++)
     {
      ZmqMsg request("Hello");
      PrintFormat("Sending Hello %d...",request_nbr);
      socket.send(request);

      // Get the reply.
      ZmqMsg reply;
      socket.recv(reply);
      PrintFormat("Received World %d",request_nbr);
     }
  }

Still Cannot call 'libzmq.dll::zmq_socket', DLL is not allowed.

Hi Ding,

I continue to have problems related to issue #17, #18 #19. I have tried nearly everything I can think of.

This was born out of trying to set-up https://github.com/darwinex/dwx-zeromq-connector.

I have done the following:

  1. Downloaded and unzipped mql-zmq-master.zip (by GitHub author @dingmaotu)
  2. Copied the contents of mql-zmq-master/Include/Mql and mql-zmq-master/Include/Zmq into MetaTrader installation's MQL4/Include directory as-is.
  3. Copy libsodium.dll and libzmq.dll from mql-zmq-master/Library/MT4 to your MetaTrader installation's MQL4/Libraries directory.
  4. Downloaded DWX_ZeroMQ_Server_vX.Y.Z_RCx.mq4 and placed it inside my MetaTrader installation's MQL4/Experts directory.

In the beginning, I was getting the following errors and for the most part was always the same errors. I tried to run the strategy tester and copy the .DLL into the tester libraries since who knows. But to no avail.

When I was running the MQ4 scripts from DarwinExchange my log files looked as follows for several attempts to restart and adjust configs like "Allow Import of DLLs".

Please check the log file below:
https://mail.google.com/mail/u/0?ui=2&ik=f879f079a4&attid=0.1&permmsgid=msg-a:r-8510298936047011599&th=16a65525468eed0d&view=att&disp=safe&realattid=f_jv1auerc0

In attempt to isolate the problem only to libzmq - I started testing with your Hello World Scripts where I was getting the same type of error shown below:

I get the following error:
image

I understand libzmq.dll requires 32Bit Microsoft Visual C++ 2015 Redistributable (x86) to compile. I have confirmed that I am using 32bit DLL; the DLL is compiled on Windows with VC++ 2015; and I have VC2015 runtime installed. I noticed that metaeditor was picking up Visual C++ 2010 at one point even though I had VC2015 installed. As an attempt, I uninstalled all VCXXXX runtimes with a fresh install of Microsoft Visual C++ 2015 Redistributable (x86) - 14.0.24123 installed.
image

My computer system information is as follow:
image

This is also with MT4

This was another screenshot of some other errors that I found randomly while I was constantly retesting with Strategy Tester.

https://mail.google.com/mail/u/0?ui=2&ik=f879f079a4&attid=0.1&permmsgid=msg-a:r5476977544650207859&th=16a654fe72da8bed&view=fimg&sz=s0-l75-ft&attbid=ANGjdJ9fJH87-0fj_EDxSDiDk44K98iSor012gKeRId3Gg1yFvtwM4FblrJ8mzbl43bPuxWtrJaUmsBUF1wDNFVJNzO1FMVlnkFu9Zk6ITtOqLu7WUcHWUI5uRaTBqI&disp=emb&realattid=ii_jv1aqxhc0

At this point, I have run out of ideas on what to do..

Access Violation write to 0x000.... Error

Hello Dingmaotu,

I am stating to getting more and more "Access Violation write to 0x000...." Error while testing the bridge between MT4 and Python.

i am on x64 bit window 10. Can you please advise a solution?

How i can open order ?

how the command i need to send ?
the
TRADE|OPEN|1|EURUSD|0|50|50|R-to-MetaTrader4|12345678
is not work

RCVTIMEO - how to

Hi,

please, how to realize:

zmq_req_socket.setsockopt( zmq.RCVTIMEO, 500 ) # milliseconds

I found this:
SOCKOPT(int,ReceiveTimeout,ZMQ_RCVTIMEO) // milliseconds

But I not understand, how to.
if I declare in global - get:

'getOption' - function not defined 4xcd_zmq.mq4 25 1

If I declare in OnInit

'getReceiveTimeout' - function can be declared only in the global scope 4xcd_zmq.mq4 44 3

Please, have a sample?
Thanks Milan

Can you modify the implementation?

thank you provide this lib。

for sub/pub model, subscriber received msg include the code。
server code:
if((i % 2) == 0)
{
ZmqMsg workMsg("A workA" + i);
socket.send(workMsg);
}
if((i % 2) == 1)
{
ZmqMsg workMsg("B workB" + i);
socket.send(workMsg);
}
subscriber A received msg is
A workA0
...
subscriber B received msg is
B workB1
...

i hope subscriber A received msg is
workA0
...
subscriber B received msg is
workB1
...

i more hope server code like this:
if((i % 2) == 0)
{
socket.subscribe("A");
ZmqMsg workMsg("workA" + i);
socket.send(workMsg);
}
if((i % 3) == 1)
{
socket.subscribe("B");
ZmqMsg workMsg("workB" + i);
socket.send(workMsg);
}

can you modify it?

Raise error in Socket::poll() as polling socket and monitor at the same time

I need listen the events from the socket, so I was polling socket and monitor at the same time in Update().

I dig the error step by step and provide test sourcecode

  1. if I just polling socket, it works. so Socket::poll() is ok.

test_zmq_poll_socket.mq5

  void ZmqServer() {
    sock_.fillPollItem(polls_[0], ZMQ_POLLIN);
  }
  void Update() {

    Socket::poll(polls_, 0); <-- just polling sokect

    if (polls_[0].hasInput())
      recieve_zmq_message();  

  }
  1. if I just polling monitor, it works too. so monitor socket is ok

test_zmq_poll_monitor.mq5

  void ZmqServer() {
    monitor_.fillPollItem(polls_[0], ZMQ_POLLIN);
  }
  void Update() {

    Socket::poll(polls_, 0);  <-- just polling monitor

    if (polls_[0].hasInput())      
      dispatch_monitor_events();

  }
  1. if I polling socket and monitor at the same time, EA failed to start up with error like screenshot.

screenshot of parallels desktop 2017 12 11 14 03

test_zmq_poll_monitor_and_socket.mq5

  void ZmqServer() {
    sock_.fillPollItem(polls_[0], ZMQ_POLLIN);
    monitor_.fillPollItem(polls_[1], ZMQ_POLLIN);
  }
  void Update() {

    Socket::poll(polls_, 0);  <-- polling socket and monitor

     if (polls_[0].hasInput())
       recieve_zmq_message();  

     if (polls_[1].hasInput())      
      dispatch_monitor_events();

  }

all test code:

test_sourcecode.zip

It confused me for a while, need help!

compile failed in mt5

MT5 build 1643, got

screenshot of parallels desktop 2017 10 15 14 32

from

   //--- curve
   SOCKOPT_CURVE_KEY(Public,ZMQ_CURVE_PUBLICKEY)
   SOCKOPT_CURVE_KEY(Secret,ZMQ_CURVE_SECRETKEY)
   SOCKOPT_CURVE_KEY(Server,ZMQ_CURVE_SERVERKEY)

#define SOCKOPT_CURVE_KEY(KeyType,Macro) \
   bool              getCurve##KeyType##Key(uchar &key[32]) {size_t len=32; return getOption(Macro,key,len);} \
   bool              getCurve##KeyType##Key(string &key) {return getStringOption(Macro,key,41);} \
   bool              setCurve##KeyType##Key(const uchar &key[32]) {return setOption(Macro,key,32);} \
   bool              setCurve##KeyType##Key(string key) {return setStringOption(Macro,key);}

cannot load libzmq.dll on WINE

I use Mac OS, which is probably the issue but just wanted an answer from you anyways. I tried libzmq.dll and libsodium.dll in the MT4 and VC2010 folder. They will either crash my wine preloader or say it cannot load libzmq.dll

Python as a server and Mql as a client

Hi,
first of all, congratulations for the tutorial!

Please, do you know if is possible put python as a server and mql as a client?

I would like to be able to build a loop to execute various (approximately 800) expert adivisors and save the equities of each of them. As this can not be done in mql I would like to know if it would be possible to perform such a task by putting Python as a server and Mql as a client.

Thanks a million!

Error when try to use in MQL5

Hello,

i tried to build to zmq to mql5, I already copy the right dll files to Libraries folder, but i keep got this error.
screenshot_715

DLL's not allowed when running EA

Hi, i have followed your steps in setting up zmq with metatrader, however when i come to running the ea on a chart i am getting this error

Screenshot 2019-04-04 at 21 09 18

Not sure why it is saying DLL is not allowed, i have installed the correct VC 2015 and the 32 bit DLL's are located in the libraries folder of the MT4.

Thanks for your help

Al

Windows 8.1 pro N on Macbook Bootcamp: cannot load .. Libraries\libzmq.dll [126]

I've opened up this issue in case anyone is having the same problem.

A bit of background:
Prior to this, I've had no problems whatsoever running the bindings with MT5 (x64) on a Lenovo notebook running Windows 8.1

As @dingmaotu has already explained in his installation guide a lot of people seem to be having problems with the x86 version of the MS VC++ redistributable.

I am currently using the 2015 14.02.3026 version and everything works fine.

I have also found it to stop working and generate the same error if I intentionally uninstall the 2015 redist.


Now the problem:
A few days ago I installed windows 8.1 pro N on a Macbook running Bootcamp.
I also installed the usual VC++ 2015 redist. using the same install files/version from my other system.

Strangely, the same code / settings now generates the "cannot load dll" on the Macbook!

I'm trying to think of reasons this could happen:

  1. Operating System: Windows 8.1 Pro vs Pro N??? (This sounds too silly!)
  2. Hardware difference: Macbook vs PC??? (This is also silly..)
  3. VC++ 2015 reacting differently on the environments? Possible .. but can't think of a reason
  4. Maybe there is something other than the standard settings (MS VC++ 2015 etc.) that I'm missing from my macbook system that prevents VC++ 2015 to execute properly??

If anyone stumbles upon this please share some suggestions :)
I would like to also thank @dingmaotu for providing such a great binding. Powerful & easy to use!

Assertion failed: Bad address (..\..\..\..\src\tcp.cpp:213)

Hi dingmaotu, Thanks a bunch for the binding. I'm trying to get it running on Linux (Elementary OS) and I'm using the python template of Darwinex. I manage to get price info into python, however when I try to buy an instrument MT4 and wine (2.22) crash and close. When I look in the PlayOnLinux debugger it gives the error:

Assertion failed: Bad address (........\src\tcp.cpp:213)

I have the feeling it has to do with libzmq.dll, not sure though.

Any thoughts?

Connect is not working in Expert Advisor,

You can check that:

Copy HelloWorldClient to OnTick method in ExpertAdvisor.

It is not working :(

My Server side is C# (.NET), I want to collect all OnTick data from MT4 , for example: I will add magical Expert Advisor to EURUSD, USDJPY,EURJPY and Collect all TickData on C# side.

2 days wasted :(

Compilation Socket Options

metaeditor - 5bsocketoptions mqh 2a 5d 2017-10-23 09-49-07
I'm using metatrader 5 32 bits, when compiling I need to comment some lines, otherwise it doesn't work.

any thought?

Socket receive timeout

Hello, how can I set the socket receive timeout?

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

    socket.connect(PROTOCOL_ADDRESS);
    socket.send(request);
    PrintFormat("sending request");

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

Fix compile warning

It's uncomfortable one warning left each time.

screenshot of parallels desktop 2017 10 16 18 47

pass size_t to int

void ZmqMsg::setData(const uchar &data[])
  {
   intptr_t dest=data();
   size_t size=size();
   ArrayToPointer(data,dest,size);    <----- here
  } 

Can't Load libzmq.dll in Backtester

Hello Dingmaotu,

I am very new zmq, so please excuse me for this naive question.

I was able to properly install mql-zmq library following your instructions. I've put MT5 .DLLs into the Libraries folder and have enabled DLL imports on the MT5 terminal.

To begin I've written an EA that just pushes the current price every 2 seconds to the socket and a python program that listens to the socket. I was able to successfully run it on the MT5 terminal.

The issue I have encountered is when I load this simple EA into the Strategy Tester. It seems that that the tester is not able to load the libzmq.dll. See the error log bellow.

DI	0	14:50:30.578	Core 1	EURUSD,H1: testing of Experts\Advisors\Python_Server2.ex5 from 2018.05.24 00:00 to 2018.05.25 00:00 started
QH	1	14:50:30.578	Core 1	2018.05.24 00:00:00   Cannot load 'C:\Users\daniy\AppData\Roaming\MetaQuotes\Tester\..\MQL5\Libraries\libzmq.dll' [126]
DQ	2	14:50:30.578	Core 1	2018.05.24 00:00:00   Cannot call 'zmq_ctx_new', 'libzmq.dll' is not loaded
ES	2	14:50:30.578	Core 1	2018.05.24 00:00:00   unresolved import function call
GG	2	14:50:30.578	Core 1	global initialization failed
IS	2	14:50:30.578	Core 1	global initialization critical error
FD	2	14:50:30.578	Core 1	tester stopped because expert initialization failed

Do you know what the issue might be?

Thank you for any help :)

How to perform authentication

How can i send Username/PAssword when connecting to server.
I am receiving below

1591613328: New connection from 122.255.11.106 on port 1883.
1591613328: Client disconnected due to protocol error.

Can you please add an example with mql

Getting "unicode not allowed, use send_string" error when implementing with python 3(.7)

Hello,

The code works very well when used with python 2.7 (thanks so much again!!!). However, for efficiency matters, I am trying to switch to python 3.7 but get the error "unicode not allowed, use send_string", would you have an idea on how I could fix this issue.

Thanks a lot for your time!

EDIT: Found the solution --> you have to encode the unicode string in python using unicode_string.encode(encoding), I used "utf-8" for encoding

Duplicate api make confuse

Socket::register vs Socket::fillPollItem

void Socket::register(PollItem &pollitem,bool read=false,bool write=false)
  {
   ZeroMemory(pollitem);
   pollitem.socket=m_ref;
   if(read) pollitem.events|=ZMQ_POLLIN;
   if(write) pollitem.events|=ZMQ_POLLOUT;
  }

void Socket::fillPollItem(PollItem &item,short events)
  {
   item.socket=m_ref;
   item.fd=0;
   item.events=events;
   item.revents=0;
  }

Authentication

There is a way add authentication from pubsup some sort of custom token or key
should i change the numbers for my code ?

#define ZMQ_PLAIN_USERNAME 45

83 | #define ZMQ_PLAIN_PASSWORD 46
84 | #define ZMQ_CURVE_SERVER 47
85 | #define ZMQ_CURVE_PUBLICKEY 48

Port from c++ of the common "Lazy Pirate" pattern client causes random memory access violation

Solution-0

I have wrapped the Lazy pirate Pattern into a .dll
And I made a MQL binding for it.
It can be found here

What is provided is included in the readme.
If I found a way to do the correct libzmq.dll imported calls from MetaTrader without crashing the terminal under wine 3.0, I would update this.

UPDATE-2 (unconfirmed hypothesis)

I will cover this in more detail in next update.
I'm having success with this pattern, only when wrapped inside another dll that contains its abstractions at C/C++ level. I'm working with it, and I will publish them when done.
This problem seems to be related with "the art" of passing strings, and objects structures through dll boundaries in imported function parameters, and the C null terminated string issues when its null end is truncated caused by an incorrect size parameter.
Also the size of the dll string returned must be allocated in the caller memory before to the call and return from dll boundaries.
And also, my advice is to avoid the MetaTrader string type at this level ignoring completely the documentation that shows an example with it.
The fact is that works "sometimes", and maps to wchar_t* type, that also, will lead to a "string marshalling" overkill at dll level.
CharArray seems to do the job when properly terminated.

As you remember in strcpy() documentation:

To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.

As this where not enough, there is also a problem with the string encoding through platforms that's not very clear how it must be resolved.

I'll update with more details.

UPDATE-1
Definitively the c++ version works as expected, it can be downloaded here:

Now here, different language but same program, throws (sometimes) an unhandled exception on socket.poll() and in init() when new Socket() is called after delete or when socket.send()
I'm trying to figure out why that happens.

Updated testing version can be found here

Also I found a related issue here.
socket.send(ZmqMsg var) will not preserve the contents of var, this is unexpected for me.
zmq c++ binding doesn't show that issue.

UPDATE-0
I found a workaround for this on a c++ version here

It can be build from command line in Linux:

g++ -ansi multiworker_lpclient.cpp -lzmq -o multiworker_lpclient

Also, I've updated the example below here
Although, that is not a very robust solution, it performs better than the previous version.

Issue description

I'm getting a Random Access violation on libzmq.dll trying to implement the "Lazy Pirate" pattern client in mql EA code.

If both or one of the workers are offline I got sometimes:

On Windows 10:

Access violation read to 0x00000390 in 'C:\Users...\MQL4\Libraries\libzmq.dll'

Wine 3.0:

Access violation read to 0xE8CA00A0 in 'C:...\MQL4\Libraries\libzmq.dll'

This is a sample startup log of that condition:

2019.05.05 05:07:15.933	2018.10.01 00:00:00  ZMQAccessViolation test started
2019.05.05 05:07:15.961	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Creating new socket
2019.05.05 05:07:15.979	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Opening new client socket connection to tcp://localhost:5555
2019.05.05 05:07:15.979	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Creating new socket
2019.05.05 05:07:15.981	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Opening new client socket connection to tcp://localhost:5566
2019.05.05 05:07:15.982	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: On tick loop number: 0
2019.05.05 05:07:15.982	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: 3 WorkerA tcp://localhost:5555 #this is a R script
2019.05.05 05:07:15.982	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 19 bytes ...
2019.05.05 05:07:15.982	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : #this is a R script
2019.05.05 05:07:16.984	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Received Response, 19 bytes
2019.05.05 05:07:16.984	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: reply body: #this is a R script
2019.05.05 05:07:16.984	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: 3 WorkerB tcp://localhost:5566 { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
2019.05.05 05:07:16.984	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 74 bytes ...
2019.05.05 05:07:16.984	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
2019.05.05 05:07:17.986	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Received Response, 74 bytes
2019.05.05 05:07:17.986	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: reply body: { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
2019.05.05 05:07:18.050	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: On tick loop number: 1
2019.05.05 05:07:18.050	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: 3 WorkerA tcp://localhost:5555 #this is a R script
2019.05.05 05:07:18.050	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 19 bytes ...
2019.05.05 05:07:18.050	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : #this is a R script
2019.05.05 05:07:20.553	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: No response from worker, retrying ... 
2019.05.05 05:07:20.553	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Retries left: 2
2019.05.05 05:07:20.553	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Creating new socket
2019.05.05 05:07:20.553	2018.10.01 00:00:02  Access violation read to 0xE8CA00A0 in 'C:\Program Files\MetaTrader Standard G\MQL4\Libraries\libzmq.dll'
2019.05.05 05:07:20.553	2018.10.01 00:00:02  Testing pass stopped due to a critical error in the EA
2019.05.05 05:07:20.553	GBPUSD+,M5: 2 tick events (1 bars, 5851652 bar states) processed in 0:00:04.619 (total time 0:00:12.962)

In this case, one of the workers simulated a failure exiting itself.
If I remove the "socket reassignment code" and just simply don't modify the socket object once created.
It can be done commenting out the lines delete(socket) and initZMQ() on lines 114, 115 of the script respectively.
I got the communication with both workers to work for a while, but sometimes it completely freezes the terminal, when some worker stop responding, or when it becomes online again after their random self exit.
If I force both workers not to exit, to verify if it is not a single point of error, and leave it run.
This can be done commenting out the break sentence on the python sample worker script at line 24
I got it to work, for a while longer than before, but after all it crashes again.
If both addresses point to the same worker, the result is the same.
I think that I'm missing something here.

This is a log recovery from non exiting workers condition:

0	06:23:29.515	Expert ZMQAccessViolation GBPUSD+,M5: loaded successfully
3	06:23:34.725	TestGenerator: no connect to trade server, default environment will be applied
0	06:23:34.725	TestGenerator: current spread 37 used
1	06:23:37.125	TestGenerator: unmatched data error (high value 1.28343 at 2019.02.14 12:20 is not reached from the least timeframe, high price 1.28337 mismatches)
1	06:23:37.125	TestGenerator: unmatched data error (low value 1.28295 at 2019.02.14 12:20 is not reached from the least timeframe, low price 1.28305 mismatches)
2	06:23:37.914	2018.10.01 00:00:00  ZMQAccessViolation test started
0	06:23:37.949	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Creating new socket
0	06:23:37.969	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Opening new client socket connection to tcp://localhost:5555
0	06:23:37.969	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Creating new socket
0	06:23:37.973	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Opening new client socket connection to tcp://localhost:5566
0	06:23:37.975	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: On tick loop number: 0
0	06:23:37.975	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: 3 WorkerA tcp://localhost:5555 #this is a R script
0	06:23:37.975	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 19 bytes ...
0	06:23:37.975	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : #this is a R script
0	06:23:38.977	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Received Response, 19 bytes
0	06:23:38.977	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: reply body: #this is a R script
0	06:23:38.977	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: 3 WorkerB tcp://localhost:5566 { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
0	06:23:38.977	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 74 bytes ...
0	06:23:38.977	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
0	06:23:39.979	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: Received Response, 74 bytes
0	06:23:39.979	2018.10.01 00:00:00  ZMQAccessViolation GBPUSD+,M5: reply body: { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
0	06:23:40.043	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: On tick loop number: 1
0	06:23:40.043	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: 3 WorkerA tcp://localhost:5555 #this is a R script
0	06:23:40.043	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 19 bytes ...
0	06:23:40.044	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : #this is a R script
0	06:23:41.045	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Received Response, 19 bytes
0	06:23:41.045	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: reply body: #this is a R script
0	06:23:41.045	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: 3 WorkerB tcp://localhost:5566 { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
0	06:23:41.045	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Sending data to worker 74 bytes ...
0	06:23:41.045	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Receiving data from worker. Sent payload : { "some_json_log": { "SYMBOL": "EURUSD", "MAGIC": "42", "etc ...":"etc" }}
0	06:23:43.546	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: No response from worker, retrying ... 
0	06:23:43.546	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Retries left: 2
0	06:23:43.546	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Creating new socket
0	06:23:43.548	2018.10.01 00:00:02  ZMQAccessViolation GBPUSD+,M5: Opening new client socket connection to tcp://localhost:5566
1	06:23:43.549	2018.10.01 00:00:02  Access violation write to 0xCA00A849 in 'C:\Program Files\MetaTrader Standard G\MQL4\Libraries\libzmq.dll'
3	06:23:43.549	2018.10.01 00:00:02  Testing pass stopped due to a critical error in the EA
0	06:23:43.549	GBPUSD+,M5: 2 tick events (1 bars, 5851652 bar states) processed in 0:00:05.635 (total time 0:00:13.871)

Sources:
libzmq.dll version 4.3.2.0 compiled in VS2019 (dlls here)
Worker code: Lazy Pirate server in Python
(code here)
Agent sample: Lazy pirate pattern MQL client to worker REQ REP tests examples
This report repository: here

Tested on:
MetaTrader Standard Version 4.00 build 1170 x86 (20 Dec 2018)
Windows 10 x64
And latest Wine 3.0 on Linux

//+------------------------------------------------------------------+
//|                                           ZMQAccessViolation.mq4 |
//|                                  Copyleft 2019, swilwerth@github |
//|                                             github.com/swilwerth |
//+------------------------------------------------------------------+
// This is a bugreport code. It'll crash Metatrader Standard Terminal
// under certain conditions.
// Do not use it in any production code.

#property copyright "Copyleft 2019, swilwerth@github"
#property link      "github.com/swilwerth"
#property version   "1.00"
#property strict

#include <Zmq/Zmq.mqh>

#define REQUEST_TIMEOUT     2500    //  msecs, (> 1000!)
#define REQUEST_RETRIES     3       //  Before we abandon

class WorkerClientBase {
    protected:
        string zmq_address;
        Socket *socket;
        Context *context;
        void connect();
        void initZMQ();
    public:
        virtual string getName() { return "WorkerClientBase"; }
        void setAddr(string addr) { zmq_address = addr; }
        ZmqMsg sendTX(string payload);
        WorkerClientBase(Context &ctx);
        ~WorkerClientBase();
};

class WorkerA: public WorkerClientBase {
    public:
        WorkerA(Context &ctx, string addr);
        string getName() { return "WorkerA"; }
        void txSomething();
};

class WorkerB: public WorkerClientBase {
    public:
        WorkerB(Context &ctx, string addr);
        string getName() { return "WorkerB"; }
        void txSomething();
};

WorkerClientBase::WorkerClientBase(Context &c) {
    context = &c;
    initZMQ();
}

WorkerClientBase::~WorkerClientBase() {
    delete(socket);
}

void WorkerClientBase::initZMQ() {
    printf("Creating new socket");
    this.socket = new Socket(context, ZMQ_REQ);
}

//Start of lazy pirate pattern client TX adapted to MQL5 from
//sample code in c++ http://zguide.zeromq.org/cpp:lpclient
void WorkerClientBase::connect() {
    printf("Opening new client socket connection to %s", zmq_address);
    while(!socket.connect(zmq_address)) {
        printf("Error connecting to worker");
    }
    //  Configure socket to not wait at close time
    int linger = 0;
    socket.setLinger(linger);
}

ZmqMsg WorkerClientBase::sendTX(string payload) {
    ZmqMsg request(payload);
    ZmqMsg reply;
    PollItem item;
    PollItem items[1];

    int global_retries = REQUEST_RETRIES;
    int retries_left = global_retries;
    int request_timeout = REQUEST_TIMEOUT;
    bool expect_reply = true;
    while(retries_left) {
        printf("%d %s %s %s", retries_left, getName(), zmq_address, payload);
        printf("Sending data to worker %d bytes ...", StringLen(request.getData()));
        socket.send(request);

        printf("Receiving data from worker. Sent payload : %s", payload);

        expect_reply = true;
        socket.fillPollItem(item, ZMQ_POLLIN);
        items[0] = item;
        while(expect_reply) {
            socket.poll(items, request_timeout);
            //got reply
            if ((items[0].revents & ZMQ_POLLIN) == 1) {
                // Get the reply.
                socket.recv(reply);
                printf("Received Response, %d bytes", reply.size());
                if(reply.size() > 0) {
                        printf("reply body: %s",reply.getData());
                        return reply;
                } else
                    printf("Malformed reply from worker");
            } else if(--retries_left == 0) {
                printf("Worker seems to be offline, abandoning ...");
                expect_reply = false;
                break;
            } else {
                printf("No response from worker, retrying ... ");
                printf("Retries left: %d", retries_left);
                delete(socket);
                initZMQ();
                connect();
                socket.send(request);
            }
        }
    }
    return reply;
}
//end of lazy pirate client code

WorkerA::WorkerA(Context &c, string addr):WorkerClientBase(c) {
    setAddr(addr);
    connect();
}

WorkerB::WorkerB(Context &c, string addr):WorkerClientBase(c) {
    setAddr(addr);
    connect();
}

void WorkerA::txSomething() {
    string payload = "#this is a R script";
    sendTX(payload);
}

void WorkerB::txSomething() {
    string payload = "{ \"some_json_log\": { \"SYMBOL\": \"EURUSD\", \"MAGIC\": \"42\", \"etc ...\":\"etc\" }}";
    sendTX(payload);
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
Context *sharedContext;
WorkerA *workerA;
WorkerB *workerB;

int OnInit()  {
   sharedContext = new Context("ECHOTEST");
   workerA = new WorkerA(sharedContext, "tcp://localhost:5555");
   workerB = new WorkerB(sharedContext, "tcp://localhost:5566");

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    delete(workerA);
    delete(workerB);
    delete(sharedContext);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int tickC = 0;
void OnTick() {
    printf("On tick loop number: %d", tickC);
    workerA.txSomething();
    workerB.txSomething();
    tickC++;
}
//+------------------------------------------------------------------+

MT4 zmq library throws compilation errors

Hi,

I imported MT4 libraries into MT4 client terminal and tried to run the hello world example as an expert advisor , but it does not compile and throws some errors at the below mentioned line of code

Context context("helloworld");

Error Message : empty class 'Context' cannot be used

An older version of this repository works fine , but with this recent commit it fails.

PFA the screenshots of errors for the same:

85516103-64b9db80-b5ed-11ea-9660-1309a3940b42

Regards,
Bhavya.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.