tardis-dev 13.4.12 → 13.6.0

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.
Files changed (66) hide show
  1. package/dist/consts.d.ts +4 -1
  2. package/dist/consts.d.ts.map +1 -1
  3. package/dist/consts.js +11 -2
  4. package/dist/consts.js.map +1 -1
  5. package/dist/handy.d.ts +1 -0
  6. package/dist/handy.d.ts.map +1 -1
  7. package/dist/handy.js +5 -1
  8. package/dist/handy.js.map +1 -1
  9. package/dist/mappers/bybit.d.ts +1 -1
  10. package/dist/mappers/bybitspot.d.ts +1 -1
  11. package/dist/mappers/cryptocom.d.ts +257 -0
  12. package/dist/mappers/cryptocom.d.ts.map +1 -0
  13. package/dist/mappers/cryptocom.js +193 -0
  14. package/dist/mappers/cryptocom.js.map +1 -0
  15. package/dist/mappers/huobi.d.ts +3 -3
  16. package/dist/mappers/index.d.ts +4 -4
  17. package/dist/mappers/index.d.ts.map +1 -1
  18. package/dist/mappers/index.js +16 -4
  19. package/dist/mappers/index.js.map +1 -1
  20. package/dist/mappers/kucoin.d.ts +109 -0
  21. package/dist/mappers/kucoin.d.ts.map +1 -0
  22. package/dist/mappers/kucoin.js +216 -0
  23. package/dist/mappers/kucoin.js.map +1 -0
  24. package/dist/realtimefeeds/binance.js +1 -1
  25. package/dist/realtimefeeds/binance.js.map +1 -1
  26. package/dist/realtimefeeds/cryptocom.d.ts +10 -0
  27. package/dist/realtimefeeds/cryptocom.d.ts.map +1 -0
  28. package/dist/realtimefeeds/cryptocom.js +49 -0
  29. package/dist/realtimefeeds/cryptocom.js.map +1 -0
  30. package/dist/realtimefeeds/cryptocomderivatives.d.ts +10 -0
  31. package/dist/realtimefeeds/cryptocomderivatives.d.ts.map +1 -0
  32. package/dist/realtimefeeds/cryptocomderivatives.js +51 -0
  33. package/dist/realtimefeeds/cryptocomderivatives.js.map +1 -0
  34. package/dist/realtimefeeds/ftx.js +1 -1
  35. package/dist/realtimefeeds/ftx.js.map +1 -1
  36. package/dist/realtimefeeds/huobi.js +2 -2
  37. package/dist/realtimefeeds/huobi.js.map +1 -1
  38. package/dist/realtimefeeds/index.d.ts.map +1 -1
  39. package/dist/realtimefeeds/index.js +7 -1
  40. package/dist/realtimefeeds/index.js.map +1 -1
  41. package/dist/realtimefeeds/kucoin.d.ts +13 -0
  42. package/dist/realtimefeeds/kucoin.d.ts.map +1 -0
  43. package/dist/realtimefeeds/kucoin.js +70 -0
  44. package/dist/realtimefeeds/kucoin.js.map +1 -0
  45. package/dist/realtimefeeds/realtimefeed.d.ts +1 -0
  46. package/dist/realtimefeeds/realtimefeed.d.ts.map +1 -1
  47. package/dist/realtimefeeds/realtimefeed.js +6 -2
  48. package/dist/realtimefeeds/realtimefeed.js.map +1 -1
  49. package/dist/replay.d.ts.map +1 -1
  50. package/dist/replay.js +11 -0
  51. package/dist/replay.js.map +1 -1
  52. package/package.json +1 -1
  53. package/src/consts.ts +14 -2
  54. package/src/handy.ts +4 -0
  55. package/src/mappers/cryptocom.ts +395 -0
  56. package/src/mappers/index.ts +16 -4
  57. package/src/mappers/kucoin.ts +311 -0
  58. package/src/realtimefeeds/binance.ts +1 -1
  59. package/src/realtimefeeds/cryptocom.ts +48 -0
  60. package/src/realtimefeeds/cryptocomderivatives.ts +50 -0
  61. package/src/realtimefeeds/ftx.ts +1 -1
  62. package/src/realtimefeeds/huobi.ts +2 -2
  63. package/src/realtimefeeds/index.ts +7 -1
  64. package/src/realtimefeeds/kucoin.ts +77 -0
  65. package/src/realtimefeeds/realtimefeed.ts +8 -3
  66. package/src/replay.ts +13 -1
