Skip to content

Monitoring multiple crypto exchanges online via MQL5 library for Node.js/CCXT

    CcxtAppServerLib is intended for working with all top-100 crypto exchanges from MQL5 via Node.js and CCXT Application Server, and it is evolving step by step. Latest beta-version includes optimized caching of exchange “markets” (instrument specifications and other trading conditions), non-blocking reading of websocket messages, and more.
    One introductory example of using the library – the script CcxtAppSrvShowcase.mq5 – was posted in the blog earlier.
    As another example of custom application development using the library, we provide a script for parallel monitoring of multiple exchanges for selected type of data. This feature is implemented by subscribing through CCXT on Node.js to specific websocket “watches”, such as watchOrderBook, watchTicker, watchTrades, etc. For details, please, see common CCXT documentation and more advanced on CCXT PRO. As the script is supposed to use only public APIs, user credentials are not involved here, but the library supports them in full degree.

    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