Skip to content

WebSocket v2 (beta)

martin-nginio edited this page Apr 9, 2019 · 27 revisions

WebSocket feed provides real-time market data covering orderbook updates, order life cycle and trades.

Overview

In order to start receiving real time messages, a WebSocket connection needs to be made followed by a message to subscribe to channels and also marketIds you are interested in.

The base url for WebSocket v2 is the same as v1: https://socket.btcmarkets.net

Improvements in v2

WebSocket v2 provides a number of improvements including:

  • Authenticated channels: allows individual traders to receive notifications for life cycle of an order including placement, cancellation, matching and triggering
  • Channel subscription: allows for easier and more flexible integration and messaging
  • Standard data and json format. e.g. ISO date and time
  • Error handling: publishing error messages for better error management
  • Heartbeat message: helps client applications to better managing connections

Channels

tick, trade, orderbook, orderChange, fundChange, heartbeat

MarketIds

Market ids represent a market and are used in order to filter events for only specific markets you are interested in.

You should be able to pass any active markets as per below: https://api.btcm.ngin.io/v2/market/active

Format: BTC-AUD, XRP-BTC, etc.

Note: marketIds are only applicable to public events (e.g. tick, orderbook, trade)

Message types

All messages published include a json attribute called messageType that represents type of event that is being received.

Those message types events include: tick, trade, orderbook, orderChange, fundChange, error, heartbeat

Subscribe

sending subscribe message allows you to start receiving events for the specified channels and marketIds. If you need to change subscription then simply send a new subscribe message with new channel names and marketIds.

Tick event

The tick event is published every time lastPrice, bestBid or bestAsk is updated for a market which is the result of orderbook changes or trade matches.

sample event:

{ marketId: 'BTC-AUD',
  timestamp: '2019-04-08T18:56:17.405Z',
  bestBid: '7309.12',
  bestAsk: '7326.88',
  lastPrice: '7316.81',
  volume24h: '299.12936654',
  messageType: 'tick' 
}

Trade event

In order to receive trade events please add trade to the list of channels when subscribing via WebSocket.

sample event:

{ marketId: 'BTC-AUD',
  timestamp: '2019-04-08T20:54:27.632Z',
  tradeId: 3153171493,
  price: '7370.11',
  volume: '0.10901605',
  messageType: 'trade' 
}

Orderbook event

In order to receive orderbook events please add orderbook to the list of channels when subscribing via WebSocket. The current orderbook event represents the latest orderbook state and maximum 50 bids and asks are included in each event.

For efficiency the bids and asks are are published as arrays of tuples representing [price, volume] each order in the orderbook.

sample event:

{ marketId: 'BTC-AUD',
  timestamp: '2019-04-08T22:23:37.643Z',
  bids:
   [ [ '7418.46', '0.04' ],
     [ '7418.45', '0.56' ],
     [ '7100', '0.01' ] ]
  asks:
   [ [ '7437.53', '0.76' ],
     [ '7437.54', '0.3646349' ],
     [ '7446.94', '0.6' ],
     [ '7700', '0.1' ] ]
  messageType: 'orderbook' 
}

Sample WebSocket client code (javascript)

Below sample code connects to tick channel. The same code can be used to subscribe to other public channels including heartbeat.

var socket = require('socket.io-client')(`https://socket.btcmarkets.net`, {
    secure: true,
    transports: ['websocket'],
    upgrade: false,
    path: '/v2'
});

var request = {
    marketIds:['BTC-AUD'],
    channels: ['tick', 'heartbeat']
}

socket.on('connect', function(){
    socket.emit('subscribe', request);
});

socket.on('error', function(err){
    console.log(err);
});

socket.on('message', function(data){
    console.log(data);
});

Authenticated events

Receiving events about life cycle of your orders require sending authentication information when subscribing to events. The authentication is similar to public trading API authentication using your API key and secret to sign the message when subscribing via WebSocket.

Below is sample javascript code with authentication:

var crypto = require('crypto');
var buffer = require("buffer");

const key = 'your api key';
const secret = 'your api key secret';

