UNPKG

tardis-dev

Version:

Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js

240 lines 9.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WooxBookTickerMapper = exports.WooxDerivativeTickerMapper = exports.WooxBookChangeMapper = exports.wooxTradesMapper = void 0; const handy_1 = require("../handy"); const mapper_1 = require("./mapper"); exports.wooxTradesMapper = { canHandle(message) { return message.topic !== undefined && message.topic.endsWith('@trade'); }, getFilters(symbols) { symbols = (0, handy_1.upperCaseSymbols)(symbols); return [ { channel: 'trade', symbols } ]; }, *map(message, localTimestamp) { const timestamp = new Date(message.ts); // any trade with source = 0 is mainly for informational purposes for our users, not actual trades printed on WOO X if (message.data.source === 0) { return; } yield { type: 'trade', symbol: message.data.symbol, exchange: 'woo-x', id: undefined, price: message.data.price, amount: message.data.size, side: message.data.side === 'SELL' ? 'sell' : 'buy', timestamp, localTimestamp: localTimestamp }; } }; class WooxBookChangeMapper { constructor() { this._symbolToDepthInfoMapping = {}; } canHandle(message) { if ('id' in message) { return message.id.endsWith('@orderbook'); } if ('topic' in message) { return message.topic.endsWith('@orderbookupdate'); } return false; } getFilters(symbols) { symbols = (0, handy_1.upperCaseSymbols)(symbols); return [ { channel: 'orderbook', symbols }, { channel: 'orderbookupdate', symbols } ]; } *map(message, localTimestamp) { const symbol = message.data.symbol; if (this._symbolToDepthInfoMapping[symbol] === undefined) { this._symbolToDepthInfoMapping[symbol] = { bufferedUpdates: [] }; } const symbolDepthInfo = this._symbolToDepthInfoMapping[symbol]; const snapshotAlreadyProcessed = symbolDepthInfo.snapshotProcessed; // first check if received message is snapshot and process it as such if it is if ('id' in message && message.success) { yield { type: 'book_change', symbol, exchange: 'woo-x', isSnapshot: true, bids: message.data.bids.map(this._mapBookLevel), asks: message.data.asks.map(this._mapBookLevel), timestamp: new Date(message.data.ts), localTimestamp }; // mark given symbol depth info that has snapshot processed symbolDepthInfo.lastUpdateTimestamp = message.data.ts; symbolDepthInfo.snapshotProcessed = true; // if there were any depth updates buffered, let's proccess those for (const update of symbolDepthInfo.bufferedUpdates) { const bookChange = this._mapBookDepthUpdate(update, localTimestamp, symbolDepthInfo, symbol); if (bookChange !== undefined) { yield bookChange; } } // remove all buffered updates symbolDepthInfo.bufferedUpdates = []; } else if (snapshotAlreadyProcessed) { // snapshot was already processed let's map the message as normal book_change const bookChange = this._mapBookDepthUpdate(message, localTimestamp, symbolDepthInfo, symbol); if (bookChange !== undefined) { yield bookChange; } } else { // if snapshot hasn't been yet processed and we've got depthUpdate message, let's buffer it for later processing symbolDepthInfo.bufferedUpdates.push(message); } } _mapBookDepthUpdate(wooxBookUpdate, localTimestamp, depthInfo, symbol) { if (wooxBookUpdate.data.prevTs < depthInfo.lastUpdateTimestamp) { return; } return { type: 'book_change', symbol, exchange: 'woo-x', isSnapshot: false, bids: wooxBookUpdate.data.bids.map(this._mapBookLevel), asks: wooxBookUpdate.data.asks.map(this._mapBookLevel), timestamp: new Date(wooxBookUpdate.ts), localTimestamp }; } _mapBookLevel(level) { const price = level[0]; const amount = level[1]; return { price, amount }; } } exports.WooxBookChangeMapper = WooxBookChangeMapper; class WooxDerivativeTickerMapper { constructor() { this.pendingTickerInfoHelper = new mapper_1.PendingTickerInfoHelper(); this._indexPrices = new Map(); } canHandle(message) { if (message.topic === undefined) { return false; } const symbol = (message.data && message.data.symbol) || ''; const isPerp = symbol.startsWith('PERP_'); return ((message.topic.endsWith('@trade') && isPerp) || (message.topic.endsWith('@markprice') && isPerp) || (message.topic.endsWith('@estfundingrate') && isPerp) || message.topic.endsWith('@indexprice') || (message.topic.endsWith('@openinterest') && isPerp)); } getFilters(symbols) { symbols = (0, handy_1.upperCaseSymbols)(symbols); const spotSymbols = symbols !== undefined ? symbols.map((s) => s.replace('PERP_', 'SPOT_')) : []; return [ { channel: 'trade', symbols }, { channel: 'markprice', symbols }, { channel: 'estfundingrate', symbols }, { channel: 'openinterest', symbols }, { channel: 'indexprice', symbols: spotSymbols } ]; } *map(message, localTimestamp) { if (message.topic.endsWith('@indexprice')) { this._indexPrices.set(message.data.symbol.replace('SPOT_', 'PERP_'), message.data.price); } else { const symbol = message.data.symbol; const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(symbol, 'woo-x'); const lastIndexPrice = this._indexPrices.get(symbol); if (lastIndexPrice !== undefined) { pendingTickerInfo.updateIndexPrice(lastIndexPrice); } if (message.topic.endsWith('@markprice')) { pendingTickerInfo.updateMarkPrice(message.data.price); pendingTickerInfo.updateTimestamp(new Date(message.ts)); } if (message.topic.endsWith('@trade')) { pendingTickerInfo.updateLastPrice(message.data.price); pendingTickerInfo.updateTimestamp(new Date(message.ts)); } if (message.topic.endsWith('@estfundingrate')) { pendingTickerInfo.updateFundingRate(message.data.fundingRate); pendingTickerInfo.updateFundingTimestamp(new Date(message.data.fundingTs)); pendingTickerInfo.updateTimestamp(new Date(message.ts)); } if (message.topic.endsWith('@openinterest')) { pendingTickerInfo.updateOpenInterest(message.data.openInterest); pendingTickerInfo.updateTimestamp(new Date(message.ts)); } if (pendingTickerInfo.hasChanged()) { yield pendingTickerInfo.getSnapshot(localTimestamp); } } } } exports.WooxDerivativeTickerMapper = WooxDerivativeTickerMapper; class WooxBookTickerMapper { canHandle(message) { return message.topic !== undefined && message.topic.endsWith('@bbo'); } getFilters(symbols) { symbols = (0, handy_1.upperCaseSymbols)(symbols); return [ { channel: 'bbo', symbols } ]; } *map(wooxBBOMessage, localTimestamp) { const wooxBookTicker = wooxBBOMessage.data; const ticker = { type: 'book_ticker', symbol: wooxBookTicker.symbol, exchange: 'woo-x', askAmount: wooxBookTicker.askSize !== undefined ? wooxBookTicker.askSize : undefined, askPrice: wooxBookTicker.ask !== undefined ? wooxBookTicker.ask : undefined, bidPrice: wooxBookTicker.bid !== undefined ? wooxBookTicker.bid : undefined, bidAmount: wooxBookTicker.bidSize !== undefined ? wooxBookTicker.bidSize : undefined, timestamp: new Date(wooxBBOMessage.ts), localTimestamp: localTimestamp }; yield ticker; } } exports.WooxBookTickerMapper = WooxBookTickerMapper; //# sourceMappingURL=woox.js.map