tardis-dev 13.4.12 → 13.4.13
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 -1
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +8 -2
- package/dist/consts.js.map +1 -1
- package/dist/mappers/bybit.d.ts +1 -1
- package/dist/mappers/bybitspot.d.ts +1 -1
- package/dist/mappers/cryptocom.d.ts +257 -0
- package/dist/mappers/cryptocom.d.ts.map +1 -0
- package/dist/mappers/cryptocom.js +193 -0
- package/dist/mappers/cryptocom.js.map +1 -0
- 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 +12 -4
- package/dist/mappers/index.js.map +1 -1
- package/dist/realtimefeeds/cryptocom.d.ts +10 -0
- package/dist/realtimefeeds/cryptocom.d.ts.map +1 -0
- package/dist/realtimefeeds/cryptocom.js +49 -0
- package/dist/realtimefeeds/cryptocom.js.map +1 -0
- package/dist/realtimefeeds/cryptocomderivatives.d.ts +10 -0
- package/dist/realtimefeeds/cryptocomderivatives.d.ts.map +1 -0
- package/dist/realtimefeeds/cryptocomderivatives.js +51 -0
- package/dist/realtimefeeds/cryptocomderivatives.js.map +1 -0
- package/dist/realtimefeeds/index.d.ts.map +1 -1
- package/dist/realtimefeeds/index.js +5 -1
- package/dist/realtimefeeds/index.js.map +1 -1
- package/package.json +1 -1
- package/src/consts.ts +10 -2
- package/src/mappers/cryptocom.ts +395 -0
- package/src/mappers/index.ts +12 -4
- package/src/realtimefeeds/cryptocom.ts +48 -0
- package/src/realtimefeeds/cryptocomderivatives.ts +50 -0
- package/src/realtimefeeds/index.ts +5 -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
|
+
}
|
package/src/mappers/index.ts
CHANGED
|
@@ -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,
|
|
@@ -168,7 +169,9 @@ const tradesMappers = {
|
|
|
168
169
|
serum: () => new SerumTradesMapper('serum'),
|
|
169
170
|
'star-atlas': () => new SerumTradesMapper('star-atlas'),
|
|
170
171
|
mango: () => new SerumTradesMapper('mango'),
|
|
171
|
-
'bybit-spot': () => new BybitSpotTradesMapper('bybit-spot')
|
|
172
|
+
'bybit-spot': () => new BybitSpotTradesMapper('bybit-spot'),
|
|
173
|
+
'crypto-com': () => new CryptoComTradesMapper('crypto-com'),
|
|
174
|
+
'crypto-com-derivatives': () => new CryptoComTradesMapper('crypto-com-derivatives')
|
|
172
175
|
}
|
|
173
176
|
|
|
174
177
|
const bookChangeMappers = {
|
|
@@ -236,7 +239,9 @@ const bookChangeMappers = {
|
|
|
236
239
|
dydx: () => new DydxBookChangeMapper(),
|
|
237
240
|
serum: () => new SerumBookChangeMapper('serum'),
|
|
238
241
|
'star-atlas': () => new SerumBookChangeMapper('star-atlas'),
|
|
239
|
-
mango: () => new SerumBookChangeMapper('mango')
|
|
242
|
+
mango: () => new SerumBookChangeMapper('mango'),
|
|
243
|
+
'crypto-com': () => new CryptoComBookChangeMapper('crypto-com'),
|
|
244
|
+
'crypto-com-derivatives': () => new CryptoComBookChangeMapper('crypto-com-derivatives')
|
|
240
245
|
}
|
|
241
246
|
|
|
242
247
|
const derivativeTickersMappers = {
|
|
@@ -264,7 +269,8 @@ const derivativeTickersMappers = {
|
|
|
264
269
|
'gate-io-futures': () => new GateIOFuturesDerivativeTickerMapper(),
|
|
265
270
|
coinflex: () => new CoinflexDerivativeTickerMapper(),
|
|
266
271
|
ascendex: () => new AscendexDerivativeTickerMapper(),
|
|
267
|
-
dydx: () => new DydxDerivativeTickerMapper()
|
|
272
|
+
dydx: () => new DydxDerivativeTickerMapper(),
|
|
273
|
+
'crypto-com-derivatives': () => new CryptoComDerivativeTickerMapper('crypto-com-derivatives')
|
|
268
274
|
}
|
|
269
275
|
|
|
270
276
|
const optionsSummaryMappers = {
|
|
@@ -341,7 +347,9 @@ const bookTickersMappers = {
|
|
|
341
347
|
'star-atlas': () => new SerumBookTickerMapper('star-atlas'),
|
|
342
348
|
mango: () => new SerumBookTickerMapper('mango'),
|
|
343
349
|
'gate-io-futures': () => new GateIOFuturesBookTickerMapper('gate-io-futures'),
|
|
344
|
-
'bybit-spot': () => new BybitSpotBookTickerMapper('bybit-spot')
|
|
350
|
+
'bybit-spot': () => new BybitSpotBookTickerMapper('bybit-spot'),
|
|
351
|
+
'crypto-com': () => new CryptoComBookTickerMapper('crypto-com'),
|
|
352
|
+
'crypto-com-derivatives': () => new CryptoComBookTickerMapper('crypto-com-derivatives')
|
|
345
353
|
}
|
|
346
354
|
|
|
347
355
|
export const normalizeTrades = <T extends keyof typeof tradesMappers>(exchange: T, localTimestamp: Date): Mapper<T, Trade> => {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Filter } from '../types'
|
|
2
|
+
import { RealTimeFeedBase } from './realtimefeed'
|
|
3
|
+
|
|
4
|
+
export class CryptoComRealTimeFeed extends RealTimeFeedBase {
|
|
5
|
+
protected wssURL = 'wss://stream.crypto.com/v2/market'
|
|
6
|
+
|
|
7
|
+
protected mapToSubscribeMessages(filters: Filter<string>[]): any[] {
|
|
8
|
+
const channels = filters
|
|
9
|
+
.map((filter) => {
|
|
10
|
+
if (!filter.symbols || filter.symbols.length === 0) {
|
|
11
|
+
throw new Error('CryptoComRealTimeFeed requires explicitly specified symbols when subscribing to live feed')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return filter.symbols.map((symbol) => {
|
|
15
|
+
const suffix = filter.channel === 'book' ? '.150' : ''
|
|
16
|
+
return `${filter.channel}.${symbol}${suffix}`
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
.flatMap((s) => s)
|
|
20
|
+
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
id: 1,
|
|
24
|
+
method: 'subscribe',
|
|
25
|
+
nonce: new Date().valueOf(),
|
|
26
|
+
params: {
|
|
27
|
+
channels: channels
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected messageIsError(message: any): boolean {
|
|
34
|
+
return message.code !== undefined && message.code !== 0
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected onMessage(msg: any) {
|
|
38
|
+
if (msg.method === 'public/heartbeat') {
|
|
39
|
+
this.send({
|
|
40
|
+
id: msg.id,
|
|
41
|
+
method: 'public/respond-heartbeat'
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
protected messageIsHeartbeat(msg: any) {
|
|
46
|
+
return msg.method === 'public/heartbeat'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Filter } from '../types'
|
|
2
|
+
import { RealTimeFeedBase } from './realtimefeed'
|
|
3
|
+
|
|
4
|
+
export class CryptoComDerivativesRealTimeFeed extends RealTimeFeedBase {
|
|
5
|
+
protected wssURL = 'wss://deriv-stream.crypto.com/v1/market'
|
|
6
|
+
|
|
7
|
+
protected mapToSubscribeMessages(filters: Filter<string>[]): any[] {
|
|
8
|
+
const channels = filters
|
|
9
|
+
.map((filter) => {
|
|
10
|
+
if (!filter.symbols || filter.symbols.length === 0) {
|
|
11
|
+
throw new Error('CryptoComDerivativesRealTimeFeed requires explicitly specified symbols when subscribing to live feed')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return filter.symbols.map((symbol) => {
|
|
15
|
+
const suffix = filter.channel === 'book' ? '.50' : ''
|
|
16
|
+
return `${filter.channel}.${symbol}${suffix}`
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
.flatMap((s) => s)
|
|
20
|
+
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
id: 1,
|
|
24
|
+
method: 'subscribe',
|
|
25
|
+
nonce: new Date().valueOf(),
|
|
26
|
+
params: {
|
|
27
|
+
channels: channels,
|
|
28
|
+
book_subscription_type: 'SNAPSHOT_AND_UPDATE',
|
|
29
|
+
book_update_frequency: 5
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected messageIsError(message: any): boolean {
|
|
36
|
+
return message.code !== undefined && message.code !== 0 && message.code !== 40003
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
protected onMessage(msg: any) {
|
|
40
|
+
if (msg.method === 'public/heartbeat') {
|
|
41
|
+
this.send({
|
|
42
|
+
id: msg.id,
|
|
43
|
+
method: 'public/respond-heartbeat'
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
protected messageIsHeartbeat(msg: any) {
|
|
48
|
+
return msg.method === 'public/heartbeat'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -42,6 +42,8 @@ import { SerumRealTimeFeed } from './serum'
|
|
|
42
42
|
import { StarAtlasRealTimeFeed } from './staratlas'
|
|
43
43
|
import { MangoRealTimeFeed } from './mango'
|
|
44
44
|
import { BybitSpotRealTimeFeed } from './bybitspot'
|
|
45
|
+
import { CryptoComRealTimeFeed } from './cryptocom'
|
|
46
|
+
import { CryptoComDerivativesRealTimeFeed } from './cryptocomderivatives'
|
|
45
47
|
|
|
46
48
|
export * from './realtimefeed'
|
|
47
49
|
|
|
@@ -91,7 +93,9 @@ const realTimeFeedsMap: {
|
|
|
91
93
|
'star-atlas': StarAtlasRealTimeFeed,
|
|
92
94
|
'huobi-dm-options': HuobiDMOptionsRealTimeFeed,
|
|
93
95
|
mango: MangoRealTimeFeed,
|
|
94
|
-
'bybit-spot': BybitSpotRealTimeFeed
|
|
96
|
+
'bybit-spot': BybitSpotRealTimeFeed,
|
|
97
|
+
'crypto-com': CryptoComRealTimeFeed,
|
|
98
|
+
'crypto-com-derivatives': CryptoComDerivativesRealTimeFeed
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
export function getRealTimeFeedFactory(exchange: Exchange): RealTimeFeed {
|