v 2.0
This commit is contained in:
+20
-25
@@ -98,20 +98,20 @@ int OnInit(){
|
|||||||
EventSetMillisecondTimer(1);
|
EventSetMillisecondTimer(1);
|
||||||
|
|
||||||
int bindSocketsDelay = 65; // Seconds to wait if binding of sockets fails.
|
int bindSocketsDelay = 65; // Seconds to wait if binding of sockets fails.
|
||||||
|
int bindAttemtps = 2; // Number of binding attemtps
|
||||||
|
|
||||||
bool result = false;
|
|
||||||
Print("Binding sockets...");
|
Print("Binding sockets...");
|
||||||
result = BindSockets();
|
|
||||||
if (result==false){
|
for(int i=0;i<bindAttemtps+1;i++){
|
||||||
// Print("Binding of sockets failed permanently.");
|
if (BindSockets()) return(INIT_SUCCEEDED);
|
||||||
Print("Binding sockets failed. Waiting ", bindSocketsDelay, " seconds to try again...");
|
else {
|
||||||
Sleep(bindSocketsDelay*1000);
|
Print("Binding sockets failed. Waiting ", bindSocketsDelay, " seconds to try again...");
|
||||||
result = BindSockets();
|
Sleep(bindSocketsDelay*1000);
|
||||||
if (result==false){
|
|
||||||
Print("Binding of sockets failed permanently.");
|
|
||||||
return(INIT_FAILED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Print("Binding of sockets failed permanently.");
|
||||||
|
return(INIT_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(INIT_SUCCEEDED);
|
return(INIT_SUCCEEDED);
|
||||||
@@ -679,23 +679,18 @@ void GetOrders(CJAVal &dataObject){
|
|||||||
//| Clear symbol subscriptions |
|
//| Clear symbol subscriptions |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
void ResetSubscriptions(CJAVal &dataObject)
|
void ResetSubscriptions(CJAVal &dataObject){
|
||||||
{
|
|
||||||
bool retVal = true;
|
|
||||||
|
|
||||||
ArrayFree(chartSymbols);
|
ArrayFree(chartSymbols);
|
||||||
chartSymbolCount=0;
|
chartSymbolCount=0;
|
||||||
ArrayFree(chartSymbolSettings);
|
ArrayFree(chartSymbolSettings);
|
||||||
|
|
||||||
if(!ArraySize(chartSymbols)) retVal=false;
|
if(ArraySize(chartSymbols)!=0 ||ArraySize(chartSymbolSettings)!=0){
|
||||||
if(!ArraySize(chartSymbolSettings)) retVal=false;
|
// TODO Implement propery error codes and descriptions
|
||||||
|
ActionDoneOrError(65540, __FUNCTION__);
|
||||||
if (retVal==false){
|
}
|
||||||
// TODO Implement propery error codes and descriptions
|
else ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
|
||||||
ActionDoneOrError(65540, __FUNCTION__);
|
}
|
||||||
}
|
|
||||||
else ActionDoneOrError(ERR_SUCCESS, __FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Trading module |
|
//| Trading module |
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# Metaquotes MQL5 - JSON - API
|
# Metaquotes MQL5 - JSON - API
|
||||||
|
|
||||||
### Development state: first stable release
|
### Development state: stable release version 2.0
|
||||||
|
|
||||||
Tested on macOS Mojave / Windows 10 in Parallels Desktop container.
|
Tested on macOS Mojave / Windows 10 in Parallels Desktop container.
|
||||||
|
|
||||||
Working in production on Debian 10 / Wine 4.
|
Working in production on Debian 10 / Wine 4.
|
||||||
|
|
||||||
An issue was found because of REP/REQ socket. Architecture changes are in development.
|
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
@@ -24,6 +24,16 @@ This project was developed to work as a server for the Backtrader Python trading
|
|||||||
|
|
||||||
Backtrader Python client is located here: [Python Backtrader - Metaquotes MQL5 ](https://github.com/khramkov/Backtrader-MQL5-API)
|
Backtrader Python client is located here: [Python Backtrader - Metaquotes MQL5 ](https://github.com/khramkov/Backtrader-MQL5-API)
|
||||||
|
|
||||||
|
Thanks to the participation of [freedumb2000] (https://github.com/freedumb2000), the project moved to a new level.
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
- support for multiple datastreams in parallel for any combination of symbols and timeframes independently of the timeframe and symbol of the attached chart
|
||||||
|
- support for tick data
|
||||||
|
- support for direct download as CSV files
|
||||||
|
- automatic retry binding to sockets. When running under Wine in Linux, sockets will be blocked for 60 seconds if closed uncleanly. This can happen if the client is still connected while the EA gets reloaded.
|
||||||
|
skip re-initialization on chart timeframe change
|
||||||
|
|
||||||
In development:
|
In development:
|
||||||
|
|
||||||
- Devitation
|
- Devitation
|
||||||
@@ -77,6 +87,7 @@ Check out the available combinations of `action` and `actionType`:
|
|||||||
| action | actionType | Description |
|
| action | actionType | Description |
|
||||||
| --------- | --------------------- | ---------------------------- |
|
| --------- | --------------------- | ---------------------------- |
|
||||||
| CONFIG | null | Set script configuration |
|
| CONFIG | null | Set script configuration |
|
||||||
|
| RESET | null | Reset subscribed symbols |
|
||||||
| ACCOUNT | null | Get account settings |
|
| ACCOUNT | null | Get account settings |
|
||||||
| BALANCE | null | Get current balance |
|
| BALANCE | null | Get current balance |
|
||||||
| POSITIONS | null | Get current open positions |
|
| POSITIONS | null | Get current open positions |
|
||||||
@@ -215,10 +226,24 @@ All examples will be on Python 3. Lets create an instance of MetaTrader API clas
|
|||||||
api = MTraderAPI()
|
api = MTraderAPI()
|
||||||
```
|
```
|
||||||
|
|
||||||
First of all we should configure the script `symbol` and `timeframe`. Live data stream will be configured to the same params.
|
First of all we should configure the script `symbol` and `timeframe`. Live data stream will be configured to the same params. You can use any number of `symbols` and `timeframes`. The server will subscribe to these symbols and translate them to `Live data` socket.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
rep = api.construct_and_send(action="CONFIG", symbol="EURUSD", chartTF="M5")
|
print(api.construct_and_send(action="CONFIG", symbol="EURUSD", chartTF="M5"))
|
||||||
|
print(api.construct_and_send(action="CONFIG", symbol="AUDUSD", chartTF="M1"))
|
||||||
|
...
|
||||||
|
```
|
||||||
|
There is also `tick` data. You can subscribe for `tick` and `candle` data at the same `symbol`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(api.construct_and_send(action="CONFIG", symbol="EURUSD", chartTF="TICK"))
|
||||||
|
print(api.construct_and_send(action="CONFIG", symbol="EURUSD", chartTF="M1"))
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to stop `Live data`, you should reset server subscriptions.
|
||||||
|
|
||||||
|
```python
|
||||||
|
rep = api.construct_and_send(action="RESET")
|
||||||
print(rep)
|
print(rep)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -315,10 +340,11 @@ while True:
|
|||||||
pass
|
pass
|
||||||
```
|
```
|
||||||
|
|
||||||
There are only two variants of `Live socket` data. When everything is ok, the script sends data on candle close:
|
There are only two variants of `Live socket` data. When everything is ok, the script sends subscribed data on new even. You can divide streams by symbol and timeframe names:
|
||||||
|
|
||||||
```
|
```
|
||||||
{"status":"CONNECTED","data":[1560780120,1.12186,1.12194,1.12186,1.12191,15.00000]}
|
{"status":"CONNECTED","symbol":"EURUSD","timeframe":"TICK","data":[1581611172734,1.08515,1.08521]}
|
||||||
|
{"status":"CONNECTED","symbol":"EURUSD","timeframe":"M1","data":[1581611100,1.08525,1.08525,1.08520,1.08520,10.00000]}
|
||||||
```
|
```
|
||||||
|
|
||||||
If the terminal has lost connection to the market:
|
If the terminal has lost connection to the market:
|
||||||
|
|||||||
Reference in New Issue
Block a user