var socket = require('socket.io-client')('https://socket.btcmarkets.net', {
    secure: true,
    transports: ['websocket'],
    upgrade: false,
    path: '/v2'
});

const now = Date.now();
const strToSign =  "/users/self/subscribe" + "\n" + now;
const signature = signMessage(secret, strToSign);

var request = {
    marketIds:['BTC-AUD'],
    channels: ['orderChange', 'heartbeat'],
    key: key,
    signature: signature,
    timestamp: now 
}

socket.on('connect', function(){
    socket.emit('subscribe', request);
});

socket.on('message', function(data){
    console.log(data);
});

function signMessage(secret, message) {
    var key = Buffer(secret, 'base64');
    var hmac = crypto.createHmac('sha512', key);
    var signature = hmac.update(message).digest('base64');
    return signature;
}
 

Order life cycle events

Below are events that are published for every step of order processing.

  • Placed
{ orderId: 79003,
  type: 'Limit',
  openVolume: '1',
  status: 'Placed',
  triggerStatus: '',
  timestamp: '2019-04-08T20:41:19.339Z',
  messageType: 'orderChange' 
}
  • Fully Matched
{ orderId: 79033,
  type: 'Limit',
  openVolume: '0',
  status: 'Fully Matched',
  triggerStatus: '',
  timestamp: '2019-04-08T20:50:39.658Z',
  messageType: 'orderChange' 
}
  • Cancelled
{ orderId: 79003,
  type: 'Limit',
  openVolume: '1',
  status: 'Cancelled',
  triggerStatus: '',
  timestamp: '2019-04-08T20:41:41.857Z',
  messageType: 'orderChange' 
}
  • Partially Matched
{ orderId: 79003,
  type: 'Limit',
  openVolume: '1',
  status: 'Partially Matched',
  triggerStatus: '',
  timestamp: '2019-04-08T20:41:41.857Z',
  messageType: 'orderChange' 
}
  • Triggered This event is published when Stop Limit orders are triggered.
{ orderId: 7903,
  type: 'Limit',
  openVolume: '1.2',
  status: 'Placed',
  triggerStatus: 'Triggered',
  timestamp: '2019-04-08T20:41:41.857Z',
  messageType: 'orderChange' 
}

Note: in case if two or more events are published by trading engine at the same time then only the last event is published. For instance in the case of a Stop order being triggered and matched at the same time then a single event is published.

Heartbeat event

if you subscribe to heartbeat event then the server will send you a heartbeat event every 5 seconds.

heartbeat event:

{ messageType: 'heartbeat',
  channels: [ 'orderChange', 'tick', 'heartbeat' ],
  marketIds: [ 'BTC-AUD', 'XRP-BTC' ] 
}

Error event

In case of errors, a message type of error is published.

  • Authentication error
  • Invalid input error
  • Internal server error
  • Throttle error

sample error events:

  • Invalid Channel names
{ messageType: 'error',
  code: 3,
  message: 'invalid channel names' 
}
  • Invalid MarketIds
{ messageType: 'error',
  code: 3,
  message: 'invalid marketIds' 
}
  • Authentication error
{ messageType: 'error',
  code: 1,
  message: 'authentication failed. invalid key' 
}

Sample client code

Below are working example of how to connect to this WebSocket feed in different languages:

socket.io

For ease of use and compatibility, we recommend using socket.io client libraries when integrating this WebSocket feed. Please refer to socket.io documentation for implementations in your preferred language: https://socket.io/docs

Rate limit

New connections (and also sending subscription message) to the WebSocket feed are rate limited to 3 attempts per 10 seconds per IP.

Connection issues

From time to time your WebSocket connection may be disconnected (e.g. as we upgrade software on our servers). We recommend refreshing your connection every 24 hours or in case if the connection drops out.

Introduction updated 9/28/18

Authentication

Pagination

WebSocket v2

WebSocket v1 deprecated

Market Data API updated 7/24/19

Trading API updated 08/19/19

Transaction API

Account API updated 3/14/19

Fund Transfer API updated 08/06/19

FAQ

Clone this wiki locally