Forex Analysis

Chris Randall

Chief Technical Officer

WebSocket/Socket.IO Tutorial: Live Forex Data with WebSockets, Node JSON and Redis

Forex Analysis in Reuters Eikon Platform

Live Forex Portal using WebSocket implementation

User expectations have change a lot over the last couple of years we now live in a age where it is expected that content is instant and data is live. Web technology has improved and using WebSockets can now offer two-way (or full-duplex) data transfer between client and server.

The prime goal of WebSockets is to provide live data transfer over a persistent TCP socket connection.

To summarise how the protocol works: The client makes a request to the server and the server responds with a handshake, Once the client and the server have shaken hands so to speak they are free to send information back and forth at will.

All the data transfer takes place over a single TCP Socket and can be done on Port 80(WS) or Port 443(WSS), Most browsers now support WebSockets you can see if you browser support web sockets on this site.

Moving thing forward...

Until the invention of WebSockets applications that needed live forex data in our world Forex Quotes, Charts and Alerts the only way to simulate live connections was to manipulate the HTTP protocol. This was done in a number of ways HTTP Streaming, HTTP Long Polling or SSE (Server Sent Events) but all of these had drawbacks.

HTTP Streaming

HTTP Streaming work on a single connection between client and server. The client makes a request for live forex data and the server opens a connection. This connection is then kept alive with the server sending the data down the connection until it is terminated.

HTTP Long Polling

Long Polling achieved simulated live transfer by polling at regular intervals:

  • The client makes a request to the server and waits for a response
  • The server keeps the connection open until it is ready to send information to the client.
  • The client receives the information and then sends a new request and the cycle starts again.
Long Polling has multiple issues including latency, timeouts and caching to name a few.

Server-send events (SEE)

SSE implementation is a true push implementation but has several limitations, Connections are limited and the code to implement SEE is very complicated.

WebSocket the way forward

The Web Socket protocol was standardized in 2011 and the WebSocket API in Web IDL by W3C. The WebSocket protocol allows true live communication between a client application (Web Browser or Client Side App) and a Web Server. WebSockets has a lower overhead that HTTP Polling and allows for live data transfer eliminating the delay between polls.

But wait what about Socket.IO....

Socket.IO is a WebSocket implementation wrapper that aids in the setup of WebSockets. Why make it hard when you can make it easy.

Web Socket vs Socket.IO

Socket.IO

WebSocket

WebSocket Wrapper  Protocol to establish a connection over HTTP
Event-Based Communication between Client and Server Full Duplex Communication over TCP Connections
Handles Proxy and Load Balancing Does not support Proxy or Load Balancing
Supports Broadcasting Broadcasting not supported
Supports fallback options Doesn't support fallback options

Before we roll our sleeves up - Conclusion

WebSocket vs Socket.IO, not really much to say WebSockets are the protocol and Socket.IO is the quickest most robust method to get them implemented.

TraderMade offers its Live Forex Data JSON, FIX and Socket.IO this is a Java wrapper class for the WebSocket protocol.


Socket.IO Live Forex Data Tutorial


This implementation is written in NodeJS and would be a good implementation to run on a server to trap Live Rates the second is written in VUE so would allow easy implementation into a client side application for a quotes grid or similar.

NodeJS WebSocket/Socket.IO Example - Client Side

This example makes a connection to the server, receives a handshake event and transmits a login ID, it then receives an onConnect. The onConnect function then subscribes to a symbol and then waits for the response. When the application receives the socket.on event it reads the message and then outputs it to the console.

Once the application is connected and receiving data we can expand it to encode the data into a JSON object and write it to a Redis Database.

For this example we will use the TraderMade Live Forex Data Service, the code for the server can be found further down the page.

Download and Install NodeJS

Windows:

Download and install NodeJS from here https://nodejs.org

Linux:

Run: apt-get install nodejs

Install Socket.IO

Run: npm install socket.io-client

Code:

Create a connection and send handshake to the server

                    
var io = require('socket.io-client');
var socket = io.connect('http://tradermade.com', {reconnect: true});
                    
            

One the connection is made to the server the server will send a "connect" event to receive this you will need a function with the identifier "connect".

For some systems that do not require further login steps this may be enough to receive data events.

The TraderMade service requires further login and subscription events. When the "connect" even is recieved the client must send a 'login; message with a userKey. The user key for the trial system is "WSTrial2891", This will allow a connection request and receive a 5 second delayed GBPUSD quote.

                    
socket.on('connect', function () {
    console.log('Connected!');
    socket.emit('login', {userKey: 'WSTrial2891'});
});
                    
            

