Here is the most important parts of the new demo-script MultiExchangeWatch.mq5 (it’s provided along with the beta-version of the library).
NB: If the script is running very first time, it will ask to unpack (manually) CCXT Application Server (extracted as ccxtappsrvbundle.jsc from built-in resource), and run Node.js with it.
First, include the headers.
#include "ccxtjsmtlib.mqh" #include "ccxtutil.mqh" #include <MQL5Book/Comments.mqh>
In the inputs, the Node server setup should be done.
input group "Connection settings" input string NodeServer = "http://127.0.0.1:8124"; input string NodeAuth = "";
Next, specify a number of exchanges you want to monitor, a ticker, and a type of the watch. By default, the script watches for order books for BCH/USDT.
To fill in these inputs properly with preferred values, you should probably need to output the list of supported exchanges and their markets beforehand. It can be viewed in another example script CcxtAppSrvShowcase.mq5, provided with the lib.
input string Exchanges = "ascendex,bitmart,binance"; input string Ticker = "BCH/USDT"; input string Watch = "watchOrderBook"; input uint WatchingDuration = 10;
Then OnStart event handler does its job. Inline comments explain the process. The imported functions, classes and methods from the library are highlighted in yellow.
string Exchange[]; void OnStart() { PrintFormat("CCXT AppSrvLibrary version: %.2f", AppSrvLibraryVersion()); const static string status[] = {"Can't deploy", "App server ZIP is deployed, but not extracted", "App server files are deployed"}; const int d = DeployCcxtAppServer(); Print(status[d + 1]); if(d <= 0) { return; } SetNodeServer(NodeServer, NodeAuth); CcxtLink *link = GetLink(); AutoPtr<CcxtJsExchangeProIntf> ccxt[]; const int n = StringSplit(Exchanges, ',', Exchange); ArrayResize(ccxt, n); for(int i = 0; i < n; i++) { ccxt[i] = CreateExchangePro(Exchange[i]); if(link.getLastHttpCode() != 200 || !ccxt[i][] || ccxt[i][][].t >= JS_NULL) { Print("Construction failed for exchange: ", Exchange[i]); return; } const bool isPro = !!*ccxt[i][]["pro"]; if(!isPro) { PrintFormat("WARNING! %s isn't PRO, there is no websocket support", Exchange[i]); } if(!ccxt[i][]["has"][Watch].get<bool>()) { PrintFormat("WARNING! %s does not support '%s' subscriptions", Exchange[i], Watch); } } int active = 0; for(int i = 0; i < n; i++) { if(ccxt[i][].upgrade()) { if(!ccxt[i][].watchAnything(StringFormat("%s(\"%s\")", Watch, Ticker))) { PrintFormat("Can't start %s for %s", Watch, Exchange[i]); ccxt[i][].close(); ccxt[i] = NULL; } else { active++; } } else { if(ccxt[i][].isConnected()) { Print("Can't upgrade to websockets"); string headers[][2]; if(ccxt[i][].ws().getHeaders(headers)) { } ccxt[i][].ws().close(); ccxt[i][].close(); ccxt[i] = NULL; } } } if(!active) return; PrintFormat("* Monitoring %d subscriptions", active); const uint start = GetTickCount(); while(!IsStopped() && (!WatchingDuration || GetTickCount() - start < WatchingDuration * 1000)) { for(int i = 0; i < n; i++) { if(ccxt[i][] && ccxt[i][].isConnected()) { AutoPtr<JsValue> j = ccxt[i][].readMessage(false); if(j[]) { ChronoComment(j[].stringify(0, 0)); } } } } Print("* Unsubscribing..."); for(int i = 0; i < n; i++) { if(ccxt[i][] && ccxt[i][].isConnected()) { ccxt[i][].un().watchAnything(StringFormat("%s(\"%s\")", Watch, Ticker)); } } GracefullClose(ccxt); // not presented here in the blog GracefullClose(ccxt, 5, true); Comment(""); }
When the script is running, the list of incoming order books (json-messages) is outputted and actively updated on the chart.
On top of such a dataflow it’s easy to implement various arbitrage strategies and calculate combined statistics.
www.mql5.com (Article Sourced Website)
#Monitoring #multiple #crypto #exchanges #online #MQL5 #library #Node.jsCCXT