tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
174 lines • 6.73 kB
JavaScript
import { upperCaseSymbols } from "../handy.js";
import { PendingTickerInfoHelper } from "./mapper.js";
// https://www.gate.io/docs/futures/ws/index.html
export class GateIOFuturesTradesMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.channel === 'futures.trades' && message.event === 'update';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'trades',
symbols
}
];
}
*map(tradesMessage, localTimestamp) {
for (const trade of tradesMessage.result) {
const timestamp = trade.create_time_ms !== undefined ? new Date(trade.create_time_ms) : new Date(trade.create_time * 1000);
const size = Number(trade.size);
yield {
type: 'trade',
symbol: trade.contract,
exchange: this._exchange,
id: trade.id.toString(),
price: Number(trade.price),
amount: Math.abs(size),
side: size < 0 ? 'sell' : 'buy',
timestamp,
localTimestamp: localTimestamp
};
}
}
}
const mapBookLevel = (level) => {
const price = Number(level.p);
const size = Number(level.s);
return { price, amount: Math.abs(size) };
};
export class GateIOFuturesBookChangeMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.channel === 'futures.order_book' && (message.event === 'all' || message.event === 'update');
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'order_book',
symbols
}
];
}
*map(depthMessage, localTimestamp) {
if (depthMessage.event === 'all') {
if (depthMessage.result.t === 0) {
return;
}
const timestamp = depthMessage.time_ms !== undefined
? new Date(depthMessage.time_ms)
: depthMessage.result.t !== undefined
? new Date(depthMessage.result.t)
: new Date(depthMessage.time * 1000);
// snapshot
yield {
type: 'book_change',
symbol: depthMessage.result.contract,
exchange: this._exchange,
isSnapshot: true,
bids: depthMessage.result.bids.map(mapBookLevel),
asks: depthMessage.result.asks.map(mapBookLevel),
timestamp,
localTimestamp: localTimestamp
};
}
else if (depthMessage.result.length > 0) {
// update
const timestamp = depthMessage.result[0].t !== undefined ? new Date(depthMessage.result[0].t) : new Date(depthMessage.time * 1000);
yield {
type: 'book_change',
symbol: depthMessage.result[0].c,
exchange: this._exchange,
isSnapshot: false,
bids: depthMessage.result.filter((l) => Number(l.s) >= 0).map(mapBookLevel),
asks: depthMessage.result.filter((l) => Number(l.s) <= 0).map(mapBookLevel),
timestamp,
localTimestamp: localTimestamp
};
}
}
}
export class GateIOFuturesDerivativeTickerMapper {
pendingTickerInfoHelper = new PendingTickerInfoHelper();
canHandle(message) {
return message.channel === 'futures.tickers' && message.event === 'update';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'tickers',
symbols
}
];
}
*map(message, localTimestamp) {
const tickers = Array.isArray(message.result) ? message.result : [message.result];
for (const futuresTicker of tickers) {
if (futuresTicker.contract === undefined) {
return;
}
const timestamp = message.time_ms !== undefined ? new Date(message.time_ms) : new Date(message.time * 1000);
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(futuresTicker.contract, 'gate-io-futures');
pendingTickerInfo.updateFundingRate(Number(futuresTicker.funding_rate));
pendingTickerInfo.updatePredictedFundingRate(Number(futuresTicker.funding_rate_indicative));
pendingTickerInfo.updateIndexPrice(Number(futuresTicker.index_price));
pendingTickerInfo.updateMarkPrice(Number(futuresTicker.mark_price));
pendingTickerInfo.updateLastPrice(Number(futuresTicker.last));
pendingTickerInfo.updateTimestamp(timestamp);
if (futuresTicker.total_size !== undefined) {
pendingTickerInfo.updateOpenInterest(Number(futuresTicker.total_size));
}
if (pendingTickerInfo.hasChanged()) {
yield pendingTickerInfo.getSnapshot(localTimestamp);
}
}
}
}
export class GateIOFuturesBookTickerMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.channel === 'futures.book_ticker' && message.event === 'update';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'book_ticker',
symbols
}
];
}
*map(gateIoFuturesBookTickerMessage, localTimestamp) {
const gateIoFuturesBookTicker = gateIoFuturesBookTickerMessage.result;
const askAmount = Number(gateIoFuturesBookTicker.A);
const bidAmount = Number(gateIoFuturesBookTicker.B);
if (gateIoFuturesBookTicker.t === 0) {
return;
}
const ticker = {
type: 'book_ticker',
symbol: gateIoFuturesBookTicker.s,
exchange: this._exchange,
askAmount: askAmount !== 0 ? askAmount : undefined,
askPrice: gateIoFuturesBookTicker.a !== '' ? Number(gateIoFuturesBookTicker.a) : undefined,
bidPrice: gateIoFuturesBookTicker.b !== '' ? Number(gateIoFuturesBookTicker.b) : undefined,
bidAmount: bidAmount !== 0 ? bidAmount : undefined,
timestamp: gateIoFuturesBookTicker.t !== undefined ? new Date(gateIoFuturesBookTicker.t) : localTimestamp,
localTimestamp: localTimestamp
};
yield ticker;
}
}
//# sourceMappingURL=gateiofutures.js.map