DWX ZeroMQ Connector will be soon be archived (available to use, but not actively maintained).
We encourage both new and existing users to please visit its successor DWX Connect, that alongside removing the ZeroMQ dependency, also brings with it native support for both MetaTrader 4 and 5 without any 3rd-party dependencies 🙌
Many thanks!
Darwinex is a UK FCA-Regulated broker & technology provider, enabling traders to:
Please take a moment to read our Risk Disclosure here
Click here to visit our Trader Hall of Fame * ranked by Performance Fees earned (over 2M EUR paid to date)
Click here to Open a Darwinex Trading Account
In this project, we present a technique employing ZeroMQ (an Open Source, Asynchronous Messaging Library and Concurrency Framework) for building a basic – but easily extensible – high performance bridge between external (non-MQL) programming languages and MetaTrader 4.
Please note that we cannot provide support for Python or MQL as programming languages themselves. Therefore, if you are new to Python and MQL, incorporating the project into your specific algorithmic trading environment will require some additional work on your part (i.e. enough Python experience to integrate the Bridge into your environment -> it is assumed that users of the Bridge are self-sufficient in Python).
Any code provided and/or referenced in this repository is NOT meant to be used "as-is". Users must treat all code as educational content that requires modification / incorporation into existing works, as per their individual requirements.
We have drafted as detailed a set of steps as possible in our project README, but cannot cover all the dependencies as they are independent projects on their own that programmers need to account for / follow / keep up to speed with when considering using the DWX ZeroMQ Connector.
This project and all accompanying source code should be run standalone (i.g. via a Python or IPython console, or batch process).
Please DO NOT run this code in Jupyter or IPython Notebooks.
The project's dependencies require MS VC++ Libraries. Without these installed, you are likely to run into "Resource Timeout" errors. The DLLs in the dependency projects (mql-zmq, libzmq, libsodium) require that you have the latest Visual C++ runtime (2015) libraries already installed.
This project has not been tested on emulated environments (e.g. WINE, VMWare, etc).
This project is intended for use solely in Windows 10 environments, at the present time.
Reasons for writing this post:
We lay the foundation for a distributed trading system that will:
Infographic: ZeroMQ-Enabled Distributed Trading Infrastructure (with MetaTrader 4)
Why ZeroMQ?
This project requires the following:
You may install Python-specific dependencies either via pip install -r ./v2.0.1/python/api/requirements.txt
or via installing the latest Anaconda distribution (Python 3 variants).
For your convenience, files from the last three items above have been included in this repository with appropriate copyrights referenced within.
This project incorporates functionality authored by Ding Li (GitHub: https://github.com/dingmaotu), who has kindly licensed his work under the Apache 2.0 license.
We acknowledge copyright as per the terms of the license, the following repositories serving as mandatory dependencies for this project:
Thank you Ding for your amazing open source contribution to this space!
Sincerely,
The Darwinex Labs Team
www.darwinex.com
Switch to the EA's Inputs tab and customize values as necessary:
Note: The variable Publish_MarketData was removed in recent versions. There is no need to modify this variable or to manually change the Publish_Symbols array. Symbols will automatically be added when the _DWX_MTX_SEND_TRACKPRICES_REQUEST_()
function is called in python (see code example below).
# subscribe to data:
_zmq._DWX_MTX_SUBSCRIBE_MARKETDATA_('EURUSD')
# tell MT4 to publish data:
_zmq._DWX_MTX_SEND_TRACKPRICES_REQUEST_(['EURUSD'])
Output:
[KERNEL] Subscribed to EURUSD BID/ASK updates. See self._Market_Data_DB.
# BID/ASK prices are now being streamed into _zmq._Market_Data_DB.
_zmq._Market_Data_DB
Output:
{'EURUSD': {
'2019-01-08 13:46:49.157431': (1.14389, 1.14392),
'2019-01-08 13:46:50.673151': (1.14389, 1.14393),
'2019-01-08 13:46:51.010993': (1.14392, 1.14395),
'2019-01-08 13:46:51.100941': (1.14394, 1.14398),
'2019-01-08 13:46:51.205881': (1.14395, 1.14398),
'2019-01-08 13:46:52.283107': (1.14394, 1.14397),
'2019-01-08 13:46:52.377055': (1.14395, 1.14398),
'2019-01-08 13:46:52.777823': (1.14394, 1.14398),
'2019-01-08 13:46:52.870773': (1.14395, 1.14398),
'2019-01-08 13:46:52.985708': (1.14395, 1.14397),
'2019-01-08 13:46:53.080652': (1.14393, 1.14397),
'2019-01-08 13:46:53.196584': (1.14394, 1.14398),
'2019-01-08 13:46:53.294541': (1.14393, 1.14397)}}
_zmq._DWX_MTX_UNSUBSCRIBE_MARKETDATA('EURUSD')
Output:
**
[KERNEL] Unsubscribing from EURUSD
**
_zmq = DWX_ZeroMQ_Connector()
_my_trade = _zmq._generate_default_order_dict()
Output:
{'_action': 'OPEN',
'_type': 0,
'_symbol': 'EURUSD',
'_price': 0.0,
'_SL': 500,
'_TP': 500,
'_comment': 'DWX_Python_to_MT',
'_lots': 0.01,
'_magic': 123456,
'_ticket': 0}
_my_trade['_lots'] = 0.05
_my_trade['_SL'] = 250
_my_trade['_TP'] = 750
_my_trade['_comment'] = 'nerds_rox0r'
_zmq._DWX_MTX_NEW_TRADE_(_order=_my_trade)
# MetaTrader response (JSON):
{'_action': 'EXECUTION',
'_magic': 123456,
'_ticket': 85051741,
'_open_price': 1.14414,
'_sl': 250,
'_tp': 750}
_zmq._DWX_MTX_GET_ALL_OPEN_TRADES_()
# MetaTrader response (JSON):
{'_action': 'OPEN_TRADES',
'_trades': {
85051741: {'_magic': 123456,
'_symbol': 'EURUSD',
'_lots': 0.05,
'_type': 0,
'_open_price': 1.14414,
'_pnl': -0.45}
}
}
_zmq._DWX_MTX_CLOSE_PARTIAL_BY_TICKET_(85051741, 0.01)
# MetaTrader response (JSON):
{'_action': 'CLOSE',
'_ticket': 85051741,
'_response': 'CLOSE_PARTIAL',
'_close_price': 1.14401,
'_close_lots': 0.01}
# Partially closing a trade renews the ticket ID, retrieve it again.
_zmq._DWX_MTX_GET_ALL_OPEN_TRADES_()
# MetaTrader response (JSON):
{'_action': 'OPEN_TRADES',
'_trades': {
85051856: {'_magic': 123456,
'_symbol': 'EURUSD',
'_lots': 0.04,
'_type': 0,
'_open_price': 1.14414,
'_pnl': -0.36}
}
}
_zmq._DWX_MTX_CLOSE_TRADE_BY_TICKET_(85051856)
# MetaTrader response (JSON):
{'_action': 'CLOSE',
'_ticket': 85051856,
'_close_price': 1.14378,
'_close_lots': 0.04,
'_response': 'CLOSE_MARKET',
'_response_value': 'SUCCESS'}
# Before running the following example, 5 trades were executed using the same values as in "_my_trade" above, the magic number being 123456.
# Check currently open trades.
_zmq._DWX_MTX_GET_ALL_OPEN_TRADES_()
# MetaTrader response (JSON):
{'_action': 'OPEN_TRADES',
'_trades': {
85052022: {'_magic': 123456, '_symbol': 'EURUSD', '_lots': 0.05, '_type': 0, '_open_price': 1.14353, '_pnl': 1.15},
85052026: {'_magic': 123456, '_symbol': 'EURUSD', '_lots': 0.05, '_type': 0, '_open_price': 1.14354, '_pnl': 1.1},
85052025: {'_magic': 123456, '_symbol': 'EURUSD', '_lots': 0.05, '_type': 0, '_open_price': 1.14354, '_pnl': 1.1},
85052024: {'_magic': 123456, '_symbol': 'EURUSD', '_lots': 0.05, '_type': 0, '_open_price': 1.14354, '_pnl': 1.1},
85052023: {'_magic': 123456, '_symbol': 'EURUSD', '_lots': 0.05, '_type': 0, '_open_price': 1.14356, '_pnl': 1}
}
}
# Close all trades with magic number 123456
_zmq._DWX_MTX_CLOSE_TRADES_BY_MAGIC_(123456)
# MetaTrader response (JSON):
{'_action': 'CLOSE_ALL_MAGIC', '_magic': 123456,
'_responses': {
85052026: {'_symbol': 'EURUSD', '_close_price': 1.14375, '_close_lots': 0.05, '_response': 'CLOSE_MARKET'},
85052025: {'_symbol': 'EURUSD', '_close_price': 1.14375, '_close_lots': 0.05, '_response': 'CLOSE_MARKET'},
85052024: {'_symbol': 'EURUSD', '_close_price': 1.14375, '_close_lots': 0.05, '_response': 'CLOSE_MARKET'},
85052023: {'_symbol': 'EURUSD', '_close_price': 1.14375, '_close_lots': 0.05, '_response': 'CLOSE_MARKET'},
85052022: {'_symbol': 'EURUSD', '_close_price': 1.14375, '_close_lots': 0.05, '_response': 'CLOSE_MARKET'}},
'_response_value': 'SUCCESS'}
# Open 5 trades
_zmq._DWX_MTX_NEW_TRADE_()
{'_action': 'EXECUTION', '_magic': 123456, '_ticket': 85090920, '_open_price': 1.15379, '_sl': 500, '_tp': 500}
_zmq._DWX_MTX_NEW_TRADE_()
{'_action': 'EXECUTION', '_magic': 123456, '_ticket': 85090921, '_open_price': 1.15379, '_sl': 500, '_tp': 500}
_zmq._DWX_MTX_NEW_TRADE_()
{'_action': 'EXECUTION', '_magic': 123456, '_ticket': 85090922, '_open_price': 1.15375, '_sl': 500, '_tp': 500}
_zmq._DWX_MTX_NEW_TRADE_()
{'_action': 'EXECUTION', '_magic': 123456, '_ticket': 85090926, '_open_price': 1.15378, '_sl': 500, '_tp': 500}
_zmq._DWX_MTX_NEW_TRADE_()
{'_action': 'EXECUTION', '_magic': 123456, '_ticket': 85090927, '_open_price': 1.15378, '_sl': 500, '_tp': 500}
# Close all open trades
_zmq._DWX_MTX_CLOSE_ALL_TRADES_()
# MetaTrader response (JSON):
{'_action': 'CLOSE_ALL',
'_responses': {85090927: {'_symbol': 'EURUSD',
'_magic': 123456,
'_close_price': 1.1537,
'_close_lots': 0.01,
'_response': 'CLOSE_MARKET'},
85090926: {'_symbol': 'EURUSD',
'_magic': 123456,
'_close_price': 1.1537,
'_close_lots': 0.01,
'_response': 'CLOSE_MARKET'},
85090922: {'_symbol': 'EURUSD',
'_magic': 123456,
'_close_price': 1.1537,
'_close_lots': 0.01,
'_response': 'CLOSE_MARKET'},
85090921: {'_symbol': 'EURUSD',
'_magic': 123456,
'_close_price': 1.15369,
'_close_lots': 0.01,
'_response': 'CLOSE_MARKET'},
85090920: {'_symbol': 'EURUSD',
'_magic': 123456,
'_close_price': 1.15369,
'_close_lots': 0.01,
'_response': 'CLOSE_MARKET'}},
'_response_value': 'SUCCESS'}
Step-by-Step Installation & Configuration Tutorials
The nuts & bolts of the DWX ZeroMQ Connector project
How to Interface Python/R Trading Strategies with MetaTrader 4
Algorithmic Trading via ZeroMQ: Trade Execution, Reporting & Management (Python to MetaTrader)
Algorithmic Trading via ZeroMQ: Subscribing to Market Data (Python to MetaTrader)
Build Algorithmic Trading Strategies with Python & ZeroMQ: Part 1
Build Algorithmic Trading Strategies with Python & ZeroMQ: Part 2
Troubleshooting Python, ZeroMQ & MetaTrader Configuration for Algorithmic Trading
BSD 3-Clause License
Copyright (c) 2019, Darwinex. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.