After the 'login' event is sent and as long as the userKey is correct the server will respond with a 'handshake' event, This confirms that the server is connected and ready for the client to request data. The client must respond to this with a 'symbolSub' request and specifiy a symbol e.g. "GBPUSD"

                    
socket.on('handshake', function (msg) {
    console.log("Handshake Recived now send symbol requests");
    socket.emit("symbolSub", {symbol: "GBPUSD"});
});
                    
             

The demo server will repond to this request with a 'subResponse' event with the following message 'This is a demo connection you can only Subscribed to GBPUSD', The live server will respond with the message 'Subscribed to SYMBOL_NAME'

Once this message is recieved you are subscribed to market events, markets events are sent with the identifier 'price'

Market data is returned in json format:
{"timestamp": 1570026463, "price": 1.22839, "bid": 1.22836, "ask": 1.22842, "symbol": "GBPUSD"}

                    
socket.on('price', function (message){
         console.log(" Price Data:" + message);
});
                    
            

Full Client Side Application Code:

                    
var io = require('socket.io-client');

//Connect to local server
var socket = io.connect('http://tradermade.com:3000', {reconnect: true});

//Connect to TraderMade Data Server
var socket = io.connect('http://tradermade.com', {reconnect: true});

const redis = require('redis-clients')();
const client = redis.client();

socket.on('connect', function () {
    console.log('Connected!');
    socket.emit('login', {userKey: 'WSTrial2891'});
});

socket.on('handshake', function (msg) {
    console.log("Handshake Recived now send symbol requests");
    socket.emit("symbolSub", {symbol: "GBPUSD"});
});

socket.on('subResponse', function (msg) {
    console.log(msg)
});

socket.on('price', function (message){
    console.log(" Price Data:" + message);
});


                    
            

Server Side

Download and Install NodeJS

Windows:

Download and install NodeJS from here https://nodejs.org

Linux:

Run: apt-get install nodejs

Install Socket.IO

Run: npm install socket.io

Code:

Create a server and wait for connections

The following code will create an http server and bind it to port 3000, Although we say that WebSocket use port 80/443 its possible for TCP connections to use any available port.

                    
const server = require('http').createServer();
const socket = require('socket.io')(server);

socket.on('connection', client => {
    console.log(" Conected ");
});

console.log(" Starting Server Port 3000 ");
server.listen(3000);
                    
            

Once we have the server running we need to listen for client connections we do this will the 'client.on(....)' function. The client.on function takes a unique identifier as discussed in the client section.

Once the client makes the connection to the server the server will automaticly send the 'connect' message and our clinet will respond with a login.

                    
client.on('login', data => {
	//If we wanted we could check the login key here
	console.log(data);
	socket.emit('handshake', 'Welcome to the TMS Data Feed');
});
                    
            

If we wished we could check the login details in this function and if we choose accept the connection or not. If you choose to reject the client at this point due to invalid credentials It is good practice not to send back a reson for rejection as this on provides melicious attacks more information out our system.

Once the client get the 'handshake' message back it will send a subscribe message'.

                    
client.on('symbolSub', data => {
    //If we wanted we could user this data to filter the prices being sent to the user.
    socket.emit('subResponse', 'This is a demo connection you can only Subscribed to GBPUSD');

    //Start a timer to send some fake date as we have no Live Forex data
    setInterval(sendData, 2000);
  });

                    

We could read this message and use the data to identify the content we wish to send back to the client. But as this is a demo server we are just going to start a process to send some data back to the client to simulate Live Forex Data.

                    
function sendData(){
    socket.emit('price', '{"timestamp": 1570026463, "price": 1.22839, "bid": 1.22836, "ask": 1.22842, "symbol": "GBPUSD"}');
}
                    
            

Full Server Code:

                    
const server = require('http').createServer();
const socket = require('socket.io')(server);

socket.on('connection', client => {
console.log(" Conected ");

  client.on('login', data => {
	//If we wanted we could check the login key here
	console.log(data);
	socket.emit('handshake', 'Welcome to the TMS Data Feed');
  });

  client.on('symbolSub', data => {
    //If we wanted we could user this data to filter the prices being sent to the user.
    socket.emit('subResponse', 'This is a demo connection you can only Subscribed to GBPUSD');

    //Start a timer to send some fake date as we have no real-time data
    setInterval(sendData, 2000);
  });

  client.on('disconnect', () => {
	console.log(" Disconnect ");
  });

  function sendData(){
	socket.emit('price', '{"timestamp": 1570026463, "price": 1.22839, "bid": 1.22836, "ask": 1.22842, "symbol": "GBPUSD"}');
  }


});

console.log(" Starting Server Port 3000 ");
server.listen(3000);
                    
            

If you would like to trial TraderMade Live Forex Data you can request a trial here.

Request 30 day free trial