tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
298 lines • 10.3 kB
JavaScript
import { asNonZeroNumberOrUndefined, upperCaseSymbols } from "../handy.js";
import { PendingTickerInfoHelper } from "./mapper.js";
export class BitgetTradesMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.arg.channel === 'trade' && message.action === 'update';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'trade',
symbols
}
];
}
*map(message, localTimestamp) {
for (let trade of message.data) {
yield {
type: 'trade',
symbol: message.arg.instId,
exchange: this._exchange,
id: trade.tradeId,
price: Number(trade.price),
amount: Number(trade.size),
side: trade.side === 'buy' ? 'buy' : 'sell',
timestamp: new Date(Number(trade.ts)),
localTimestamp: localTimestamp
};
}
}
}
function mapPriceLevel(level) {
return {
price: Number(level[0]),
amount: Number(level[1])
};
}
export class BitgetBookChangeMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.arg.channel === 'books15' && message.action === 'snapshot';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'books15',
symbols
}
];
}
*map(message, localTimestamp) {
for (let orderbookData of message.data) {
yield {
type: 'book_change',
symbol: message.arg.instId,
exchange: this._exchange,
isSnapshot: message.action === 'snapshot',
bids: orderbookData.bids.map(mapPriceLevel),
asks: orderbookData.asks.map(mapPriceLevel),
timestamp: new Date(Number(orderbookData.ts)),
localTimestamp
};
}
}
}
export class BitgetBookTickerMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.arg.channel === 'books1' && message.action === 'snapshot';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: `books1`,
symbols
}
];
}
*map(message, localTimestamp) {
for (const bboMessage of message.data) {
const ticker = {
type: 'book_ticker',
symbol: message.arg.instId,
exchange: this._exchange,
askAmount: bboMessage.asks[0] ? Number(bboMessage.asks[0][1]) : undefined,
askPrice: bboMessage.asks[0] ? Number(bboMessage.asks[0][0]) : undefined,
bidPrice: bboMessage.bids[0] ? Number(bboMessage.bids[0][0]) : undefined,
bidAmount: bboMessage.bids[0] ? Number(bboMessage.bids[0][1]) : undefined,
timestamp: new Date(Number(bboMessage.ts)),
localTimestamp: localTimestamp
};
yield ticker;
}
}
}
export class BitgetDerivativeTickerMapper {
pendingTickerInfoHelper = new PendingTickerInfoHelper();
canHandle(message) {
return message.arg.channel === 'ticker' && message.action === 'snapshot';
}
getFilters(symbols) {
return [
{
channel: 'ticker',
symbols
}
];
}
*map(message, localTimestamp) {
for (const tickerMessage of message.data) {
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(tickerMessage.symbol, 'bitget-futures');
pendingTickerInfo.updateIndexPrice(Number(tickerMessage.indexPrice));
pendingTickerInfo.updateMarkPrice(Number(tickerMessage.markPrice));
pendingTickerInfo.updateOpenInterest(Number(tickerMessage.holdingAmount));
pendingTickerInfo.updateLastPrice(Number(tickerMessage.lastPr));
pendingTickerInfo.updateTimestamp(new Date(Number(tickerMessage.ts)));
if (tickerMessage.nextFundingTime !== '0') {
pendingTickerInfo.updateFundingTimestamp(new Date(Number(tickerMessage.nextFundingTime)));
pendingTickerInfo.updateFundingRate(Number(tickerMessage.fundingRate));
}
if (pendingTickerInfo.hasChanged()) {
yield pendingTickerInfo.getSnapshot(localTimestamp);
}
}
}
}
export class BitgetV3TradesMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.arg.topic === 'publicTrade' && message.action === 'update';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'publicTrade',
symbols
}
];
}
*map(message, localTimestamp) {
for (const trade of message.data) {
yield {
type: 'trade',
symbol: message.arg.symbol,
exchange: this._exchange,
id: trade.i,
price: Number(trade.p),
amount: Number(trade.v),
side: trade.S === 'buy' ? 'buy' : 'sell',
timestamp: new Date(Number(trade.T)),
localTimestamp
};
}
}
}
export class BitgetV3BookChangeMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.arg.topic === 'books' && (message.action === 'snapshot' || message.action === 'update');
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'books',
symbols
}
];
}
*map(message, localTimestamp) {
for (const orderbookData of message.data) {
yield {
type: 'book_change',
symbol: message.arg.symbol,
exchange: this._exchange,
isSnapshot: message.action === 'snapshot',
bids: orderbookData.b.map(mapPriceLevel),
asks: orderbookData.a.map(mapPriceLevel),
timestamp: new Date(Number(orderbookData.ts)),
localTimestamp
};
}
}
}
export class BitgetV3BookTickerMapper {
_exchange;
constructor(_exchange) {
this._exchange = _exchange;
}
canHandle(message) {
return message.arg.topic === 'books1' && message.action === 'snapshot';
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'books1',
symbols
}
];
}
*map(message, localTimestamp) {
for (const bboMessage of message.data) {
yield {
type: 'book_ticker',
symbol: message.arg.symbol,
exchange: this._exchange,
askPrice: asNonZeroNumberOrUndefined(bboMessage.a[0]?.[0]),
askAmount: asNonZeroNumberOrUndefined(bboMessage.a[0]?.[1]),
bidPrice: asNonZeroNumberOrUndefined(bboMessage.b[0]?.[0]),
bidAmount: asNonZeroNumberOrUndefined(bboMessage.b[0]?.[1]),
timestamp: new Date(Number(bboMessage.ts)),
localTimestamp
};
}
}
}
export class BitgetV3DerivativeTickerMapper {
pendingTickerInfoHelper = new PendingTickerInfoHelper();
canHandle(message) {
return message.arg.topic === 'ticker' && (message.action === 'snapshot' || message.action === 'update');
}
getFilters(symbols) {
symbols = upperCaseSymbols(symbols);
return [
{
channel: 'ticker',
symbols
}
];
}
*map(message, localTimestamp) {
for (const tickerMessage of message.data) {
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(message.arg.symbol, 'bitget-futures');
pendingTickerInfo.updateIndexPrice(Number(tickerMessage.indexPrice));
pendingTickerInfo.updateMarkPrice(Number(tickerMessage.markPrice));
pendingTickerInfo.updateOpenInterest(Number(tickerMessage.openInterest));
pendingTickerInfo.updateLastPrice(Number(tickerMessage.lastPrice));
pendingTickerInfo.updateTimestamp(new Date(Number(message.ts)));
if (tickerMessage.nextFundingTime !== '' && tickerMessage.nextFundingTime !== '0') {
pendingTickerInfo.updateFundingTimestamp(new Date(Number(tickerMessage.nextFundingTime)));
pendingTickerInfo.updateFundingRate(Number(tickerMessage.fundingRate));
}
if (pendingTickerInfo.hasChanged()) {
yield pendingTickerInfo.getSnapshot(localTimestamp);
}
}
}
}
export class BitgetV3LiquidationsMapper {
canHandle(message) {
return message.arg.topic === 'liquidation' && message.action === 'update';
}
getFilters() {
return [
{
channel: 'liquidation',
symbols: undefined
}
];
}
*map(message, localTimestamp) {
for (const liquidation of message.data) {
yield {
type: 'liquidation',
symbol: liquidation.symbol,
exchange: 'bitget-futures',
id: undefined,
price: Number(liquidation.price),
amount: Number(liquidation.amount),
// Bitget side is position side, normalized side is the liquidated aggressor side.
side: liquidation.side === 'buy' ? 'sell' : 'buy',
timestamp: new Date(Number(liquidation.ts)),
localTimestamp
};
}
}
}
//# sourceMappingURL=bitget.js.map