
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
A JavaScript library for connecting to realtime public APIs on all cryptocurrency exchanges.
CCXWS provides a standardized eventing interface for connection to public APIs. Currently CCXWS support ticker, trade and orderbook events.
The CCXWS socket client performs automatic reconnection when there are disconnections. It also has silent reconnection logic to assist when no data has been seen by the client but the socket remains open.
CCXWS uses similar market structures to those generated by the CCXT library. This allows interoperability between the RESTful interfaces provided by CCXT and the realtime interfaces provided by CCXWS.
Check out the FAQS for more inforamtion on common issues you may encounter.
Check out the CONTRIBUTING guide for how to get involved.
Install ccxws
npm install ccxws
Create a new client for an exchange. Subscribe to the events that you want to listen to by supplying a market.
import { BinanceClient } from "ccxws";
const binance = new BinanceClient();
// market could be from CCXT or genearted by the user
const market = {
id: "BTCUSDT", // remote_id used by the exchange
base: "BTC", // standardized base symbol for Bitcoin
quote: "USDT", // standardized quote symbol for Tether
};
// handle trade events
binance.on("trade", trade => console.log(trade));
// handle level2 orderbook snapshots
binance.on("l2snapshot", snapshot => console.log(snapshot));
// subscribe to trades
binance.subscribeTrades(market);
// subscribe to level2 orderbook snapshots
binance.subscribeLevel2Snapshots(market);
| Exchange | API | Class | Ticker | Trades | Candles | OB-L2 Snapshot | OB-L2 Updates | OB-L3 Snapshot | OB-L3 Updates |
|---|---|---|---|---|---|---|---|---|---|
| Bibox | 1 | BiboxClient | âś“ | âś“ | âś“ | âś“ | - | - | |
| Binance | 1 | BinanceClient | âś“ | âś“ | âś“ | âś“ | âś“** | - | - |
| Binance Futures Coin-M | 1 | BinanceFuturesCoinmClient | âś“ | âś“ | âś“ | âś“ | âś“** | - | - |
| Binance Futures USDT-M | 1 | BinanceFuturesUsdtmClient | âś“ | âś“ | âś“ | âś“ | âś“** | - | - |
| Binance US | 1 | BinanceUsClient | âś“ | âś“ | âś“ | âś“ | âś“** | - | - |
| Bitfinex | 2 | BitfinexClient | âś“ | âś“ | - | - | âś“* | - | âś“* |
| bitFlyer | 1 | BitflyerClient | âś“ | âś“ | - | - | âś“** | - | - |
| Bithumb | 1 | BithumbClient | âś“ | âś“ | - | - | âś“** | - | - |
| BitMEX | 1 | BitmexClient | âś“ | âś“ | âś“ | - | âś“* | - | - |
| Bitstamp | 2 | BitstampClient | - | âś“ | - | âś“ | âś“** | - | - |
| Bittrex | 3 | BittrexClient | âś“ | âś“ | âś“ | - | âś“* | - | - |
| Cex.io | 1 | CexClient | âś“ | âś“ | âś“ | âś“ | - | - | |
| Coinbase Pro | 1 | CoinbaseProClient | âś“ | âś“ | - | - | âś“* | - | âś“ |
| Coinex | 1 | CoinexClient | âś“ | âś“ | âś“ | - | âś“* | - | - |
| Deribit | 2 | DeribitClient | âś“ | âś“ | âś“ | - | âś“* | - | - |
| Digifinex | 1 | DigifinexClient | âś“ | âś“ | - | - | âś“* | - | - |
| ErisX | 3.4 | ErisXClient | - | âś“ | - | - | - | - | âś“* |
| FTX | 1 | FtxClient | âś“ | âś“ | - | - | âś“* | - | - |
| FTX US | 1 | FtxUsClient | âś“ | âś“ | - | - | âś“* | - | - |
| Gate.io | 3 | GateioClient | âś“ | âś“ | - | - | âś“* | - | - |
| Gemini | 1 | GeminiClient | - | âś“ | - | - | âś“* | - | - |
| HitBTC | 2 | HitBtcClient | âś“ | âś“ | âś“ | - | âś“* | - | - |
| Huobi Global | 1 | HuobiClient | âś“ | âś“ | âś“ | âś“ | - | - | - |
| Huobi Global Futures | 1 | HuobiFuturesClient | âś“ | âś“ | âś“ | âś“ | âś“* | - | - |
| Huobi Global Swaps | 1 | HuobiSwapsClient | âś“ | âś“ | âś“ | âś“ | âś“* | - | - |
| Huobi Japan | 1 | HuobiJapanClient | âś“ | âś“ | âś“ | âś“ | - | - | - |
| Huobi Korea | 1 | HuobiKoreaClient | âś“ | âś“ | âś“ | âś“ | - | - | - |
| KuCoin | 2 | KucoinClient | âś“ | âś“ | âś“ | - | âś“** | - | âś“* |
| Kraken | 0 | KrakenClient | âś“ | âś“ | âś“ | - | âś“* | - | - |
| LedgerX | 1 | LedgerXClient | - | âś“ | - | - | - | - | âś“* |
| Liquid | 2 | LiquidClient | âś“ | âś“ | - | - | âś“ | - | - |
| OKEx | 3 | OkexClient | âś“ | âś“ | âś“ | âś“ | âś“* | - | - |
| Poloniex | 2 | PoloniexClient | âś“ | âś“ | - | - | âś“* | - | - |
| Upbit | 1 | UpbitClient | âś“ | âś“ | - | âś“ | - | - | - |
| ZB | 1 | ZbClient | âś“ | âś“ | - | âś“ | - | - | - |
Notes:
Trades - A maker/taker match has been made. Broadcast as an aggregated event.
Orderbook level 2 - has aggregated price points for bids/asks that include the price and total volume at that point. Some exchange may include the number of orders making up the volume at that price point.
Orderbook level 3 - this is the most granual order book information. It has raw order information for bids/asks that can be used to build aggregated volume information for the price points.
MarketMarkets are used as input to many of the client functions. Markets can be generated and stored by you the developer or loaded from the CCXT library.
These properties are required by CCXWS.
id: string - the identifier used by the remote exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettype: string - the type of market: spot, futures, option, swapClientA websocket client that connects to a specific exchange. There is an implementation of this class for each exchange that governs the specific rules for managing the realtime connections to the exchange. You must instantiate the specific exchanges client to conncet to the exchange.
const binance = new ccxws.Binance();
const coinbase = new ccxws.CoinbasePro();
Clients can be instantiated with an options object that has several properties properties:
wssPath: string - allows customization of the web socket path. When this is configured, additional rules surrounding connection may be ignored.watcherMs: number - allows customization of the reconnection watcher. This value is the duration of time that must pass without a message for a reconnection is peroformed. This value can be customized depending on the type and liquidity of markets that you are subscribing to.apiKey: string - any API key needed for the exchangeapiSecret: string - any API secret needed for the exchangeSubscribe to events by addding an event handler to the client .on(<event>) method of the client. Multiple event handlers can be added for the same event.
Once an event handler is attached you can start the stream using the subscribe<X> methods.
All events emit the market used to subscribe to the event as a second property of the event handler.
binance.on("error", err => console.error(err));
binance.on("trades", (trade, market) => console.log(trade, market));
binance.on("l2snapshot", (snapshot, market) => console.log(snapshot, market));
error emits ErrorYou must subscribe to the error event to prevent the process exiting. More information in the Node.js Events Documentation
If an EventEmitter does not have at least one listener registered for the 'error' event, and an 'error' event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits.
ticker emits Ticker, MarketFired when a ticker update is received. Returns an instance of Ticker and the Market used to subscribe to the event.
trade emits Trade, MarketFired when a trade is received. Returns an instance of Trade and the Market used to subscribe to the event.
candle emits Candle, MarketFired when a candle is received. Returns an instance of Candle and the Market used to subscribe to the event.
l2snapshot emits Level2Snapshot, MarketFired when a orderbook level 2 snapshot is received. Returns an instance of Level2Snapshot and the Market used to subscribe to the event.
The level of detail will depend on the specific exchange and may include 5/10/20/50/100/1000 bids and asks.
This event is also fired when subscribing to the l2update event on many exchanges.
l2update emits Level2Update, MarketFired when a orderbook level 2 update is recieved. Returns an instance of Level2Update and the Market used to subscribe to the event.
Subscribing to this event may trigger an initial l2snapshot event for many exchanges.
l3snapshot emits Level3Snapshot, MarketFired when a orderbook level 3 snapshot is received. Returns an instance of Level3Snapshot and the Market used to subscribe to the event.
l3update emits Level3Update, MarketFired when a level 3 update is recieved. Returns an instance of Level3Update and the Market used to subscribe to the event.
Clients emit events as their state changes.
+-------+
| |
| start |
| |
+---+---+
|
|
|
| subscribe
|
|
|
+------v-------+ initiate
| | reconnect
| connecting <------------------------+
| | |
+------+-------+ |
| |
| +-------+-------+
| | |
| socket | disconnected |
| open | |
| +-------^-------+
| |
+------v-------+ |
| | |
| connected +------------------------+
| | socket
+------+-------+ closed
|
|
|
| close
| requested
|
|
|
+------v-------+ +--------------+
| | | |
| closing +------------------> closed |
| | socket | |
+--------------+ closed +--------------+
connectingFires prior to a socket initiating the connection. This event also fires when a reconnection starts.
connectedFires when a socket has connected. This event will also fire for reconnection completed.
disconnectedFires when a socket prematurely disconnects. Automatic reconnection will be triggered. The expected
flow is disconnected -> connecting -> connected.
closingFires when the client is preparing to close its connection(s). This event is not fired during reconnections.
closedFires when the client has closed its connection(s). This event is not fired during reconnections, it is fired when the close method is called and the connection(s) are successfully closed.
reconnectingFires when a socket has initiated the reconnection process due to inactivity. This is fired at the start of the reconnection process reconnecting -> closing -> closed -> connecting -> connected
subscribeTicker(market): voidSubscribes to a ticker feed for a market. This method will cause the client to emit ticker events that have a payload of the Ticker object.
unsubscribeTicker(market): voidUnsubscribes from a ticker feed for a market.
subscribeTrades(market): voidSubscribes to a trade feed for a market. This method will cause the client to emit trade events that have a payload of the Trade object.
unsubscribeTrades(market): voidUnsubscribes from a trade feed for a market.
*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.
subscribeCandles(market): voidSubscribes to a candle feed for a market. This method will cause the client to emit candle events that have a payload of the Candle object. Set the
candlePeriod property of the client to control which candle is returned by the feed.
unsubscribeCandles(market): voidUnsubscribes from a candle feed for a market.
*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.
subscribeLevel2Snapshots(market): voidSubscribes to the orderbook level 2 snapshot feed for a market. This method will cause the client to emit l2snapshot events that have a payload of the Level2Snaphot object.
This method is a no-op for exchanges that do not support level 2 snapshot subscriptions.
unsubscribeLevel2Snapshots(market): voidUnbusbscribes from the orderbook level 2 snapshot for a market.
*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.
subscribeLevel2Updates(market): voidSubscribes to the orderbook level 2 update feed for a market. This method will cause the client to emit l2update events that have a payload of the Level2Update object.
This method is a no-op for exchanges that do not support level 2 snapshot subscriptions.
unsubscribeLevel2Updates(market): voidUnbusbscribes from the orderbook level 2 updates for a market.
*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.
subscribeLevel3Snapshots(market): voidSubscribes to the orderbook level 3 snapshot feed for a market. This method will cause the client to emit l3snapshot events that have a payload of the Level3Snaphot object.
This method is a no-op for exchanges that do not support level 2 snapshot subscriptions.
unsubscribeLevel3Snapshots(market): voidUnbusbscribes from the orderbook level 3 snapshot for a market.
*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.
subscribeLevel3Updates(market): voidSubscribes to the orderbook level 3 update feed for a market. This method will cause the client to emit l3update events that have a payload of the Level3Update object.
This method is a no-op for exchanges that do not support level 3 snapshot subscriptions.
unsubscribeLevel3Updates(market): voidUnbusbscribes from the orderbook level 3 updates for a market.
*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.
TickerThe ticker class is the result of a ticker event.
exchange: string - the name of the exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettimestamp: int - the unix timestamp in millisecondslast: string - the last price of a match that caused a tickopen: string - the price 24 hours agolow: string - the highest price in the last 24 hourshigh: string - the lowest price in the last 24 hoursvolume: string - the base volume traded in the last 24 hoursquoteVolume: string - the quote volume traded in the last 24 hourschange: string - the price change (last - open)changePercent: string - the price change in percent (last - open) / open * 100bid: string - the best bid pricebidVolume: string - the volume at the best bid priceask: string - the best ask priceaskVolume: string - the volume at the best ask priceTradeThe trade class is the result of a trade event emitted from a client.
exchange: string - the name of the exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettradeId: string - the unique trade identifer from the exchanges feedunix: int - the unix timestamp in milliseconds for when the trade executedside: string - whether the buyer buy or seller sell was the maker for the matchprice: string - the price at which the match executedamount: string - the amount executed in the matchbuyOrderId: string - the order id of the buy sidesellOrderId: string - the order id of the sell sideCandleThe candle class is the result of a candle event emitted from a client.
timestampMs: int - the unix timestamp in milliseconds for the candleopen: string - the open price for the periodhigh: string - the high price for the periodlow: string - the low price for the periodclose: string - the close price for the periodvolume: string - the volume exchanged during the periodLevel2PointRepresents a price point in a level 2 orderbook
price: string - pricesize: string - aggregated volume for all orders at this price pointcount: int - optional number of orders aggregated into the price pointLevel2SnapshotThe level 2 snapshot class is the result of a l2snapshot or l2update event emitted from the client.
exchange: string - the name of the exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettimestampMs: int - optional timestamp in milliseconds for the snapshotsequenceId: int - optional sequence identifier for the snapshotasks: [Level2Point] - the ask (seller side) price pointsbids: [Level2Point] - the bid (buyer side) price pointsLevel2UpdateThe level 2 update class is a result of a l2update event emitted from the client. It consists of a collection of bids/asks even exchanges broadcast single events at a time.
exchange: string - the name of the exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettimestampMs: int - optional timestamp in milliseconds for the snapshotsequenceId: int - optional sequence identifier for the snapshotasks: [Level2Point] - the ask (seller side) price pointsbids: [Level2Point] - the bid (buyer side) price pointsLevel3PointRepresents a price point in a level 3 orderbook
orderId: string - identifier for the orderprice: string - pricesize: string - volume of the ordermeta: object - optional exchange specific metadata with additional information about the update.Level3SnapshotThe level 3 snapshot class is the result of a l3snapshot or l3update event emitted from the client.
exchange: string - the name of the exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettimestampMs: int - optional timestamp in milliseconds for the snapshotsequenceId: int - optional sequence identifier for the snapshotasks: [Level3Point] - the ask (seller side) price pointsbids: [Level3Point] - the bid (buyer side) price pointsLevel3UpdateThe level 3 update class is a result of a l3update event emitted from the client. It consists of a collection of bids/asks even exchanges broadcast single events at a time.
Additional metadata is often provided in the meta property that has more detailed information that is often required to propertly manage a level 3 orderbook.
exchange: string - the name of the exchangebase: string - the normalized base symbol for the marketquote: string - the normalized quote symbol for the markettimestampMs: int - optional timestamp in milliseconds for the snapshotsequenceId: int - optional sequence identifier for the snapshotasks: [Level3Point] - the ask (seller side) price pointsbids: [Level3Point] - the bid (buyer side) price pointsFor exchanges which request the Level2Snapshot or Level3Snapshot over REST, there can be a race condition where messages are missed between the snapshot and the first update, for example the snapshot sequenceId is 100 and the first update's sequenceId is 105.
For a not-so-reliable fix you can monkey-patch a delay so that the snapshot is requested after subscribing to updates to better ensure the snapshot arrives with a sequenceId >= the first update that arrives. See example below:
const REST_DELAY_MS = 500;
client._originalRequestLevel2Snapshot = client._requestLevel2Snapshot;
client._requestLevel2Snapshot = market =>
setTimeout(() => client._originalRequestLevel2Snapshot(market), REST_DELAY_MS);
Otherwise you should be prepared to manually verify the sequenceId if possible, and request the snapshot again if there is a gap between the snapshot and the first update by calling client.requestLevel2Snapshot(market) again.
FAQs
Websocket client for 37 cryptocurrency exchanges
We found that ccxws demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.