tardis-dev 13.19.1 → 13.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/consts.d.ts +3 -2
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +25 -2
- package/dist/consts.js.map +1 -1
- package/dist/mappers/bybit.d.ts +200 -2
- package/dist/mappers/bybit.d.ts.map +1 -1
- package/dist/mappers/bybit.js +262 -3
- package/dist/mappers/bybit.js.map +1 -1
- package/dist/mappers/bybitspot.d.ts +1 -1
- package/dist/mappers/cryptocom.d.ts +1 -1
- package/dist/mappers/huobi.d.ts +3 -3
- package/dist/mappers/index.d.ts +4 -4
- package/dist/mappers/index.d.ts.map +1 -1
- package/dist/mappers/index.js +19 -11
- package/dist/mappers/index.js.map +1 -1
- package/dist/realtimefeeds/bybit.d.ts +16 -4
- package/dist/realtimefeeds/bybit.d.ts.map +1 -1
- package/dist/realtimefeeds/bybit.js +67 -19
- package/dist/realtimefeeds/bybit.js.map +1 -1
- package/dist/realtimefeeds/index.d.ts.map +1 -1
- package/dist/realtimefeeds/index.js +2 -2
- package/dist/realtimefeeds/index.js.map +1 -1
- package/package.json +1 -1
- package/src/consts.ts +26 -2
- package/src/mappers/bybit.ts +428 -5
- package/src/mappers/index.ts +40 -12
- package/src/realtimefeeds/bybit.ts +60 -38
- package/src/realtimefeeds/index.ts +3 -3
- package/dist/realtimefeeds/bybitspot.d.ts +0 -10
- package/dist/realtimefeeds/bybitspot.d.ts.map +0 -1
- package/dist/realtimefeeds/bybitspot.js +0 -40
- package/dist/realtimefeeds/bybitspot.js.map +0 -1
- package/src/realtimefeeds/bybitspot.ts +0 -39
package/src/consts.ts
CHANGED
|
@@ -24,6 +24,7 @@ export const EXCHANGES = [
|
|
|
24
24
|
'poloniex',
|
|
25
25
|
'bybit',
|
|
26
26
|
'bybit-spot',
|
|
27
|
+
'bybit-options',
|
|
27
28
|
'phemex',
|
|
28
29
|
'delta',
|
|
29
30
|
'ftx-us',
|
|
@@ -336,7 +337,29 @@ const BINANCE_OPTIONS_CHANNELS = ['TRADE', 'TICKER', 'DEPTH100', 'INDEX'] as con
|
|
|
336
337
|
|
|
337
338
|
const PHEMEX_CHANNELS = ['book', 'orderbook_p', 'trades', 'trades_p', 'market24h', 'spot_market24h', 'perp_market24h_pack_p'] as const
|
|
338
339
|
|
|
339
|
-
const BYBIT_CHANNELS = [
|
|
340
|
+
const BYBIT_CHANNELS = [
|
|
341
|
+
'trade',
|
|
342
|
+
'instrument_info',
|
|
343
|
+
'orderBookL2_25',
|
|
344
|
+
'insurance',
|
|
345
|
+
'orderBook_200',
|
|
346
|
+
'liquidation',
|
|
347
|
+
'trade',
|
|
348
|
+
'instrument_info',
|
|
349
|
+
'orderBookL2_25',
|
|
350
|
+
'insurance',
|
|
351
|
+
'orderBook_200',
|
|
352
|
+
'liquidation',
|
|
353
|
+
'long_short_ratio',
|
|
354
|
+
'orderbook.1',
|
|
355
|
+
'orderbook.50',
|
|
356
|
+
'orderbook.500',
|
|
357
|
+
'publicTrade',
|
|
358
|
+
'tickers',
|
|
359
|
+
'liquidation'
|
|
360
|
+
] as const
|
|
361
|
+
|
|
362
|
+
const BYBIT_OPTIONS_CHANNELS = ['orderbook.25', 'orderbook.100', 'publicTrade', 'tickers']
|
|
340
363
|
|
|
341
364
|
const HITBTC_CHANNELS = ['updateTrades', 'snapshotTrades', 'snapshotOrderbook', 'updateOrderbook'] as const
|
|
342
365
|
|
|
@@ -392,7 +415,7 @@ const MANGO_CHANNELS = [
|
|
|
392
415
|
|
|
393
416
|
const HUOBI_DM_OPTIONS_CHANNELS = ['trade', 'detail', 'depth', 'bbo', 'open_interest', 'option_market_index', 'option_index'] as const
|
|
394
417
|
|
|
395
|
-
const BYBIT_SPOT_CHANNELS = ['trade', 'bookTicker', 'depth']
|
|
418
|
+
const BYBIT_SPOT_CHANNELS = ['trade', 'bookTicker', 'depth', 'orderbook.1', 'orderbook.50', 'publicTrade', 'tickers', 'lt']
|
|
396
419
|
|
|
397
420
|
const CRYPTO_COM_CHANNELS = ['trade', 'book', 'ticker', 'settlement', 'index', 'mark', 'funding']
|
|
398
421
|
|
|
@@ -445,6 +468,7 @@ export const EXCHANGE_CHANNELS_INFO = {
|
|
|
445
468
|
'huobi-dm-linear-swap': HUOBI_DM_LINEAR_SWAP_CHANNELS,
|
|
446
469
|
bybit: BYBIT_CHANNELS,
|
|
447
470
|
'bybit-spot': BYBIT_SPOT_CHANNELS,
|
|
471
|
+
'bybit-options': BYBIT_OPTIONS_CHANNELS,
|
|
448
472
|
okcoin: OKCOIN_CHANNELS,
|
|
449
473
|
hitbtc: HITBTC_CHANNELS,
|
|
450
474
|
coinflex: COINFLEX_CHANNELS,
|
package/src/mappers/bybit.ts
CHANGED
|
@@ -1,7 +1,317 @@
|
|
|
1
|
-
import { upperCaseSymbols } from '../handy'
|
|
2
|
-
import { BookChange, DerivativeTicker, Exchange, Liquidation, Trade } from '../types'
|
|
1
|
+
import { asNumberIfValid, upperCaseSymbols } from '../handy'
|
|
2
|
+
import { BookChange, BookTicker, DerivativeTicker, Exchange, Liquidation, OptionSummary, Trade } from '../types'
|
|
3
3
|
import { Mapper, PendingTickerInfoHelper } from './mapper'
|
|
4
4
|
|
|
5
|
+
// v5 https://bybit-exchange.github.io/docs/v5/ws/connect
|
|
6
|
+
|
|
7
|
+
export class BybitV5TradesMapper implements Mapper<'bybit' | 'bybit-spot' | 'bybit-options', Trade> {
|
|
8
|
+
constructor(private readonly _exchange: Exchange) {}
|
|
9
|
+
|
|
10
|
+
canHandle(message: BybitV5Trade) {
|
|
11
|
+
if (message.topic === undefined) {
|
|
12
|
+
return false
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return message.topic.startsWith('publicTrade.')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getFilters(symbols?: string[]) {
|
|
19
|
+
symbols = upperCaseSymbols(symbols)
|
|
20
|
+
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
channel: 'publicTrade',
|
|
24
|
+
symbols
|
|
25
|
+
} as const
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
*map(message: BybitV5Trade, localTimestamp: Date): IterableIterator<Trade> {
|
|
30
|
+
for (const trade of message.data) {
|
|
31
|
+
yield {
|
|
32
|
+
type: 'trade',
|
|
33
|
+
symbol: trade.s,
|
|
34
|
+
exchange: this._exchange,
|
|
35
|
+
id: trade.i,
|
|
36
|
+
price: Number(trade.p),
|
|
37
|
+
amount: Number(trade.v),
|
|
38
|
+
side: trade.S == 'Buy' ? 'buy' : trade.S === 'Sell' ? 'sell' : 'unknown',
|
|
39
|
+
timestamp: new Date(trade.T),
|
|
40
|
+
localTimestamp
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class BybitV5BookChangeMapper implements Mapper<'bybit' | 'bybit-spot' | 'bybit-options', BookChange> {
|
|
47
|
+
constructor(protected readonly _exchange: Exchange, private readonly _depth: number) {}
|
|
48
|
+
|
|
49
|
+
canHandle(message: BybitV5OrderBookMessage) {
|
|
50
|
+
if (message.topic === undefined) {
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
return message.topic.startsWith(`orderbook.${this._depth}.`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getFilters(symbols?: string[]) {
|
|
57
|
+
symbols = upperCaseSymbols(symbols)
|
|
58
|
+
return [
|
|
59
|
+
{
|
|
60
|
+
channel: `orderbook.${this._depth}`,
|
|
61
|
+
symbols
|
|
62
|
+
} as const
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
*map(message: BybitV5OrderBookMessage, localTimestamp: Date) {
|
|
67
|
+
yield {
|
|
68
|
+
type: 'book_change',
|
|
69
|
+
symbol: message.data.s,
|
|
70
|
+
exchange: this._exchange,
|
|
71
|
+
isSnapshot: message.type === 'snapshot',
|
|
72
|
+
bids: message.data.b.map(this._mapBookLevel),
|
|
73
|
+
asks: message.data.a.map(this._mapBookLevel),
|
|
74
|
+
timestamp: new Date(message.ts),
|
|
75
|
+
localTimestamp
|
|
76
|
+
} as const
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private _mapBookLevel(level: [string, string]) {
|
|
80
|
+
return { price: Number(level[0]), amount: Number(level[1]) }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class BybitV5BookTickerMapper implements Mapper<'bybit' | 'bybit-spot', BookTicker> {
|
|
85
|
+
private _snapshots: {
|
|
86
|
+
[key: string]: {
|
|
87
|
+
askAmount: number | undefined
|
|
88
|
+
askPrice: number | undefined
|
|
89
|
+
bidPrice: number | undefined
|
|
90
|
+
bidAmount: number | undefined
|
|
91
|
+
}
|
|
92
|
+
} = {}
|
|
93
|
+
|
|
94
|
+
constructor(protected readonly _exchange: Exchange) {}
|
|
95
|
+
|
|
96
|
+
canHandle(message: BybitV5OrderBookMessage) {
|
|
97
|
+
if (message.topic === undefined) {
|
|
98
|
+
return false
|
|
99
|
+
}
|
|
100
|
+
return message.topic.startsWith(`orderbook.1.`)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
getFilters(symbols?: string[]) {
|
|
104
|
+
symbols = upperCaseSymbols(symbols)
|
|
105
|
+
return [
|
|
106
|
+
{
|
|
107
|
+
channel: 'orderbook.1',
|
|
108
|
+
symbols
|
|
109
|
+
} as const
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
*map(message: BybitV5OrderBookMessage, localTimestamp: Date) {
|
|
114
|
+
const bestAsk = message.data.a[0]
|
|
115
|
+
const bestBid = message.data.b[0]
|
|
116
|
+
|
|
117
|
+
if (message.type === 'snapshot') {
|
|
118
|
+
this._snapshots[message.data.s] = {
|
|
119
|
+
askAmount: bestAsk !== undefined ? Number(bestAsk[1]) : undefined,
|
|
120
|
+
askPrice: bestAsk !== undefined ? Number(bestAsk[0]) : undefined,
|
|
121
|
+
bidPrice: bestBid !== undefined ? Number(bestBid[0]) : undefined,
|
|
122
|
+
bidAmount: bestBid !== undefined ? Number(bestBid[1]) : undefined
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const matchingSnapshot = this._snapshots[message.data.s]
|
|
127
|
+
if (!matchingSnapshot) {
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const bookTicker: BookTicker = {
|
|
132
|
+
type: 'book_ticker',
|
|
133
|
+
symbol: message.data.s,
|
|
134
|
+
exchange: this._exchange,
|
|
135
|
+
askAmount: bestAsk !== undefined ? Number(bestAsk[1]) : matchingSnapshot.askAmount,
|
|
136
|
+
askPrice: bestAsk !== undefined ? Number(bestAsk[0]) : matchingSnapshot.askPrice,
|
|
137
|
+
bidPrice: bestBid !== undefined ? Number(bestBid[0]) : matchingSnapshot.bidPrice,
|
|
138
|
+
bidAmount: bestBid !== undefined ? Number(bestBid[1]) : matchingSnapshot.bidAmount,
|
|
139
|
+
timestamp: new Date(message.ts),
|
|
140
|
+
localTimestamp: localTimestamp
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
yield bookTicker
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export class BybitV5DerivativeTickerMapper implements Mapper<'bybit', DerivativeTicker> {
|
|
148
|
+
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
149
|
+
|
|
150
|
+
canHandle(message: BybitV5DerivTickerMessage) {
|
|
151
|
+
if (message.topic === undefined) {
|
|
152
|
+
return false
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return message.topic.startsWith('tickers.')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
getFilters(symbols?: string[]) {
|
|
159
|
+
symbols = upperCaseSymbols(symbols)
|
|
160
|
+
|
|
161
|
+
return [
|
|
162
|
+
{
|
|
163
|
+
channel: 'tickers',
|
|
164
|
+
symbols
|
|
165
|
+
} as const
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
*map(message: BybitV5DerivTickerMessage, localTimestamp: Date): IterableIterator<DerivativeTicker> {
|
|
170
|
+
const instrumentInfo = message.data
|
|
171
|
+
|
|
172
|
+
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(instrumentInfo.symbol, 'bybit')
|
|
173
|
+
|
|
174
|
+
if (instrumentInfo.fundingRate !== undefined && instrumentInfo.fundingRate !== '') {
|
|
175
|
+
pendingTickerInfo.updateFundingRate(Number(instrumentInfo.fundingRate))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (instrumentInfo.nextFundingTime !== undefined && instrumentInfo.nextFundingTime !== '') {
|
|
179
|
+
pendingTickerInfo.updateFundingTimestamp(new Date(Number(instrumentInfo.nextFundingTime)))
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (instrumentInfo.indexPrice !== undefined && instrumentInfo.indexPrice !== '') {
|
|
183
|
+
pendingTickerInfo.updateIndexPrice(Number(instrumentInfo.indexPrice))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (instrumentInfo.markPrice !== undefined && instrumentInfo.markPrice !== '') {
|
|
187
|
+
pendingTickerInfo.updateMarkPrice(Number(instrumentInfo.markPrice))
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (instrumentInfo.openInterest !== undefined && instrumentInfo.openInterest !== '') {
|
|
191
|
+
pendingTickerInfo.updateOpenInterest(Number(instrumentInfo.openInterest))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (instrumentInfo.lastPrice !== undefined && instrumentInfo.lastPrice !== '') {
|
|
195
|
+
pendingTickerInfo.updateLastPrice(Number(instrumentInfo.lastPrice))
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
pendingTickerInfo.updateTimestamp(new Date(message.ts))
|
|
199
|
+
|
|
200
|
+
if (pendingTickerInfo.hasChanged()) {
|
|
201
|
+
yield pendingTickerInfo.getSnapshot(localTimestamp)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export class BybitV5LiquidationsMapper implements Mapper<'bybit', Liquidation> {
|
|
207
|
+
constructor(private readonly _exchange: Exchange) {}
|
|
208
|
+
canHandle(message: BybitV5LiquidationMessage) {
|
|
209
|
+
if (message.topic === undefined) {
|
|
210
|
+
return false
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return message.topic.startsWith('liquidation.')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
getFilters(symbols?: string[]) {
|
|
217
|
+
symbols = upperCaseSymbols(symbols)
|
|
218
|
+
|
|
219
|
+
return [
|
|
220
|
+
{
|
|
221
|
+
channel: 'liquidation',
|
|
222
|
+
symbols
|
|
223
|
+
} as const
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
*map(message: BybitV5LiquidationMessage, localTimestamp: Date): IterableIterator<Liquidation> {
|
|
228
|
+
// from bybit telegram: When "side":"Buy", a long position was liquidated. Will fix the docs.
|
|
229
|
+
|
|
230
|
+
const bybitLiquidation = message.data
|
|
231
|
+
const liquidation: Liquidation = {
|
|
232
|
+
type: 'liquidation',
|
|
233
|
+
symbol: bybitLiquidation.symbol,
|
|
234
|
+
exchange: this._exchange,
|
|
235
|
+
id: undefined,
|
|
236
|
+
price: Number(bybitLiquidation.price),
|
|
237
|
+
amount: Number(bybitLiquidation.size),
|
|
238
|
+
side: bybitLiquidation.side == 'Buy' ? 'sell' : 'buy',
|
|
239
|
+
timestamp: new Date(message.ts),
|
|
240
|
+
localTimestamp
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
yield liquidation
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export class BybitV5OptionSummaryMapper implements Mapper<'bybit-options', OptionSummary> {
|
|
248
|
+
canHandle(message: BybitV5OptionTickerMessage) {
|
|
249
|
+
if (message.topic === undefined) {
|
|
250
|
+
return false
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return message.topic.startsWith('tickers.')
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
getFilters(symbols?: string[]) {
|
|
257
|
+
symbols = upperCaseSymbols(symbols)
|
|
258
|
+
|
|
259
|
+
return [
|
|
260
|
+
{
|
|
261
|
+
channel: 'tickers',
|
|
262
|
+
symbols
|
|
263
|
+
} as const
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
*map(message: BybitV5OptionTickerMessage, localTimestamp: Date) {
|
|
268
|
+
const symbolParts = message.data.symbol.split('-')
|
|
269
|
+
|
|
270
|
+
const isPut = symbolParts[3] === 'P'
|
|
271
|
+
|
|
272
|
+
const strikePrice = Number(symbolParts[2])
|
|
273
|
+
|
|
274
|
+
const expirationDate = new Date(symbolParts[1] + 'Z')
|
|
275
|
+
expirationDate.setUTCHours(8)
|
|
276
|
+
|
|
277
|
+
const optionSummary: OptionSummary = {
|
|
278
|
+
type: 'option_summary',
|
|
279
|
+
symbol: message.data.symbol,
|
|
280
|
+
exchange: 'bybit-options',
|
|
281
|
+
optionType: isPut ? 'put' : 'call',
|
|
282
|
+
strikePrice,
|
|
283
|
+
expirationDate,
|
|
284
|
+
|
|
285
|
+
bestBidPrice: asNumberIfValid(message.data.bidPrice),
|
|
286
|
+
bestBidAmount: asNumberIfValid(message.data.bidSize),
|
|
287
|
+
bestBidIV: asNumberIfValid(message.data.bidIv),
|
|
288
|
+
|
|
289
|
+
bestAskPrice: asNumberIfValid(message.data.askPrice),
|
|
290
|
+
bestAskAmount: asNumberIfValid(message.data.askSize),
|
|
291
|
+
bestAskIV: asNumberIfValid(message.data.askIv),
|
|
292
|
+
|
|
293
|
+
lastPrice: asNumberIfValid(message.data.lastPrice),
|
|
294
|
+
openInterest: asNumberIfValid(message.data.openInterest),
|
|
295
|
+
|
|
296
|
+
markPrice: asNumberIfValid(message.data.markPrice),
|
|
297
|
+
markIV: asNumberIfValid(message.data.markPriceIv),
|
|
298
|
+
|
|
299
|
+
delta: asNumberIfValid(message.data.delta),
|
|
300
|
+
gamma: asNumberIfValid(message.data.gamma),
|
|
301
|
+
vega: asNumberIfValid(message.data.vega),
|
|
302
|
+
theta: asNumberIfValid(message.data.theta),
|
|
303
|
+
rho: undefined,
|
|
304
|
+
|
|
305
|
+
underlyingPrice: asNumberIfValid(message.data.underlyingPrice),
|
|
306
|
+
underlyingIndex: '',
|
|
307
|
+
timestamp: new Date(message.ts),
|
|
308
|
+
localTimestamp: localTimestamp
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
yield optionSummary
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
5
315
|
// https://github.com/bybit-exchange/bybit-official-api-docs/blob/master/en/websocket.md
|
|
6
316
|
|
|
7
317
|
export class BybitTradesMapper implements Mapper<'bybit', Trade> {
|
|
@@ -96,9 +406,6 @@ export class BybitBookChangeMapper implements Mapper<'bybit', BookChange> {
|
|
|
96
406
|
: message.data
|
|
97
407
|
: [...message.data.delete, ...message.data.update, ...message.data.insert]
|
|
98
408
|
|
|
99
|
-
// TODO: test instrument info
|
|
100
|
-
// TODO: test liquidations?
|
|
101
|
-
|
|
102
409
|
const timestampBybit = message.timestamp_e6 !== undefined ? Number(message.timestamp_e6) : Number(message.timestampE6)
|
|
103
410
|
const timestamp = new Date(timestampBybit / 1000)
|
|
104
411
|
timestamp.μs = timestampBybit % 1000
|
|
@@ -276,6 +583,122 @@ export class BybitLiquidationsMapper implements Mapper<'bybit', Liquidation> {
|
|
|
276
583
|
}
|
|
277
584
|
}
|
|
278
585
|
|
|
586
|
+
type BybitV5Trade =
|
|
587
|
+
| {
|
|
588
|
+
topic: 'publicTrade.LTCUSDT'
|
|
589
|
+
type: 'snapshot'
|
|
590
|
+
ts: 1680688979985
|
|
591
|
+
data: [
|
|
592
|
+
{
|
|
593
|
+
T: 1680688979983
|
|
594
|
+
s: 'LTCUSDT'
|
|
595
|
+
S: 'Buy'
|
|
596
|
+
v: '0.4'
|
|
597
|
+
p: '94.53'
|
|
598
|
+
L: 'ZeroMinusTick'
|
|
599
|
+
i: '4c7b6bdc-b4a3-5716-9c7b-bbe01dc7072f'
|
|
600
|
+
BT: false
|
|
601
|
+
}
|
|
602
|
+
]
|
|
603
|
+
}
|
|
604
|
+
| {
|
|
605
|
+
topic: 'publicTrade.BTCUSDC'
|
|
606
|
+
ts: 1680688980000
|
|
607
|
+
type: 'snapshot'
|
|
608
|
+
data: [{ i: '2240000000041223438'; T: 1680688979998; p: '28528.98'; v: '0.00433'; S: 'Buy'; s: 'BTCUSDC'; BT: false }]
|
|
609
|
+
}
|
|
610
|
+
| {
|
|
611
|
+
id: 'publicTrade.BTC-3414637898-1680652922102'
|
|
612
|
+
topic: 'publicTrade.BTC'
|
|
613
|
+
ts: 1680652922102
|
|
614
|
+
data: [
|
|
615
|
+
{ p: '985'; v: '0.01'; i: '0404c393-8419-5bac-95c3-5fea28404754'; T: 1680652922081; BT: false; s: 'BTC-28APR23-29500-C'; S: 'Sell' }
|
|
616
|
+
]
|
|
617
|
+
type: 'snapshot'
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
type BybitV5OrderBookMessage = {
|
|
621
|
+
topic: 'orderbook.50.LTCUSD'
|
|
622
|
+
type: 'snapshot' | 'delta'
|
|
623
|
+
ts: 1680673822478
|
|
624
|
+
data: {
|
|
625
|
+
s: string
|
|
626
|
+
b: [string, string][]
|
|
627
|
+
a: [string, string][]
|
|
628
|
+
u: 11802648
|
|
629
|
+
seq: 941860281
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
type BybitV5DerivTickerMessage = {
|
|
634
|
+
topic: 'tickers.BTCUSD'
|
|
635
|
+
type: 'snapshot' | 'delta'
|
|
636
|
+
data: {
|
|
637
|
+
symbol: string
|
|
638
|
+
lastPrice?: string
|
|
639
|
+
|
|
640
|
+
markPrice?: string
|
|
641
|
+
indexPrice?: string
|
|
642
|
+
openInterest?: string
|
|
643
|
+
openInterestValue?: string
|
|
644
|
+
nextFundingTime?: string
|
|
645
|
+
fundingRate?: string
|
|
646
|
+
bid1Price?: string
|
|
647
|
+
bid1Size?: string
|
|
648
|
+
ask1Price?: string
|
|
649
|
+
ask1Size?: string
|
|
650
|
+
}
|
|
651
|
+
cs: 20856433578
|
|
652
|
+
ts: 1680673822577
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
type BybitV5LiquidationMessage = {
|
|
656
|
+
data: {
|
|
657
|
+
price: '0.03803'
|
|
658
|
+
side: 'Buy'
|
|
659
|
+
size: '1637'
|
|
660
|
+
symbol: 'GALAUSDT'
|
|
661
|
+
updatedTime: 1673251091822
|
|
662
|
+
}
|
|
663
|
+
topic: 'liquidation.GALAUSDT'
|
|
664
|
+
ts: 1673251091822
|
|
665
|
+
type: 'snapshot'
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
type BybitV5OptionTickerMessage = {
|
|
669
|
+
id: 'tickers.ETH-30JUN23-200-P-3164908233-1680652859919'
|
|
670
|
+
topic: 'tickers.ETH-30JUN23-200-P'
|
|
671
|
+
ts: 1680652859919
|
|
672
|
+
data: {
|
|
673
|
+
symbol: 'ETH-30JUN23-200-P'
|
|
674
|
+
bidPrice: '0.1'
|
|
675
|
+
bidSize: '5'
|
|
676
|
+
bidIv: '1.4744'
|
|
677
|
+
askPrice: '0'
|
|
678
|
+
askSize: '0'
|
|
679
|
+
askIv: '0'
|
|
680
|
+
lastPrice: '1'
|
|
681
|
+
highPrice24h: '0'
|
|
682
|
+
lowPrice24h: '0'
|
|
683
|
+
markPrice: '0.2548522'
|
|
684
|
+
indexPrice: '1871.27'
|
|
685
|
+
markPriceIv: '1.5991'
|
|
686
|
+
underlyingPrice: '1886.16'
|
|
687
|
+
openInterest: '231.5'
|
|
688
|
+
turnover24h: '0'
|
|
689
|
+
volume24h: '0'
|
|
690
|
+
totalVolume: '232'
|
|
691
|
+
totalTurnover: '362305'
|
|
692
|
+
delta: '-0.00052953'
|
|
693
|
+
gamma: '0.00000128'
|
|
694
|
+
vega: '0.01719155'
|
|
695
|
+
theta: '-0.0159208'
|
|
696
|
+
predictedDeliveryPrice: '0'
|
|
697
|
+
change24h: '0'
|
|
698
|
+
}
|
|
699
|
+
type: 'snapshot'
|
|
700
|
+
}
|
|
701
|
+
|
|
279
702
|
type BybitDataMessage = {
|
|
280
703
|
topic: string
|
|
281
704
|
}
|
package/src/mappers/index.ts
CHANGED
|
@@ -29,7 +29,18 @@ import {
|
|
|
29
29
|
import { BitnomialBookChangMapper, bitnomialTradesMapper } from './bitnomial'
|
|
30
30
|
import { BitstampBookChangeMapper, bitstampTradesMapper } from './bitstamp'
|
|
31
31
|
import { BlockchainComBookChangeMapper, BlockchainComTradesMapper } from './blockchaincom'
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
BybitBookChangeMapper,
|
|
34
|
+
BybitDerivativeTickerMapper,
|
|
35
|
+
BybitLiquidationsMapper,
|
|
36
|
+
BybitTradesMapper,
|
|
37
|
+
BybitV5BookChangeMapper,
|
|
38
|
+
BybitV5BookTickerMapper,
|
|
39
|
+
BybitV5DerivativeTickerMapper,
|
|
40
|
+
BybitV5LiquidationsMapper,
|
|
41
|
+
BybitV5OptionSummaryMapper,
|
|
42
|
+
BybitV5TradesMapper
|
|
43
|
+
} from './bybit'
|
|
33
44
|
import { BybitSpotBookChangeMapper, BybitSpotBookTickerMapper, BybitSpotTradesMapper } from './bybitspot'
|
|
34
45
|
import { CoinbaseBookChangMapper, coinbaseBookTickerMapper, coinbaseTradesMapper } from './coinbase'
|
|
35
46
|
import { coinflexBookChangeMapper, CoinflexDerivativeTickerMapper, coinflexTradesMapper } from './coinflex'
|
|
@@ -136,6 +147,12 @@ const shouldIgnoreBookSnapshotOverlap = (date: Date) => {
|
|
|
136
147
|
return isRealTime(date) === false
|
|
137
148
|
}
|
|
138
149
|
|
|
150
|
+
const BYBIT_V5_API_SWITCH_DATE = new Date('2023-04-05T00:00:00.000Z')
|
|
151
|
+
|
|
152
|
+
const shouldUseBybitV5Mappers = (localTimestamp: Date) => {
|
|
153
|
+
return isRealTime(localTimestamp) || localTimestamp.valueOf() >= BYBIT_V5_API_SWITCH_DATE.valueOf()
|
|
154
|
+
}
|
|
155
|
+
|
|
139
156
|
const tradesMappers = {
|
|
140
157
|
bitmex: () => bitmexTradesMapper,
|
|
141
158
|
binance: () => new BinanceTradesMapper('binance'),
|
|
@@ -172,7 +189,8 @@ const tradesMappers = {
|
|
|
172
189
|
'huobi-dm-swap': () => new HuobiTradesMapper('huobi-dm-swap'),
|
|
173
190
|
'huobi-dm-linear-swap': () => new HuobiTradesMapper('huobi-dm-linear-swap'),
|
|
174
191
|
'huobi-dm-options': () => new HuobiTradesMapper('huobi-dm-options'),
|
|
175
|
-
bybit: () =>
|
|
192
|
+
bybit: (localTimestamp: Date) =>
|
|
193
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5TradesMapper('bybit') : new BybitTradesMapper('bybit'),
|
|
176
194
|
okcoin: () => new OkexTradesMapper('okcoin', 'spot'),
|
|
177
195
|
hitbtc: () => hitBtcTradesMapper,
|
|
178
196
|
phemex: () => phemexTradesMapper,
|
|
@@ -189,13 +207,15 @@ const tradesMappers = {
|
|
|
189
207
|
serum: () => new SerumTradesMapper('serum'),
|
|
190
208
|
'star-atlas': () => new SerumTradesMapper('star-atlas'),
|
|
191
209
|
mango: () => new SerumTradesMapper('mango'),
|
|
192
|
-
'bybit-spot': () =>
|
|
210
|
+
'bybit-spot': (localTimestamp: Date) =>
|
|
211
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5TradesMapper('bybit-spot') : new BybitSpotTradesMapper('bybit-spot'),
|
|
193
212
|
'crypto-com': () => new CryptoComTradesMapper('crypto-com'),
|
|
194
213
|
'crypto-com-derivatives': () => new CryptoComTradesMapper('crypto-com-derivatives'),
|
|
195
214
|
kucoin: () => new KucoinTradesMapper('kucoin'),
|
|
196
215
|
bitnomial: () => bitnomialTradesMapper,
|
|
197
216
|
'woo-x': () => wooxTradesMapper,
|
|
198
|
-
'blockchain-com': () => new BlockchainComTradesMapper()
|
|
217
|
+
'blockchain-com': () => new BlockchainComTradesMapper(),
|
|
218
|
+
'bybit-options': () => new BybitV5TradesMapper('bybit-options')
|
|
199
219
|
}
|
|
200
220
|
|
|
201
221
|
const bookChangeMappers = {
|
|
@@ -247,8 +267,10 @@ const bookChangeMappers = {
|
|
|
247
267
|
'huobi-dm-swap': () => new HuobiBookChangeMapper('huobi-dm-swap'),
|
|
248
268
|
'huobi-dm-linear-swap': () => new HuobiBookChangeMapper('huobi-dm-linear-swap'),
|
|
249
269
|
'huobi-dm-options': () => new HuobiBookChangeMapper('huobi-dm-options'),
|
|
250
|
-
'bybit-spot': () =>
|
|
251
|
-
|
|
270
|
+
'bybit-spot': (localTimestamp: Date) =>
|
|
271
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5BookChangeMapper('bybit-spot', 50) : new BybitSpotBookChangeMapper('bybit-spot'),
|
|
272
|
+
bybit: (localTimestamp: Date) =>
|
|
273
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5BookChangeMapper('bybit', 50) : new BybitBookChangeMapper('bybit', false),
|
|
252
274
|
okcoin: (localTimestamp: Date) =>
|
|
253
275
|
new OkexBookChangeMapper('okcoin', 'spot', localTimestamp.valueOf() >= new Date('2020-02-13').valueOf()),
|
|
254
276
|
hitbtc: () => hitBtcBookChangeMapper,
|
|
@@ -271,7 +293,8 @@ const bookChangeMappers = {
|
|
|
271
293
|
kucoin: (localTimestamp: Date) => new KucoinBookChangeMapper('kucoin', isRealTime(localTimestamp) === false),
|
|
272
294
|
bitnomial: () => new BitnomialBookChangMapper(),
|
|
273
295
|
'woo-x': () => new WooxBookChangeMapper(),
|
|
274
|
-
'blockchain-com': () => new BlockchainComBookChangeMapper()
|
|
296
|
+
'blockchain-com': () => new BlockchainComBookChangeMapper(),
|
|
297
|
+
'bybit-options': () => new BybitV5BookChangeMapper('bybit-options', 25)
|
|
275
298
|
}
|
|
276
299
|
|
|
277
300
|
const derivativeTickersMappers = {
|
|
@@ -289,7 +312,8 @@ const derivativeTickersMappers = {
|
|
|
289
312
|
'okex-swap': (localTimestamp: Date) =>
|
|
290
313
|
shouldUseOkexV5Mappers(localTimestamp) ? new OkexV5DerivativeTickerMapper('okex-swap') : new OkexDerivativeTickerMapper('okex-swap'),
|
|
291
314
|
|
|
292
|
-
bybit: () =>
|
|
315
|
+
bybit: (localTimestamp: Date) =>
|
|
316
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5DerivativeTickerMapper() : new BybitDerivativeTickerMapper(),
|
|
293
317
|
phemex: () => new PhemexDerivativeTickerMapper(),
|
|
294
318
|
ftx: () => new FTXDerivativeTickerMapper('ftx'),
|
|
295
319
|
delta: (localTimestamp: Date) => new DeltaDerivativeTickerMapper(localTimestamp.valueOf() >= new Date('2020-10-14').valueOf()),
|
|
@@ -310,7 +334,8 @@ const optionsSummaryMappers = {
|
|
|
310
334
|
'okex-options': (localTimestamp: Date) =>
|
|
311
335
|
shouldUseOkexV5Mappers(localTimestamp) ? new OkexV5OptionSummaryMapper() : new OkexOptionSummaryMapper(),
|
|
312
336
|
'binance-options': () => new BinanceOptionSummaryMapper(),
|
|
313
|
-
'huobi-dm-options': () => new HuobiOptionsSummaryMapper()
|
|
337
|
+
'huobi-dm-options': () => new HuobiOptionsSummaryMapper(),
|
|
338
|
+
'bybit-options': () => new BybitV5OptionSummaryMapper()
|
|
314
339
|
}
|
|
315
340
|
|
|
316
341
|
const liquidationsMappers = {
|
|
@@ -324,7 +349,8 @@ const liquidationsMappers = {
|
|
|
324
349
|
'huobi-dm': () => new HuobiLiquidationsMapper('huobi-dm'),
|
|
325
350
|
'huobi-dm-swap': () => new HuobiLiquidationsMapper('huobi-dm-swap'),
|
|
326
351
|
'huobi-dm-linear-swap': () => new HuobiLiquidationsMapper('huobi-dm-linear-swap'),
|
|
327
|
-
bybit: () =>
|
|
352
|
+
bybit: (localTimestamp: Date) =>
|
|
353
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5LiquidationsMapper('bybit') : new BybitLiquidationsMapper('bybit'),
|
|
328
354
|
'okex-futures': (localTimestamp: Date) =>
|
|
329
355
|
shouldUseOkexV5Mappers(localTimestamp)
|
|
330
356
|
? new OkexV5LiquidationsMapper('okex-futures')
|
|
@@ -379,12 +405,14 @@ const bookTickersMappers = {
|
|
|
379
405
|
'star-atlas': () => new SerumBookTickerMapper('star-atlas'),
|
|
380
406
|
mango: () => new SerumBookTickerMapper('mango'),
|
|
381
407
|
'gate-io-futures': () => new GateIOFuturesBookTickerMapper('gate-io-futures'),
|
|
382
|
-
'bybit-spot': () =>
|
|
408
|
+
'bybit-spot': (localTimestamp: Date) =>
|
|
409
|
+
shouldUseBybitV5Mappers(localTimestamp) ? new BybitV5BookTickerMapper('bybit-spot') : new BybitSpotBookTickerMapper('bybit-spot'),
|
|
383
410
|
'crypto-com': () => new CryptoComBookTickerMapper('crypto-com'),
|
|
384
411
|
'crypto-com-derivatives': () => new CryptoComBookTickerMapper('crypto-com-derivatives'),
|
|
385
412
|
kucoin: () => new KucoinBookTickerMapper('kucoin'),
|
|
386
413
|
'woo-x': () => new WooxBookTickerMapper(),
|
|
387
|
-
delta: () => new DeltaBookTickerMapper()
|
|
414
|
+
delta: () => new DeltaBookTickerMapper(),
|
|
415
|
+
bybit: () => new BybitV5BookTickerMapper('bybit')
|
|
388
416
|
}
|
|
389
417
|
|
|
390
418
|
export const normalizeTrades = <T extends keyof typeof tradesMappers>(exchange: T, localTimestamp: Date): Mapper<T, Trade> => {
|