tardis-dev 13.4.10 → 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 +6 -2
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +26 -3
- package/dist/consts.js.map +1 -1
- package/dist/mappers/bybit.d.ts +1 -1
- package/dist/mappers/bybitspot.d.ts +96 -0
- package/dist/mappers/bybitspot.d.ts.map +1 -0
- package/dist/mappers/bybitspot.js +102 -0
- package/dist/mappers/bybitspot.js.map +1 -0
- 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 +25 -6
- package/dist/mappers/index.js.map +1 -1
- package/dist/mappers/poloniex.d.ts +60 -0
- package/dist/mappers/poloniex.d.ts.map +1 -1
- package/dist/mappers/poloniex.js +73 -2
- package/dist/mappers/poloniex.js.map +1 -1
- package/dist/mappers/serum.d.ts +12 -0
- package/dist/mappers/serum.d.ts.map +1 -1
- package/dist/mappers/serum.js +2 -2
- package/dist/mappers/serum.js.map +1 -1
- package/dist/realtimefeeds/ascendex.d.ts +2 -0
- package/dist/realtimefeeds/ascendex.d.ts.map +1 -1
- package/dist/realtimefeeds/ascendex.js +6 -0
- package/dist/realtimefeeds/ascendex.js.map +1 -1
- package/dist/realtimefeeds/bybit.d.ts +2 -0
- package/dist/realtimefeeds/bybit.d.ts.map +1 -1
- package/dist/realtimefeeds/bybit.js +6 -0
- package/dist/realtimefeeds/bybit.js.map +1 -1
- package/dist/realtimefeeds/bybitspot.d.ts +10 -0
- package/dist/realtimefeeds/bybitspot.d.ts.map +1 -0
- package/dist/realtimefeeds/bybitspot.js +40 -0
- package/dist/realtimefeeds/bybitspot.js.map +1 -0
- 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/delta.d.ts +2 -0
- package/dist/realtimefeeds/delta.d.ts.map +1 -1
- package/dist/realtimefeeds/delta.js +6 -0
- package/dist/realtimefeeds/delta.js.map +1 -1
- package/dist/realtimefeeds/ftx.d.ts +2 -0
- package/dist/realtimefeeds/ftx.d.ts.map +1 -1
- package/dist/realtimefeeds/ftx.js +6 -0
- package/dist/realtimefeeds/ftx.js.map +1 -1
- package/dist/realtimefeeds/index.d.ts.map +1 -1
- package/dist/realtimefeeds/index.js +9 -1
- package/dist/realtimefeeds/index.js.map +1 -1
- package/dist/realtimefeeds/mango.d.ts +5 -0
- package/dist/realtimefeeds/mango.d.ts.map +1 -0
- package/dist/realtimefeeds/mango.js +12 -0
- package/dist/realtimefeeds/mango.js.map +1 -0
- package/dist/realtimefeeds/poloniex.d.ts +6 -3
- package/dist/realtimefeeds/poloniex.d.ts.map +1 -1
- package/dist/realtimefeeds/poloniex.js +14 -9
- package/dist/realtimefeeds/poloniex.js.map +1 -1
- package/dist/realtimefeeds/realtimefeed.d.ts +1 -0
- package/dist/realtimefeeds/realtimefeed.d.ts.map +1 -1
- package/dist/realtimefeeds/realtimefeed.js +7 -1
- package/dist/realtimefeeds/realtimefeed.js.map +1 -1
- package/package.json +1 -1
- package/src/consts.ts +30 -3
- package/src/mappers/bybitspot.ts +129 -0
- package/src/mappers/cryptocom.ts +395 -0
- package/src/mappers/index.ts +30 -8
- package/src/mappers/poloniex.ts +134 -1
- package/src/mappers/serum.ts +27 -13
- package/src/realtimefeeds/ascendex.ts +8 -0
- package/src/realtimefeeds/bybit.ts +8 -0
- package/src/realtimefeeds/bybitspot.ts +39 -0
- package/src/realtimefeeds/cryptocom.ts +48 -0
- package/src/realtimefeeds/cryptocomderivatives.ts +50 -0
- package/src/realtimefeeds/delta.ts +8 -0
- package/src/realtimefeeds/ftx.ts +8 -0
- package/src/realtimefeeds/index.ts +9 -1
- package/src/realtimefeeds/mango.ts +5 -0
- package/src/realtimefeeds/poloniex.ts +16 -10
- package/src/realtimefeeds/realtimefeed.ts +7 -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
|
@@ -28,8 +28,10 @@ import {
|
|
|
28
28
|
} from './bitmex'
|
|
29
29
|
import { BitstampBookChangeMapper, bitstampTradesMapper } from './bitstamp'
|
|
30
30
|
import { BybitBookChangeMapper, BybitDerivativeTickerMapper, BybitLiquidationsMapper, BybitTradesMapper } from './bybit'
|
|
31
|
+
import { BybitSpotBookChangeMapper, BybitSpotBookTickerMapper, BybitSpotTradesMapper } from './bybitspot'
|
|
31
32
|
import { CoinbaseBookChangMapper, coinbaseBookTickerMapper, coinbaseTradesMapper } from './coinbase'
|
|
32
33
|
import { coinflexBookChangeMapper, CoinflexDerivativeTickerMapper, coinflexTradesMapper } from './coinflex'
|
|
34
|
+
import { CryptoComBookChangeMapper, CryptoComBookTickerMapper, CryptoComDerivativeTickerMapper, CryptoComTradesMapper } from './cryptocom'
|
|
33
35
|
import {
|
|
34
36
|
cryptofacilitiesBookChangeMapper,
|
|
35
37
|
CryptofacilitiesDerivativeTickerMapper,
|
|
@@ -83,7 +85,7 @@ import {
|
|
|
83
85
|
OkexV5TradesMapper
|
|
84
86
|
} from './okex'
|
|
85
87
|
import { phemexBookChangeMapper, PhemexDerivativeTickerMapper, phemexTradesMapper } from './phemex'
|
|
86
|
-
import { PoloniexBookChangeMapper, PoloniexTradesMapper } from './poloniex'
|
|
88
|
+
import { PoloniexBookChangeMapper, PoloniexTradesMapper, PoloniexV2BookChangeMapper, PoloniexV2TradesMapper } from './poloniex'
|
|
87
89
|
import { SerumBookChangeMapper, SerumBookTickerMapper, SerumTradesMapper } from './serum'
|
|
88
90
|
import { UpbitBookChangeMapper, UpbitTradesMapper } from './upbit'
|
|
89
91
|
|
|
@@ -108,6 +110,12 @@ const canUseOkexTbtBookTicker = (localTimestamp: Date) => {
|
|
|
108
110
|
return isRealTime(localTimestamp) || localTimestamp.valueOf() >= OKEX_V5_TBT_BOOK_TICKER_RELEASE_DATE.valueOf()
|
|
109
111
|
}
|
|
110
112
|
|
|
113
|
+
const POLONIEX_V2_API_SWITCH_DATE = new Date('2022-08-02T00:00:00.000Z')
|
|
114
|
+
|
|
115
|
+
const shouldUsePoloniexV2Mappers = (localTimestamp: Date) => {
|
|
116
|
+
return isRealTime(localTimestamp) || localTimestamp.valueOf() >= POLONIEX_V2_API_SWITCH_DATE.valueOf()
|
|
117
|
+
}
|
|
118
|
+
|
|
111
119
|
const tradesMappers = {
|
|
112
120
|
bitmex: () => bitmexTradesMapper,
|
|
113
121
|
binance: () => new BinanceTradesMapper('binance'),
|
|
@@ -151,14 +159,19 @@ const tradesMappers = {
|
|
|
151
159
|
delta: (localTimestamp: Date) => new DeltaTradesMapper(localTimestamp.valueOf() >= new Date('2020-10-14').valueOf()),
|
|
152
160
|
'gate-io': () => new GateIOTradesMapper('gate-io'),
|
|
153
161
|
'gate-io-futures': () => new GateIOFuturesTradesMapper('gate-io-futures'),
|
|
154
|
-
poloniex: () =>
|
|
162
|
+
poloniex: (localTimestamp: Date) =>
|
|
163
|
+
shouldUsePoloniexV2Mappers(localTimestamp) ? new PoloniexV2TradesMapper() : new PoloniexTradesMapper(),
|
|
155
164
|
coinflex: () => coinflexTradesMapper,
|
|
156
165
|
'binance-options': () => new BinanceOptionsTradesMapper(),
|
|
157
166
|
upbit: () => new UpbitTradesMapper(),
|
|
158
167
|
ascendex: () => new AscendexTradesMapper(),
|
|
159
168
|
dydx: () => new DydxTradesMapper(),
|
|
160
169
|
serum: () => new SerumTradesMapper('serum'),
|
|
161
|
-
'star-atlas': () => new SerumTradesMapper('star-atlas')
|
|
170
|
+
'star-atlas': () => new SerumTradesMapper('star-atlas'),
|
|
171
|
+
mango: () => new SerumTradesMapper('mango'),
|
|
172
|
+
'bybit-spot': () => new BybitSpotTradesMapper('bybit-spot'),
|
|
173
|
+
'crypto-com': () => new CryptoComTradesMapper('crypto-com'),
|
|
174
|
+
'crypto-com-derivatives': () => new CryptoComTradesMapper('crypto-com-derivatives')
|
|
162
175
|
}
|
|
163
176
|
|
|
164
177
|
const bookChangeMappers = {
|
|
@@ -208,7 +221,7 @@ const bookChangeMappers = {
|
|
|
208
221
|
'huobi-dm-swap': () => new HuobiBookChangeMapper('huobi-dm-swap'),
|
|
209
222
|
'huobi-dm-linear-swap': () => new HuobiBookChangeMapper('huobi-dm-linear-swap'),
|
|
210
223
|
'huobi-dm-options': () => new HuobiBookChangeMapper('huobi-dm-options'),
|
|
211
|
-
|
|
224
|
+
'bybit-spot': () => new BybitSpotBookChangeMapper('bybit-spot'),
|
|
212
225
|
bybit: () => new BybitBookChangeMapper('bybit', false),
|
|
213
226
|
okcoin: (localTimestamp: Date) =>
|
|
214
227
|
new OkexBookChangeMapper('okcoin', 'spot', localTimestamp.valueOf() >= new Date('2020-02-13').valueOf()),
|
|
@@ -217,14 +230,18 @@ const bookChangeMappers = {
|
|
|
217
230
|
delta: () => deltaBookChangeMapper,
|
|
218
231
|
'gate-io': () => new GateIOBookChangeMapper('gate-io'),
|
|
219
232
|
'gate-io-futures': () => new GateIOFuturesBookChangeMapper('gate-io-futures'),
|
|
220
|
-
poloniex: () =>
|
|
233
|
+
poloniex: (localTimestamp: Date) =>
|
|
234
|
+
shouldUsePoloniexV2Mappers(localTimestamp) ? new PoloniexV2BookChangeMapper() : new PoloniexBookChangeMapper(),
|
|
221
235
|
coinflex: () => coinflexBookChangeMapper,
|
|
222
236
|
'binance-options': () => new BinanceOptionsBookChangeMapper(),
|
|
223
237
|
upbit: () => new UpbitBookChangeMapper(),
|
|
224
238
|
ascendex: () => new AscendexBookChangeMapper(),
|
|
225
239
|
dydx: () => new DydxBookChangeMapper(),
|
|
226
240
|
serum: () => new SerumBookChangeMapper('serum'),
|
|
227
|
-
'star-atlas': () => new SerumBookChangeMapper('star-atlas')
|
|
241
|
+
'star-atlas': () => new SerumBookChangeMapper('star-atlas'),
|
|
242
|
+
mango: () => new SerumBookChangeMapper('mango'),
|
|
243
|
+
'crypto-com': () => new CryptoComBookChangeMapper('crypto-com'),
|
|
244
|
+
'crypto-com-derivatives': () => new CryptoComBookChangeMapper('crypto-com-derivatives')
|
|
228
245
|
}
|
|
229
246
|
|
|
230
247
|
const derivativeTickersMappers = {
|
|
@@ -252,7 +269,8 @@ const derivativeTickersMappers = {
|
|
|
252
269
|
'gate-io-futures': () => new GateIOFuturesDerivativeTickerMapper(),
|
|
253
270
|
coinflex: () => new CoinflexDerivativeTickerMapper(),
|
|
254
271
|
ascendex: () => new AscendexDerivativeTickerMapper(),
|
|
255
|
-
dydx: () => new DydxDerivativeTickerMapper()
|
|
272
|
+
dydx: () => new DydxDerivativeTickerMapper(),
|
|
273
|
+
'crypto-com-derivatives': () => new CryptoComDerivativeTickerMapper('crypto-com-derivatives')
|
|
256
274
|
}
|
|
257
275
|
|
|
258
276
|
const optionsSummaryMappers = {
|
|
@@ -327,7 +345,11 @@ const bookTickersMappers = {
|
|
|
327
345
|
okcoin: () => new OkexBookTickerMapper('okcoin', 'spot'),
|
|
328
346
|
serum: () => new SerumBookTickerMapper('serum'),
|
|
329
347
|
'star-atlas': () => new SerumBookTickerMapper('star-atlas'),
|
|
330
|
-
|
|
348
|
+
mango: () => new SerumBookTickerMapper('mango'),
|
|
349
|
+
'gate-io-futures': () => new GateIOFuturesBookTickerMapper('gate-io-futures'),
|
|
350
|
+
'bybit-spot': () => new BybitSpotBookTickerMapper('bybit-spot'),
|
|
351
|
+
'crypto-com': () => new CryptoComBookTickerMapper('crypto-com'),
|
|
352
|
+
'crypto-com-derivatives': () => new CryptoComBookTickerMapper('crypto-com-derivatives')
|
|
331
353
|
}
|
|
332
354
|
|
|
333
355
|
export const normalizeTrades = <T extends keyof typeof tradesMappers>(exchange: T, localTimestamp: Date): Mapper<T, Trade> => {
|
package/src/mappers/poloniex.ts
CHANGED
|
@@ -2,12 +2,87 @@ import { upperCaseSymbols } from '../handy'
|
|
|
2
2
|
import { BookChange, Trade } from '../types'
|
|
3
3
|
import { Mapper } from './mapper'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
export class PoloniexV2TradesMapper implements Mapper<'poloniex', Trade> {
|
|
6
|
+
canHandle(message: any) {
|
|
7
|
+
return message.channel === 'trades' && message.data !== undefined && message.data.length > 0
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
getFilters(symbols?: string[]) {
|
|
11
|
+
symbols = upperCaseSymbols(symbols)
|
|
12
|
+
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
channel: 'trades',
|
|
16
|
+
symbols
|
|
17
|
+
} as const
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
*map(message: PoloniexV2TradesMessage, localTimestamp: Date): IterableIterator<Trade> {
|
|
22
|
+
for (const item of message.data) {
|
|
23
|
+
yield {
|
|
24
|
+
type: 'trade',
|
|
25
|
+
symbol: item.symbol,
|
|
26
|
+
exchange: 'poloniex',
|
|
27
|
+
id: item.id,
|
|
28
|
+
price: Number(item.price),
|
|
29
|
+
amount: Number(item.quantity),
|
|
30
|
+
side: item.takerSide === 'sell' ? 'sell' : 'buy',
|
|
31
|
+
timestamp: new Date(item.createTime),
|
|
32
|
+
localTimestamp: localTimestamp
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mapBookLevelV2 = (level: [string, string]) => {
|
|
39
|
+
return {
|
|
40
|
+
price: Number(level[0]),
|
|
41
|
+
amount: Number(level[1])
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export class PoloniexV2BookChangeMapper implements Mapper<'poloniex', BookChange> {
|
|
45
|
+
canHandle(message: any) {
|
|
46
|
+
return message.channel === 'book_lv2' && message.data !== undefined && message.data.length > 0
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getFilters(symbols?: string[]) {
|
|
50
|
+
symbols = upperCaseSymbols(symbols)
|
|
51
|
+
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
channel: 'book_lv2',
|
|
55
|
+
symbols
|
|
56
|
+
} as const
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
*map(message: PoloniexV2BookMessage, localTimestamp: Date): IterableIterator<BookChange> {
|
|
61
|
+
for (const item of message.data) {
|
|
62
|
+
const bookSnapshot: BookChange = {
|
|
63
|
+
type: 'book_change',
|
|
64
|
+
symbol: item.symbol,
|
|
65
|
+
exchange: 'poloniex',
|
|
66
|
+
isSnapshot: message.action === 'snapshot',
|
|
67
|
+
bids: item.bids.map(mapBookLevelV2),
|
|
68
|
+
asks: item.asks.map(mapBookLevelV2),
|
|
69
|
+
timestamp: new Date(item.ts),
|
|
70
|
+
localTimestamp: localTimestamp
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
yield bookSnapshot
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
6
77
|
|
|
7
78
|
export class PoloniexTradesMapper implements Mapper<'poloniex', Trade> {
|
|
8
79
|
private readonly _channelIdToSymbolMap: Map<number, string> = new Map()
|
|
9
80
|
|
|
10
81
|
canHandle(message: PoloniexPriceAggreatedMessage) {
|
|
82
|
+
if (Array.isArray(message) === false) {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
11
86
|
if (message.length < 3) {
|
|
12
87
|
return false
|
|
13
88
|
}
|
|
@@ -80,6 +155,10 @@ export class PoloniexBookChangeMapper implements Mapper<'poloniex', BookChange>
|
|
|
80
155
|
private readonly _channelIdToSymbolMap: Map<number, string> = new Map()
|
|
81
156
|
|
|
82
157
|
canHandle(message: PoloniexPriceAggreatedMessage) {
|
|
158
|
+
if (Array.isArray(message) === false) {
|
|
159
|
+
return false
|
|
160
|
+
}
|
|
161
|
+
|
|
83
162
|
if (message.length < 3) {
|
|
84
163
|
return false
|
|
85
164
|
}
|
|
@@ -153,3 +232,57 @@ type PoloniexBookUpdate = ['o', 0 | 1, string, string]
|
|
|
153
232
|
type PoloniexTrade = ['t', string, 1 | 0, string, string, number]
|
|
154
233
|
|
|
155
234
|
type PoloniexPriceAggreatedMessage = [number, number, (PoloniexBookSnapshot | PoloniexBookUpdate | PoloniexTrade)[], string?]
|
|
235
|
+
|
|
236
|
+
type PoloniexV2SubscribeMessage = {
|
|
237
|
+
event: 'subscribe'
|
|
238
|
+
channel: 'trades'
|
|
239
|
+
symbols: string[]
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
type PoloniexV2TradesMessage = {
|
|
243
|
+
channel: 'trades'
|
|
244
|
+
data: [
|
|
245
|
+
{
|
|
246
|
+
symbol: 'USDD_USDT'
|
|
247
|
+
amount: '53.17153856'
|
|
248
|
+
quantity: '53.0866'
|
|
249
|
+
takerSide: 'sell'
|
|
250
|
+
createTime: 1659916859838
|
|
251
|
+
price: '1.0016'
|
|
252
|
+
id: '60100203'
|
|
253
|
+
ts: 1659916859843
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
type PoloniexV2BookMessage =
|
|
259
|
+
| {
|
|
260
|
+
channel: 'book_lv2'
|
|
261
|
+
data: [
|
|
262
|
+
{
|
|
263
|
+
symbol: 'AAVE_BTC'
|
|
264
|
+
createTime: 1659916859818
|
|
265
|
+
asks: [string, string][]
|
|
266
|
+
bids: [string, string][]
|
|
267
|
+
lastId: 20251
|
|
268
|
+
id: 20252
|
|
269
|
+
ts: 1659916859824
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
action: 'update'
|
|
273
|
+
}
|
|
274
|
+
| {
|
|
275
|
+
channel: 'book_lv2'
|
|
276
|
+
data: [
|
|
277
|
+
{
|
|
278
|
+
symbol: 'AAVE_BTC'
|
|
279
|
+
createTime: 1659900600092
|
|
280
|
+
asks: [string, string][]
|
|
281
|
+
bids: [string, string][]
|
|
282
|
+
lastId: 85
|
|
283
|
+
id: 86
|
|
284
|
+
ts: 1659916800614
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
action: 'snapshot'
|
|
288
|
+
}
|