tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
796 lines • 32.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OkexBookTickerMapper = exports.OkexLiquidationsMapper = exports.OkexOptionSummaryMapper = exports.OkexDerivativeTickerMapper = exports.OkexBookChangeMapper = exports.OkexTradesMapper = exports.OkexV5OptionSummaryMapper = exports.OkexV5LiquidationsMapper = exports.OkexV5DerivativeTickerMapper = exports.OkexV5BookTickerMapper = exports.OkexV5BookChangeMapper = exports.OkexV5TradesMapper = void 0;
const handy_1 = require("../handy");
const mapper_1 = require("./mapper");
// V5 Okex API mappers
// https://www.okex.com/docs-v5/en/#websocket-api-public-channel-trades-channel
class OkexV5TradesMapper {
constructor(_exchange, _useTradesAll) {
this._exchange = _exchange;
this._useTradesAll = _useTradesAll;
}
canHandle(message) {
if (message.event !== undefined || message.arg === undefined) {
return false;
}
return message.arg.channel === 'trades' || message.arg.channel === 'trades-all';
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
if (this._useTradesAll) {
return [
{
channel: `trades-all`,
symbols
}
];
}
return [
{
channel: `trades`,
symbols
}
];
}
*map(okexTradesMessage, localTimestamp) {
for (const okexTrade of okexTradesMessage.data) {
yield {
type: 'trade',
symbol: okexTrade.instId,
exchange: this._exchange,
id: okexTrade.tradeId,
price: Number(okexTrade.px),
amount: Number(okexTrade.sz),
side: okexTrade.side === 'buy' ? 'buy' : 'sell',
timestamp: new Date(Number(okexTrade.ts)),
localTimestamp: localTimestamp
};
}
}
}
exports.OkexV5TradesMapper = OkexV5TradesMapper;
const mapV5BookLevel = (level) => {
const price = Number(level[0]);
const amount = Number(level[1]);
return { price, amount };
};
class OkexV5BookChangeMapper {
constructor(_exchange, usePublicBooksChannel) {
this._exchange = _exchange;
this._hasCredentials = process.env.OKX_API_KEY !== undefined;
this._hasVip5Access = process.env.OKX_API_VIP_5 !== undefined;
this._hasColoAccess = process.env.OKX_API_COLO !== undefined;
this._channelName = this._getBooksChannelName(usePublicBooksChannel);
}
canHandle(message) {
if (message.event !== undefined || message.arg === undefined) {
return false;
}
return message.arg.channel === this._channelName;
}
_getBooksChannelName(usePublicBooksChannel) {
if (usePublicBooksChannel === false) {
// historical data always uses books-l2-tbt
return 'books-l2-tbt';
}
if (this._hasCredentials && this._hasVip5Access) {
return 'books-l2-tbt';
}
if (this._hasColoAccess) {
return 'books-l2-tbt';
}
if (this._hasCredentials) {
return 'books50-l2-tbt';
}
return 'books';
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
return [
{
channel: this._channelName,
symbols
}
];
}
*map(okexDepthDataMessage, localTimestamp) {
for (const message of okexDepthDataMessage.data) {
if (okexDepthDataMessage.action === 'update' && message.bids.length === 0 && message.asks.length === 0) {
continue;
}
const timestamp = new Date(Number(message.ts));
if (timestamp.valueOf() === 0) {
continue;
}
yield {
type: 'book_change',
symbol: okexDepthDataMessage.arg.instId,
exchange: this._exchange,
isSnapshot: okexDepthDataMessage.action === 'snapshot',
bids: message.bids.map(mapV5BookLevel),
asks: message.asks.map(mapV5BookLevel),
timestamp,
localTimestamp: localTimestamp
};
}
}
}
exports.OkexV5BookChangeMapper = OkexV5BookChangeMapper;
class OkexV5BookTickerMapper {
constructor(_exchange, _useTbtTickerChannel) {
this._exchange = _exchange;
this._useTbtTickerChannel = _useTbtTickerChannel;
}
canHandle(message) {
if (message.event !== undefined || message.arg === undefined) {
return false;
}
if (this._useTbtTickerChannel) {
return message.arg.channel === 'bbo-tbt';
}
return message.arg.channel === 'tickers';
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
if (this._useTbtTickerChannel) {
return [
{
channel: `bbo-tbt`,
symbols
}
];
}
return [
{
channel: `tickers`,
symbols
}
];
}
map(message, localTimestamp) {
if (message.arg.channel === 'bbo-tbt') {
return this._mapFromTbtTicker(message, localTimestamp);
}
else {
return this._mapFromTicker(message, localTimestamp);
}
}
*_mapFromTbtTicker(message, localTimestamp) {
if (!message.data) {
return;
}
for (const tbtTicker of message.data) {
const bestAsk = tbtTicker.asks !== undefined && tbtTicker.asks[0] ? mapBookLevel(tbtTicker.asks[0]) : undefined;
const bestBid = tbtTicker.bids !== undefined && tbtTicker.bids[0] ? mapBookLevel(tbtTicker.bids[0]) : undefined;
const ticker = {
type: 'book_ticker',
symbol: message.arg.instId,
exchange: this._exchange,
askAmount: bestAsk === null || bestAsk === void 0 ? void 0 : bestAsk.amount,
askPrice: bestAsk === null || bestAsk === void 0 ? void 0 : bestAsk.price,
bidPrice: bestBid === null || bestBid === void 0 ? void 0 : bestBid.price,
bidAmount: bestBid === null || bestBid === void 0 ? void 0 : bestBid.amount,
timestamp: new Date(Number(tbtTicker.ts)),
localTimestamp: localTimestamp
};
yield ticker;
}
}
*_mapFromTicker(message, localTimestamp) {
for (const okexTicker of message.data) {
const ticker = {
type: 'book_ticker',
symbol: okexTicker.instId,
exchange: this._exchange,
askAmount: (0, handy_1.asNumberIfValid)(okexTicker.askSz),
askPrice: (0, handy_1.asNumberIfValid)(okexTicker.askPx),
bidPrice: (0, handy_1.asNumberIfValid)(okexTicker.bidPx),
bidAmount: (0, handy_1.asNumberIfValid)(okexTicker.bidSz),
timestamp: new Date(Number(okexTicker.ts)),
localTimestamp: localTimestamp
};
yield ticker;
}
}
}
exports.OkexV5BookTickerMapper = OkexV5BookTickerMapper;
class OkexV5DerivativeTickerMapper {
constructor(_exchange) {
this._exchange = _exchange;
this.pendingTickerInfoHelper = new mapper_1.PendingTickerInfoHelper();
this._indexPrices = new Map();
this._futuresChannels = ['tickers', 'open-interest', 'mark-price', 'index-tickers'];
this._swapChannels = ['tickers', 'open-interest', 'mark-price', 'index-tickers', 'funding-rate'];
}
canHandle(message) {
const channels = this._exchange === 'okex-futures' ? this._futuresChannels : this._swapChannels;
if (message.event !== undefined || message.arg === undefined) {
return false;
}
return channels.includes(message.arg.channel);
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
const channels = this._exchange === 'okex-futures' ? this._futuresChannels : this._swapChannels;
return channels.map((channel) => {
if (channel === 'index-tickers') {
const indexes = symbols !== undefined
? symbols.map((s) => {
const symbolParts = s.split('-');
const quotePart = symbolParts[1] === 'USDC' ? 'USD' : symbolParts[1];
return `${symbolParts[0]}-${quotePart}`;
})
: undefined;
return {
channel,
symbols: indexes
};
}
return {
channel,
symbols
};
});
}
*map(message, localTimestamp) {
if (message.arg.channel === 'index-tickers') {
for (const dataMessage of message.data) {
const indexTickerMessage = dataMessage;
const lastIndexPrice = Number(indexTickerMessage.idxPx);
if (lastIndexPrice > 0) {
this._indexPrices.set(indexTickerMessage.instId, lastIndexPrice);
}
}
return;
}
for (const dataMessage of message.data) {
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(dataMessage.instId, this._exchange);
const symbolParts = dataMessage.instId.split('-');
const quotePart = symbolParts[1] === 'USDC' ? 'USD' : symbolParts[1];
const indexSymbol = `${symbolParts[0]}-${quotePart}`;
const indexPrice = this._indexPrices.get(indexSymbol);
if (indexPrice !== undefined) {
pendingTickerInfo.updateIndexPrice(indexPrice);
}
if (message.arg.channel === 'mark-price') {
const markPriceMessage = dataMessage;
const markPrice = Number(markPriceMessage.markPx);
if (markPrice > 0) {
pendingTickerInfo.updateMarkPrice(markPrice);
pendingTickerInfo.updateTimestamp(new Date(Number(markPriceMessage.ts)));
}
}
if (message.arg.channel === 'open-interest') {
const openInterestMessage = dataMessage;
const openInterest = Number(openInterestMessage.oi);
if (openInterest > 0) {
pendingTickerInfo.updateOpenInterest(openInterest);
pendingTickerInfo.updateTimestamp(new Date(Number(openInterestMessage.ts)));
}
}
if (message.arg.channel === 'funding-rate') {
const fundingRateMessage = dataMessage;
if (fundingRateMessage.fundingRate !== undefined) {
pendingTickerInfo.updateFundingRate(Number(fundingRateMessage.fundingRate));
}
if (fundingRateMessage.fundingTime !== undefined) {
pendingTickerInfo.updateFundingTimestamp(new Date(Number(fundingRateMessage.fundingTime)));
}
if (fundingRateMessage.nextFundingRate !== undefined && fundingRateMessage.nextFundingRate !== '') {
pendingTickerInfo.updatePredictedFundingRate(Number(fundingRateMessage.nextFundingRate));
}
}
if (message.arg.channel === 'tickers') {
const tickerMessage = dataMessage;
const lastPrice = Number(tickerMessage.last);
if (lastPrice > 0) {
pendingTickerInfo.updateLastPrice(lastPrice);
pendingTickerInfo.updateTimestamp(new Date(Number(tickerMessage.ts)));
}
}
if (pendingTickerInfo.hasChanged()) {
yield pendingTickerInfo.getSnapshot(localTimestamp);
}
}
}
}
exports.OkexV5DerivativeTickerMapper = OkexV5DerivativeTickerMapper;
class OkexV5LiquidationsMapper {
constructor(_exchange) {
this._exchange = _exchange;
this._isFirstMessage = true;
}
canHandle(message) {
if (message.event !== undefined || message.arg === undefined) {
return false;
}
return message.arg.channel === 'liquidations' || message.arg.channel === 'liquidation-orders';
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
return [
{
channel: 'liquidations',
symbols
},
{
channel: 'liquidation-orders',
symbols
}
];
}
*map(okexLiquidationMessage, localTimestamp) {
if (okexLiquidationMessage.arg.channel === 'liquidation-orders') {
if (this._isFirstMessage) {
this._isFirstMessage = false;
return;
}
for (const okexLiquidation of okexLiquidationMessage.data) {
for (const detail of okexLiquidation.details) {
const liquidation = {
type: 'liquidation',
symbol: okexLiquidation.instId,
exchange: this._exchange,
id: undefined,
price: Number(detail.bkPx),
amount: Number(detail.sz),
side: detail.side === 'buy' ? 'buy' : 'sell',
timestamp: new Date(Number(detail.ts)),
localTimestamp: localTimestamp
};
yield liquidation;
}
}
}
else {
for (const okexLiquidation of okexLiquidationMessage.data) {
const liquidation = {
type: 'liquidation',
symbol: okexLiquidationMessage.arg.instId,
exchange: this._exchange,
id: undefined,
price: Number(okexLiquidation.bkPx),
amount: Number(okexLiquidation.sz),
side: okexLiquidation.side === 'buy' ? 'buy' : 'sell',
timestamp: new Date(Number(okexLiquidation.ts)),
localTimestamp: localTimestamp
};
yield liquidation;
}
}
}
}
exports.OkexV5LiquidationsMapper = OkexV5LiquidationsMapper;
class OkexV5OptionSummaryMapper {
constructor() {
this._indexPrices = new Map();
this._openInterests = new Map();
this._markPrices = new Map();
this._tickers = new Map();
this.expiration_regex = /(\d{2})(\d{2})(\d{2})/;
}
canHandle(message) {
if (message.event !== undefined || message.arg === undefined) {
return false;
}
return (message.arg.channel === 'opt-summary' ||
message.arg.channel === 'index-tickers' ||
message.arg.channel === 'tickers' ||
message.arg.channel === 'open-interest' ||
message.arg.channel === 'mark-price');
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
const indexes = symbols !== undefined
? symbols.map((s) => {
const symbolParts = s.split('-');
return `${symbolParts[0]}-${symbolParts[1]}`;
})
: undefined;
return [
{
channel: `opt-summary`,
symbols: []
},
{
channel: `index-tickers`,
symbols: indexes
},
{
channel: `tickers`,
symbols: symbols
},
{
channel: `open-interest`,
symbols: symbols
},
{
channel: `mark-price`,
symbols: symbols
}
];
}
*map(message, localTimestamp) {
if (message.arg.channel === 'index-tickers') {
for (const dataMessage of message.data) {
const indexTickerMessage = dataMessage;
const lastIndexPrice = (0, handy_1.asNumberIfValid)(indexTickerMessage.idxPx);
if (lastIndexPrice !== undefined) {
this._indexPrices.set(indexTickerMessage.instId, lastIndexPrice);
}
}
return;
}
if (message.arg.channel === 'open-interest') {
for (const dataMessage of message.data) {
const openInterestMessage = dataMessage;
const openInterestValue = (0, handy_1.asNumberIfValid)(openInterestMessage.oi);
if (openInterestValue !== undefined) {
this._openInterests.set(openInterestMessage.instId, openInterestValue);
}
}
return;
}
if (message.arg.channel === 'mark-price') {
for (const dataMessage of message.data) {
const markPriceMessage = dataMessage;
const markPrice = (0, handy_1.asNumberIfValid)(markPriceMessage.markPx);
if (markPrice !== undefined) {
this._markPrices.set(markPriceMessage.instId, markPrice);
}
}
return;
}
if (message.arg.channel === 'tickers') {
for (const dataMessage of message.data) {
const tickerMessage = dataMessage;
this._tickers.set(tickerMessage.instId, tickerMessage);
}
return;
}
if (message.arg.channel === 'opt-summary') {
for (const dataMessage of message.data) {
const summary = dataMessage;
const symbolParts = summary.instId.split('-');
const isPut = symbolParts[4] === 'P';
const strikePrice = Number(symbolParts[3]);
var dateArray = this.expiration_regex.exec(symbolParts[2]);
const expirationDate = new Date(Date.UTC(+('20' + dateArray[1]), +dateArray[2] - 1, +dateArray[3], 8, 0, 0, 0));
const lastUnderlyingPrice = this._indexPrices.get(summary.uly);
const lastOpenInterest = this._openInterests.get(summary.instId);
const lastMarkPrice = this._markPrices.get(summary.instId);
const lastTickerInfo = this._tickers.get(summary.instId);
const optionSummary = {
type: 'option_summary',
symbol: summary.instId,
exchange: 'okex-options',
optionType: isPut ? 'put' : 'call',
strikePrice,
expirationDate,
bestBidPrice: lastTickerInfo !== undefined ? (0, handy_1.asNumberIfValid)(lastTickerInfo.bidPx) : undefined,
bestBidAmount: lastTickerInfo !== undefined ? (0, handy_1.asNumberIfValid)(lastTickerInfo.bidSz) : undefined,
bestBidIV: (0, handy_1.asNumberIfValid)(summary.bidVol),
bestAskPrice: lastTickerInfo !== undefined ? (0, handy_1.asNumberIfValid)(lastTickerInfo.askPx) : undefined,
bestAskAmount: lastTickerInfo !== undefined ? (0, handy_1.asNumberIfValid)(lastTickerInfo.askSz) : undefined,
bestAskIV: (0, handy_1.asNumberIfValid)(summary.askVol),
lastPrice: lastTickerInfo !== undefined ? (0, handy_1.asNumberIfValid)(lastTickerInfo.last) : undefined,
openInterest: lastOpenInterest,
markPrice: lastMarkPrice,
markIV: (0, handy_1.asNumberIfValid)(summary.markVol),
delta: (0, handy_1.asNumberIfValid)(summary.delta),
gamma: (0, handy_1.asNumberIfValid)(summary.gamma),
vega: (0, handy_1.asNumberIfValid)(summary.vega),
theta: (0, handy_1.asNumberIfValid)(summary.theta),
rho: undefined,
underlyingPrice: lastUnderlyingPrice,
underlyingIndex: summary.uly,
timestamp: new Date(Number(summary.ts)),
localTimestamp: localTimestamp
};
yield optionSummary;
}
}
}
}
exports.OkexV5OptionSummaryMapper = OkexV5OptionSummaryMapper;
//---
//V3 Okex API mappers
// https://www.okex.com/docs/en/#ws_swap-README
class OkexTradesMapper {
constructor(_exchange, _market) {
this._exchange = _exchange;
this._market = _market;
}
canHandle(message) {
return message.table === `${this._market}/trade`;
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
return [
{
channel: `${this._market}/trade`,
symbols
}
];
}
*map(okexTradesMessage, localTimestamp) {
for (const okexTrade of okexTradesMessage.data) {
const symbol = okexTrade.instrument_id;
yield {
type: 'trade',
symbol,
exchange: this._exchange,
id: typeof okexTrade.trade_id === 'string' ? okexTrade.trade_id : undefined,
price: Number(okexTrade.price),
amount: okexTrade.qty !== undefined ? Number(okexTrade.qty) : Number(okexTrade.size),
side: okexTrade.side,
timestamp: new Date(okexTrade.timestamp),
localTimestamp: localTimestamp
};
}
}
}
exports.OkexTradesMapper = OkexTradesMapper;
const mapBookLevel = (level) => {
const price = Number(level[0]);
const amount = Number(level[1]);
return { price, amount };
};
class OkexBookChangeMapper {
constructor(_exchange, _market, _canUseTickByTickChannel) {
this._exchange = _exchange;
this._market = _market;
this._canUseTickByTickChannel = _canUseTickByTickChannel;
}
canHandle(message) {
const channelSuffix = this._canUseTickByTickChannel ? 'depth_l2_tbt' : 'depth';
return message.table === `${this._market}/${channelSuffix}`;
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
if (this._canUseTickByTickChannel) {
return [
{
channel: `${this._market}/depth_l2_tbt`,
symbols
}
];
}
// subscribe to both book channels and in canHandle decide which one to use
// as one can subscribe to date range period that overlaps both when only depth channel has been available
// and when both were available (both depth and depth_l2_tbt)
return [
{
channel: `${this._market}/depth_l2_tbt`,
symbols
},
{
channel: `${this._market}/depth`,
symbols
}
];
}
*map(okexDepthDataMessage, localTimestamp) {
for (const message of okexDepthDataMessage.data) {
if (message.bids.length === 0 && message.asks.length === 0 && okexDepthDataMessage.action !== 'partial') {
continue;
}
const timestamp = new Date(message.timestamp);
if (timestamp.valueOf() === 0) {
continue;
}
yield {
type: 'book_change',
symbol: message.instrument_id,
exchange: this._exchange,
isSnapshot: okexDepthDataMessage.action === 'partial',
bids: message.bids.map(mapBookLevel),
asks: message.asks.map(mapBookLevel),
timestamp,
localTimestamp: localTimestamp
};
}
}
}
exports.OkexBookChangeMapper = OkexBookChangeMapper;
class OkexDerivativeTickerMapper {
constructor(_exchange) {
this._exchange = _exchange;
this.pendingTickerInfoHelper = new mapper_1.PendingTickerInfoHelper();
this._futuresChannels = ['futures/ticker', 'futures/mark_price'];
this._swapChannels = ['swap/ticker', 'swap/mark_price', 'swap/funding_rate'];
}
canHandle(message) {
const channels = this._exchange === 'okex-futures' ? this._futuresChannels : this._swapChannels;
return channels.includes(message.table);
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
const channels = this._exchange === 'okex-futures' ? this._futuresChannels : this._swapChannels;
return channels.map((channel) => {
return {
channel,
symbols
};
});
}
*map(message, localTimestamp) {
for (const okexMessage of message.data) {
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(okexMessage.instrument_id, this._exchange);
if ('funding_rate' in okexMessage) {
pendingTickerInfo.updateFundingRate(Number(okexMessage.funding_rate));
pendingTickerInfo.updateFundingTimestamp(new Date(okexMessage.funding_time));
if (okexMessage.estimated_rate !== undefined) {
pendingTickerInfo.updatePredictedFundingRate(Number(okexMessage.estimated_rate));
}
}
if ('mark_price' in okexMessage) {
pendingTickerInfo.updateMarkPrice(Number(okexMessage.mark_price));
}
if ('open_interest' in okexMessage) {
const openInterest = Number(okexMessage.open_interest);
if (openInterest > 0) {
pendingTickerInfo.updateOpenInterest(Number(okexMessage.open_interest));
}
}
if ('last' in okexMessage) {
pendingTickerInfo.updateLastPrice(Number(okexMessage.last));
}
if (okexMessage.timestamp !== undefined) {
pendingTickerInfo.updateTimestamp(new Date(okexMessage.timestamp));
}
if (pendingTickerInfo.hasChanged()) {
yield pendingTickerInfo.getSnapshot(localTimestamp);
}
}
}
}
exports.OkexDerivativeTickerMapper = OkexDerivativeTickerMapper;
class OkexOptionSummaryMapper {
constructor() {
this._indexPrices = new Map();
this.expiration_regex = /(\d{2})(\d{2})(\d{2})/;
}
canHandle(message) {
return message.table === 'index/ticker' || message.table === 'option/summary';
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
const indexes = symbols !== undefined
? symbols.map((s) => {
const symbolParts = s.split('-');
return `${symbolParts[0]}-${symbolParts[1]}`;
})
: undefined;
return [
{
channel: `option/summary`,
symbols
},
{
channel: `index/ticker`,
symbols: indexes
}
];
}
*map(message, localTimestamp) {
if (message.table === 'index/ticker') {
for (const index of message.data) {
const lastIndexPrice = Number(index.last);
if (lastIndexPrice > 0) {
this._indexPrices.set(index.instrument_id, lastIndexPrice);
}
}
return;
}
for (const summary of message.data) {
const symbolParts = summary.instrument_id.split('-');
const isPut = symbolParts[4] === 'P';
const strikePrice = Number(symbolParts[3]);
var dateArray = this.expiration_regex.exec(symbolParts[2]);
const expirationDate = new Date(Date.UTC(+('20' + dateArray[1]), +dateArray[2] - 1, +dateArray[3], 8, 0, 0, 0));
const lastUnderlyingPrice = this._indexPrices.get(summary.underlying);
const optionSummary = {
type: 'option_summary',
symbol: summary.instrument_id,
exchange: 'okex-options',
optionType: isPut ? 'put' : 'call',
strikePrice,
expirationDate,
bestBidPrice: (0, handy_1.asNumberIfValid)(summary.best_bid),
bestBidAmount: (0, handy_1.asNumberIfValid)(summary.best_bid_size),
bestBidIV: (0, handy_1.asNumberIfValid)(summary.bid_vol),
bestAskPrice: (0, handy_1.asNumberIfValid)(summary.best_ask),
bestAskAmount: (0, handy_1.asNumberIfValid)(summary.best_ask_size),
bestAskIV: (0, handy_1.asNumberIfValid)(summary.ask_vol),
lastPrice: (0, handy_1.asNumberIfValid)(summary.last),
openInterest: (0, handy_1.asNumberIfValid)(summary.open_interest),
markPrice: (0, handy_1.asNumberIfValid)(summary.mark_price),
markIV: (0, handy_1.asNumberIfValid)(summary.mark_vol),
delta: (0, handy_1.asNumberIfValid)(summary.delta),
gamma: (0, handy_1.asNumberIfValid)(summary.gamma),
vega: (0, handy_1.asNumberIfValid)(summary.vega),
theta: (0, handy_1.asNumberIfValid)(summary.theta),
rho: undefined,
underlyingPrice: lastUnderlyingPrice,
underlyingIndex: summary.underlying,
timestamp: new Date(summary.timestamp),
localTimestamp: localTimestamp
};
yield optionSummary;
}
}
}
exports.OkexOptionSummaryMapper = OkexOptionSummaryMapper;
class OkexLiquidationsMapper {
constructor(_exchange, _market) {
this._exchange = _exchange;
this._market = _market;
}
canHandle(message) {
return message.table === `${this._market}/liquidation`;
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
return [
{
channel: `${this._market}/liquidation`,
symbols
}
];
}
*map(okexLiquidationDataMessage, localTimestamp) {
for (const okexLiquidation of okexLiquidationDataMessage.data) {
const liquidation = {
type: 'liquidation',
symbol: okexLiquidation.instrument_id,
exchange: this._exchange,
id: undefined,
price: Number(okexLiquidation.price),
amount: Number(okexLiquidation.size),
side: okexLiquidation.type === '3' ? 'sell' : 'buy',
timestamp: new Date(okexLiquidation.created_at),
localTimestamp: localTimestamp
};
yield liquidation;
}
}
}
exports.OkexLiquidationsMapper = OkexLiquidationsMapper;
class OkexBookTickerMapper {
constructor(_exchange, _market) {
this._exchange = _exchange;
this._market = _market;
}
canHandle(message) {
return message.table === `${this._market}/ticker`;
}
getFilters(symbols) {
symbols = (0, handy_1.upperCaseSymbols)(symbols);
return [
{
channel: `${this._market}/ticker`,
symbols
}
];
}
*map(message, localTimestamp) {
for (const okexTicker of message.data) {
const ticker = {
type: 'book_ticker',
symbol: okexTicker.instrument_id,
exchange: this._exchange,
askAmount: (0, handy_1.asNumberIfValid)(okexTicker.best_ask_size),
askPrice: (0, handy_1.asNumberIfValid)(okexTicker.best_ask),
bidPrice: (0, handy_1.asNumberIfValid)(okexTicker.best_bid),
bidAmount: (0, handy_1.asNumberIfValid)(okexTicker.best_bid_size),
timestamp: new Date(okexTicker.timestamp),
localTimestamp: localTimestamp
};
yield ticker;
}
}
}
exports.OkexBookTickerMapper = OkexBookTickerMapper;
//# sourceMappingURL=okex.js.map