WebSocket client library
@cloud9trader/websocket-api-client is the JavaScript client for the WebSocket API. It runs in Node.js and in the browser, signs private connections, matches answers to requests, and reconnects with every subscription restored. Source: Cloud9Trader/websocket-api-client.
Install
Section titled “Install”npm install @cloud9trader/websocket-api-clientIn a web page without a bundler:
<script src="https://unpkg.com/@cloud9trader/websocket-api-client@0.0.25/dist/global.js"></script><script> const client = new Cloud9Trader.Client({ key: "YOUR_API_KEY" })</script>Quick start
Section titled “Quick start”Public market data, from Node.js or a browser:
import Client from "@cloud9trader/websocket-api-client"
const client = new Client({ key: process.env.C9T_API_KEY! })client.on("connected", () => console.log("connected"))client.on("error", (error) => console.error(error))client.subscribe("price.EUR_USD:OANDA", (price) => console.log(price))client.start()Your account and orders, from Node.js only:
import Client from "@cloud9trader/websocket-api-client"
const client = new Client({ key: process.env.C9T_API_KEY!, secret: process.env.C9T_API_SECRET! })client.subscribe("positions", (positions) => console.log(positions))client.start()
client.on("connected", () => { client.submit("order", { broker: "Bitfinex", symbol: "BTCUSD", side: "BUY", type: "LIMIT", quantity: 0.01, limitPrice: 60000 }, (error, order) => { if (error) return console.error("Refused:", error) console.log("Accepted:", order) })})The library refuses to start with a secret in a browser, so a secret never ends up in a web page.
new Client({ key, secret?, host? })
Section titled “new Client({ key, secret?, host? })”| Option | Meaning |
|---|---|
key |
Your API key. Required, even for public data. |
secret |
Your API secret. Add it for the private socket. Node.js only. |
host |
The socket address. Defaults to wss://sockets.cloud9trader.com. |
Methods
Section titled “Methods”| Method | What it does |
|---|---|
start() |
Opens the socket. Call it once. |
isConnected() |
true while the socket is open. |
on(event, handler) |
Listens for connected, disconnected, status or error. |
subscribe(topic, listener) |
Calls listener with each snapshot and update. Subscribing before start() or while disconnected is fine: it waits for the connection. |
unsubscribe(topic, listener) |
Removes a listener. The last one removed unsubscribes on the server. Pass the same function you subscribed with. |
request(topic, (error, data) => {}) |
Asks for a topic once. Gives up after 3 seconds with error set to "timeout". |
submit("order", order, (error, order) => {}) |
Sends an order. See Submit an order. Gives up after 5 seconds with "timeout", and answers "Socket is not connected" straight away when disconnected. |
Avoid fetchInstruments() and fetchHistoricalPrice() for now: they do not send your key. Call the REST API directly instead.
Events
Section titled “Events”| Event | Arguments | When |
|---|---|---|
connected |
none | The socket opened. |
disconnected |
none | The socket closed. The library reconnects by itself. |
status |
Connected, Disconnected, Waiting for reconnect or Error |
The connection changed state. |
error |
the error | The socket failed. A refused private connection gives “401 Authentication rejected by server. Check that your key and secret are correct”. |
Reconnection
Section titled “Reconnection”When the socket closes, the library waits and reconnects: 1, 1, 2, 2, 4, 4, 8 and 8 seconds, then every 15 seconds until it connects. It signs each new private connection afresh and subscribes to every topic again. Keep your own order book or position list ready to be replaced by the new snapshot.
The library does not send ["ping"], so a connection that dies silently is only noticed when the network reports it. If that matters to you, check that updates keep arriving.