tardis-dev 16.5.1 → 16.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/consts.d.ts +3 -1
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +21 -1
- package/dist/consts.js.map +1 -1
- package/dist/handy.d.ts.map +1 -1
- package/dist/handy.js +6 -3
- package/dist/handy.js.map +1 -1
- package/dist/instrumentinfo.d.ts +1 -1
- package/dist/instrumentinfo.d.ts.map +1 -1
- package/dist/instrumentinfo.js +3 -1
- package/dist/instrumentinfo.js.map +1 -1
- package/dist/mappers/ascendex.d.ts +6 -99
- package/dist/mappers/ascendex.d.ts.map +1 -1
- package/dist/mappers/ascendex.js +13 -4
- package/dist/mappers/ascendex.js.map +1 -1
- package/dist/mappers/binance.d.ts +27 -154
- package/dist/mappers/binance.d.ts.map +1 -1
- package/dist/mappers/binance.js +49 -15
- package/dist/mappers/binance.js.map +1 -1
- package/dist/mappers/binancedex.d.ts +7 -4
- package/dist/mappers/binancedex.d.ts.map +1 -1
- package/dist/mappers/binancedex.js +11 -3
- package/dist/mappers/binancedex.js.map +1 -1
- package/dist/mappers/binanceeuropeanoptions.d.ts +6 -216
- package/dist/mappers/binanceeuropeanoptions.d.ts.map +1 -1
- package/dist/mappers/binanceeuropeanoptions.js +26 -7
- package/dist/mappers/binanceeuropeanoptions.js.map +1 -1
- package/dist/mappers/bitfinex.d.ts +15 -100
- package/dist/mappers/bitfinex.d.ts.map +1 -1
- package/dist/mappers/bitfinex.js +20 -5
- package/dist/mappers/bitfinex.js.map +1 -1
- package/dist/mappers/bitflyer.d.ts +5 -41
- package/dist/mappers/bitflyer.d.ts.map +1 -1
- package/dist/mappers/bitflyer.js +11 -3
- package/dist/mappers/bitflyer.js.map +1 -1
- package/dist/mappers/bitget.d.ts +12 -269
- package/dist/mappers/bitget.d.ts.map +1 -1
- package/dist/mappers/bitget.js +46 -9
- package/dist/mappers/bitget.js.map +1 -1
- package/dist/mappers/bitmex.d.ts +8 -56
- package/dist/mappers/bitmex.d.ts.map +1 -1
- package/dist/mappers/bitmex.js +15 -5
- package/dist/mappers/bitmex.js.map +1 -1
- package/dist/mappers/bitnomial.d.ts +4 -44
- package/dist/mappers/bitnomial.d.ts.map +1 -1
- package/dist/mappers/bitnomial.js +9 -2
- package/dist/mappers/bitnomial.js.map +1 -1
- package/dist/mappers/bitstamp.d.ts +4 -44
- package/dist/mappers/bitstamp.d.ts.map +1 -1
- package/dist/mappers/bitstamp.js +9 -2
- package/dist/mappers/bitstamp.js.map +1 -1
- package/dist/mappers/blockchaincom.d.ts +4 -63
- package/dist/mappers/blockchaincom.d.ts.map +1 -1
- package/dist/mappers/blockchaincom.js +9 -2
- package/dist/mappers/blockchaincom.js.map +1 -1
- package/dist/mappers/bullish.d.ts +8 -158
- package/dist/mappers/bullish.d.ts.map +1 -1
- package/dist/mappers/bullish.js +15 -5
- package/dist/mappers/bullish.js.map +1 -1
- package/dist/mappers/bybit.d.ts +61 -407
- package/dist/mappers/bybit.d.ts.map +1 -1
- package/dist/mappers/bybit.js +60 -15
- package/dist/mappers/bybit.js.map +1 -1
- package/dist/mappers/bybitspot.d.ts +1 -1
- package/dist/mappers/coinbase.d.ts +6 -39
- package/dist/mappers/coinbase.d.ts.map +1 -1
- package/dist/mappers/coinbase.js +11 -3
- package/dist/mappers/coinbase.js.map +1 -1
- package/dist/mappers/coinbaseinternational.d.ts +7 -78
- package/dist/mappers/coinbaseinternational.d.ts.map +1 -1
- package/dist/mappers/coinbaseinternational.js +13 -4
- package/dist/mappers/coinbaseinternational.js.map +1 -1
- package/dist/mappers/coinflex.d.ts +6 -24
- package/dist/mappers/coinflex.d.ts.map +1 -1
- package/dist/mappers/coinflex.js +11 -3
- package/dist/mappers/coinflex.js.map +1 -1
- package/dist/mappers/cryptocom.d.ts +22 -328
- package/dist/mappers/cryptocom.d.ts.map +1 -1
- package/dist/mappers/cryptocom.js +13 -4
- package/dist/mappers/cryptocom.js.map +1 -1
- package/dist/mappers/cryptofacilities.d.ts +8 -96
- package/dist/mappers/cryptofacilities.d.ts.map +1 -1
- package/dist/mappers/cryptofacilities.js +24 -7
- package/dist/mappers/cryptofacilities.js.map +1 -1
- package/dist/mappers/delta.d.ts +7 -114
- package/dist/mappers/delta.d.ts.map +1 -1
- package/dist/mappers/delta.js +30 -10
- package/dist/mappers/delta.js.map +1 -1
- package/dist/mappers/deribit.d.ts +8 -66
- package/dist/mappers/deribit.d.ts.map +1 -1
- package/dist/mappers/deribit.js +17 -6
- package/dist/mappers/deribit.js.map +1 -1
- package/dist/mappers/dydx.d.ts +5 -146
- package/dist/mappers/dydx.d.ts.map +1 -1
- package/dist/mappers/dydx.js +11 -3
- package/dist/mappers/dydx.js.map +1 -1
- package/dist/mappers/dydxv4.d.ts +6 -173
- package/dist/mappers/dydxv4.d.ts.map +1 -1
- package/dist/mappers/dydxv4.js +13 -4
- package/dist/mappers/dydxv4.js.map +1 -1
- package/dist/mappers/ftx.d.ts +12 -107
- package/dist/mappers/ftx.d.ts.map +1 -1
- package/dist/mappers/ftx.js +21 -6
- package/dist/mappers/ftx.js.map +1 -1
- package/dist/mappers/gateio.d.ts +6 -191
- package/dist/mappers/gateio.d.ts.map +1 -1
- package/dist/mappers/gateio.js +28 -8
- package/dist/mappers/gateio.js.map +1 -1
- package/dist/mappers/gateiofutures.d.ts +7 -122
- package/dist/mappers/gateiofutures.d.ts.map +1 -1
- package/dist/mappers/gateiofutures.js +13 -4
- package/dist/mappers/gateiofutures.js.map +1 -1
- package/dist/mappers/gemini.d.ts +6 -3
- package/dist/mappers/gemini.d.ts.map +1 -1
- package/dist/mappers/gemini.js +9 -2
- package/dist/mappers/gemini.js.map +1 -1
- package/dist/mappers/hitbtc.d.ts +6 -3
- package/dist/mappers/hitbtc.d.ts.map +1 -1
- package/dist/mappers/hitbtc.js +9 -2
- package/dist/mappers/hitbtc.js.map +1 -1
- package/dist/mappers/huobi.d.ts +118 -289
- package/dist/mappers/huobi.d.ts.map +1 -1
- package/dist/mappers/huobi.js +45 -7
- package/dist/mappers/huobi.js.map +1 -1
- package/dist/mappers/hyperliquid.d.ts +6 -86
- package/dist/mappers/hyperliquid.d.ts.map +1 -1
- package/dist/mappers/hyperliquid.js +13 -4
- package/dist/mappers/hyperliquid.js.map +1 -1
- package/dist/mappers/index.d.ts +784 -272
- package/dist/mappers/index.d.ts.map +1 -1
- package/dist/mappers/index.js +64 -432
- package/dist/mappers/index.js.map +1 -1
- package/dist/mappers/kraken.d.ts +7 -4
- package/dist/mappers/kraken.d.ts.map +1 -1
- package/dist/mappers/kraken.js +11 -3
- package/dist/mappers/kraken.js.map +1 -1
- package/dist/mappers/kucoin.d.ts +6 -122
- package/dist/mappers/kucoin.d.ts.map +1 -1
- package/dist/mappers/kucoin.js +13 -5
- package/dist/mappers/kucoin.js.map +1 -1
- package/dist/mappers/kucoinfutures.d.ts +6 -207
- package/dist/mappers/kucoinfutures.d.ts.map +1 -1
- package/dist/mappers/kucoinfutures.js +15 -6
- package/dist/mappers/kucoinfutures.js.map +1 -1
- package/dist/mappers/lighter.d.ts +8 -156
- package/dist/mappers/lighter.d.ts.map +1 -1
- package/dist/mappers/lighter.js +15 -5
- package/dist/mappers/lighter.js.map +1 -1
- package/dist/mappers/mapper.d.ts +3 -1
- package/dist/mappers/mapper.d.ts.map +1 -1
- package/dist/mappers/mapper.js.map +1 -1
- package/dist/mappers/mexc.d.ts +122 -0
- package/dist/mappers/mexc.d.ts.map +1 -0
- package/dist/mappers/mexc.js +205 -0
- package/dist/mappers/mexc.js.map +1 -0
- package/dist/mappers/mexcfutures.d.ts +137 -0
- package/dist/mappers/mexcfutures.d.ts.map +1 -0
- package/dist/mappers/mexcfutures.js +225 -0
- package/dist/mappers/mexcfutures.js.map +1 -0
- package/dist/mappers/okex.d.ts +36 -473
- package/dist/mappers/okex.d.ts.map +1 -1
- package/dist/mappers/okex.js +143 -37
- package/dist/mappers/okex.js.map +1 -1
- package/dist/mappers/phemex.d.ts +5 -82
- package/dist/mappers/phemex.d.ts.map +1 -1
- package/dist/mappers/phemex.js +22 -4
- package/dist/mappers/phemex.js.map +1 -1
- package/dist/mappers/poloniex.d.ts +5 -90
- package/dist/mappers/poloniex.d.ts.map +1 -1
- package/dist/mappers/poloniex.js +18 -4
- package/dist/mappers/poloniex.js.map +1 -1
- package/dist/mappers/polymarket.d.ts +7 -31
- package/dist/mappers/polymarket.d.ts.map +1 -1
- package/dist/mappers/polymarket.js +11 -3
- package/dist/mappers/polymarket.js.map +1 -1
- package/dist/mappers/registry.d.ts +41 -0
- package/dist/mappers/registry.d.ts.map +1 -0
- package/dist/mappers/registry.js +111 -0
- package/dist/mappers/registry.js.map +1 -0
- package/dist/mappers/serum.d.ts +16 -89
- package/dist/mappers/serum.d.ts.map +1 -1
- package/dist/mappers/serum.js +21 -3
- package/dist/mappers/serum.js.map +1 -1
- package/dist/mappers/upbit.d.ts +5 -47
- package/dist/mappers/upbit.d.ts.map +1 -1
- package/dist/mappers/upbit.js +9 -2
- package/dist/mappers/upbit.js.map +1 -1
- package/dist/mappers/woox.d.ts +6 -107
- package/dist/mappers/woox.d.ts.map +1 -1
- package/dist/mappers/woox.js +263 -5
- package/dist/mappers/woox.js.map +1 -1
- package/dist/okexsymbols.d.ts +3 -0
- package/dist/okexsymbols.d.ts.map +1 -0
- package/dist/okexsymbols.js +10 -0
- package/dist/okexsymbols.js.map +1 -0
- package/dist/realtimefeeds/hyperliquid.d.ts.map +1 -1
- package/dist/realtimefeeds/hyperliquid.js +3 -1
- package/dist/realtimefeeds/hyperliquid.js.map +1 -1
- package/dist/realtimefeeds/index.d.ts.map +1 -1
- package/dist/realtimefeeds/index.js +4 -0
- package/dist/realtimefeeds/index.js.map +1 -1
- package/dist/realtimefeeds/mexc.d.ts +35 -0
- package/dist/realtimefeeds/mexc.d.ts.map +1 -0
- package/dist/realtimefeeds/mexc.js +261 -0
- package/dist/realtimefeeds/mexc.js.map +1 -0
- package/dist/realtimefeeds/mexcfutures.d.ts +25 -0
- package/dist/realtimefeeds/mexcfutures.d.ts.map +1 -0
- package/dist/realtimefeeds/mexcfutures.js +203 -0
- package/dist/realtimefeeds/mexcfutures.js.map +1 -0
- package/dist/realtimefeeds/okex.d.ts +1 -0
- package/dist/realtimefeeds/okex.d.ts.map +1 -1
- package/dist/realtimefeeds/okex.js +7 -5
- package/dist/realtimefeeds/okex.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 +4 -1
- package/dist/realtimefeeds/realtimefeed.js.map +1 -1
- package/dist/realtimefeeds/woox.d.ts +1 -0
- package/dist/realtimefeeds/woox.d.ts.map +1 -1
- package/dist/realtimefeeds/woox.js +41 -25
- package/dist/realtimefeeds/woox.js.map +1 -1
- package/dist/replay.d.ts.map +1 -1
- package/dist/replay.js +62 -13
- package/dist/replay.js.map +1 -1
- package/example.js +133 -31
- package/package.json +2 -1
- package/src/consts.ts +22 -1
- package/src/handy.ts +6 -3
- package/src/instrumentinfo.ts +5 -2
- package/src/mappers/ascendex.ts +14 -4
- package/src/mappers/binance.ts +61 -21
- package/src/mappers/binancedex.ts +12 -3
- package/src/mappers/binanceeuropeanoptions.ts +28 -7
- package/src/mappers/bitfinex.ts +21 -5
- package/src/mappers/bitflyer.ts +12 -3
- package/src/mappers/bitget.ts +48 -9
- package/src/mappers/bitmex.ts +16 -5
- package/src/mappers/bitnomial.ts +10 -2
- package/src/mappers/bitstamp.ts +10 -2
- package/src/mappers/blockchaincom.ts +10 -2
- package/src/mappers/bullish.ts +16 -5
- package/src/mappers/bybit.ts +70 -15
- package/src/mappers/coinbase.ts +12 -3
- package/src/mappers/coinbaseinternational.ts +14 -4
- package/src/mappers/coinflex.ts +12 -3
- package/src/mappers/cryptocom.ts +14 -4
- package/src/mappers/cryptofacilities.ts +30 -6
- package/src/mappers/delta.ts +41 -7
- package/src/mappers/deribit.ts +18 -6
- package/src/mappers/dydx.ts +12 -3
- package/src/mappers/dydxv4.ts +14 -4
- package/src/mappers/ftx.ts +22 -6
- package/src/mappers/gateio.ts +34 -8
- package/src/mappers/gateiofutures.ts +14 -4
- package/src/mappers/gemini.ts +10 -2
- package/src/mappers/hitbtc.ts +10 -2
- package/src/mappers/huobi.ts +47 -10
- package/src/mappers/hyperliquid.ts +14 -4
- package/src/mappers/index.ts +133 -679
- package/src/mappers/kraken.ts +12 -3
- package/src/mappers/kucoin.ts +19 -5
- package/src/mappers/kucoinfutures.ts +20 -5
- package/src/mappers/lighter.ts +16 -5
- package/src/mappers/mapper.ts +3 -1
- package/src/mappers/mexc.ts +324 -0
- package/src/mappers/mexcfutures.ts +352 -0
- package/src/mappers/okex.ts +178 -37
- package/src/mappers/phemex.ts +25 -4
- package/src/mappers/poloniex.ts +20 -4
- package/src/mappers/polymarket.ts +12 -3
- package/src/mappers/registry.ts +203 -0
- package/src/mappers/serum.ts +22 -3
- package/src/mappers/upbit.ts +10 -2
- package/src/mappers/woox.ts +380 -6
- package/src/okexsymbols.ts +10 -0
- package/src/realtimefeeds/hyperliquid.ts +4 -1
- package/src/realtimefeeds/index.ts +4 -0
- package/src/realtimefeeds/mexc.ts +327 -0
- package/src/realtimefeeds/mexcfutures.ts +269 -0
- package/src/realtimefeeds/okex.ts +7 -5
- package/src/realtimefeeds/realtimefeed.ts +5 -1
- package/src/realtimefeeds/woox.ts +63 -26
- package/src/replay.ts +73 -15
package/src/mappers/woox.ts
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
|
-
import { upperCaseSymbols } from '../handy.ts'
|
|
2
|
-
import { BookChange, BookTicker, DerivativeTicker,
|
|
1
|
+
import { asNumberOrUndefined, upperCaseSymbols } from '../handy.ts'
|
|
2
|
+
import { BookChange, BookTicker, DerivativeTicker, Trade } from '../types.ts'
|
|
3
3
|
import { Mapper, PendingTickerInfoHelper } from './mapper.ts'
|
|
4
|
+
import { exchangeMappers, mapper } from './registry.ts'
|
|
5
|
+
|
|
6
|
+
const WOOX_V3_SWITCH_DATE = new Date('2026-06-29T22:02:00.000Z')
|
|
7
|
+
|
|
8
|
+
// WOO X kept Tardis channel names during the V3 rollout, but changed raw topic layout and payload fields.
|
|
9
|
+
// Keep old and V3 mappers separate so replay uses the schema that was actually recorded at the message time.
|
|
10
|
+
export const wooxMappers = exchangeMappers({
|
|
11
|
+
'woo-x': {
|
|
12
|
+
trades: mapper([{ until: WOOX_V3_SWITCH_DATE, use: () => wooxTradesMapper }, { use: () => wooxV3TradesMapper }]),
|
|
13
|
+
bookChanges: mapper([
|
|
14
|
+
{ until: WOOX_V3_SWITCH_DATE, use: () => new WooxBookChangeMapper() },
|
|
15
|
+
{ use: () => new WooxV3BookChangeMapper() }
|
|
16
|
+
]),
|
|
17
|
+
derivativeTickers: mapper([
|
|
18
|
+
{ until: WOOX_V3_SWITCH_DATE, use: () => new WooxDerivativeTickerMapper() },
|
|
19
|
+
{ use: () => new WooxV3DerivativeTickerMapper() }
|
|
20
|
+
]),
|
|
21
|
+
bookTickers: mapper([
|
|
22
|
+
{ until: WOOX_V3_SWITCH_DATE, use: () => new WooxBookTickerMapper() },
|
|
23
|
+
{ use: () => new WooxV3BookTickerMapper() }
|
|
24
|
+
])
|
|
25
|
+
}
|
|
26
|
+
})
|
|
4
27
|
|
|
5
|
-
|
|
28
|
+
const wooxTradesMapper: Mapper<'woo-x', Trade> = {
|
|
6
29
|
canHandle(message: WooxTradeMessage) {
|
|
7
30
|
return message.topic !== undefined && message.topic.endsWith('@trade')
|
|
8
31
|
},
|
|
@@ -39,7 +62,42 @@ export const wooxTradesMapper: Mapper<'woo-x', Trade> = {
|
|
|
39
62
|
}
|
|
40
63
|
}
|
|
41
64
|
|
|
42
|
-
|
|
65
|
+
const wooxV3TradesMapper: Mapper<'woo-x', Trade> = {
|
|
66
|
+
canHandle(message: WooxV3TradeMessage) {
|
|
67
|
+
return message.topic !== undefined && message.topic.startsWith('trade@')
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
getFilters(symbols?: string[]) {
|
|
71
|
+
symbols = upperCaseSymbols(symbols)
|
|
72
|
+
|
|
73
|
+
return [
|
|
74
|
+
{
|
|
75
|
+
channel: 'trade',
|
|
76
|
+
symbols
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
*map(message: WooxV3TradeMessage, localTimestamp: Date): IterableIterator<Trade> {
|
|
82
|
+
if (message.data.src === 0) {
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
yield {
|
|
87
|
+
type: 'trade',
|
|
88
|
+
symbol: message.data.s,
|
|
89
|
+
exchange: 'woo-x',
|
|
90
|
+
id: undefined,
|
|
91
|
+
price: Number(message.data.px),
|
|
92
|
+
amount: Number(message.data.sx),
|
|
93
|
+
side: message.data.sd === 'SELL' ? 'sell' : 'buy',
|
|
94
|
+
timestamp: new Date(message.data.ts),
|
|
95
|
+
localTimestamp
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class WooxBookChangeMapper implements Mapper<'woo-x', BookChange> {
|
|
43
101
|
private readonly _symbolToDepthInfoMapping: { [key: string]: LocalDepthInfo } = {}
|
|
44
102
|
|
|
45
103
|
canHandle(message: WooxOrderbookMessage | WooxOrderbookupdateMessage) {
|
|
@@ -149,7 +207,130 @@ export class WooxBookChangeMapper implements Mapper<'woo-x', BookChange> {
|
|
|
149
207
|
}
|
|
150
208
|
}
|
|
151
209
|
|
|
152
|
-
|
|
210
|
+
class WooxV3BookChangeMapper implements Mapper<'woo-x', BookChange> {
|
|
211
|
+
private readonly _symbolToDepthInfoMapping: { [key: string]: WooxV3LocalDepthInfo } = {}
|
|
212
|
+
|
|
213
|
+
canHandle(message: WooxV3OrderbookMessage | WooxV3OrderbookupdateMessage) {
|
|
214
|
+
if (message.topic === undefined) {
|
|
215
|
+
return false
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (message.topic.startsWith('orderbook@')) {
|
|
219
|
+
return 'generated' in message && message.generated === true
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return message.topic.startsWith('orderbookupdate@')
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
getFilters(symbols?: string[]) {
|
|
226
|
+
symbols = upperCaseSymbols(symbols)
|
|
227
|
+
|
|
228
|
+
return [
|
|
229
|
+
{
|
|
230
|
+
channel: 'orderbook',
|
|
231
|
+
symbols
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
channel: 'orderbookupdate',
|
|
235
|
+
symbols
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
*map(message: WooxV3OrderbookMessage | WooxV3OrderbookupdateMessage, localTimestamp: Date): IterableIterator<BookChange> {
|
|
241
|
+
if ('generated' in message) {
|
|
242
|
+
const symbol = message.data.s ?? message.topic.split('@')[1]
|
|
243
|
+
const timestamp = message.data.ts ?? message.ts
|
|
244
|
+
|
|
245
|
+
if (this._symbolToDepthInfoMapping[symbol] === undefined) {
|
|
246
|
+
this._symbolToDepthInfoMapping[symbol] = {
|
|
247
|
+
bufferedUpdates: []
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const symbolDepthInfo = this._symbolToDepthInfoMapping[symbol]
|
|
252
|
+
|
|
253
|
+
yield {
|
|
254
|
+
type: 'book_change',
|
|
255
|
+
symbol,
|
|
256
|
+
exchange: 'woo-x',
|
|
257
|
+
isSnapshot: true,
|
|
258
|
+
bids: message.data.bids.map(this._mapSnapshotLevel),
|
|
259
|
+
asks: message.data.asks.map(this._mapSnapshotLevel),
|
|
260
|
+
timestamp: new Date(timestamp),
|
|
261
|
+
localTimestamp
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
symbolDepthInfo.lastUpdateTimestamp = timestamp
|
|
265
|
+
symbolDepthInfo.snapshotProcessed = true
|
|
266
|
+
|
|
267
|
+
for (const update of symbolDepthInfo.bufferedUpdates) {
|
|
268
|
+
const bookChange = this._mapBookDepthUpdate(update, localTimestamp, symbolDepthInfo, symbol)
|
|
269
|
+
if (bookChange !== undefined) {
|
|
270
|
+
yield bookChange
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
symbolDepthInfo.bufferedUpdates = []
|
|
274
|
+
return
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const symbol = message.data.s
|
|
278
|
+
|
|
279
|
+
if (this._symbolToDepthInfoMapping[symbol] === undefined) {
|
|
280
|
+
this._symbolToDepthInfoMapping[symbol] = {
|
|
281
|
+
bufferedUpdates: []
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const symbolDepthInfo = this._symbolToDepthInfoMapping[symbol]
|
|
286
|
+
const snapshotAlreadyProcessed = symbolDepthInfo.snapshotProcessed
|
|
287
|
+
|
|
288
|
+
if (snapshotAlreadyProcessed) {
|
|
289
|
+
const bookChange = this._mapBookDepthUpdate(message, localTimestamp, symbolDepthInfo, symbol)
|
|
290
|
+
if (bookChange !== undefined) {
|
|
291
|
+
yield bookChange
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
symbolDepthInfo.bufferedUpdates.push(message)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private _mapBookDepthUpdate(
|
|
299
|
+
wooxBookUpdate: WooxV3OrderbookupdateMessage,
|
|
300
|
+
localTimestamp: Date,
|
|
301
|
+
depthInfo: WooxV3LocalDepthInfo,
|
|
302
|
+
symbol: string
|
|
303
|
+
): BookChange | undefined {
|
|
304
|
+
if (wooxBookUpdate.data.prevTs < depthInfo.lastUpdateTimestamp!) {
|
|
305
|
+
return
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
type: 'book_change',
|
|
310
|
+
symbol,
|
|
311
|
+
exchange: 'woo-x',
|
|
312
|
+
isSnapshot: false,
|
|
313
|
+
bids: wooxBookUpdate.data.bids.map(this._mapUpdateLevel),
|
|
314
|
+
asks: wooxBookUpdate.data.asks.map(this._mapUpdateLevel),
|
|
315
|
+
timestamp: new Date(wooxBookUpdate.data.ts),
|
|
316
|
+
localTimestamp
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private _mapSnapshotLevel(level: WooxV3OrderbookSnapshotLevel): { price: number; amount: number } {
|
|
321
|
+
if (Array.isArray(level)) {
|
|
322
|
+
return { price: Number(level[0]), amount: Number(level[1]) }
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return { price: Number(level.price), amount: Number(level.quantity) }
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private _mapUpdateLevel(level: WooxV3BookLevel) {
|
|
329
|
+
return { price: Number(level[0]), amount: Number(level[1]) }
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
class WooxDerivativeTickerMapper implements Mapper<'woo-x', DerivativeTicker> {
|
|
153
334
|
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
154
335
|
private readonly _indexPrices = new Map<string, number>()
|
|
155
336
|
|
|
@@ -236,7 +417,100 @@ export class WooxDerivativeTickerMapper implements Mapper<'woo-x', DerivativeTic
|
|
|
236
417
|
}
|
|
237
418
|
}
|
|
238
419
|
|
|
239
|
-
|
|
420
|
+
class WooxV3DerivativeTickerMapper implements Mapper<'woo-x', DerivativeTicker> {
|
|
421
|
+
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
422
|
+
private readonly _indexPrices = new Map<string, number>()
|
|
423
|
+
|
|
424
|
+
canHandle(message: WooxV3TradeMessage | WooxV3EstFundingRate | WooxV3MarkPrice | WooxV3IndexPrice | WooxV3OpenInterest) {
|
|
425
|
+
if (message.topic === undefined) {
|
|
426
|
+
return false
|
|
427
|
+
}
|
|
428
|
+
const symbol = (message.data && message.data.s) || ''
|
|
429
|
+
const isPerp = symbol.startsWith('PERP_')
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
(message.topic.startsWith('trade@') && isPerp) ||
|
|
433
|
+
(message.topic.startsWith('markprice@') && isPerp) ||
|
|
434
|
+
(message.topic.startsWith('estfundingrate@') && isPerp) ||
|
|
435
|
+
message.topic.startsWith('indexprice@') ||
|
|
436
|
+
(message.topic.startsWith('openinterest@') && isPerp)
|
|
437
|
+
)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
getFilters(symbols?: string[]) {
|
|
441
|
+
symbols = upperCaseSymbols(symbols)
|
|
442
|
+
const spotSymbols = symbols !== undefined ? symbols.map((s) => s.replace('PERP_', 'SPOT_')) : []
|
|
443
|
+
|
|
444
|
+
return [
|
|
445
|
+
{
|
|
446
|
+
channel: 'trade',
|
|
447
|
+
symbols
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
channel: 'markprice',
|
|
451
|
+
symbols
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
channel: 'estfundingrate',
|
|
455
|
+
symbols
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
channel: 'openinterest',
|
|
459
|
+
symbols
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
channel: 'indexprice',
|
|
463
|
+
symbols: spotSymbols
|
|
464
|
+
}
|
|
465
|
+
]
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
*map(message: WooxV3TradeMessage | WooxV3EstFundingRate | WooxV3MarkPrice | WooxV3IndexPrice | WooxV3OpenInterest, localTimestamp: Date) {
|
|
469
|
+
if (message.topic.startsWith('indexprice@')) {
|
|
470
|
+
const data = message.data as WooxV3IndexPrice['data']
|
|
471
|
+
this._indexPrices.set(data.s.replace('SPOT_', 'PERP_'), Number(data.px))
|
|
472
|
+
} else {
|
|
473
|
+
const symbol = message.data.s
|
|
474
|
+
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(symbol, 'woo-x')
|
|
475
|
+
|
|
476
|
+
const lastIndexPrice = this._indexPrices.get(symbol)
|
|
477
|
+
if (lastIndexPrice !== undefined) {
|
|
478
|
+
pendingTickerInfo.updateIndexPrice(lastIndexPrice)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (message.topic.startsWith('markprice@')) {
|
|
482
|
+
const data = message.data as WooxV3MarkPrice['data']
|
|
483
|
+
pendingTickerInfo.updateMarkPrice(Number(data.px))
|
|
484
|
+
pendingTickerInfo.updateTimestamp(new Date(message.data.ts))
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (message.topic.startsWith('trade@')) {
|
|
488
|
+
const data = message.data as WooxV3TradeMessage['data']
|
|
489
|
+
pendingTickerInfo.updateLastPrice(Number(data.px))
|
|
490
|
+
pendingTickerInfo.updateTimestamp(new Date(message.data.ts))
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (message.topic.startsWith('estfundingrate@')) {
|
|
494
|
+
const data = message.data as WooxV3EstFundingRate['data']
|
|
495
|
+
pendingTickerInfo.updateFundingRate(Number(data.r))
|
|
496
|
+
pendingTickerInfo.updateFundingTimestamp(new Date(Number(data.ft)))
|
|
497
|
+
pendingTickerInfo.updateTimestamp(new Date(message.data.ts))
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (message.topic.startsWith('openinterest@')) {
|
|
501
|
+
const data = message.data as WooxV3OpenInterest['data']
|
|
502
|
+
pendingTickerInfo.updateOpenInterest(Number(data.oi))
|
|
503
|
+
pendingTickerInfo.updateTimestamp(new Date(message.data.ts))
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (pendingTickerInfo.hasChanged()) {
|
|
507
|
+
yield pendingTickerInfo.getSnapshot(localTimestamp)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
class WooxBookTickerMapper implements Mapper<'woo-x', BookTicker> {
|
|
240
514
|
canHandle(message: WooxTradeMessage) {
|
|
241
515
|
return message.topic !== undefined && message.topic.endsWith('@bbo')
|
|
242
516
|
}
|
|
@@ -272,6 +546,42 @@ export class WooxBookTickerMapper implements Mapper<'woo-x', BookTicker> {
|
|
|
272
546
|
}
|
|
273
547
|
}
|
|
274
548
|
|
|
549
|
+
class WooxV3BookTickerMapper implements Mapper<'woo-x', BookTicker> {
|
|
550
|
+
canHandle(message: WooxV3BBOMessage) {
|
|
551
|
+
return message.topic !== undefined && message.topic.startsWith('bbo@')
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
getFilters(symbols?: string[]) {
|
|
555
|
+
symbols = upperCaseSymbols(symbols)
|
|
556
|
+
|
|
557
|
+
return [
|
|
558
|
+
{
|
|
559
|
+
channel: 'bbo',
|
|
560
|
+
symbols
|
|
561
|
+
}
|
|
562
|
+
]
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
*map(wooxBBOMessage: WooxV3BBOMessage, localTimestamp: Date) {
|
|
566
|
+
const wooxBookTicker = wooxBBOMessage.data
|
|
567
|
+
|
|
568
|
+
const ticker: BookTicker = {
|
|
569
|
+
type: 'book_ticker',
|
|
570
|
+
symbol: wooxBookTicker.s,
|
|
571
|
+
exchange: 'woo-x',
|
|
572
|
+
askAmount: asNumberOrUndefined(wooxBookTicker.aq),
|
|
573
|
+
askPrice: asNumberOrUndefined(wooxBookTicker.ap),
|
|
574
|
+
|
|
575
|
+
bidPrice: asNumberOrUndefined(wooxBookTicker.bp),
|
|
576
|
+
bidAmount: asNumberOrUndefined(wooxBookTicker.bq),
|
|
577
|
+
timestamp: new Date(wooxBookTicker.ts),
|
|
578
|
+
localTimestamp: localTimestamp
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
yield ticker
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
275
585
|
type LocalDepthInfo = {
|
|
276
586
|
bufferedUpdates: WooxOrderbookupdateMessage[]
|
|
277
587
|
snapshotProcessed?: boolean
|
|
@@ -284,6 +594,12 @@ type WooxTradeMessage = {
|
|
|
284
594
|
data: { symbol: 'PERP_GALA_USDT'; price: 0.048756; size: 4109; side: 'SELL'; source: 0 }
|
|
285
595
|
}
|
|
286
596
|
|
|
597
|
+
type WooxV3TradeMessage = {
|
|
598
|
+
topic: string
|
|
599
|
+
ts: number
|
|
600
|
+
data: { s: string; px: string; sx: string; sd: 'BUY' | 'SELL'; src: number; ts: number }
|
|
601
|
+
}
|
|
602
|
+
|
|
287
603
|
type WooxOrderbookupdateMessage = {
|
|
288
604
|
topic: 'PERP_BTC_USDT@orderbookupdate'
|
|
289
605
|
ts: 1674432000020
|
|
@@ -308,19 +624,77 @@ type WooxOrderbookMessage = {
|
|
|
308
624
|
}
|
|
309
625
|
}
|
|
310
626
|
|
|
627
|
+
type WooxV3LocalDepthInfo = {
|
|
628
|
+
bufferedUpdates: WooxV3OrderbookupdateMessage[]
|
|
629
|
+
snapshotProcessed?: boolean
|
|
630
|
+
lastUpdateTimestamp?: number
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
type WooxV3BookLevel = [string, string]
|
|
634
|
+
|
|
635
|
+
type WooxV3OrderbookupdateMessage = {
|
|
636
|
+
topic: string
|
|
637
|
+
ts: number
|
|
638
|
+
data: {
|
|
639
|
+
s: string
|
|
640
|
+
prevTs: number
|
|
641
|
+
ts: number
|
|
642
|
+
asks: WooxV3BookLevel[]
|
|
643
|
+
bids: WooxV3BookLevel[]
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
type WooxV3OrderbookRestSnapshotLevel = {
|
|
648
|
+
price: string
|
|
649
|
+
quantity: string
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
type WooxV3OrderbookSnapshotLevel = WooxV3BookLevel | WooxV3OrderbookRestSnapshotLevel
|
|
653
|
+
|
|
654
|
+
type WooxV3OrderbookMessage = {
|
|
655
|
+
topic: string
|
|
656
|
+
ts: number
|
|
657
|
+
generated: true
|
|
658
|
+
data: {
|
|
659
|
+
s?: string
|
|
660
|
+
ts?: number
|
|
661
|
+
asks: WooxV3OrderbookSnapshotLevel[]
|
|
662
|
+
bids: WooxV3OrderbookSnapshotLevel[]
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
311
666
|
type WooxBBOMessage = {
|
|
312
667
|
topic: 'SPOT_ETH_USDT@bbo'
|
|
313
668
|
ts: 1674431999996
|
|
314
669
|
data: { symbol: 'SPOT_ETH_USDT'; ask: 1627.61; askSize: 38.3755; bid: 1627.26; bidSize: 20.424926 }
|
|
315
670
|
}
|
|
316
671
|
|
|
672
|
+
type WooxV3BBOMessage = {
|
|
673
|
+
topic: string
|
|
674
|
+
ts: number
|
|
675
|
+
data: { s: string; ts: number; ap?: string; aq?: string; bp?: string; bq?: string }
|
|
676
|
+
}
|
|
677
|
+
|
|
317
678
|
type WooxMarkPrice = { topic: 'PERP_BTC_USDT@markprice'; ts: 1674432000007; data: { symbol: 'PERP_BTC_USDT'; price: 22711.11 } }
|
|
318
679
|
|
|
680
|
+
type WooxV3MarkPrice = { topic: string; ts: number; data: { s: string; ts: number; px: string } }
|
|
681
|
+
|
|
319
682
|
type WooxEstFundingRate = {
|
|
320
683
|
topic: 'PERP_BTC_USDT@estfundingrate'
|
|
321
684
|
ts: 1674432059002
|
|
322
685
|
data: { symbol: 'PERP_BTC_USDT'; fundingRate: 0.00000782; fundingTs: 1674435600005 }
|
|
323
686
|
}
|
|
324
687
|
|
|
688
|
+
type WooxV3EstFundingRate = {
|
|
689
|
+
topic: string
|
|
690
|
+
ts: number
|
|
691
|
+
data: { s: string; ts: number; r: string; ft: number | string }
|
|
692
|
+
}
|
|
693
|
+
|
|
325
694
|
type WooxIndexPrice = { topic: 'SPOT_BTC_USDT@indexprice'; ts: 1674432000024; data: { symbol: 'SPOT_BTC_USDT'; price: 22708.44 } }
|
|
695
|
+
|
|
696
|
+
type WooxV3IndexPrice = { topic: string; ts: number; data: { s: string; ts: number; px: string } }
|
|
697
|
+
|
|
326
698
|
type WooxOpenInterest = { topic: 'PERP_BTC_USDT@openinterest'; ts: 1674432013624; data: { symbol: 'PERP_BTC_USDT'; openInterest: 83.2241 } }
|
|
699
|
+
|
|
700
|
+
type WooxV3OpenInterest = { topic: string; ts: number; data: { s: string; ts: number; oi: string } }
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function getOkexOptionsFamilyOrIndex(symbol: string) {
|
|
2
|
+
const symbolParts = symbol.split('-')
|
|
3
|
+
return `${symbolParts[0]}-${symbolParts[1]}`
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function getOkexOptionsUnderlyingIndex(symbol: string) {
|
|
7
|
+
const symbolParts = symbol.split('-')
|
|
8
|
+
const quote = symbolParts[1].split('_')[0]
|
|
9
|
+
return `${symbolParts[0]}-${quote}`
|
|
10
|
+
}
|
|
@@ -12,11 +12,14 @@ export class HyperliquidRealTimeFeed extends RealTimeFeedBase {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
return filter.symbols.map((symbol) => {
|
|
15
|
+
const isFastBook = filter.channel === 'fastBook'
|
|
16
|
+
|
|
15
17
|
return {
|
|
16
18
|
method: 'subscribe',
|
|
17
19
|
subscription: {
|
|
18
20
|
coin: symbol,
|
|
19
|
-
type: filter.channel
|
|
21
|
+
type: isFastBook ? 'l2Book' : filter.channel,
|
|
22
|
+
fast: isFastBook ? true : undefined
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
})
|
|
@@ -54,6 +54,8 @@ import { CoinbaseInternationalRealTimeFeed } from './coinbaseinternational.ts'
|
|
|
54
54
|
import { HyperliquidRealTimeFeed } from './hyperliquid.ts'
|
|
55
55
|
import { LighterRealTimeFeed } from './lighter.ts'
|
|
56
56
|
import { BullishRealTimeFeed } from './bullish.ts'
|
|
57
|
+
import { MexcFuturesRealTimeFeed } from './mexcfutures.ts'
|
|
58
|
+
import { MexcRealTimeFeed } from './mexc.ts'
|
|
57
59
|
import { PolymarketRealTimeFeed } from './polymarket.ts'
|
|
58
60
|
|
|
59
61
|
export * from './realtimefeed.ts'
|
|
@@ -94,6 +96,7 @@ const realTimeFeedsMap: {
|
|
|
94
96
|
delta: DeltaRealTimeFeed,
|
|
95
97
|
'gate-io': GateIORealTimeFeed,
|
|
96
98
|
'gate-io-futures': GateIOFuturesRealTimeFeed,
|
|
99
|
+
'mexc-futures': MexcFuturesRealTimeFeed,
|
|
97
100
|
poloniex: PoloniexRealTimeFeed,
|
|
98
101
|
coinflex: CoinflexRealTimeFeed,
|
|
99
102
|
upbit: UpbitRealTimeFeed,
|
|
@@ -120,6 +123,7 @@ const realTimeFeedsMap: {
|
|
|
120
123
|
hyperliquid: HyperliquidRealTimeFeed,
|
|
121
124
|
lighter: LighterRealTimeFeed,
|
|
122
125
|
bullish: BullishRealTimeFeed,
|
|
126
|
+
mexc: MexcRealTimeFeed,
|
|
123
127
|
polymarket: PolymarketRealTimeFeed
|
|
124
128
|
}
|
|
125
129
|
|