tardis-dev 13.29.16 → 13.31.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.
- package/dist/consts.d.ts +5 -2
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +13 -3
- package/dist/consts.js.map +1 -1
- package/dist/handy.d.ts +1 -0
- package/dist/handy.d.ts.map +1 -1
- package/dist/handy.js +7 -1
- package/dist/handy.js.map +1 -1
- package/dist/mappers/bitget.d.ts +142 -0
- package/dist/mappers/bitget.d.ts.map +1 -0
- package/dist/mappers/bitget.js +145 -0
- package/dist/mappers/bitget.js.map +1 -0
- package/dist/mappers/bybit.d.ts +2 -2
- package/dist/mappers/bybitspot.d.ts +1 -1
- package/dist/mappers/cryptocom.d.ts +1 -1
- package/dist/mappers/dydxv4.d.ts +177 -0
- package/dist/mappers/dydxv4.d.ts.map +1 -0
- package/dist/mappers/dydxv4.js +189 -0
- package/dist/mappers/dydxv4.js.map +1 -0
- package/dist/mappers/huobi.d.ts +3 -3
- package/dist/mappers/index.d.ts +5 -5
- package/dist/mappers/index.d.ts.map +1 -1
- package/dist/mappers/index.js +17 -4
- package/dist/mappers/index.js.map +1 -1
- package/dist/realtimefeeds/bitget.d.ts +17 -0
- package/dist/realtimefeeds/bitget.d.ts.map +1 -0
- package/dist/realtimefeeds/bitget.js +55 -0
- package/dist/realtimefeeds/bitget.js.map +1 -0
- package/dist/realtimefeeds/dydx_v4.d.ts +8 -0
- package/dist/realtimefeeds/dydx_v4.d.ts.map +1 -0
- package/dist/realtimefeeds/dydx_v4.js +40 -0
- package/dist/realtimefeeds/dydx_v4.js.map +1 -0
- package/dist/realtimefeeds/index.d.ts.map +1 -1
- package/dist/realtimefeeds/index.js +6 -1
- package/dist/realtimefeeds/index.js.map +1 -1
- package/package.json +1 -1
- package/src/consts.ts +14 -3
- package/src/handy.ts +5 -0
- package/src/mappers/bitget.ts +230 -0
- package/src/mappers/dydxv4.ts +339 -0
- package/src/mappers/index.ts +17 -4
- package/src/realtimefeeds/bitget.ts +59 -0
- package/src/realtimefeeds/dydx_v4.ts +39 -0
- package/src/realtimefeeds/index.ts +6 -1
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { upperCaseSymbols } from '../handy'
|
|
2
|
+
import { BookChange, DerivativeTicker, Liquidation, Trade } from '../types'
|
|
3
|
+
import { Mapper, PendingTickerInfoHelper } from './mapper'
|
|
4
|
+
|
|
5
|
+
export class DydxV4TradesMapper implements Mapper<'dydx-v4', Trade> {
|
|
6
|
+
canHandle(message: DyDxTrade) {
|
|
7
|
+
return message.channel === 'v4_trades' && message.type === 'channel_data'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
getFilters(symbols?: string[]) {
|
|
11
|
+
symbols = upperCaseSymbols(symbols)
|
|
12
|
+
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
channel: 'v4_trades',
|
|
16
|
+
symbols
|
|
17
|
+
} as const
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
*map(message: DyDxTrade, localTimestamp: Date): IterableIterator<Trade> {
|
|
22
|
+
for (let trade of message.contents.trades) {
|
|
23
|
+
yield {
|
|
24
|
+
type: 'trade',
|
|
25
|
+
symbol: message.id,
|
|
26
|
+
exchange: 'dydx-v4',
|
|
27
|
+
id: trade.id,
|
|
28
|
+
price: Number(trade.price),
|
|
29
|
+
amount: Number(trade.size),
|
|
30
|
+
side: trade.side === 'SELL' ? 'sell' : 'buy',
|
|
31
|
+
timestamp: trade.createdAt ? new Date(trade.createdAt) : localTimestamp,
|
|
32
|
+
localTimestamp: localTimestamp
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function mapSnapshotPriceLevel(level: { price: string; size: string }) {
|
|
39
|
+
return {
|
|
40
|
+
price: Number(level.price),
|
|
41
|
+
amount: Number(level.size)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function mapUpdatePriceLevel(level: [string, string]) {
|
|
46
|
+
return {
|
|
47
|
+
price: Number(level[0]),
|
|
48
|
+
amount: Number(level[1])
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export class DydxV4BookChangeMapper implements Mapper<'dydx-v4', BookChange> {
|
|
52
|
+
canHandle(message: DyDxOrderbookSnapshot | DyDxOrderBookUpdate) {
|
|
53
|
+
return message.channel === 'v4_orderbook'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getFilters(symbols?: string[]) {
|
|
57
|
+
symbols = upperCaseSymbols(symbols)
|
|
58
|
+
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
channel: 'v4_orderbook',
|
|
62
|
+
symbols
|
|
63
|
+
} as const
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
*map(message: DyDxOrderbookSnapshot | DyDxOrderBookUpdate, localTimestamp: Date): IterableIterator<BookChange> {
|
|
68
|
+
if (message.type === 'subscribed') {
|
|
69
|
+
yield {
|
|
70
|
+
type: 'book_change',
|
|
71
|
+
symbol: message.id,
|
|
72
|
+
exchange: 'dydx-v4',
|
|
73
|
+
isSnapshot: true,
|
|
74
|
+
bids: message.contents.bids.map(mapSnapshotPriceLevel),
|
|
75
|
+
asks: message.contents.asks.map(mapSnapshotPriceLevel),
|
|
76
|
+
timestamp: localTimestamp,
|
|
77
|
+
localTimestamp
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
if (!message.contents) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const bookChange: BookChange = {
|
|
85
|
+
type: 'book_change',
|
|
86
|
+
symbol: message.id,
|
|
87
|
+
exchange: 'dydx-v4',
|
|
88
|
+
isSnapshot: false,
|
|
89
|
+
bids: message.contents.bids !== undefined ? message.contents.bids.map(mapUpdatePriceLevel) : [],
|
|
90
|
+
asks: message.contents.asks !== undefined ? message.contents.asks.map(mapUpdatePriceLevel) : [],
|
|
91
|
+
timestamp: localTimestamp,
|
|
92
|
+
localTimestamp
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (bookChange.bids.length > 0 || bookChange.asks.length > 0) {
|
|
96
|
+
yield bookChange
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export class DydxV4DerivativeTickerMapper implements Mapper<'dydx-v4', DerivativeTicker> {
|
|
103
|
+
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
104
|
+
|
|
105
|
+
canHandle(message: DydxMarketsSnapshot | DyDxMarketsUpdate | DyDxTrade) {
|
|
106
|
+
return message.channel === 'v4_markets' || (message.channel === 'v4_trades' && message.type === 'channel_data')
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
getFilters(symbols?: string[]) {
|
|
110
|
+
symbols = upperCaseSymbols(symbols)
|
|
111
|
+
|
|
112
|
+
return [
|
|
113
|
+
{
|
|
114
|
+
channel: 'v4_markets',
|
|
115
|
+
symbols: [] as string[]
|
|
116
|
+
} as const,
|
|
117
|
+
{
|
|
118
|
+
channel: 'v4_trades',
|
|
119
|
+
symbols
|
|
120
|
+
} as const
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
*map(message: DydxMarketsSnapshot | DyDxMarketsUpdate | DyDxTrade, localTimestamp: Date): IterableIterator<DerivativeTicker> {
|
|
125
|
+
if (message.channel === 'v4_trades') {
|
|
126
|
+
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(message.id, 'dydx-v4')
|
|
127
|
+
pendingTickerInfo.updateLastPrice(Number(message.contents.trades[message.contents.trades.length - 1].price))
|
|
128
|
+
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
if (message.type === 'subscribed' || (message.type === 'channel_data' && message.contents.trading !== undefined)) {
|
|
132
|
+
const contents = message.type === 'subscribed' ? message.contents.markets : message.contents.trading
|
|
133
|
+
for (const key in contents) {
|
|
134
|
+
const marketInfo = (contents as any)[key] as DydxMarketsSnapshotContent | DydxMarketTradeUpdate
|
|
135
|
+
|
|
136
|
+
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(key, 'dydx-v4')
|
|
137
|
+
|
|
138
|
+
if (marketInfo.oraclePrice !== undefined) {
|
|
139
|
+
pendingTickerInfo.updateMarkPrice(Number(marketInfo.oraclePrice))
|
|
140
|
+
}
|
|
141
|
+
if (marketInfo.openInterest !== undefined) {
|
|
142
|
+
pendingTickerInfo.updateOpenInterest(Number(marketInfo.openInterest))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (marketInfo.nextFundingRate !== undefined) {
|
|
146
|
+
pendingTickerInfo.updateFundingRate(Number(marketInfo.nextFundingRate))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
pendingTickerInfo.updateTimestamp(localTimestamp)
|
|
150
|
+
|
|
151
|
+
if (pendingTickerInfo.hasChanged()) {
|
|
152
|
+
yield pendingTickerInfo.getSnapshot(localTimestamp)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (message.type === 'channel_data' && message.contents.oraclePrices !== undefined) {
|
|
158
|
+
for (const key in message.contents.oraclePrices) {
|
|
159
|
+
const oraclePriceInfo = (message.contents.oraclePrices as any)[key] as OraclePriceInfo
|
|
160
|
+
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(key, 'dydx-v4')
|
|
161
|
+
if (oraclePriceInfo.oraclePrice !== undefined) {
|
|
162
|
+
pendingTickerInfo.updateMarkPrice(Number(oraclePriceInfo.oraclePrice))
|
|
163
|
+
}
|
|
164
|
+
pendingTickerInfo.updateTimestamp(localTimestamp)
|
|
165
|
+
|
|
166
|
+
if (pendingTickerInfo.hasChanged()) {
|
|
167
|
+
yield pendingTickerInfo.getSnapshot(localTimestamp)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export class DydxV4LiquidationsMapper implements Mapper<'dydx-v4', Liquidation> {
|
|
175
|
+
canHandle(message: DyDxTrade) {
|
|
176
|
+
return message.channel === 'v4_trades' && message.type === 'channel_data'
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
getFilters(symbols?: string[]) {
|
|
180
|
+
symbols = upperCaseSymbols(symbols)
|
|
181
|
+
|
|
182
|
+
return [
|
|
183
|
+
{
|
|
184
|
+
channel: 'v4_trades',
|
|
185
|
+
symbols
|
|
186
|
+
} as const
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
*map(message: DyDxTrade, localTimestamp: Date): IterableIterator<Liquidation> {
|
|
191
|
+
for (let trade of message.contents.trades) {
|
|
192
|
+
if (trade.type === 'LIQUIDATED') {
|
|
193
|
+
yield {
|
|
194
|
+
type: 'liquidation',
|
|
195
|
+
symbol: message.id,
|
|
196
|
+
exchange: 'dydx-v4',
|
|
197
|
+
id: trade.id,
|
|
198
|
+
price: Number(trade.price),
|
|
199
|
+
amount: Number(trade.size),
|
|
200
|
+
side: trade.side === 'SELL' ? 'sell' : 'buy',
|
|
201
|
+
timestamp: trade.createdAt ? new Date(trade.createdAt) : localTimestamp,
|
|
202
|
+
localTimestamp: localTimestamp
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
type DyDxTrade = {
|
|
210
|
+
type: 'channel_data'
|
|
211
|
+
connection_id: '3a2e4c0c-7579-4bf6-a570-e0979418bbe9'
|
|
212
|
+
message_id: 15897
|
|
213
|
+
id: 'BTC-USD'
|
|
214
|
+
channel: 'v4_trades'
|
|
215
|
+
version: '2.1.0'
|
|
216
|
+
contents: {
|
|
217
|
+
trades: [
|
|
218
|
+
{
|
|
219
|
+
id: '0165e6170000000200000002'
|
|
220
|
+
size: '0.0001'
|
|
221
|
+
price: '60392'
|
|
222
|
+
side: 'BUY' | 'SELL'
|
|
223
|
+
createdAt: '2024-08-23T00:00:57.627Z'
|
|
224
|
+
type: 'LIMIT' | 'LIQUIDATED'
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
type DyDxOrderbookSnapshot = {
|
|
231
|
+
type: 'subscribed'
|
|
232
|
+
connection_id: '67838890-75de-4bf3-a638-d7bcdea5f245'
|
|
233
|
+
message_id: 7
|
|
234
|
+
channel: 'v4_orderbook'
|
|
235
|
+
id: 'GRT-USD'
|
|
236
|
+
contents: {
|
|
237
|
+
bids: [{ price: '0.1547'; size: '35520' }]
|
|
238
|
+
asks: [{ price: '0.155'; size: '3220' }]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
type DyDxOrderBookUpdate = {
|
|
243
|
+
type: 'channel_data'
|
|
244
|
+
connection_id: '00908030-4a70-43aa-9263-8ccdf57b5d40'
|
|
245
|
+
message_id: 10290
|
|
246
|
+
id: 'EOS-USD'
|
|
247
|
+
channel: 'v4_orderbook'
|
|
248
|
+
version: '1.0.0'
|
|
249
|
+
contents: { bids: [['0.1003', '2017130']]; asks: undefined | [['0.1003', '2017130']] }
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
type DydxMarketsSnapshot = {
|
|
253
|
+
type: 'subscribed'
|
|
254
|
+
connection_id: '3a2e4c0c-7579-4bf6-a570-e0979418bbe9'
|
|
255
|
+
message_id: 17
|
|
256
|
+
channel: 'v4_markets'
|
|
257
|
+
contents: {
|
|
258
|
+
markets: {
|
|
259
|
+
[key: string]: DydxMarketsSnapshotContent
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
type DydxMarketsSnapshotContent = {
|
|
264
|
+
clobPairId: '0'
|
|
265
|
+
ticker: 'BTC-USD'
|
|
266
|
+
status: 'ACTIVE'
|
|
267
|
+
oraclePrice: '60387.51779'
|
|
268
|
+
priceChange24H: '-782.58326'
|
|
269
|
+
volume24H: '247515340.0835'
|
|
270
|
+
trades24H: 73556
|
|
271
|
+
nextFundingRate: '0.00001351666666666667'
|
|
272
|
+
initialMarginFraction: '0.05'
|
|
273
|
+
maintenanceMarginFraction: '0.03'
|
|
274
|
+
openInterest: '648.2389'
|
|
275
|
+
atomicResolution: -10
|
|
276
|
+
quantumConversionExponent: -9
|
|
277
|
+
tickSize: '1'
|
|
278
|
+
stepSize: '0.0001'
|
|
279
|
+
stepBaseQuantums: 1000000
|
|
280
|
+
subticksPerTick: 100000
|
|
281
|
+
marketType: 'CROSS'
|
|
282
|
+
openInterestLowerCap: '0'
|
|
283
|
+
openInterestUpperCap: '0'
|
|
284
|
+
baseOpenInterest: '648.4278'
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
type DyDxMarketsUpdate =
|
|
288
|
+
| {
|
|
289
|
+
type: 'channel_data'
|
|
290
|
+
connection_id: '3a2e4c0c-7579-4bf6-a570-e0979418bbe9'
|
|
291
|
+
message_id: 15871
|
|
292
|
+
channel: 'v4_markets'
|
|
293
|
+
version: '1.0.0'
|
|
294
|
+
contents: {
|
|
295
|
+
oraclePrices: undefined
|
|
296
|
+
trading: {
|
|
297
|
+
'ETH-USD': DydxMarketTradeUpdate
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
| {
|
|
302
|
+
type: 'channel_data'
|
|
303
|
+
connection_id: '3a2e4c0c-7579-4bf6-a570-e0979418bbe9'
|
|
304
|
+
message_id: 50
|
|
305
|
+
channel: 'v4_markets'
|
|
306
|
+
version: '1.0.0'
|
|
307
|
+
contents: {
|
|
308
|
+
trading: undefined
|
|
309
|
+
oraclePrices: {
|
|
310
|
+
'ZERO-USD': OraclePriceInfo
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
type OraclePriceInfo = { oraclePrice: string; effectiveAt: string; effectiveAtHeight: string; marketId: number }
|
|
316
|
+
|
|
317
|
+
type DydxMarketTradeUpdate = {
|
|
318
|
+
id?: string
|
|
319
|
+
clobPairId?: string
|
|
320
|
+
ticker?: string
|
|
321
|
+
marketId?: number
|
|
322
|
+
oraclePrice: undefined
|
|
323
|
+
baseAsset?: string
|
|
324
|
+
quoteAsset?: string
|
|
325
|
+
initialMarginFraction?: string
|
|
326
|
+
maintenanceMarginFraction?: string
|
|
327
|
+
basePositionSize?: string
|
|
328
|
+
incrementalPositionSize?: string
|
|
329
|
+
maxPositionSize?: string
|
|
330
|
+
openInterest?: string
|
|
331
|
+
quantumConversionExponent?: number
|
|
332
|
+
atomicResolution?: number
|
|
333
|
+
subticksPerTick?: number
|
|
334
|
+
stepBaseQuantums?: number
|
|
335
|
+
priceChange24H?: string
|
|
336
|
+
volume24H?: string
|
|
337
|
+
trades24H?: number
|
|
338
|
+
nextFundingRate?: string
|
|
339
|
+
}
|
package/src/mappers/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
BitfinexTradesMapper
|
|
25
25
|
} from './bitfinex'
|
|
26
26
|
import { BitflyerBookChangeMapper, bitflyerBookTickerMapper, bitflyerTradesMapper } from './bitflyer'
|
|
27
|
+
import { BitgetBookChangeMapper, BitgetBookTickerMapper, BitgetDerivativeTickerMapper, BitgetTradesMapper } from './bitget'
|
|
27
28
|
import {
|
|
28
29
|
BitmexBookChangeMapper,
|
|
29
30
|
BitmexDerivativeTickerMapper,
|
|
@@ -67,6 +68,7 @@ import {
|
|
|
67
68
|
deribitTradesMapper
|
|
68
69
|
} from './deribit'
|
|
69
70
|
import { DydxBookChangeMapper, DydxDerivativeTickerMapper, DydxTradesMapper } from './dydx'
|
|
71
|
+
import { DydxV4BookChangeMapper, DydxV4DerivativeTickerMapper, DydxV4LiquidationsMapper, DydxV4TradesMapper } from './dydxv4'
|
|
70
72
|
import { FTXBookChangeMapper, FTXDerivativeTickerMapper, FTXLiquidationsMapper, FTXBookTickerMapper, FTXTradesMapper } from './ftx'
|
|
71
73
|
import {
|
|
72
74
|
GateIOBookChangeMapper,
|
|
@@ -255,6 +257,7 @@ const tradesMappers = {
|
|
|
255
257
|
upbit: () => new UpbitTradesMapper(),
|
|
256
258
|
ascendex: () => new AscendexTradesMapper(),
|
|
257
259
|
dydx: () => new DydxTradesMapper(),
|
|
260
|
+
'dydx-v4': () => new DydxV4TradesMapper(),
|
|
258
261
|
serum: () => new SerumTradesMapper('serum'),
|
|
259
262
|
'star-atlas': () => new SerumTradesMapper('star-atlas'),
|
|
260
263
|
mango: () => new SerumTradesMapper('mango'),
|
|
@@ -269,7 +272,9 @@ const tradesMappers = {
|
|
|
269
272
|
'blockchain-com': () => new BlockchainComTradesMapper(),
|
|
270
273
|
'bybit-options': () => new BybitV5TradesMapper('bybit-options'),
|
|
271
274
|
'binance-european-options': () => new BinanceEuropeanOptionsTradesMapper(),
|
|
272
|
-
'okex-spreads': () => new OkexSpreadsTradesMapper()
|
|
275
|
+
'okex-spreads': () => new OkexSpreadsTradesMapper(),
|
|
276
|
+
bitget: () => new BitgetTradesMapper('bitget'),
|
|
277
|
+
'bitget-futures': () => new BitgetTradesMapper('bitget-futures')
|
|
273
278
|
}
|
|
274
279
|
|
|
275
280
|
const bookChangeMappers = {
|
|
@@ -344,6 +349,7 @@ const bookChangeMappers = {
|
|
|
344
349
|
upbit: () => new UpbitBookChangeMapper(),
|
|
345
350
|
ascendex: () => new AscendexBookChangeMapper(),
|
|
346
351
|
dydx: () => new DydxBookChangeMapper(),
|
|
352
|
+
'dydx-v4': () => new DydxV4BookChangeMapper(),
|
|
347
353
|
serum: () => new SerumBookChangeMapper('serum'),
|
|
348
354
|
'star-atlas': () => new SerumBookChangeMapper('star-atlas'),
|
|
349
355
|
mango: () => new SerumBookChangeMapper('mango'),
|
|
@@ -356,7 +362,9 @@ const bookChangeMappers = {
|
|
|
356
362
|
'blockchain-com': () => new BlockchainComBookChangeMapper(),
|
|
357
363
|
'bybit-options': () => new BybitV5BookChangeMapper('bybit-options', 25),
|
|
358
364
|
'binance-european-options': () => new BinanceEuropeanOptionsBookChangeMapper(),
|
|
359
|
-
'okex-spreads': () => new OkexSpreadsBookChangeMapper()
|
|
365
|
+
'okex-spreads': () => new OkexSpreadsBookChangeMapper(),
|
|
366
|
+
bitget: () => new BitgetBookChangeMapper('bitget'),
|
|
367
|
+
'bitget-futures': () => new BitgetBookChangeMapper('bitget-futures')
|
|
360
368
|
}
|
|
361
369
|
|
|
362
370
|
const derivativeTickersMappers = {
|
|
@@ -386,10 +394,12 @@ const derivativeTickersMappers = {
|
|
|
386
394
|
coinflex: () => new CoinflexDerivativeTickerMapper(),
|
|
387
395
|
ascendex: () => new AscendexDerivativeTickerMapper(),
|
|
388
396
|
dydx: () => new DydxDerivativeTickerMapper(),
|
|
397
|
+
'dydx-v4': () => new DydxV4DerivativeTickerMapper(),
|
|
389
398
|
'crypto-com-derivatives': () => new CryptoComDerivativeTickerMapper('crypto-com-derivatives'),
|
|
390
399
|
'crypto-com': () => new CryptoComDerivativeTickerMapper('crypto-com'),
|
|
391
400
|
'woo-x': () => new WooxDerivativeTickerMapper(),
|
|
392
|
-
'kucoin-futures': () => new KucoinFuturesDerivativeTickerMapper()
|
|
401
|
+
'kucoin-futures': () => new KucoinFuturesDerivativeTickerMapper(),
|
|
402
|
+
'bitget-futures': () => new BitgetDerivativeTickerMapper()
|
|
393
403
|
}
|
|
394
404
|
|
|
395
405
|
const optionsSummaryMappers = {
|
|
@@ -411,6 +421,7 @@ const liquidationsMappers = {
|
|
|
411
421
|
'bitfinex-derivatives': () => new BitfinexLiquidationsMapper('bitfinex-derivatives'),
|
|
412
422
|
cryptofacilities: () => cryptofacilitiesLiquidationsMapper,
|
|
413
423
|
'huobi-dm': () => new HuobiLiquidationsMapper('huobi-dm'),
|
|
424
|
+
'dydx-v4': () => new DydxV4LiquidationsMapper(),
|
|
414
425
|
'huobi-dm-swap': () => new HuobiLiquidationsMapper('huobi-dm-swap'),
|
|
415
426
|
'huobi-dm-linear-swap': () => new HuobiLiquidationsMapper('huobi-dm-linear-swap'),
|
|
416
427
|
bybit: (localTimestamp: Date) =>
|
|
@@ -480,7 +491,9 @@ const bookTickersMappers = {
|
|
|
480
491
|
bybit: () => new BybitV5BookTickerMapper('bybit'),
|
|
481
492
|
'gate-io': () => new GateIOV4BookTickerMapper('gate-io'),
|
|
482
493
|
'okex-spreads': () => new OkexSpreadsBookTickerMapper(),
|
|
483
|
-
'kucoin-futures': () => new KucoinFuturesBookTickerMapper()
|
|
494
|
+
'kucoin-futures': () => new KucoinFuturesBookTickerMapper(),
|
|
495
|
+
bitget: () => new BitgetBookTickerMapper('bitget'),
|
|
496
|
+
'bitget-futures': () => new BitgetBookTickerMapper('bitget-futures')
|
|
484
497
|
}
|
|
485
498
|
|
|
486
499
|
export const normalizeTrades = <T extends keyof typeof tradesMappers>(exchange: T, localTimestamp: Date): Mapper<T, Trade> => {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { batchObjects } from '../handy'
|
|
2
|
+
import { Filter } from '../types'
|
|
3
|
+
import { RealTimeFeedBase } from './realtimefeed'
|
|
4
|
+
|
|
5
|
+
abstract class BitgetRealTimeFeedBase extends RealTimeFeedBase {
|
|
6
|
+
protected throttleSubscribeMS = 100
|
|
7
|
+
protected readonly wssURL = 'wss://ws.bitget.com/v2/ws/public'
|
|
8
|
+
|
|
9
|
+
protected mapToSubscribeMessages(filters: Filter<string>[]): any[] {
|
|
10
|
+
const argsInputs = filters.flatMap((filter) => {
|
|
11
|
+
if (!filter.symbols || filter.symbols.length === 0) {
|
|
12
|
+
throw new Error('BitgetRealTimeFeed requires explicitly specified symbols when subscribing to live feed')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return filter.symbols.map((symbol) => {
|
|
16
|
+
return {
|
|
17
|
+
instType: this.getInstType(symbol),
|
|
18
|
+
channel: filter.channel,
|
|
19
|
+
instId: symbol
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const payload = [...batchObjects(argsInputs, 5)].map((args) => {
|
|
25
|
+
return {
|
|
26
|
+
op: 'subscribe',
|
|
27
|
+
args
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
return payload
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected messageIsError(message: any): boolean {
|
|
35
|
+
return message.event === 'error'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
abstract getInstType(symbol: string): string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class BitgetRealTimeFeed extends BitgetRealTimeFeedBase {
|
|
42
|
+
getInstType(_: string) {
|
|
43
|
+
return 'SPOT'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class BitgetFuturesRealTimeFeed extends BitgetRealTimeFeedBase {
|
|
48
|
+
getInstType(symbol: string) {
|
|
49
|
+
if (symbol.endsWith('USDT')) {
|
|
50
|
+
return 'USDT-FUTURES'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (symbol.endsWith('PERP')) {
|
|
54
|
+
return 'USDC-FUTURES'
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return 'COIN-FUTURES'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Filter } from '../types'
|
|
2
|
+
import { RealTimeFeedBase } from './realtimefeed'
|
|
3
|
+
|
|
4
|
+
export class DydxV4RealTimeFeed extends RealTimeFeedBase {
|
|
5
|
+
protected readonly wssURL = 'wss://indexer.dydx.trade/v4/ws'
|
|
6
|
+
|
|
7
|
+
protected mapToSubscribeMessages(filters: Filter<string>[]): any[] {
|
|
8
|
+
const subs = filters
|
|
9
|
+
.map((filter) => {
|
|
10
|
+
if (filter.channel === 'v4_markets') {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
type: 'subscribe',
|
|
14
|
+
channel: 'v4_markets'
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!filter.symbols || filter.symbols.length === 0) {
|
|
20
|
+
throw new Error('DydxV4RealTimeFeed requires explicitly specified symbols when subscribing to live feed')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return filter.symbols.map((symbol) => {
|
|
24
|
+
return {
|
|
25
|
+
type: 'subscribe',
|
|
26
|
+
channel: filter.channel,
|
|
27
|
+
id: symbol
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
.flatMap((f) => f)
|
|
32
|
+
|
|
33
|
+
return subs
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
protected messageIsError(message: any): boolean {
|
|
37
|
+
return message.type === 'error'
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -49,6 +49,8 @@ import { BlockchainComRealTimeFeed } from './blockchaincom'
|
|
|
49
49
|
import { BinanceEuropeanOptionsRealTimeFeed } from './binanceeuropeanoptions'
|
|
50
50
|
import { OkexSpreadsRealTimeFeed } from './okexspreads'
|
|
51
51
|
import { KucoinFuturesRealTimeFeed } from './kucoinfutures'
|
|
52
|
+
import { DydxV4RealTimeFeed } from './dydx_v4'
|
|
53
|
+
import { BitgetFuturesRealTimeFeed, BitgetRealTimeFeed } from './bitget'
|
|
52
54
|
|
|
53
55
|
export * from './realtimefeed'
|
|
54
56
|
|
|
@@ -108,7 +110,10 @@ const realTimeFeedsMap: {
|
|
|
108
110
|
'blockchain-com': BlockchainComRealTimeFeed,
|
|
109
111
|
'binance-european-options': BinanceEuropeanOptionsRealTimeFeed,
|
|
110
112
|
'okex-spreads': OkexSpreadsRealTimeFeed,
|
|
111
|
-
'kucoin-futures': KucoinFuturesRealTimeFeed
|
|
113
|
+
'kucoin-futures': KucoinFuturesRealTimeFeed,
|
|
114
|
+
'dydx-v4': DydxV4RealTimeFeed,
|
|
115
|
+
bitget: BitgetRealTimeFeed,
|
|
116
|
+
'bitget-futures': BitgetFuturesRealTimeFeed
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
export function getRealTimeFeedFactory(exchange: Exchange): RealTimeFeed {
|