Websocket

Websocket Endpoints

Environments

There are two environments to access our websocket market data feeds:

  1. Live

wss://marketdata.aquanow.com/ 
  1. Sandbox

wss://marketdata.staging.aquanow.com/

Websocket Access and Authorization

API Authentication is done using an OAuth2.0. User needs to associate the following information in the payload of the subscription message. View the Authorization page for more detail.

Subscribe

In order to receive data feed, users sends a subscribe message to the server, after successful websocket connection. Users must also indicate the channel they wish to subscribe on in the subscription request.

When a subscribe message is received with a pair and channel, the server will respond with a subscription message that lists all channels you are subscribed to.

There are three channels you can subscribe for:

  1. orderBook - Orderbook across various marketplaces and exchanges.

  2. ticker - Open, High, Low, Close for a ticker, every minute published

  3. gbbo - Real time best price/bids updates for subscribed ticker

  4. priceStatistics - 24 hour statistics for High, Low, % change in price and notional change for a pair over websocket channel. It is published every minute

Note: that the Subscribe request MUST be a JSON string. For example, in Javascript this can be achieved by using the JSON.stringify method.

Request Parameters

Unsubscribe

You can unsubscribe from a channel at any time.

Example Request

JSON.stringify({
  "type": "unsubscribe",      // Message Type
  "channel": 'orderBook',     // Subscription Channel
  "pair": 'BTC-USD'           // Symbol
})

Example Usage

import axios from 'axios';
import qs from 'qs';
import WebSocket from 'ws';

const address = "wss://marketdata.aquanow.com";

const ws = new WebSocket(address);
const clientId = '';
const clientSecret = '';
const tokenEndpoint = `https://auth.cert.aquanow.com/oauth2/token`;
const scope = 'marketdata/read';

async function getAccessToken() {
  const authString = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
  const data = qs.stringify({
    grant_type: 'client_credentials',
    scope: scope,
  });

  try {
    const response = await axios.post(tokenEndpoint, data, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        Authorization: `Basic ${authString}`,
      },
    });

    return response.data.access_token;
  } catch (error) {
    console.error('Error obtaining access token:', error.response.data);
  }
}

async function subscribeToOrders() {
  const authorization = await getAccessToken();
  const timestamp = Date.now();
  const subsOption = JSON.stringify({
    type: 'subscribe',
    channel: 'orderBook',
    authorization: 'Bearer XXXXXXXX',
    username: 'testAccount',
    pair: 'BTC-USD',
    nonce: timestamp,
    depth: 5
  });

  ws.send(subsOption);
}

ws.on('open', () => {
  console.log(`WS tunnel opened - trade`);
  subscribeToOrders();
});

ws.on('message', (data) => {
  console.log('data', JSON.parse(data));
});

Example Responses

{
  dataType: 'aggOB',
  lastUpdated: 1726790944059,
  symbol: 'BTC-USD',
  precision: [ -1, 0, 1, 2 ],
  bids: [
    { quote: 62708.59, quantity: 0.1, cumulativeQuantity: 0.1 },
    { quote: 62707.84, quantity: 0.2, cumulativeQuantity: 0.3 },
    { quote: 62707.39, quantity: 0.1, cumulativeQuantity: 0.4 },
    { quote: 62707.04, quantity: 0.3, cumulativeQuantity: 0.7 },
    { quote: 62706.84, quantity: 0.1, cumulativeQuantity: 0.8 }
  ],
  asks: [
    { quote: 63025.77, quantity: 0.1, cumulativeQuantity: 0.1 },
    { quote: 63026.65, quantity: 0.1, cumulativeQuantity: 0.2 },
    { quote: 63026.66, quantity: 0.1, cumulativeQuantity: 0.3 },
    { quote: 63028.97, quantity: 4, cumulativeQuantity: 4.3 },
    { quote: 63029.02, quantity: 0.1, cumulativeQuantity: 4.4 }
  ]
}

Last updated