Update README.md
This commit is contained in:
@@ -18,23 +18,16 @@ Backtrader Python client located here: [Python Backtrader - Metaquotes MQL5 ](ht
|
|||||||
|
|
||||||
In development:
|
In development:
|
||||||
* Historical data load speed
|
* Historical data load speed
|
||||||
<<<<<<< HEAD
|
|
||||||
* Add error handling to docs
|
* Add error handling to docs
|
||||||
* Trades info
|
* Trades info
|
||||||
* Experation
|
* Experation
|
||||||
* Devitation
|
* Devitation
|
||||||
* Netting/hedging mode switch
|
* Netting/hedging mode switch
|
||||||
* Stop limit orders
|
* Stop limit orders
|
||||||
=======
|
|
||||||
* Trades info
|
|
||||||
* Experation
|
|
||||||
* Devitation
|
|
||||||
>>>>>>> f5db7b13fe223453c6b2950ab4e5cddea7a80e19
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Install ZeroMQ for MQL5 [https://github.com/dingmaotu/mql-zmq](https://github.com/dingmaotu/mql-zmq)
|
1. Install ZeroMQ for MQL5 [https://github.com/dingmaotu/mql-zmq](https://github.com/dingmaotu/mql-zmq)
|
||||||
<<<<<<< HEAD
|
|
||||||
2. Put `include/Json.mqh` from this repo to your MetaEditor `include` directoty.
|
2. Put `include/Json.mqh` from this repo to your MetaEditor `include` directoty.
|
||||||
3. Download and compile `experts/JsonAPI.mq5` script.
|
3. Download and compile `experts/JsonAPI.mq5` script.
|
||||||
4. Check if Metatrader 5 automatic trading is allowed.
|
4. Check if Metatrader 5 automatic trading is allowed.
|
||||||
@@ -56,29 +49,6 @@ The script uses four ZeroMQ sockets:
|
|||||||
The idea is to send requests via `System socket` and recieve results/errors via `Data socket`. For `Live socket` and `Streaming socket` event handlers should be created because server sends data to theese sockets automatically. See examples in [Usage](#usage) section.
|
The idea is to send requests via `System socket` and recieve results/errors via `Data socket`. For `Live socket` and `Streaming socket` event handlers should be created because server sends data to theese sockets automatically. See examples in [Usage](#usage) section.
|
||||||
|
|
||||||
`System socket` request uses default JSON dictionary:
|
`System socket` request uses default JSON dictionary:
|
||||||
=======
|
|
||||||
2. Put 'include/Json.mqh' from this repo to your MetaEditor 'include' directoty.
|
|
||||||
3. Download and compile JsonAPI script.
|
|
||||||
4. Check if automatic trading is allowed.
|
|
||||||
5. Attach the script to a chart in Metatrader 5.
|
|
||||||
6. Allow DLL import in dialog window.
|
|
||||||
7. Check if the ports are free to use. (default: 15555, 15556, 15557, 15558)
|
|
||||||
|
|
||||||
Tested on macOS Mojave and Windows 10 in Parallels Desktop container.
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
The script uses 4 ZeroMQ sockets:
|
|
||||||
|
|
||||||
1. System socket - recives requests from client and replies 'OK'
|
|
||||||
2. Data socket - pushes data to client depending on request via System socket.
|
|
||||||
3. Live socket - pushes last candle when it closes.
|
|
||||||
4. Streaming socket - pushes last transaction info when it happens.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Configure the script:
|
|
||||||
>>>>>>> f5db7b13fe223453c6b2950ab4e5cddea7a80e19
|
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
@@ -99,7 +69,6 @@ Configure the script:
|
|||||||
"comment": None
|
"comment": None
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
<<<<<<< HEAD
|
|
||||||
Check out the available combinations of `action` and `actionType`:
|
Check out the available combinations of `action` and `actionType`:
|
||||||
|
|
||||||
action | actionType | Description |
|
action | actionType | Description |
|
||||||
@@ -111,18 +80,6 @@ POSITIONS | None | Get current open positions |
|
|||||||
ORDERS | None | Get current open orders |
|
ORDERS | None | Get current open orders |
|
||||||
HISTORY | DATA | Get data history |
|
HISTORY | DATA | Get data history |
|
||||||
HISTORY | TRADES | Get trades history |
|
HISTORY | TRADES | Get trades history |
|
||||||
=======
|
|
||||||
|
|
||||||
action | actionType | Description |
|
|
||||||
-----------|----------------------|----------------------------|
|
|
||||||
CONFIG | null | Set script configuration |
|
|
||||||
ACCOUNT | null | Get account settings |
|
|
||||||
BALANCE | null | Get current balance |
|
|
||||||
HISTORY | null | Get symbol history |
|
|
||||||
POSITIONS | null | Get current open positions |
|
|
||||||
ORDERS | null | Get current open orders |
|
|
||||||
-----------|----------------------|----------------------------|
|
|
||||||
>>>>>>> f5db7b13fe223453c6b2950ab4e5cddea7a80e19
|
|
||||||
TRADE | ORDER_TYPE_BUY | Buy market |
|
TRADE | ORDER_TYPE_BUY | Buy market |
|
||||||
TRADE | ORDER_TYPE_SELL | Sell market |
|
TRADE | ORDER_TYPE_SELL | Sell market |
|
||||||
TRADE | ORDER_TYPE_BUY_LIMIT | Buy limit |
|
TRADE | ORDER_TYPE_BUY_LIMIT | Buy limit |
|
||||||
@@ -131,26 +88,17 @@ TRADE | ORDER_TYPE_BUY_STOP | Buy stop |
|
|||||||
TRADE | ORDER_TYPE_SELL_STOP | Sell stop |
|
TRADE | ORDER_TYPE_SELL_STOP | Sell stop |
|
||||||
TRADE | POSITION_MODIFY | Position modify |
|
TRADE | POSITION_MODIFY | Position modify |
|
||||||
TRADE | POSITION_PARTIAL | Position close partial |
|
TRADE | POSITION_PARTIAL | Position close partial |
|
||||||
<<<<<<< HEAD
|
|
||||||
TRADE | POSITION_CLOSE_ID | Position close by id |
|
TRADE | POSITION_CLOSE_ID | Position close by id |
|
||||||
TRADE | POSITION_CLOSE_SYMBOL| Positions close by symbol |
|
TRADE | POSITION_CLOSE_SYMBOL| Positions close by symbol |
|
||||||
TRADE | ORDER_MODIFY | Order modify |
|
TRADE | ORDER_MODIFY | Order modify |
|
||||||
TRADE | ORDER_CANCEL | Order cancel |
|
TRADE | ORDER_CANCEL | Order cancel |
|
||||||
|
|
||||||
Example Python API class:
|
Example Python API class:
|
||||||
=======
|
|
||||||
TRADE | POSITION_ID | Position close by id |
|
|
||||||
TRADE | POSITION_CLOSE | Position close |
|
|
||||||
TRADE | ORDER_MODIFY | Order modify |
|
|
||||||
TRADE | ORDER_CANCEL | Order cancel |
|
|
||||||
|
|
||||||
>>>>>>> f5db7b13fe223453c6b2950ab4e5cddea7a80e19
|
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
import zmq
|
import zmq
|
||||||
|
|
||||||
class MTraderAPI:
|
class MTraderAPI:
|
||||||
<<<<<<< HEAD
|
|
||||||
def __init__(self, host=None):
|
def __init__(self, host=None):
|
||||||
self.HOST = host or 'localhost'
|
self.HOST = host or 'localhost'
|
||||||
self.SYS_PORT = 15555 # REP/REQ port
|
self.SYS_PORT = 15555 # REP/REQ port
|
||||||
@@ -176,39 +124,6 @@ class MTraderAPI:
|
|||||||
self.data_socket.connect('tcp://{}:{}'.format(self.HOST, self.DATA_PORT))
|
self.data_socket.connect('tcp://{}:{}'.format(self.HOST, self.DATA_PORT))
|
||||||
except zmq.ZMQError:
|
except zmq.ZMQError:
|
||||||
raise zmq.ZMQBindError("Binding ports ERROR")
|
raise zmq.ZMQBindError("Binding ports ERROR")
|
||||||
=======
|
|
||||||
|
|
||||||
HOST = 'localhost'
|
|
||||||
SYS_PORT = 15555 # REP/REQ port
|
|
||||||
DATA_PORT = 15556 # PUSH/PULL port
|
|
||||||
LIVE_PORT = 15557 # PUSH/PULL port
|
|
||||||
EVENTS_PORT = 15558 # PUSH/PULL port
|
|
||||||
|
|
||||||
# ZeroMQ timeout in seconds
|
|
||||||
sys_sock_tmout = 1
|
|
||||||
data_sock_tmout = 10
|
|
||||||
|
|
||||||
# initialise ZMQ context
|
|
||||||
context = zmq.Context()
|
|
||||||
|
|
||||||
# connect to server sockets
|
|
||||||
try:
|
|
||||||
sys_socket = context.socket(zmq.REQ)
|
|
||||||
sys_socket.RCVTIMEO = sys_sock_tmout * 1000
|
|
||||||
sys_socket.connect('tcp://{}:{}'.format(HOST, SYS_PORT))
|
|
||||||
|
|
||||||
data_socket = context.socket(zmq.PULL)
|
|
||||||
data_socket.RCVTIMEO = data_sock_tmout * 1000
|
|
||||||
data_socket.connect('tcp://{}:{}'.format(HOST, DATA_PORT))
|
|
||||||
|
|
||||||
live_socket = context.socket(zmq.PULL)
|
|
||||||
live_socket.connect('tcp://{}:{}'.format(HOST, LIVE_PORT))
|
|
||||||
|
|
||||||
events_socket = context.socket(zmq.PULL)
|
|
||||||
events_socket.connect('tcp://{}:{}'.format(HOST, EVENTS_PORT))
|
|
||||||
except zmq.ZMQError:
|
|
||||||
raise zmq.ZMQBindError("Binding ports ERROR")
|
|
||||||
>>>>>>> f5db7b13fe223453c6b2950ab4e5cddea7a80e19
|
|
||||||
|
|
||||||
def _send_request(self, data: dict) -> None:
|
def _send_request(self, data: dict) -> None:
|
||||||
""" Send request to server via ZeroMQ System socket """
|
""" Send request to server via ZeroMQ System socket """
|
||||||
@@ -230,7 +145,6 @@ class MTraderAPI:
|
|||||||
raise zmq.NotDone('Data socket timeout ERROR')
|
raise zmq.NotDone('Data socket timeout ERROR')
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
def live_socket(self, context=None):
|
def live_socket(self, context=None):
|
||||||
try:
|
try:
|
||||||
context = context or zmq.Context.instance()
|
context = context or zmq.Context.instance()
|
||||||
@@ -378,60 +292,3 @@ while True:
|
|||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See `LICENSE` for more information.
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See `LICENSE` for more information.
|
||||||
=======
|
|
||||||
def live_data(self):
|
|
||||||
""" Catch live data from server """
|
|
||||||
try:
|
|
||||||
candle = self.live_socket.recv_json()
|
|
||||||
except zmq.ZMQError:
|
|
||||||
raise zmq.NotDone("Live data ERROR")
|
|
||||||
return candle
|
|
||||||
|
|
||||||
def streaming_events(self):
|
|
||||||
""" Catch events from server """
|
|
||||||
try:
|
|
||||||
candle = self.events_socket.recv_json()
|
|
||||||
except zmq.ZMQError:
|
|
||||||
raise zmq.NotDone("Streaming events ERROR")
|
|
||||||
return candle
|
|
||||||
|
|
||||||
def construct_and_send(self, **kwargs) -> dict:
|
|
||||||
""" Construct request dictionary from default """
|
|
||||||
|
|
||||||
# default dictionary
|
|
||||||
request = {
|
|
||||||
"action": None,
|
|
||||||
"actionType": None,
|
|
||||||
"symbol": None,
|
|
||||||
"chartTF": None,
|
|
||||||
"fromDate": None,
|
|
||||||
"toDate": None,
|
|
||||||
"id": None,
|
|
||||||
"magic": None,
|
|
||||||
"volume": None,
|
|
||||||
"price": None,
|
|
||||||
"stoploss": None,
|
|
||||||
"takeprofit": None,
|
|
||||||
"expiration": None,
|
|
||||||
"deviation": None,
|
|
||||||
"comment": None
|
|
||||||
}
|
|
||||||
|
|
||||||
# update dict values if exist
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
if key in request:
|
|
||||||
request[key] = value
|
|
||||||
else:
|
|
||||||
raise KeyError('Unknown key in **kwargs ERROR')
|
|
||||||
|
|
||||||
# send dict to server
|
|
||||||
self._send_request(request)
|
|
||||||
|
|
||||||
# return server reply
|
|
||||||
return self._pull_reply()
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
|
||||||
Distributed under the GNU v3 License. See `LICENSE` for more information.
|
|
||||||
>>>>>>> f5db7b13fe223453c6b2950ab4e5cddea7a80e19
|
|
||||||
|
|||||||
Reference in New Issue
Block a user