UNPKG

ccxws

Version:

Websocket client for 37 cryptocurrency exchanges

266 lines 9.58 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HitBtcClient = 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 moment_1 = __importDefault(require("moment")); const BasicClient_1 = require("../BasicClient"); const Candle_1 = require("../Candle"); const CandlePeriod_1 = require("../CandlePeriod"); const Throttle_1 = require("../flowcontrol/Throttle"); 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 HitBtcClient extends BasicClient_1.BasicClient { constructor({ wssPath = "wss://api.hitbtc.com/api/2/ws", throttleMs = 25, watcherMs, } = {}) { super(wssPath, "HitBTC", undefined, watcherMs); 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._id = 0; this.hasTickers = true; this.hasTrades = true; this.hasCandles = true; this.hasLevel2Updates = true; this.candlePeriod = CandlePeriod_1.CandlePeriod._1m; this._send = (0, Throttle_1.throttle)(this.__send.bind(this), throttleMs); } _beforeClose() { this._send.cancel(); } __send(msg) { this._wss.send(msg); } _sendSubTicker(remote_id) { this._send(JSON.stringify({ method: "subscribeTicker", params: { symbol: remote_id, }, id: ++this._id, })); } _sendUnsubTicker(remote_id) { this._send(JSON.stringify({ method: "unsubscribeTicker", params: { symbol: remote_id, }, })); } _sendSubTrades(remote_id) { this._send(JSON.stringify({ method: "subscribeTrades", params: { symbol: remote_id, }, id: ++this._id, })); } _sendUnsubTrades(remote_id) { this._send(JSON.stringify({ method: "unsubscribeTrades", params: { symbol: remote_id, }, })); } _sendSubCandles(remote_id) { this._send(JSON.stringify({ method: "subscribeCandles", params: { symbol: remote_id, period: candlePeriod(this.candlePeriod), }, id: ++this._id, })); } _sendUnsubCandles(remote_id) { this._send(JSON.stringify({ method: "unsubscribeCandles", params: { symbol: remote_id, period: candlePeriod(this.candlePeriod), }, })); } _sendSubLevel2Updates(remote_id) { this._send(JSON.stringify({ method: "subscribeOrderbook", params: { symbol: remote_id, }, id: ++this._id, })); } _sendUnsubLevel2Updates(remote_id) { this._send(JSON.stringify({ method: "unsubscribeOrderbook", params: { symbol: remote_id, }, })); } _onMessage(raw) { const msg = JSON.parse(raw); // The payload for a subscribe confirm will include the id that // was attached in the JSON-RPC call creation. For example: // { jsonrpc: '2.0', result: true, id: 7 } if (msg.result === true && msg.id) { // console.log(msg); // return; } // For unsubscribe calls, we are not including an id // so we can ignore messages that do not can an id value: // { jsonrpc: '2.0', result: true, id: null } if (msg.result !== undefined && msg.id) { return; } const remote_id = msg.params && msg.params.symbol; if (msg.method === "ticker") { const market = this._tickerSubs.get(remote_id); if (!market) return; const ticker = this._constructTicker(msg.params, market); this.emit("ticker", ticker, market); } if (msg.method === "updateTrades") { const market = this._tradeSubs.get(remote_id); if (!market) return; for (const datum of msg.params.data) { const trade = this._constructTradesFromMessage(datum, market); this.emit("trade", trade, market); } return; } if (msg.method === "updateCandles") { const market = this._candleSubs.get(remote_id); if (!market) return; for (const datum of msg.params.data) { const candle = this._constructCandle(datum); this.emit("candle", candle, market); } } if (msg.method === "snapshotOrderbook") { const market = this._level2UpdateSubs.get(remote_id); // coming from l2update sub if (!market) return; const result = this._constructLevel2Snapshot(msg.params, market); this.emit("l2snapshot", result, market); return; } if (msg.method === "updateOrderbook") { const market = this._level2UpdateSubs.get(remote_id); if (!market) return; const result = this._constructLevel2Update(msg.params, market); this.emit("l2update", result, market); return; } } _constructTicker(param, market) { const { ask, bid, last, open, low, high, volume, volumeQuote, timestamp } = param; const change = (parseFloat(last) - parseFloat(open)).toFixed(8); const changePercent = (((parseFloat(last) - parseFloat(open)) / parseFloat(open)) * 100).toFixed(8); return new Ticker_1.Ticker({ exchange: this.name, base: market.base, quote: market.quote, timestamp: moment_1.default.utc(timestamp).valueOf(), last, open, high, low, volume, quoteVolume: volumeQuote, ask, bid, change, changePercent, }); } _constructTradesFromMessage(datum, market) { const { id, price, quantity, side, timestamp } = datum; const unix = (0, moment_1.default)(timestamp).valueOf(); return new Trade_1.Trade({ exchange: this.name, base: market.base, quote: market.quote, tradeId: id.toFixed(), side, unix, price, amount: quantity, }); } _constructCandle(datum) { const unix = (0, moment_1.default)(datum.timestamp).valueOf(); return new Candle_1.Candle(unix, datum.open, datum.max, datum.min, datum.close, datum.volume); } _constructLevel2Snapshot(data, market) { const { ask, bid, sequence } = data; const asks = ask.map(p => new Level2Point_1.Level2Point(p.price, p.size)); const bids = bid.map(p => new Level2Point_1.Level2Point(p.price, p.size)); return new Level2Snapshots_1.Level2Snapshot({ exchange: this.name, base: market.base, quote: market.quote, sequenceId: sequence, asks, bids, }); } _constructLevel2Update(data, market) { const { ask, bid, sequence } = data; const asks = ask.map(p => new Level2Point_1.Level2Point(p.price, p.size, p.count)); const bids = bid.map(p => new Level2Point_1.Level2Point(p.price, p.size, p.count)); return new Level2Update_1.Level2Update({ exchange: this.name, base: market.base, quote: market.quote, sequenceId: sequence, asks, bids, }); } } exports.HitBtcClient = HitBtcClient; function candlePeriod(period) { switch (period) { case CandlePeriod_1.CandlePeriod._1m: return "M1"; case CandlePeriod_1.CandlePeriod._3m: return "M3"; case CandlePeriod_1.CandlePeriod._5m: return "M5"; case CandlePeriod_1.CandlePeriod._15m: return "M15"; case CandlePeriod_1.CandlePeriod._30m: return "M30"; case CandlePeriod_1.CandlePeriod._1h: return "H1"; case CandlePeriod_1.CandlePeriod._4h: return "H4"; case CandlePeriod_1.CandlePeriod._1d: return "D1"; case CandlePeriod_1.CandlePeriod._1w: return "D7"; case CandlePeriod_1.CandlePeriod._1M: return "1M"; } } //# sourceMappingURL=HitBtcClient.js.map