@@ -0,0 +1,395 @@
1
+ import { upperCaseSymbols } from '../handy'
2
+ import { BookChange, Exchange, BookTicker, Trade, DerivativeTicker } from '../types'
3
+ import { Mapper, PendingTickerInfoHelper } from './mapper'
4
+
5
+ export class CryptoComTradesMapper implements Mapper<'crypto-com' | 'crypto-com-derivatives', Trade> {
6
+ constructor(private readonly _exchange: Exchange) {}
7
+ canHandle(message: CryptoComTradeMessage) {
8
+ return message.result !== undefined && message.result.channel === 'trade'
9
+ }
10
+
11
+ getFilters(symbols?: string[]) {
12
+ symbols = upperCaseSymbols(symbols)
13
+
14
+ return [
15
+ {
16
+ channel: 'trade',
17
+ symbols
18
+ } as const
19
+ ]
20
+ }
21
+
22
+ *map(message: CryptoComTradeMessage, localTimestamp: Date): IterableIterator<Trade> {
23
+ message.result.data.reverse()
24
+
25
+ for (const item of message.result.data) {
26
+ const trade: Trade = {
27
+ type: 'trade',
28
+ symbol: message.result.instrument_name,
29
+ exchange: this._exchange,
30
+ id: item.d.toString(),
31
+ price: Number(item.p),
32
+ amount: Number(item.q),
33
+ side: item.s === 'BUY' ? 'buy' : 'sell',
34
+ timestamp: new Date(item.t),
35
+ localTimestamp
36
+ }
37
+
38
+ yield trade
39
+ }
40
+ }
41
+ }
42
+
43
+ export class CryptoComBookChangeMapper implements Mapper<'crypto-com' | 'crypto-com-derivatives', BookChange> {
44
+ constructor(protected readonly _exchange: Exchange) {}
45
+
46
+ canHandle(message: CryptoComBookMessage) {
47
+ return message.result !== undefined && message.result.channel.startsWith('book')
48
+ }
49
+
50
+ getFilters(symbols?: string[]) {
51
+ symbols = upperCaseSymbols(symbols)
52
+ return [
53
+ {
54
+ channel: 'book',
55
+ symbols
56
+ } as const
57
+ ]
58
+ }
59
+
60
+ *map(message: CryptoComBookMessage, localTimestamp: Date) {
61
+ if (message.result.data === undefined || message.result.data[0] === undefined) {
62
+ return
63
+ }
64
+
65
+ const bids = (message.result.channel === 'book' ? message.result.data[0].bids : message.result.data[0].update.bids) || []
66
+ const asks = (message.result.channel === 'book' ? message.result.data[0].asks : message.result.data[0].update.asks) || []
67
+
68
+ yield {
69
+ type: 'book_change',
70
+ symbol: message.result.instrument_name,
71
+ exchange: this._exchange,
72
+ isSnapshot: message.result.channel === 'book',
73
+ bids: bids.map(this._mapBookLevel),
74
+ asks: asks.map(this._mapBookLevel),
75
+ timestamp: new Date(message.result.data[0].t),
76
+ localTimestamp
77
+ } as const
78
+ }
79
+
80
+ private _mapBookLevel(level: [number | string, number | string]) {
81
+ return { price: Number(level[0]), amount: Number(level[1]) }
82
+ }
83
+ }
84
+
85
+ export class CryptoComBookTickerMapper implements Mapper<'crypto-com' | 'crypto-com-derivatives', BookTicker> {
86
+ constructor(protected readonly _exchange: Exchange) {}
87
+
88
+ canHandle(message: CryptoComTickerMessage) {
89
+ return message.result !== undefined && message.result.channel === 'ticker'
90
+ }
91
+
92
+ getFilters(symbols?: string[]) {
93
+ symbols = upperCaseSymbols(symbols)
94
+ return [
95
+ {
96
+ channel: 'ticker',
97
+ symbols
98
+ } as const
99
+ ]
100
+ }
101
+
102
+ *map(message: CryptoComTickerMessage, localTimestamp: Date) {
103
+ for (const item of message.result.data) {
104
+ const bookTicker: BookTicker = {
105
+ type: 'book_ticker',
106
+ symbol: message.result.instrument_name,
107
+ exchange: this._exchange,
108
+
109
+ askAmount: undefined,
110
+ askPrice: item.k !== undefined && item.k !== null ? Number(item.k) : undefined,
111
+ bidPrice: item.b !== undefined && item.b !== null ? Number(item.b) : undefined,
112
+ bidAmount: undefined,
113
+ timestamp: new Date(item.t),
114
+ localTimestamp: localTimestamp
115
+ }
116
+
117
+ yield bookTicker
118
+ }
119
+ }
120
+ }
121
+
122
+ export class CryptoComDerivativeTickerMapper implements Mapper<'crypto-com-derivatives', DerivativeTicker> {
123
+ private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
124
+ private readonly _indexPrices = new Map<string, number>()
125
+
126
+ constructor(protected readonly exchange: Exchange) {}
127
+
128
+ canHandle(message: CryptoComDerivativesTickerMessage | CryptoComIndexMessage | CryptoComMarkPriceMessage | CryptoComFundingMessage) {
129
+ if (message.result === undefined) {
130
+ return false
131
+ }
132
+
133
+ return (
134
+ message.result.channel === 'ticker' ||
135
+ message.result.channel === 'index' ||
136
+ message.result.channel === 'mark' ||
137
+ message.result.channel === 'funding'
138
+ )
139
+ }
140
+
141
+ getFilters(symbols?: string[]) {
142
+ symbols = upperCaseSymbols(symbols)
143
+
144
+ let indexes: string[] = []
145
+ if (symbols !== undefined) {
146
+ indexes = [...new Set(symbols.map((s) => `${s.split('-')[0]}-INDEX`))]
147
+ }
148
+ const filters = [
149
+ {
150
+ channel: 'ticker',
151
+ symbols
152
+ } as const,
153
+ {
154
+ channel: 'index',
155
+ symbols: indexes
156
+ } as const,
157
+ {
158
+ channel: 'mark',
159
+ symbols
160
+ } as const,
161
+ {
162
+ channel: 'funding',
163
+ symbols
164
+ } as const
165
+ ]
166
+
167
+ return filters
168
+ }
169
+
170
+ *map(
171
+ message: CryptoComDerivativesTickerMessage | CryptoComIndexMessage | CryptoComMarkPriceMessage | CryptoComFundingMessage,
172
+ localTimestamp: Date
173
+ ): IterableIterator<DerivativeTicker> {
174
+ if (message.result.channel === 'index') {
175
+ this._indexPrices.set(message.result.instrument_name.split('-')[0], Number(message.result.data[0].v))
176
+ return
177
+ }
178
+
179
+ const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(message.result.instrument_name, this.exchange)
180
+
181
+ const lastIndexPrice = this._indexPrices.get(message.result.instrument_name.split('-')[0])
182
+ if (lastIndexPrice !== undefined) {
183
+ pendingTickerInfo.updateIndexPrice(lastIndexPrice)
184
+ }
185
+
186
+ if (message.result.channel === 'ticker') {
187
+ if (message.result.data[0].a !== null && message.result.data[0].a !== undefined) {
188
+ pendingTickerInfo.updateLastPrice(Number(message.result.data[0].a))
189
+ }
190
+ if (message.result.data[0].oi !== null && message.result.data[0].oi !== undefined) {
191
+ pendingTickerInfo.updateOpenInterest(Number(message.result.data[0].oi))
192
+ }
193
+ }
194
+
195
+ if (message.result.channel === 'mark') {
196
+ if (message.result.data[0].v !== null && message.result.data[0].v !== undefined) {
197
+ pendingTickerInfo.updateMarkPrice(Number(message.result.data[0].v))
198
+ }
199
+ }
200
+
201
+ if (message.result.channel === 'funding') {
202
+ if (message.result.data[0].v !== null && message.result.data[0].v !== undefined) {
203
+ pendingTickerInfo.updateFundingRate(Number(message.result.data[0].v))
204
+ const nextFundingTimestamp = new Date(message.result.data[0].t)
205
+ nextFundingTimestamp.setUTCHours(nextFundingTimestamp.getUTCHours() + 1)
206
+ nextFundingTimestamp.setUTCMinutes(0, 0, 0)
207
+ pendingTickerInfo.updateFundingTimestamp(nextFundingTimestamp)
208
+ }
209
+ }
210
+
211
+ pendingTickerInfo.updateTimestamp(new Date(message.result.data[0].t))
212
+
213
+ if (pendingTickerInfo.hasChanged()) {
214
+ yield pendingTickerInfo.getSnapshot(localTimestamp)
215
+ }
216
+ }
217
+ }
218
+
219
+ type CryptoComTradeMessage =
220
+ | {
221
+ method: 'subscribe'
222
+ result: {
223
+ instrument_name: 'ETH_CRO' // instrument_name
224
+ subscription: 'trade.ETH_CRO'
225
+ channel: 'trade'
226
+ data: [
227
+ {
228
+ p: 162.12 // price
229
+ q: 11.085 // quantity
230
+ s: 'BUY' // side
231
+ d: 1210447366 // trade id
232
+ t: 1587523078844 // trade time
233
+ dataTime: 0 // please ignore this field
234
+ }
235
+ ]
236
+ }
237
+ }
238
+ | {
239
+ id: -1
240
+ code: 0
241
+ method: 'subscribe'
242
+ result: {
243
+ channel: 'trade'
244
+ subscription: 'trade.BTCUSD-PERP'
245
+ instrument_name: 'BTCUSD-PERP'
246
+ data: [{ d: '4611686018439397540'; t: 1653992578435; p: '31603.5'; q: '0.1000'; s: 'BUY'; i: 'BTCUSD-PERP' }]
247
+ }
248
+ }
249
+
250
+ type CryptoComBookMessage =
251
+ | {
252
+ code: 0
253
+ method: 'subscribe'
254
+ result: {
255
+ instrument_name: 'ETH_CRO'
256
+ subscription: 'book.ETH_CRO.150'
257
+ channel: 'book'
258
+ depth: 150
259
+ data: [
260
+ {
261
+ bids: [number, number][]
262
+ asks: [number, number][]
263
+ t: 1659311999933
264
+ s: 788293808
265
+ }
266
+ ]
267
+ }
268
+ }
269
+ | {
270
+ code: 0
271
+ method: 'subscribe'
272
+ result: {
273
+ instrument_name: 'DOT_USDT'
274
+ subscription: 'book.DOT_USDT.150'
275
+ channel: 'book.update'
276
+ depth: 150
277
+ data: [
278
+ {
279
+ update: { bids: [number, number][]; asks: [number, number][] }
280
+ t: 1659312000046
281
+ s: 763793123
282
+ }
283
+ ]
284
+ }
285
+ }
286
+ | {
287
+ id: -1
288
+ code: 0
289
+ method: 'subscribe'
290
+ result: {
291
+ channel: 'book.update'
292
+ subscription: 'book.BTCUSD-PERP.50'
293
+ instrument_name: 'BTCUSD-PERP'
294
+ depth: 50
295
+ data: [
296
+ {
297
+ update: { asks: [string, string][]; bids: [string, string][] }
298
+ t: 1653992578436
299
+ tt: 1653992578428
300
+ u: 72560693920
301
+ pu: 72560688000
302
+ cs: 380529173
303
+ }
304
+ ]
305
+ }
306
+ }
307
+
308
+ type CryptoComTickerMessage =
309
+ | {
310
+ code: 0
311
+ method: 'subscribe'
312
+ result: {
313
+ instrument_name: 'GODS_USDT'
314
+ subscription: 'ticker.GODS_USDT'
315
+ channel: 'ticker'
316
+ data: [
317
+ {
318
+ i: 'GODS_USDT'
319
+ b: 0.4262
320
+ k: 0.4272
321
+ a: 0.4272
322
+ t: 1659311999946
323
+ v: 100623.01
324
+ vv: 42986.1541
325
+ h: 0.4624
326
+ l: 0.4229
327
+ c: -0.0062
328
+ pc: -1.4302
329
+ }
330
+ ]
331
+ }
332
+ }
333
+ | CryptoComDerivativesTickerMessage
334
+
335
+ type CryptoComDerivativesTickerMessage = {
336
+ id: -1
337
+ code: 0
338
+ method: 'subscribe'
339
+ result: {
340
+ channel: 'ticker'
341
+ instrument_name: 'BTCUSD-PERP'
342
+ subscription: 'ticker.BTCUSD-PERP'
343
+ data: [
344
+ {
345
+ h: '32222.5'
346
+ l: '30240.0'
347
+ a: '31611.0'
348
+ c: '0.0320'
349
+ b: '31613.0'
350
+ k: '31613.5'
351
+ i: 'BTCUSD-PERP'
352
+ v: '13206.4884'
353
+ vv: '433945264.39'
354
+ oi: '318.5162'
355
+ t: 1653992543383
356
+ }
357
+ ]
358
+ }
359
+ }
360
+
361
+ type CryptoComIndexMessage = {
362
+ id: -1
363
+ method: 'subscribe'
364
+ code: 0
365
+ result: {
366
+ instrument_name: 'BTCUSD-INDEX'
367
+ subscription: 'index.BTCUSD-INDEX'
368
+ channel: 'index'
369
+ data: [{ v: '31601.35'; t: 1653992545000 }]
370
+ }
371
+ }
372
+
373
+ type CryptoComMarkPriceMessage = {
374
+ id: 1
375
+ method: 'subscribe'
376
+ code: 0
377
+ result: {
378
+ instrument_name: 'BTCUSD-PERP'
379
+ subscription: 'mark.BTCUSD-PERP'
380
+ channel: 'mark'
381
+ data: [{ v: '31606.3'; t: 1653992543000 }]
382
+ }
383
+ }
384
+
385
+ type CryptoComFundingMessage = {
386
+ id: -1
387
+ method: 'subscribe'
388
+ code: 0
389
+ result: {
390
+ instrument_name: 'BTCUSD-PERP'
391
+ subscription: 'funding.BTCUSD-PERP'
392
+ channel: 'funding'
393
+ data: [{ v: '0.00000700'; t: 1653992579000 }]
394
+ }
395
+ }
@@ -31,6 +31,7 @@ import { BybitBookChangeMapper, BybitDerivativeTickerMapper, BybitLiquidationsMa
31
31
  import { BybitSpotBookChangeMapper, BybitSpotBookTickerMapper, BybitSpotTradesMapper } from './bybitspot'
32
32
  import { CoinbaseBookChangMapper, coinbaseBookTickerMapper, coinbaseTradesMapper } from './coinbase'
33
33
  import { coinflexBookChangeMapper, CoinflexDerivativeTickerMapper, coinflexTradesMapper } from './coinflex'
34
+ import { CryptoComBookChangeMapper, CryptoComBookTickerMapper, CryptoComDerivativeTickerMapper, CryptoComTradesMapper } from './cryptocom'
34
35
  import {
35
36
  cryptofacilitiesBookChangeMapper,
36
37
  CryptofacilitiesDerivativeTickerMapper,
@@ -68,6 +69,7 @@ import {
68
69
  HuobiTradesMapper
69
70
  } from './huobi'
70
71
  import { krakenBookChangeMapper, krakenBookTickerMapper, krakenTradesMapper } from './kraken'
72
+ import { KucoinBookChangeMapper, KucoinBookTickerMapper, KucoinTradesMapper } from './kucoin'
71
73
  import { Mapper } from './mapper'
72
74
  import {
73
75
  OkexBookChangeMapper,
@@ -168,7 +170,10 @@ const tradesMappers = {
168
170
  serum: () => new SerumTradesMapper('serum'),
169
171
  'star-atlas': () => new SerumTradesMapper('star-atlas'),
170
172
  mango: () => new SerumTradesMapper('mango'),
171
- 'bybit-spot': () => new BybitSpotTradesMapper('bybit-spot')
173
+ 'bybit-spot': () => new BybitSpotTradesMapper('bybit-spot'),
174
+ 'crypto-com': () => new CryptoComTradesMapper('crypto-com'),
175
+ 'crypto-com-derivatives': () => new CryptoComTradesMapper('crypto-com-derivatives'),
176
+ kucoin: () => new KucoinTradesMapper('kucoin')
172
177
  }
173
178
 
174
179
  const bookChangeMappers = {
@@ -236,7 +241,10 @@ const bookChangeMappers = {
236
241
  dydx: () => new DydxBookChangeMapper(),
237
242
  serum: () => new SerumBookChangeMapper('serum'),
238
243
  'star-atlas': () => new SerumBookChangeMapper('star-atlas'),
239
- mango: () => new SerumBookChangeMapper('mango')
244
+ mango: () => new SerumBookChangeMapper('mango'),
245
+ 'crypto-com': () => new CryptoComBookChangeMapper('crypto-com'),
246
+ 'crypto-com-derivatives': () => new CryptoComBookChangeMapper('crypto-com-derivatives'),
247
+ kucoin: () => new KucoinBookChangeMapper('kucoin')
240
248
  }
241
249
 
242
250
  const derivativeTickersMappers = {
@@ -264,7 +272,8 @@ const derivativeTickersMappers = {
264
272
  'gate-io-futures': () => new GateIOFuturesDerivativeTickerMapper(),
265
273
  coinflex: () => new CoinflexDerivativeTickerMapper(),
266
274
  ascendex: () => new AscendexDerivativeTickerMapper(),
267
- dydx: () => new DydxDerivativeTickerMapper()
275
+ dydx: () => new DydxDerivativeTickerMapper(),
276
+ 'crypto-com-derivatives': () => new CryptoComDerivativeTickerMapper('crypto-com-derivatives')
268
277
  }
269
278
 
270
279
  const optionsSummaryMappers = {
@@ -341,7 +350,10 @@ const bookTickersMappers = {
341
350
  'star-atlas': () => new SerumBookTickerMapper('star-atlas'),
342
351
  mango: () => new SerumBookTickerMapper('mango'),
343
352
  'gate-io-futures': () => new GateIOFuturesBookTickerMapper('gate-io-futures'),
344
- 'bybit-spot': () => new BybitSpotBookTickerMapper('bybit-spot')
353
+ 'bybit-spot': () => new BybitSpotBookTickerMapper('bybit-spot'),
354
+ 'crypto-com': () => new CryptoComBookTickerMapper('crypto-com'),
355
+ 'crypto-com-derivatives': () => new CryptoComBookTickerMapper('crypto-com-derivatives'),
356
+ kucoin: () => new KucoinBookTickerMapper('kucoin')
345
357
  }
346
358
 
347
359
  export const normalizeTrades = <T extends keyof typeof tradesMappers>(exchange: T, localTimestamp: Date): Mapper<T, Trade> => {