ccxws
Version:
Websocket client for 37 cryptocurrency exchanges
180 lines • 6.95 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FtxBaseClient = void 0;
/* eslint-disable @typescript-eslint/member-ordering */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
const decimal_js_1 = __importDefault(require("decimal.js"));
const moment = require("moment");
const BasicClient_1 = require("../BasicClient");
const Level2Point_1 = require("../Level2Point");
const Level2Snapshots_1 = require("../Level2Snapshots");
const Level2Update_1 = require("../Level2Update");
const NotImplementedFn_1 = require("../NotImplementedFn");
const Ticker_1 = require("../Ticker");
const Trade_1 = require("../Trade");
class FtxBaseClient extends BasicClient_1.BasicClient {
constructor({ name, wssPath, watcherMs }) {
super(wssPath, name, undefined, watcherMs);
this._sendSubCandles = NotImplementedFn_1.NotImplementedFn;
this._sendUnsubCandles = NotImplementedFn_1.NotImplementedFn;
this._sendSubLevel2Snapshots = NotImplementedFn_1.NotImplementedFn;
this._sendUnsubLevel2Snapshots = NotImplementedFn_1.NotImplementedFn;
this._sendSubLevel3Snapshots = NotImplementedFn_1.NotImplementedFn;
this._sendUnsubLevel3Snapshots = NotImplementedFn_1.NotImplementedFn;
this._sendSubLevel3Updates = NotImplementedFn_1.NotImplementedFn;
this._sendUnsubLevel3Updates = NotImplementedFn_1.NotImplementedFn;
this.hasTickers = true;
this.hasTrades = true;
this.hasLevel2Updates = true;
}
_sendSubTicker(market) {
this._wss.send(JSON.stringify({
op: "subscribe",
channel: "ticker",
market,
}));
}
_sendUnsubTicker(market) {
this._wss.send(JSON.stringify({
op: "unsubscribe",
channel: "ticker",
market,
}));
}
_sendSubTrades(market) {
this._wss.send(JSON.stringify({
op: "subscribe",
channel: "trades",
market,
}));
}
_sendUnsubTrades(market) {
this._wss.send(JSON.stringify({
op: "unsubscribe",
channel: "trades",
market,
}));
}
_sendSubLevel2Updates(market) {
this._wss.send(JSON.stringify({
op: "subscribe",
channel: "orderbook",
market,
}));
}
_sendUnsubLevel2Updates(market) {
this._wss.send(JSON.stringify({
op: "subscribe",
channel: "orderbook",
market,
}));
}
_onMessage(raw) {
const { type, channel, market: symbol, data } = JSON.parse(raw);
if (!data || !type || !channel || !symbol) {
return;
}
switch (channel) {
case "ticker":
this._tickerMessageHandler(data, symbol);
break;
case "trades":
this._tradesMessageHandler(data, symbol);
break;
case "orderbook":
this._orderbookMessageHandler(data, symbol, type);
break;
}
}
_tickerMessageHandler(data, symbol) {
const market = this._tickerSubs.get(symbol);
if (!market || !market.base || !market.quote) {
return;
}
const timestamp = this._timeToTimestampMs(data.time);
const { last, bid, ask, bidSize: bidVolume, askSize: askVolume } = data;
const ticker = new Ticker_1.Ticker({
exchange: this.name,
base: market.base,
quote: market.quote,
timestamp,
last: last !== undefined && last !== null ? last.toFixed(8) : undefined,
bid: bid !== undefined && bid !== null ? bid.toFixed(8) : undefined,
ask: ask !== undefined && ask !== null ? ask.toFixed(8) : undefined,
bidVolume: bidVolume !== undefined && bidVolume !== null ? bidVolume.toFixed(8) : undefined,
askVolume: askVolume !== undefined && askVolume !== null ? askVolume.toFixed(8) : undefined,
});
this.emit("ticker", ticker, market);
}
_tradesMessageHandler(data, symbol) {
const market = this._tradeSubs.get(symbol);
if (!market || !market.base || !market.quote) {
return;
}
for (const entry of data) {
const { id, price, size, side, time, liquidation } = entry;
const unix = moment.utc(time).valueOf();
const trade = new Trade_1.Trade({
exchange: this.name,
base: market.base,
quote: market.quote,
tradeId: id.toString(),
side,
unix,
price: price.toFixed(8),
amount: size.toFixed(8),
liquidation,
});
this.emit("trade", trade, market);
}
}
_orderbookMessageHandler(data, symbol, type) {
const market = this._level2UpdateSubs.get(symbol);
if (!market || !market.base || !market.quote || (!data.asks.length && !data.bids.length)) {
return;
}
switch (type) {
case "partial":
this._orderbookSnapshotEvent(data, market);
break;
case "update":
this._orderbookUpdateEvent(data, market);
break;
}
}
_orderbookUpdateEvent(data, market) {
const content = this._orderbookEventContent(data, market);
const eventData = new Level2Update_1.Level2Update(content);
this.emit("l2update", eventData, market);
}
_orderbookSnapshotEvent(data, market) {
const content = this._orderbookEventContent(data, market);
const eventData = new Level2Snapshots_1.Level2Snapshot(content);
this.emit("l2snapshot", eventData, market);
}
_orderbookEventContent(data, market) {
const { time, asks, bids, checksum } = data;
const level2PointAsks = asks.map(p => new Level2Point_1.Level2Point(p[0].toFixed(8), p[1].toFixed(8)));
const level2PointBids = bids.map(p => new Level2Point_1.Level2Point(p[0].toFixed(8), p[1].toFixed(8)));
const timestampMs = this._timeToTimestampMs(time);
return {
exchange: this.name,
base: market.base,
quote: market.quote,
timestampMs,
asks: level2PointAsks,
bids: level2PointBids,
checksum,
};
}
_timeToTimestampMs(time) {
return new decimal_js_1.default(time).mul(1000).toDecimalPlaces(0).toNumber();
}
}
exports.FtxBaseClient = FtxBaseClient;
//# sourceMappingURL=FtxBase.js.map
;