tardis-dev
Version: 
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
190 lines • 7.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DydxDerivativeTickerMapper = exports.DydxBookChangeMapper = exports.DydxTradesMapper = void 0;
const handy_1 = require("../handy");
const mapper_1 = require("./mapper");
class DydxTradesMapper {
    canHandle(message) {
        return message.channel === 'v3_trades' && message.type === 'channel_data';
    }
    getFilters(symbols) {
        symbols = (0, handy_1.upperCaseSymbols)(symbols);
        return [
            {
                channel: 'v3_trades',
                symbols
            }
        ];
    }
    *map(message, localTimestamp) {
        for (let trade of message.contents.trades) {
            yield {
                type: 'trade',
                symbol: message.id,
                exchange: 'dydx',
                id: undefined,
                price: Number(trade.price),
                amount: Number(trade.size),
                side: trade.side === 'SELL' ? 'sell' : 'buy',
                timestamp: trade.createdAt ? new Date(trade.createdAt) : localTimestamp,
                localTimestamp: localTimestamp
            };
        }
    }
}
exports.DydxTradesMapper = DydxTradesMapper;
class DydxBookChangeMapper {
    constructor() {
        this._bidsOffsets = {};
        this._asksOffsets = {};
    }
    canHandle(message) {
        return message.channel === 'v3_orderbook';
    }
    getFilters(symbols) {
        symbols = (0, handy_1.upperCaseSymbols)(symbols);
        return [
            {
                channel: 'v3_orderbook',
                symbols
            }
        ];
    }
    *map(message, localTimestamp) {
        if (message.type === 'subscribed') {
            this._bidsOffsets[message.id] = {};
            this._asksOffsets[message.id] = {};
            yield {
                type: 'book_change',
                symbol: message.id,
                exchange: 'dydx',
                isSnapshot: true,
                bids: message.contents.bids.map((bid) => {
                    this._bidsOffsets[message.id][bid.price] = Number(bid.offset);
                    return {
                        price: Number(bid.price),
                        amount: Number(bid.size)
                    };
                }),
                asks: message.contents.asks.map((ask) => {
                    this._asksOffsets[message.id][ask.price] = Number(ask.offset);
                    return {
                        price: Number(ask.price),
                        amount: Number(ask.size)
                    };
                }),
                timestamp: localTimestamp,
                localTimestamp
            };
        }
        else {
            if (!message.contents) {
                return;
            }
            // https://docs.dydx.exchange/#orderbook
            const updateOffset = Number(message.contents.offset);
            const bookChange = {
                type: 'book_change',
                symbol: message.id,
                exchange: 'dydx',
                isSnapshot: false,
                bids: message.contents.bids
                    .map((bid) => {
                    const lastPriceLevelOffset = this._bidsOffsets[message.id] && this._bidsOffsets[message.id][bid[0]];
                    if (lastPriceLevelOffset !== undefined && lastPriceLevelOffset >= updateOffset) {
                        return;
                    }
                    return {
                        price: Number(bid[0]),
                        amount: Number(bid[1])
                    };
                })
                    .filter((b) => b !== undefined),
                asks: message.contents.asks
                    .map((ask) => {
                    const lastPriceLevelOffset = this._asksOffsets[message.id] && this._asksOffsets[message.id][ask[0]];
                    if (lastPriceLevelOffset !== undefined && lastPriceLevelOffset >= updateOffset) {
                        return;
                    }
                    return {
                        price: Number(ask[0]),
                        amount: Number(ask[1])
                    };
                })
                    .filter((b) => b !== undefined),
                timestamp: localTimestamp,
                localTimestamp
            };
            if (!this._bidsOffsets[message.id]) {
                this._bidsOffsets[message.id] = {};
            }
            for (const bid of message.contents.bids) {
                this._bidsOffsets[message.id][bid[0]] = updateOffset;
            }
            if (!this._asksOffsets[message.id]) {
                this._asksOffsets[message.id] = {};
            }
            for (const ask of message.contents.asks) {
                this._asksOffsets[message.id][ask[0]] = updateOffset;
            }
            if (bookChange.bids.length > 0 || bookChange.asks.length > 0) {
                yield bookChange;
            }
        }
    }
}
exports.DydxBookChangeMapper = DydxBookChangeMapper;
class DydxDerivativeTickerMapper {
    constructor() {
        this.pendingTickerInfoHelper = new mapper_1.PendingTickerInfoHelper();
    }
    canHandle(message) {
        return message.channel === 'v3_markets' || (message.channel === 'v3_trades' && message.type === 'channel_data');
    }
    getFilters(symbols) {
        symbols = (0, handy_1.upperCaseSymbols)(symbols);
        return [
            {
                channel: 'v3_markets',
                symbols: []
            },
            {
                channel: 'v3_trades',
                symbols
            }
        ];
    }
    *map(message, localTimestamp) {
        if (message.channel === 'v3_trades') {
            const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(message.id, 'dydx');
            pendingTickerInfo.updateLastPrice(Number(message.contents.trades[message.contents.trades.length - 1].price));
            return;
        }
        const contents = message.type === 'subscribed' ? message.contents.markets : message.contents;
        for (const key in contents) {
            const marketInfo = contents[key];
            const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(key, 'dydx');
            if (marketInfo.indexPrice !== undefined) {
                pendingTickerInfo.updateIndexPrice(Number(marketInfo.indexPrice));
            }
            if (marketInfo.oraclePrice !== undefined) {
                pendingTickerInfo.updateMarkPrice(Number(marketInfo.oraclePrice));
            }
            if (marketInfo.openInterest !== undefined) {
                pendingTickerInfo.updateOpenInterest(Number(marketInfo.openInterest));
            }
            if (marketInfo.nextFundingRate !== undefined) {
                pendingTickerInfo.updateFundingRate(Number(marketInfo.nextFundingRate));
            }
            if (marketInfo.nextFundingAt !== undefined) {
                pendingTickerInfo.updateFundingTimestamp(new Date(marketInfo.nextFundingAt));
            }
            pendingTickerInfo.updateTimestamp(localTimestamp);
            if (pendingTickerInfo.hasChanged()) {
                yield pendingTickerInfo.getSnapshot(localTimestamp);
            }
        }
    }
}
exports.DydxDerivativeTickerMapper = DydxDerivativeTickerMapper;
//# sourceMappingURL=dydx.js.map