{"id":13633101,"url":"https://github.com/altangent/ccxws","last_synced_at":"2025-04-18T10:34:09.869Z","repository":{"id":38630365,"uuid":"129456680","full_name":"altangent/ccxws","owner":"altangent","description":"WebSocket client for 38 cryptocurrency exchanges","archived":true,"fork":false,"pushed_at":"2024-08-15T09:14:45.000Z","size":1688,"stargazers_count":618,"open_issues_count":67,"forks_count":186,"subscribers_count":21,"default_branch":"master","last_synced_at":"2024-10-02T00:48:48.581Z","etag":null,"topics":["binance","bitmex","coinbase","cryptocurrency","cryptocurrency-exchanges","deribit","exchange","hacktoberfest","huobi","kucoin","websocket","websocket-api"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/altangent.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-04-13T21:46:54.000Z","updated_at":"2024-09-25T01:11:28.000Z","dependencies_parsed_at":"2024-01-12T20:03:41.735Z","dependency_job_id":null,"html_url":"https://github.com/altangent/ccxws","commit_stats":{"total_commits":765,"total_committers":33,"mean_commits":"23.181818181818183","dds":"0.19738562091503264","last_synced_commit":"50ec03d4900ee9027a05678869ba05adb4d02fa3"},"previous_names":[],"tags_count":124,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altangent%2Fccxws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altangent%2Fccxws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altangent%2Fccxws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altangent%2Fccxws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/altangent","download_url":"https://codeload.github.com/altangent/ccxws/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223779524,"owners_count":17201200,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binance","bitmex","coinbase","cryptocurrency","cryptocurrency-exchanges","deribit","exchange","hacktoberfest","huobi","kucoin","websocket","websocket-api"],"created_at":"2024-08-01T23:00:27.604Z","updated_at":"2024-11-09T02:31:19.527Z","avatar_url":"https://github.com/altangent.png","language":"TypeScript","funding_links":[],"categories":["Market data libraries"],"sub_categories":[],"readme":"# CryptoCurrency eXchange WebSockets\n\n[![CI](https://github.com/altangent/ccxws/workflows/Node.js%20CI/badge.svg)](https://github.com/altangent/ccxws/actions?query=workflow%3A%22Node.js+CI%22)\n[![Coverage](https://coveralls.io/repos/github/altangent/ccxws/badge.svg?branch=master)](https://coveralls.io/github/altangent/ccxws?branch=master)\n\nA JavaScript library for connecting to realtime public APIs on all cryptocurrency exchanges.\n\nCCXWS provides a standardized eventing interface for connection to public APIs. Currently CCXWS support ticker, trade and orderbook events.\n\nThe 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.\n\nCCXWS 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.\n\nCheck out the [FAQS](/FAQ.md) for more inforamtion on common issues you may encounter.\n\nCheck out the [CONTRIBUTING guide](/CONTRIBUTING.md) for how to get involved.\n\n## Getting Started\n\nInstall ccxws\n\n```bash\nnpm install ccxws\n```\n\nCreate a new client for an exchange. Subscribe to the events that you want to listen to by supplying a market.\n\n```javascript\nimport { BinanceClient } from \"ccxws\";\nconst binance = new BinanceClient();\n\n// market could be from CCXT or genearted by the user\nconst market = {\n  id: \"BTCUSDT\", // remote_id used by the exchange\n  base: \"BTC\", // standardized base symbol for Bitcoin\n  quote: \"USDT\", // standardized quote symbol for Tether\n};\n\n// handle trade events\nbinance.on(\"trade\", trade =\u003e console.log(trade));\n\n// handle level2 orderbook snapshots\nbinance.on(\"l2snapshot\", snapshot =\u003e console.log(snapshot));\n\n// subscribe to trades\nbinance.subscribeTrades(market);\n\n// subscribe to level2 orderbook snapshots\nbinance.subscribeLevel2Snapshots(market);\n```\n\n## Exchanges\n\n| Exchange               | API | Class                     | Ticker   | Trades   | Candles  | OB-L2 Snapshot | OB-L2 Updates | OB-L3 Snapshot | OB-L3 Updates |\n| ---------------------- | --- | ------------------------- | -------- | -------- | -------- | -------------- | ------------- | -------------- | ------------- |\n| Bibox                  | 1   | BiboxClient               | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       |               | -              | -             |\n| Binance                | 1   | BinanceClient             | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*\\*  | -              | -             |\n| Binance Futures Coin-M | 1   | BinanceFuturesCoinmClient | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*\\*  | -              | -             |\n| Binance Futures USDT-M | 1   | BinanceFuturesUsdtmClient | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*\\*  | -              | -             |\n| Binance US             | 1   | BinanceUsClient           | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*\\*  | -              | -             |\n| Bitfinex               | 2   | BitfinexClient            | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | \u0026#10003;\\*    |\n| bitFlyer               | 1   | BitflyerClient            | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*\\*  | -              | -             |\n| Bithumb                | 1   | BithumbClient             | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*\\*  | -              | -             |\n| BitMEX                 | 1   | BitmexClient              | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*    | -              | -             |\n| Bitstamp               | 2   | BitstampClient            | -        | \u0026#10003; | -        | \u0026#10003;       | \u0026#10003;\\*\\*  | -              | -             |\n| Bittrex                | 3   | BittrexClient             | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*    | -              | -             |\n| Cex.io                 | 1   | CexClient                 | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       |               | -              | -             |\n| Coinbase Pro           | 1   | CoinbaseProClient         | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | \u0026#10003;      |\n| Coinex                 | 1   | CoinexClient              | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*    | -              | -             |\n| Deribit                | 2   | DeribitClient             | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*    | -              | -             |\n| Digifinex              | 1   | DigifinexClient           | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | -             |\n| ErisX                  | 3.4 | ErisXClient               | -        | \u0026#10003; | -        | -              | -             | -              | \u0026#10003;\\*    |\n| FTX                    | 1   | FtxClient                 | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | -             |\n| FTX US                 | 1   | FtxUsClient               | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | -             |\n| Gate.io                | 3   | GateioClient              | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | -             |\n| Gemini                 | 1   | GeminiClient              | -        | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | -             |\n| HitBTC                 | 2   | HitBtcClient              | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*    | -              | -             |\n| Huobi Global           | 1   | HuobiClient               | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | -             | -              | -             |\n| Huobi Global Futures   | 1   | HuobiFuturesClient        | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*    | -              | -             |\n| Huobi Global Swaps     | 1   | HuobiSwapsClient          | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*    | -              | -             |\n| Huobi Japan            | 1   | HuobiJapanClient          | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | -             | -              | -             |\n| Huobi Korea            | 1   | HuobiKoreaClient          | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | -             | -              | -             |\n| KuCoin                 | 2   | KucoinClient              | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*\\*  | -              | \u0026#10003;\\*    |\n| Kraken                 | 0   | KrakenClient              | \u0026#10003; | \u0026#10003; | \u0026#10003; | -              | \u0026#10003;\\*    | -              | -             |\n| LedgerX                | 1   | LedgerXClient             | -        | \u0026#10003; | -        | -              | -             | -              | \u0026#10003;\\*    |\n| Liquid                 | 2   | LiquidClient              | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;      | -              | -             |\n| OKEx                   | 3   | OkexClient                | \u0026#10003; | \u0026#10003; | \u0026#10003; | \u0026#10003;       | \u0026#10003;\\*    | -              | -             |\n| Poloniex               | 2   | PoloniexClient            | \u0026#10003; | \u0026#10003; | -        | -              | \u0026#10003;\\*    | -              | -             |\n| Upbit                  | 1   | UpbitClient               | \u0026#10003; | \u0026#10003; | -        | \u0026#10003;       | -             | -              | -             |\n| ZB                     | 1   | ZbClient                  | \u0026#10003; | \u0026#10003; | -        | \u0026#10003;       | -             | -              | -             |\n\nNotes:\n\n- \u0026#10003;\\* broadcasts a snapshot event at startup\n- \u0026#10003;\\*\\* broadcasts a snapshot by using the REST API\n\n## Definitions\n\nTrades - A maker/taker match has been made. Broadcast as an aggregated event.\n\nOrderbook 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.\n\nOrderbook 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.\n\n## API\n\n### `Market`\n\nMarkets 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.\n\nThese properties are required by CCXWS.\n\n- `id: string` - the identifier used by the remote exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `type: string` - the type of market: `spot`, `futures`, `option`, `swap`\n\n### `Client`\n\nA 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.\n\n```javascript\nconst binance = new ccxws.Binance();\nconst coinbase = new ccxws.CoinbasePro();\n```\n\nClients can be instantiated with an options object that has several properties properties:\n\n- `wssPath: string` - allows customization of the web socket path. When this is configured, additional rules surrounding connection may be ignored.\n- `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.\n- `apiKey: string` - any API key needed for the exchange\n- `apiSecret: string` - any API secret needed for the exchange\n\n#### Events\n\nSubscribe to events by addding an event handler to the client `.on(\u003cevent\u003e)` method of the client. Multiple event handlers can be added for the same event.\n\nOnce an event handler is attached you can start the stream using the `subscribe\u003cX\u003e` methods.\n\nAll events emit the market used to subscribe to the event as a second property of the event handler.\n\n```javascript\nbinance.on(\"error\", err =\u003e console.error(err));\nbinance.on(\"trades\", (trade, market) =\u003e console.log(trade, market));\nbinance.on(\"l2snapshot\", (snapshot, market) =\u003e console.log(snapshot, market));\n```\n\n##### `error` emits `Error`\n\nYou must subscribe to the `error` event to prevent the process exiting. More information in the [Node.js Events Documentation](https://nodejs.org/dist/latest-v10.x/docs/api/events.html#events_error_events)\n\n\u003e 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.\n\n##### `ticker` emits `Ticker`, `Market`\n\nFired when a ticker update is received. Returns an instance of `Ticker` and the `Market` used to subscribe to the event.\n\n##### `trade` emits `Trade`, `Market`\n\nFired when a trade is received. Returns an instance of `Trade` and the `Market` used to subscribe to the event.\n\n##### `candle` emits `Candle`, `Market`\n\nFired when a candle is received. Returns an instance of `Candle` and the `Market` used to subscribe to the event.\n\n##### `l2snapshot` emits `Level2Snapshot`, `Market`\n\nFired when a orderbook level 2 snapshot is received. Returns an instance of `Level2Snapshot` and the `Market` used to subscribe to the event.\n\nThe level of detail will depend on the specific exchange and may include 5/10/20/50/100/1000 bids and asks.\n\nThis event is also fired when subscribing to the `l2update` event on many exchanges.\n\n##### `l2update` emits `Level2Update`, `Market`\n\nFired when a orderbook level 2 update is recieved. Returns an instance of `Level2Update` and the `Market` used to subscribe to the event.\n\nSubscribing to this event may trigger an initial `l2snapshot` event for many exchanges.\n\n##### `l3snapshot` emits `Level3Snapshot`, `Market`\n\nFired when a orderbook level 3 snapshot is received. Returns an instance of `Level3Snapshot` and the `Market` used to subscribe to the event.\n\n##### `l3update` emits `Level3Update`, `Market`\n\nFired when a level 3 update is recieved. Returns an instance of `Level3Update` and the `Market` used to subscribe to the event.\n\n#### Connection Events\n\nClients emit events as their state changes.\n\n```\n   +-------+\n   |       |\n   | start |\n   |       |\n   +---+---+\n       |\n       |\n       |\n       | subscribe\n       |\n       |\n       |\n+------v-------+       initiate\n|              |       reconnect\n|  connecting  \u003c------------------------+\n|              |                        |\n+------+-------+                        |\n       |                                |\n       |                        +-------+-------+\n       |                        |               |\n       | socket                 | disconnected  |\n       | open                   |               |\n       |                        +-------^-------+\n       |                                |\n+------v-------+                        |\n|              |                        |\n|  connected   +------------------------+\n|              |        socket\n+------+-------+        closed\n       |\n       |\n       |\n       | close\n       | requested\n       |\n       |\n       |\n+------v-------+                  +--------------+\n|              |                  |              |\n|   closing    +------------------\u003e    closed    |\n|              |     socket       |              |\n+--------------+     closed       +--------------+\n```\n\n##### `connecting`\n\nFires prior to a socket initiating the connection. This event also fires when a reconnection starts.\n\n##### `connected`\n\nFires when a socket has connected. This event will also fire for reconnection completed.\n\n##### `disconnected`\n\nFires when a socket prematurely disconnects. Automatic reconnection will be triggered. The expected\nflow is `disconnected -\u003e connecting -\u003e connected`.\n\n##### `closing`\n\nFires when the client is preparing to close its connection(s). This event is not fired during reconnections.\n\n##### `closed`\n\nFires 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.\n\n##### `reconnecting`\n\nFires when a socket has initiated the reconnection process due to inactivity. This is fired at the start of the reconnection process `reconnecting -\u003e closing -\u003e closed -\u003e connecting -\u003e connected`\n\n#### Methods\n\n##### `subscribeTicker(market): void`\n\nSubscribes 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.\n\n##### `unsubscribeTicker(market): void`\n\nUnsubscribes from a ticker feed for a market.\n\n##### `subscribeTrades(market): void`\n\nSubscribes 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.\n\n##### `unsubscribeTrades(market): void`\n\nUnsubscribes from a trade feed for a market.\n\n\\*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.\n\n##### `subscribeCandles(market): void`\n\nSubscribes 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\n`candlePeriod` property of the client to control which candle is returned by the feed.\n\n##### `unsubscribeCandles(market): void`\n\nUnsubscribes from a candle feed for a market.\n\n\\*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.\n\n##### `subscribeLevel2Snapshots(market): void`\n\nSubscribes 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.\n\nThis method is a no-op for exchanges that do not support level 2 snapshot subscriptions.\n\n##### `unsubscribeLevel2Snapshots(market): void`\n\nUnbusbscribes from the orderbook level 2 snapshot for a market.\n\n\\*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.\n\n##### `subscribeLevel2Updates(market): void`\n\nSubscribes 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.\n\nThis method is a no-op for exchanges that do not support level 2 snapshot subscriptions.\n\n##### `unsubscribeLevel2Updates(market): void`\n\nUnbusbscribes from the orderbook level 2 updates for a market.\n\n\\*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.\n\n##### `subscribeLevel3Snapshots(market): void`\n\nSubscribes 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.\n\nThis method is a no-op for exchanges that do not support level 2 snapshot subscriptions.\n\n##### `unsubscribeLevel3Snapshots(market): void`\n\nUnbusbscribes from the orderbook level 3 snapshot for a market.\n\n\\*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.\n\n##### `subscribeLevel3Updates(market): void`\n\nSubscribes 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.\n\nThis method is a no-op for exchanges that do not support level 3 snapshot subscriptions.\n\n##### `unsubscribeLevel3Updates(market): void`\n\nUnbusbscribes from the orderbook level 3 updates for a market.\n\n\\*For some exchanges, calling unsubscribe may cause a temporary disruption in all feeds.\n\n### `Ticker`\n\nThe ticker class is the result of a `ticker` event.\n\n#### Properties\n\n- `exchange: string` - the name of the exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `timestamp: int` - the unix timestamp in milliseconds\n- `last: string` - the last price of a match that caused a tick\n- `open: string` - the price 24 hours ago\n- `low: string` - the highest price in the last 24 hours\n- `high: string` - the lowest price in the last 24 hours\n- `volume: string` - the base volume traded in the last 24 hours\n- `quoteVolume: string` - the quote volume traded in the last 24 hours\n- `change: string` - the price change (last - open)\n- `changePercent: string` - the price change in percent (last - open) / open \\* 100\n- `bid: string` - the best bid price\n- `bidVolume: string` - the volume at the best bid price\n- `ask: string` - the best ask price\n- `askVolume: string` - the volume at the best ask price\n\n### `Trade`\n\nThe trade class is the result of a `trade` event emitted from a client.\n\n#### Properties\n\n- `exchange: string` - the name of the exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `tradeId: string` - the unique trade identifer from the exchanges feed\n- `unix: int` - the unix timestamp in milliseconds for when the trade executed\n- `side: string` - whether the buyer `buy` or seller `sell` was the maker for the match\n- `price: string` - the price at which the match executed\n- `amount: string` - the amount executed in the match\n- `buyOrderId: string` - the order id of the buy side\n- `sellOrderId: string` - the order id of the sell side\n\n### `Candle`\n\nThe candle class is the result of a `candle` event emitted from a client.\n\n#### Properties\n\n- `timestampMs: int` - the unix timestamp in milliseconds for the candle\n- `open: string` - the open price for the period\n- `high: string` - the high price for the period\n- `low: string` - the low price for the period\n- `close: string` - the close price for the period\n- `volume: string` - the volume exchanged during the period\n\n### `Level2Point`\n\nRepresents a price point in a level 2 orderbook\n\n#### Properties\n\n- `price: string` - price\n- `size: string` - aggregated volume for all orders at this price point\n- `count: int` - optional number of orders aggregated into the price point\n\n### `Level2Snapshot`\n\nThe level 2 snapshot class is the result of a `l2snapshot` or `l2update` event emitted from the client.\n\n#### Properties\n\n- `exchange: string` - the name of the exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `timestampMs: int` - optional timestamp in milliseconds for the snapshot\n- `sequenceId: int` - optional sequence identifier for the snapshot\n- `asks: [Level2Point]` - the ask (seller side) price points\n- `bids: [Level2Point]` - the bid (buyer side) price points\n\n### `Level2Update`\n\nThe 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.\n\n#### Properties\n\n- `exchange: string` - the name of the exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `timestampMs: int` - optional timestamp in milliseconds for the snapshot\n- `sequenceId: int` - optional sequence identifier for the snapshot\n- `asks: [Level2Point]` - the ask (seller side) price points\n- `bids: [Level2Point]` - the bid (buyer side) price points\n\n### `Level3Point`\n\nRepresents a price point in a level 3 orderbook\n\n#### Properties\n\n- `orderId: string` - identifier for the order\n- `price: string` - price\n- `size: string` - volume of the order\n- `meta: object` - optional exchange specific metadata with additional information about the update.\n\n### `Level3Snapshot`\n\nThe level 3 snapshot class is the result of a `l3snapshot` or `l3update` event emitted from the client.\n\n#### Properties\n\n- `exchange: string` - the name of the exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `timestampMs: int` - optional timestamp in milliseconds for the snapshot\n- `sequenceId: int` - optional sequence identifier for the snapshot\n- `asks: [Level3Point]` - the ask (seller side) price points\n- `bids: [Level3Point]` - the bid (buyer side) price points\n\n### `Level3Update`\n\nThe 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.\n\nAdditional metadata is often provided in the `meta` property that has more detailed information that is often required to propertly manage a level 3 orderbook.\n\n#### Properties\n\n- `exchange: string` - the name of the exchange\n- `base: string` - the normalized base symbol for the market\n- `quote: string` - the normalized quote symbol for the market\n- `timestampMs: int` - optional timestamp in milliseconds for the snapshot\n- `sequenceId: int` - optional sequence identifier for the snapshot\n- `asks: [Level3Point]` - the ask (seller side) price points\n- `bids: [Level3Point]` - the bid (buyer side) price points\n\n## Caveats\n\n### Snapshots broadcast using the REST API\n\nFor 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.\n\nFor 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` \u003e= the first update that arrives. See example below:\n\n```js\nconst REST_DELAY_MS = 500;\nclient._originalRequestLevel2Snapshot = client._requestLevel2Snapshot;\nclient._requestLevel2Snapshot = market =\u003e\n  setTimeout(() =\u003e client._originalRequestLevel2Snapshot(market), REST_DELAY_MS);\n```\n\nOtherwise 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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltangent%2Fccxws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faltangent%2Fccxws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltangent%2Fccxws/lists"}