tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
172 lines (148 loc) • 4.65 kB
text/typescript
import { upperCaseSymbols } from '../handy'
import { BookChange, BookTicker, Trade } from '../types'
import { Mapper } from './mapper'
// https://docs.binance.org/api-reference/dex-api/ws-streams.html
export const binanceDexTradesMapper: Mapper<'binance-dex', Trade> = {
canHandle(message: BinanceDexResponse<any>) {
return message.stream === 'trades'
},
getFilters(symbols?: string[]) {
symbols = upperCaseSymbols(symbols)
return [
{
channel: 'trades',
symbols
}
]
},
*map(binanceDexTradeResponse: BinanceDexResponse<BinanceDexTradeData>, localTimestamp: Date): IterableIterator<Trade> {
for (const binanceDexTrade of binanceDexTradeResponse.data) {
yield {
type: 'trade',
symbol: binanceDexTrade.s,
exchange: 'binance-dex',
id: binanceDexTrade.t,
price: Number(binanceDexTrade.p),
amount: Number(binanceDexTrade.q),
side: binanceDexTrade.tt === 2 ? 'sell' : 'buy',
timestamp: new Date(Math.floor(binanceDexTrade.T / 1000000)),
localTimestamp: localTimestamp
}
}
}
}
const mapBookLevel = (level: BinanceDexBookLevel) => {
const price = Number(level[0])
const amount = Number(level[1])
return { price, amount }
}
export const binanceDexBookChangeMapper: Mapper<'binance-dex', BookChange> = {
canHandle(message: BinanceDexResponse<any>) {
return message.stream === 'marketDiff' || message.stream === 'depthSnapshot'
},
getFilters(symbols?: string[]) {
symbols = upperCaseSymbols(symbols)
return [
{
channel: 'depthSnapshot',
symbols
},
{
channel: 'marketDiff',
symbols
}
]
},
*map(
message: BinanceDexResponse<BinanceDexDepthSnapshotData | BinanceDexMarketDiffData>,
localTimestamp: Date
): IterableIterator<BookChange> {
if ('symbol' in message.data) {
// we've got snapshot message
yield {
type: 'book_change',
symbol: message.data.symbol,
exchange: 'binance-dex',
isSnapshot: true,
bids: message.data.bids.map(mapBookLevel),
asks: message.data.asks.map(mapBookLevel),
timestamp: localTimestamp,
localTimestamp
}
} else {
// we've got update
yield {
type: 'book_change',
symbol: message.data.s,
exchange: 'binance-dex',
isSnapshot: false,
bids: message.data.b.map(mapBookLevel),
asks: message.data.a.map(mapBookLevel),
timestamp: localTimestamp,
localTimestamp
}
}
}
}
export const binanceDexBookTickerMapper: Mapper<'binance-dex', BookTicker> = {
canHandle(message: BinanceDexResponse<any>) {
return message.stream === 'ticker'
},
getFilters(symbols?: string[]) {
symbols = upperCaseSymbols(symbols)
return [
{
channel: 'ticker',
symbols
}
]
},
*map(binanceDexTradeResponse: BinanceDexResponse<BinanceDexTickerData>, localTimestamp: Date): IterableIterator<BookTicker> {
const binanceDexTicker = binanceDexTradeResponse.data
const ticker: BookTicker = {
type: 'book_ticker',
symbol: binanceDexTicker.s,
exchange: 'binance-dex',
askAmount: binanceDexTicker.A !== undefined ? Number(binanceDexTicker.A) : undefined,
askPrice: binanceDexTicker.a !== undefined ? Number(binanceDexTicker.a) : undefined,
bidPrice: binanceDexTicker.b !== undefined ? Number(binanceDexTicker.b) : undefined,
bidAmount: binanceDexTicker.B !== undefined ? Number(binanceDexTicker.B) : undefined,
timestamp: binanceDexTicker.E !== undefined ? new Date(binanceDexTicker.E * 1000) : localTimestamp,
localTimestamp: localTimestamp
}
yield ticker
}
}
type BinanceDexResponse<T> = {
stream: string
data: T
}
type BinanceDexTradeData = {
s: string // Symbol
t: string // Trade ID
p: string // Price
q: string // Quantity
T: number // Trade time
tt: number //tiekertype 0: Unknown 1: SellTaker 2: BuyTaker 3: BuySurplus 4: SellSurplus 5: Neutral
}[]
type BinanceDexBookLevel = [string, string]
type BinanceDexDepthSnapshotData = {
symbol: string
bids: BinanceDexBookLevel[]
asks: BinanceDexBookLevel[]
}
type BinanceDexMarketDiffData = {
E: number // Event time
s: string // Symbol
b: BinanceDexBookLevel[]
a: BinanceDexBookLevel[]
}
type BinanceDexTickerData = {
e: '24hrTicker' // Event type
E: 123456789 // Event time
s: 'ABC_0DX-BNB' // Symbol
b: '0.0024' // Best bid price
B: '10' // Best bid quantity
a: '0.0026' // Best ask price
A: '100' // Best ask quantity
}