tardis-dev 16.5.0 → 16.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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 +19 -7
- 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 +13 -4
- 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/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/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 +21 -8
- 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 +14 -4
- 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/replay.ts +73 -15
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { debug } from '../debug.ts'
|
|
2
|
+
import { CircularBuffer, upperCaseSymbols } from '../handy.ts'
|
|
3
|
+
import { BookChange, DerivativeTicker, Trade } from '../types.ts'
|
|
4
|
+
import { Mapper, PendingTickerInfoHelper } from './mapper.ts'
|
|
5
|
+
import { exchangeMappers, isRealTime } from './registry.ts'
|
|
6
|
+
|
|
7
|
+
export const mexcFuturesMappers = exchangeMappers({
|
|
8
|
+
'mexc-futures': {
|
|
9
|
+
trades: () => new MexcFuturesTradesMapper(),
|
|
10
|
+
bookChanges: (localTimestamp) =>
|
|
11
|
+
new MexcFuturesBookChangeMapper({ ignoreBookSnapshotOverlapError: isRealTime(localTimestamp) === false }),
|
|
12
|
+
derivativeTickers: () => new MexcFuturesDerivativeTickerMapper()
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export class MexcFuturesTradesMapper implements Mapper<'mexc-futures', Trade> {
|
|
17
|
+
canHandle(message: MexcFuturesDealMessage) {
|
|
18
|
+
return message.channel === 'push.deal'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getFilters(symbols?: string[]) {
|
|
22
|
+
return [{ channel: 'push.deal', symbols: upperCaseSymbols(symbols) } as const]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
*map(message: MexcFuturesDealMessage, localTimestamp: Date): IterableIterator<Trade> {
|
|
26
|
+
for (const trade of message.data) {
|
|
27
|
+
yield {
|
|
28
|
+
type: 'trade',
|
|
29
|
+
symbol: message.symbol,
|
|
30
|
+
exchange: 'mexc-futures',
|
|
31
|
+
id: trade.i,
|
|
32
|
+
price: trade.p,
|
|
33
|
+
amount: trade.v,
|
|
34
|
+
side: trade.T === MexcFuturesTradeSide.Buy ? 'buy' : 'sell',
|
|
35
|
+
timestamp: new Date(trade.t),
|
|
36
|
+
localTimestamp
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class MexcFuturesBookChangeMapper implements Mapper<'mexc-futures', BookChange> {
|
|
43
|
+
private readonly symbolDepthInfo: Record<string, MexcFuturesDepthInfo> = {}
|
|
44
|
+
private readonly ignoreBookSnapshotOverlapError: boolean
|
|
45
|
+
|
|
46
|
+
constructor({ ignoreBookSnapshotOverlapError }: { ignoreBookSnapshotOverlapError: boolean }) {
|
|
47
|
+
this.ignoreBookSnapshotOverlapError = ignoreBookSnapshotOverlapError
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
canHandle(message: MexcFuturesDepthMessage) {
|
|
51
|
+
return message.channel === 'push.depth' || message.channel === 'push.depth.snapshot'
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
getFilters(symbols?: string[]) {
|
|
55
|
+
const normalizedSymbols = upperCaseSymbols(symbols)
|
|
56
|
+
|
|
57
|
+
return [
|
|
58
|
+
{ channel: 'push.depth', symbols: normalizedSymbols } as const,
|
|
59
|
+
{ channel: 'push.depth.snapshot', symbols: normalizedSymbols } as const
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
*map(message: MexcFuturesDepthMessage, localTimestamp: Date): IterableIterator<BookChange> {
|
|
64
|
+
const depthInfo = this.getSymbolDepthInfo(message.symbol)
|
|
65
|
+
if (message.generated === true) {
|
|
66
|
+
if (depthInfo.snapshotEmitted) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const update of depthInfo.updates.items()) {
|
|
71
|
+
const updateFirstVersion = this.getFirstVersion(update.data)
|
|
72
|
+
const updateLastVersion = this.getLastVersion(update.data)
|
|
73
|
+
if (message.data.version >= updateLastVersion) {
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!depthInfo.isContinuityValidated) {
|
|
78
|
+
if (updateFirstVersion > message.data.version + 1 || updateLastVersion < message.data.version + 1) {
|
|
79
|
+
const errorMessage = `MEXC futures depth snapshot has no overlap with first update, update ${JSON.stringify(update)}, currentBookVersion: ${message.data.version}`
|
|
80
|
+
if (this.ignoreBookSnapshotOverlapError) {
|
|
81
|
+
depthInfo.isContinuityValidated = true
|
|
82
|
+
debug(errorMessage)
|
|
83
|
+
} else {
|
|
84
|
+
throw new Error(errorMessage)
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
depthInfo.isContinuityValidated = true
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const bid of update.data.bids) {
|
|
92
|
+
this.applyLevel(message.data.bids, bid)
|
|
93
|
+
}
|
|
94
|
+
for (const ask of update.data.asks) {
|
|
95
|
+
this.applyLevel(message.data.asks, ask)
|
|
96
|
+
}
|
|
97
|
+
message.data.version = updateLastVersion
|
|
98
|
+
}
|
|
99
|
+
depthInfo.updates.clear()
|
|
100
|
+
depthInfo.currentBookVersion = message.data.version
|
|
101
|
+
depthInfo.snapshotEmitted = true
|
|
102
|
+
|
|
103
|
+
yield {
|
|
104
|
+
type: 'book_change',
|
|
105
|
+
symbol: message.symbol,
|
|
106
|
+
exchange: 'mexc-futures',
|
|
107
|
+
isSnapshot: true,
|
|
108
|
+
bids: message.data.bids.map(this.mapBookLevel),
|
|
109
|
+
asks: message.data.asks.map(this.mapBookLevel),
|
|
110
|
+
timestamp: new Date(message.data.timestamp),
|
|
111
|
+
localTimestamp
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!depthInfo.snapshotEmitted) {
|
|
118
|
+
depthInfo.updates.append(message)
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const firstVersion = this.getFirstVersion(message.data)
|
|
123
|
+
const lastVersion = this.getLastVersion(message.data)
|
|
124
|
+
if (lastVersion <= depthInfo.currentBookVersion!) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!depthInfo.isContinuityValidated) {
|
|
129
|
+
if (firstVersion > depthInfo.currentBookVersion! + 1 || lastVersion < depthInfo.currentBookVersion! + 1) {
|
|
130
|
+
const errorMessage = `MEXC futures depth snapshot has no overlap with first update, update ${JSON.stringify(message)}, currentBookVersion: ${depthInfo.currentBookVersion}`
|
|
131
|
+
if (this.ignoreBookSnapshotOverlapError) {
|
|
132
|
+
depthInfo.isContinuityValidated = true
|
|
133
|
+
debug(errorMessage)
|
|
134
|
+
} else {
|
|
135
|
+
throw new Error(errorMessage)
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
depthInfo.isContinuityValidated = true
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
depthInfo.currentBookVersion = lastVersion
|
|
143
|
+
|
|
144
|
+
yield {
|
|
145
|
+
type: 'book_change',
|
|
146
|
+
symbol: message.symbol,
|
|
147
|
+
exchange: 'mexc-futures',
|
|
148
|
+
isSnapshot: false,
|
|
149
|
+
bids: message.data.bids.map(this.mapBookLevel),
|
|
150
|
+
asks: message.data.asks.map(this.mapBookLevel),
|
|
151
|
+
timestamp: new Date(message.ts),
|
|
152
|
+
localTimestamp
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private getFirstVersion(data: MexcFuturesDepthUpdateData) {
|
|
157
|
+
return data.begin !== undefined && data.begin !== null && data.begin !== 0 ? data.begin : data.version
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private getLastVersion(data: MexcFuturesDepthUpdateData) {
|
|
161
|
+
return data.end !== undefined && data.end !== null && data.end !== 0 ? data.end : data.version
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private applyLevel(bookSide: MexcFuturesDepthLevel[], levelUpdate: MexcFuturesDepthLevel) {
|
|
165
|
+
const existingIndex = bookSide.findIndex((level) => level[0] === levelUpdate[0])
|
|
166
|
+
if (levelUpdate[1] === 0) {
|
|
167
|
+
if (existingIndex !== -1) {
|
|
168
|
+
bookSide.splice(existingIndex, 1)
|
|
169
|
+
}
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (existingIndex === -1) {
|
|
174
|
+
bookSide.push(levelUpdate)
|
|
175
|
+
} else {
|
|
176
|
+
bookSide[existingIndex] = levelUpdate
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private mapBookLevel(level: MexcFuturesDepthLevel) {
|
|
181
|
+
return {
|
|
182
|
+
price: level[0],
|
|
183
|
+
amount: level[1]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private getSymbolDepthInfo(symbol: string) {
|
|
188
|
+
if (this.symbolDepthInfo[symbol] === undefined) {
|
|
189
|
+
this.symbolDepthInfo[symbol] = { updates: new CircularBuffer<MexcFuturesDepthUpdateMessage>(2000) }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return this.symbolDepthInfo[symbol]
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export class MexcFuturesDerivativeTickerMapper implements Mapper<'mexc-futures', DerivativeTicker> {
|
|
197
|
+
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
198
|
+
|
|
199
|
+
canHandle(message: MexcFuturesTickerMessage | MexcFuturesFundingRateMessage) {
|
|
200
|
+
return message.channel === 'push.ticker' || message.channel === 'push.funding.rate'
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
getFilters(symbols?: string[]) {
|
|
204
|
+
const normalizedSymbols = upperCaseSymbols(symbols)
|
|
205
|
+
|
|
206
|
+
return [
|
|
207
|
+
{ channel: 'push.ticker', symbols: normalizedSymbols } as const,
|
|
208
|
+
{ channel: 'push.funding.rate', symbols: normalizedSymbols } as const
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
*map(message: MexcFuturesTickerMessage | MexcFuturesFundingRateMessage, localTimestamp: Date): IterableIterator<DerivativeTicker> {
|
|
213
|
+
const pendingTickerInfo = this.pendingTickerInfoHelper.getPendingTickerInfo(message.symbol, 'mexc-futures')
|
|
214
|
+
|
|
215
|
+
if (message.channel === 'push.funding.rate') {
|
|
216
|
+
pendingTickerInfo.updateFundingRate(message.data.rate)
|
|
217
|
+
pendingTickerInfo.updateFundingTimestamp(
|
|
218
|
+
message.data.nextSettleTime !== undefined ? new Date(message.data.nextSettleTime) : undefined
|
|
219
|
+
)
|
|
220
|
+
return
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
pendingTickerInfo.updateLastPrice(message.data.lastPrice)
|
|
224
|
+
pendingTickerInfo.updateOpenInterest(message.data.holdVol)
|
|
225
|
+
pendingTickerInfo.updateIndexPrice(message.data.indexPrice)
|
|
226
|
+
pendingTickerInfo.updateMarkPrice(message.data.fairPrice)
|
|
227
|
+
pendingTickerInfo.updateTimestamp(new Date(message.data.timestamp))
|
|
228
|
+
|
|
229
|
+
if (pendingTickerInfo.hasChanged()) {
|
|
230
|
+
yield pendingTickerInfo.getSnapshot(localTimestamp)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const MEXC_FUTURES_MAPPED_PUSH_CHANNELS = [
|
|
236
|
+
'push.deal',
|
|
237
|
+
'push.depth',
|
|
238
|
+
'push.depth.snapshot',
|
|
239
|
+
'push.ticker',
|
|
240
|
+
'push.index.price',
|
|
241
|
+
'push.fair.price',
|
|
242
|
+
'push.funding.rate'
|
|
243
|
+
] as const
|
|
244
|
+
type MexcFuturesMappedPushChannel = (typeof MEXC_FUTURES_MAPPED_PUSH_CHANNELS)[number]
|
|
245
|
+
type MexcFuturesMessage<TChannel extends MexcFuturesMappedPushChannel, TData> = {
|
|
246
|
+
channel: TChannel
|
|
247
|
+
symbol: string
|
|
248
|
+
ts: number
|
|
249
|
+
data: TData
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
type MexcFuturesDealMessage = MexcFuturesMessage<
|
|
253
|
+
'push.deal',
|
|
254
|
+
{
|
|
255
|
+
p: number
|
|
256
|
+
v: number
|
|
257
|
+
T: MexcFuturesTradeSide
|
|
258
|
+
O: MexcFuturesOpenCloseFlag
|
|
259
|
+
M: MexcFuturesSelfTrade
|
|
260
|
+
t: number
|
|
261
|
+
i: string
|
|
262
|
+
cts?: string
|
|
263
|
+
}[]
|
|
264
|
+
>
|
|
265
|
+
|
|
266
|
+
enum MexcFuturesTradeSide {
|
|
267
|
+
Buy = 1,
|
|
268
|
+
Sell = 2
|
|
269
|
+
}
|
|
270
|
+
enum MexcFuturesOpenCloseFlag {
|
|
271
|
+
NewPosition = 1,
|
|
272
|
+
ReducePosition = 2,
|
|
273
|
+
Unchanged = 3
|
|
274
|
+
}
|
|
275
|
+
enum MexcFuturesSelfTrade {
|
|
276
|
+
Yes = 1,
|
|
277
|
+
No = 2
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
type MexcFuturesDepthInfo = {
|
|
281
|
+
isContinuityValidated?: boolean
|
|
282
|
+
currentBookVersion?: number
|
|
283
|
+
snapshotEmitted?: boolean
|
|
284
|
+
updates: CircularBuffer<MexcFuturesDepthUpdateMessage>
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
type MexcFuturesDepthMessage = MexcFuturesDepthSnapshotMessage | MexcFuturesDepthUpdateMessage
|
|
288
|
+
|
|
289
|
+
export type MexcFuturesDepthSnapshotMessage = {
|
|
290
|
+
channel: 'push.depth.snapshot'
|
|
291
|
+
symbol: string
|
|
292
|
+
generated: true
|
|
293
|
+
data: MexcFuturesDepthSnapshotData
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export type MexcFuturesDepthSnapshotData = {
|
|
297
|
+
asks: MexcFuturesDepthLevel[]
|
|
298
|
+
bids: MexcFuturesDepthLevel[]
|
|
299
|
+
cts?: number | null
|
|
300
|
+
timestamp: number
|
|
301
|
+
version: number
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
type MexcFuturesDepthUpdateMessage = MexcFuturesMessage<'push.depth', MexcFuturesDepthUpdateData> & { generated?: undefined }
|
|
305
|
+
|
|
306
|
+
export type MexcFuturesDepthUpdateData = {
|
|
307
|
+
asks: MexcFuturesDepthLevel[]
|
|
308
|
+
bids: MexcFuturesDepthLevel[]
|
|
309
|
+
begin?: number | null
|
|
310
|
+
cts?: number
|
|
311
|
+
end?: number | null
|
|
312
|
+
version: number
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export type MexcFuturesDepthLevel = [price: number, quantity: number, ordersCount: number]
|
|
316
|
+
|
|
317
|
+
type MexcFuturesTickerMessage = MexcFuturesMessage<
|
|
318
|
+
'push.ticker',
|
|
319
|
+
{
|
|
320
|
+
ask1: number
|
|
321
|
+
bid1: number
|
|
322
|
+
contractId?: number
|
|
323
|
+
fairPrice: number
|
|
324
|
+
fundingRate: number
|
|
325
|
+
high24Price: number
|
|
326
|
+
indexPrice: number
|
|
327
|
+
lastPrice: number
|
|
328
|
+
lower24Price: number
|
|
329
|
+
maxBidPrice: number
|
|
330
|
+
minAskPrice: number
|
|
331
|
+
riseFallRate: number
|
|
332
|
+
riseFallValue: number
|
|
333
|
+
symbol: string
|
|
334
|
+
timestamp: number
|
|
335
|
+
holdVol: number
|
|
336
|
+
volume24: number
|
|
337
|
+
amount24?: number
|
|
338
|
+
riseFallRates?: number[]
|
|
339
|
+
riseFallRatesOfTimezone?: number[]
|
|
340
|
+
zone?: string
|
|
341
|
+
}
|
|
342
|
+
>
|
|
343
|
+
|
|
344
|
+
type MexcFuturesIndexPriceMessage = MexcFuturesMessage<'push.index.price', MexcFuturesPriceData>
|
|
345
|
+
type MexcFuturesFairPriceMessage = MexcFuturesMessage<'push.fair.price', MexcFuturesPriceData>
|
|
346
|
+
|
|
347
|
+
type MexcFuturesPriceData = {
|
|
348
|
+
price: number
|
|
349
|
+
symbol: string
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
type MexcFuturesFundingRateMessage = MexcFuturesMessage<'push.funding.rate', { rate: number; symbol: string; nextSettleTime?: number }>
|
package/src/mappers/okex.ts
CHANGED
|
@@ -1,15 +1,138 @@
|
|
|
1
1
|
import { asNonZeroNumberOrUndefined, upperCaseSymbols } from '../handy.ts'
|
|
2
|
+
import { getOkexOptionsFamilyOrIndex, getOkexOptionsUnderlyingIndex } from '../okexsymbols.ts'
|
|
2
3
|
import { BookChange, BookTicker, DerivativeTicker, Exchange, Liquidation, OptionSummary, Trade } from '../types.ts'
|
|
3
4
|
import { Mapper, PendingTickerInfoHelper } from './mapper.ts'
|
|
5
|
+
import { OkexSpreadsBookChangeMapper, OkexSpreadsBookTickerMapper, OkexSpreadsTradesMapper } from './okexspreads.ts'
|
|
6
|
+
import { exchangeMappers, mapper } from './registry.ts'
|
|
7
|
+
|
|
8
|
+
const OKEX_V5_API_SWITCH_DATE = new Date('2021-12-23T00:00:00.000Z')
|
|
9
|
+
const OKEX_V5_TBT_BOOK_TICKER_RELEASE_DATE = new Date('2022-05-06T00:00:00.000Z')
|
|
10
|
+
const OKX_PUBLIC_BOOKS_CHANNEL_START_DATE = new Date('2023-02-25T00:00:00.000Z')
|
|
11
|
+
const OKX_PUBLIC_BOOKS_CHANNEL_END_DATE = new Date('2023-03-09T00:00:00.000Z')
|
|
12
|
+
const OKEX_PUBLIC_BOOKS_SWITCH_DATE = new Date('2026-05-21T00:00:00.000Z')
|
|
13
|
+
const OKEX_SPOT_DEPTH_L2_TBT_SWITCH_DATE = new Date('2020-04-10T00:00:00.000Z')
|
|
14
|
+
const OKEX_FUTURES_DEPTH_L2_TBT_SWITCH_DATE = new Date('2019-12-05T00:00:00.000Z')
|
|
15
|
+
const OKEX_SWAP_DEPTH_L2_TBT_SWITCH_DATE = new Date('2020-02-08T00:00:00.000Z')
|
|
16
|
+
const OKCOIN_DEPTH_L2_TBT_SWITCH_DATE = new Date('2020-02-13T00:00:00.000Z')
|
|
17
|
+
const OKCOIN_V5_API_SWITCH_DATE = new Date('2023-04-27T00:00:00.000Z')
|
|
18
|
+
const OKX_TRADES_ALL_CHANNEL_SWITCH_DATE = new Date('2023-10-19T00:00:00.000Z')
|
|
19
|
+
|
|
20
|
+
const useOKXTradesAllChannel = () => process.env.OKX_USE_TRADES_CHANNEL === undefined
|
|
21
|
+
|
|
22
|
+
export const okexMappers = exchangeMappers({
|
|
23
|
+
okex: {
|
|
24
|
+
trades: okexTradesMapper('okex', { market: 'spot' }),
|
|
25
|
+
bookChanges: okexBookChangesMapper('okex', { market: 'spot', depthL2TbtSwitchDate: OKEX_SPOT_DEPTH_L2_TBT_SWITCH_DATE }),
|
|
26
|
+
bookTickers: okexBookTickersMapper('okex', { market: 'spot' })
|
|
27
|
+
},
|
|
28
|
+
'okex-futures': {
|
|
29
|
+
trades: okexTradesMapper('okex-futures', { market: 'futures' }),
|
|
30
|
+
bookChanges: okexBookChangesMapper('okex-futures', {
|
|
31
|
+
market: 'futures',
|
|
32
|
+
depthL2TbtSwitchDate: OKEX_FUTURES_DEPTH_L2_TBT_SWITCH_DATE
|
|
33
|
+
}),
|
|
34
|
+
derivativeTickers: mapper([
|
|
35
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexDerivativeTickerMapper('okex-futures') },
|
|
36
|
+
{ use: () => new OkexV5DerivativeTickerMapper('okex-futures') }
|
|
37
|
+
]),
|
|
38
|
+
liquidations: mapper([
|
|
39
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexLiquidationsMapper('okex-futures', { market: 'futures' }) },
|
|
40
|
+
{ use: () => new OkexV5LiquidationsMapper('okex-futures') }
|
|
41
|
+
]),
|
|
42
|
+
bookTickers: okexBookTickersMapper('okex-futures', { market: 'futures' })
|
|
43
|
+
},
|
|
44
|
+
'okex-swap': {
|
|
45
|
+
trades: okexTradesMapper('okex-swap', { market: 'swap' }),
|
|
46
|
+
bookChanges: okexBookChangesMapper('okex-swap', { market: 'swap', depthL2TbtSwitchDate: OKEX_SWAP_DEPTH_L2_TBT_SWITCH_DATE }),
|
|
47
|
+
derivativeTickers: mapper([
|
|
48
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexDerivativeTickerMapper('okex-swap') },
|
|
49
|
+
{ use: () => new OkexV5DerivativeTickerMapper('okex-swap') }
|
|
50
|
+
]),
|
|
51
|
+
liquidations: mapper([
|
|
52
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexLiquidationsMapper('okex-swap', { market: 'swap' }) },
|
|
53
|
+
{ use: () => new OkexV5LiquidationsMapper('okex-swap') }
|
|
54
|
+
]),
|
|
55
|
+
bookTickers: okexBookTickersMapper('okex-swap', { market: 'swap' })
|
|
56
|
+
},
|
|
57
|
+
'okex-options': {
|
|
58
|
+
trades: okexTradesMapper('okex-options', { market: 'option' }),
|
|
59
|
+
bookChanges: okexBookChangesMapper('okex-options', { market: 'option', depthL2TbtSwitchDate: OKEX_SWAP_DEPTH_L2_TBT_SWITCH_DATE }),
|
|
60
|
+
optionsSummary: mapper([
|
|
61
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexOptionSummaryMapper() },
|
|
62
|
+
{ use: () => new OkexV5OptionSummaryMapper() }
|
|
63
|
+
]),
|
|
64
|
+
bookTickers: okexBookTickersMapper('okex-options', { market: 'option' })
|
|
65
|
+
},
|
|
66
|
+
okcoin: {
|
|
67
|
+
trades: mapper([
|
|
68
|
+
{ until: OKCOIN_V5_API_SWITCH_DATE, use: () => new OkexTradesMapper('okcoin', { market: 'spot' }) },
|
|
69
|
+
{ use: () => new OkexV5TradesMapper('okcoin', { useTradesAllChannel: false }) }
|
|
70
|
+
]),
|
|
71
|
+
bookChanges: mapper([
|
|
72
|
+
{
|
|
73
|
+
until: OKCOIN_DEPTH_L2_TBT_SWITCH_DATE,
|
|
74
|
+
use: () => new OkexBookChangeMapper('okcoin', { market: 'spot', useTickByTickChannel: false })
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
until: OKCOIN_V5_API_SWITCH_DATE,
|
|
78
|
+
use: () => new OkexBookChangeMapper('okcoin', { market: 'spot', useTickByTickChannel: true })
|
|
79
|
+
},
|
|
80
|
+
{ use: () => new OkexV5BookChangeMapper('okcoin', { allowPublicBooksChannel: true }) }
|
|
81
|
+
]),
|
|
82
|
+
bookTickers: mapper([
|
|
83
|
+
{ until: OKCOIN_V5_API_SWITCH_DATE, use: () => new OkexBookTickerMapper('okcoin', { market: 'spot' }) },
|
|
84
|
+
{ use: () => new OkexV5BookTickerMapper('okcoin', { useTbtTickerChannel: true }) }
|
|
85
|
+
])
|
|
86
|
+
},
|
|
87
|
+
'okex-spreads': {
|
|
88
|
+
trades: () => new OkexSpreadsTradesMapper(),
|
|
89
|
+
bookChanges: () => new OkexSpreadsBookChangeMapper(),
|
|
90
|
+
bookTickers: () => new OkexSpreadsBookTickerMapper()
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
function okexTradesMapper(exchange: OKEX_EXCHANGES, { market }: { market: OKEX_MARKETS }) {
|
|
95
|
+
return mapper([
|
|
96
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexTradesMapper(exchange, { market }) },
|
|
97
|
+
{ until: OKX_TRADES_ALL_CHANNEL_SWITCH_DATE, use: () => new OkexV5TradesMapper(exchange, { useTradesAllChannel: false }) },
|
|
98
|
+
{ use: () => new OkexV5TradesMapper(exchange, { useTradesAllChannel: useOKXTradesAllChannel() }) }
|
|
99
|
+
])
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function okexBookChangesMapper(
|
|
103
|
+
exchange: OKEX_EXCHANGES,
|
|
104
|
+
{ market, depthL2TbtSwitchDate }: { market: OKEX_MARKETS; depthL2TbtSwitchDate: Date }
|
|
105
|
+
) {
|
|
106
|
+
return mapper([
|
|
107
|
+
{ until: depthL2TbtSwitchDate, use: () => new OkexBookChangeMapper(exchange, { market, useTickByTickChannel: false }) },
|
|
108
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexBookChangeMapper(exchange, { market, useTickByTickChannel: true }) },
|
|
109
|
+
{ until: OKX_PUBLIC_BOOKS_CHANNEL_START_DATE, use: () => new OkexV5BookChangeMapper(exchange, { allowPublicBooksChannel: false }) },
|
|
110
|
+
{ until: OKX_PUBLIC_BOOKS_CHANNEL_END_DATE, use: () => new OkexV5BookChangeMapper(exchange, { allowPublicBooksChannel: true }) },
|
|
111
|
+
{ until: OKEX_PUBLIC_BOOKS_SWITCH_DATE, use: () => new OkexV5BookChangeMapper(exchange, { allowPublicBooksChannel: false }) },
|
|
112
|
+
{ use: () => new OkexV5BookChangeMapper(exchange, { allowPublicBooksChannel: true }) }
|
|
113
|
+
])
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function okexBookTickersMapper(exchange: OKEX_EXCHANGES, { market }: { market: OKEX_MARKETS }) {
|
|
117
|
+
return mapper([
|
|
118
|
+
{ until: OKEX_V5_API_SWITCH_DATE, use: () => new OkexBookTickerMapper(exchange, { market }) },
|
|
119
|
+
{ until: OKEX_V5_TBT_BOOK_TICKER_RELEASE_DATE, use: () => new OkexV5BookTickerMapper(exchange, { useTbtTickerChannel: false }) },
|
|
120
|
+
{ use: () => new OkexV5BookTickerMapper(exchange, { useTbtTickerChannel: true }) }
|
|
121
|
+
])
|
|
122
|
+
}
|
|
4
123
|
|
|
5
124
|
// V5 Okex API mappers
|
|
6
125
|
// https://www.okex.com/docs-v5/en/#websocket-api-public-channel-trades-channel
|
|
7
126
|
|
|
8
|
-
|
|
127
|
+
class OkexV5TradesMapper implements Mapper<OKEX_EXCHANGES, Trade> {
|
|
128
|
+
private readonly _useTradesAll: boolean
|
|
129
|
+
|
|
9
130
|
constructor(
|
|
10
131
|
private readonly _exchange: Exchange,
|
|
11
|
-
|
|
12
|
-
) {
|
|
132
|
+
{ useTradesAllChannel }: { useTradesAllChannel: boolean }
|
|
133
|
+
) {
|
|
134
|
+
this._useTradesAll = useTradesAllChannel
|
|
135
|
+
}
|
|
13
136
|
|
|
14
137
|
canHandle(message: any) {
|
|
15
138
|
if (message.event !== undefined || message.arg === undefined) {
|
|
@@ -62,14 +185,14 @@ const mapV5BookLevel = (level: OkexV5BookLevel) => {
|
|
|
62
185
|
return { price, amount }
|
|
63
186
|
}
|
|
64
187
|
|
|
65
|
-
|
|
188
|
+
class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange> {
|
|
66
189
|
private _channelName: string
|
|
67
190
|
|
|
68
191
|
constructor(
|
|
69
192
|
private readonly _exchange: Exchange,
|
|
70
|
-
|
|
193
|
+
{ allowPublicBooksChannel }: { allowPublicBooksChannel: boolean }
|
|
71
194
|
) {
|
|
72
|
-
this._channelName = this._getBooksChannelName(
|
|
195
|
+
this._channelName = this._getBooksChannelName(allowPublicBooksChannel)
|
|
73
196
|
}
|
|
74
197
|
|
|
75
198
|
canHandle(message: any) {
|
|
@@ -84,8 +207,8 @@ export class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange
|
|
|
84
207
|
private _hasVip5Access = process.env.OKX_API_VIP_5 !== undefined
|
|
85
208
|
private _hasColoAccess = process.env.OKX_API_COLO !== undefined
|
|
86
209
|
|
|
87
|
-
private _getBooksChannelName(
|
|
88
|
-
if (
|
|
210
|
+
private _getBooksChannelName(allowPublicBooksChannel: boolean) {
|
|
211
|
+
if (allowPublicBooksChannel === false) {
|
|
89
212
|
// historical data always uses books-l2-tbt
|
|
90
213
|
return 'books-l2-tbt'
|
|
91
214
|
}
|
|
@@ -142,11 +265,15 @@ export class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange
|
|
|
142
265
|
}
|
|
143
266
|
}
|
|
144
267
|
|
|
145
|
-
|
|
268
|
+
class OkexV5BookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker> {
|
|
269
|
+
private readonly _useTbtTickerChannel: boolean
|
|
270
|
+
|
|
146
271
|
constructor(
|
|
147
272
|
private readonly _exchange: Exchange,
|
|
148
|
-
|
|
149
|
-
) {
|
|
273
|
+
{ useTbtTickerChannel }: { useTbtTickerChannel: boolean }
|
|
274
|
+
) {
|
|
275
|
+
this._useTbtTickerChannel = useTbtTickerChannel
|
|
276
|
+
}
|
|
150
277
|
|
|
151
278
|
canHandle(message: any) {
|
|
152
279
|
if (message.event !== undefined || message.arg === undefined) {
|
|
@@ -235,7 +362,7 @@ export class OkexV5BookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker
|
|
|
235
362
|
}
|
|
236
363
|
}
|
|
237
364
|
|
|
238
|
-
|
|
365
|
+
class OkexV5DerivativeTickerMapper implements Mapper<'okex-futures' | 'okex-swap', DerivativeTicker> {
|
|
239
366
|
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
240
367
|
private readonly _indexPrices = new Map<string, number>()
|
|
241
368
|
|
|
@@ -366,7 +493,7 @@ export class OkexV5DerivativeTickerMapper implements Mapper<'okex-futures' | 'ok
|
|
|
366
493
|
}
|
|
367
494
|
}
|
|
368
495
|
|
|
369
|
-
|
|
496
|
+
class OkexV5LiquidationsMapper implements Mapper<OKEX_EXCHANGES, Liquidation> {
|
|
370
497
|
private _isFirstMessage = true
|
|
371
498
|
constructor(private readonly _exchange: Exchange) {}
|
|
372
499
|
|
|
@@ -437,7 +564,7 @@ export class OkexV5LiquidationsMapper implements Mapper<OKEX_EXCHANGES, Liquidat
|
|
|
437
564
|
}
|
|
438
565
|
}
|
|
439
566
|
|
|
440
|
-
|
|
567
|
+
class OkexV5OptionSummaryMapper implements Mapper<'okex-options', OptionSummary> {
|
|
441
568
|
private readonly _indexPrices = new Map<string, number>()
|
|
442
569
|
private readonly _openInterests = new Map<string, number>()
|
|
443
570
|
private readonly _markPrices = new Map<string, number>()
|
|
@@ -461,18 +588,15 @@ export class OkexV5OptionSummaryMapper implements Mapper<'okex-options', OptionS
|
|
|
461
588
|
getFilters(symbols?: string[]) {
|
|
462
589
|
symbols = upperCaseSymbols(symbols)
|
|
463
590
|
|
|
464
|
-
const indexes =
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
return `${symbolParts[0]}-${symbolParts[1]}`
|
|
469
|
-
})
|
|
470
|
-
: undefined
|
|
591
|
+
const indexes = symbols !== undefined ? [...new Set(symbols.map((s) => getOkexOptionsUnderlyingIndex(s)))] : undefined
|
|
592
|
+
|
|
593
|
+
const optionSummaryInstrumentFamilies =
|
|
594
|
+
symbols !== undefined ? [...new Set(symbols.map((s) => getOkexOptionsFamilyOrIndex(s)))] : undefined
|
|
471
595
|
|
|
472
596
|
return [
|
|
473
597
|
{
|
|
474
598
|
channel: `opt-summary`,
|
|
475
|
-
symbols:
|
|
599
|
+
symbols: optionSummaryInstrumentFamilies
|
|
476
600
|
} as const,
|
|
477
601
|
{
|
|
478
602
|
channel: `index-tickers`,
|
|
@@ -734,11 +858,15 @@ type OkexV5SummaryMessage = {
|
|
|
734
858
|
//V3 Okex API mappers
|
|
735
859
|
// https://www.okex.com/docs/en/#ws_swap-README
|
|
736
860
|
|
|
737
|
-
|
|
861
|
+
class OkexTradesMapper implements Mapper<OKEX_EXCHANGES, Trade> {
|
|
862
|
+
private readonly _market: OKEX_MARKETS
|
|
863
|
+
|
|
738
864
|
constructor(
|
|
739
865
|
private readonly _exchange: Exchange,
|
|
740
|
-
|
|
741
|
-
) {
|
|
866
|
+
{ market }: { market: OKEX_MARKETS }
|
|
867
|
+
) {
|
|
868
|
+
this._market = market
|
|
869
|
+
}
|
|
742
870
|
|
|
743
871
|
canHandle(message: OkexDataMessage) {
|
|
744
872
|
return message.table === `${this._market}/trade`
|
|
@@ -781,12 +909,17 @@ const mapBookLevel = (level: OkexBookLevel) => {
|
|
|
781
909
|
return { price, amount }
|
|
782
910
|
}
|
|
783
911
|
|
|
784
|
-
|
|
912
|
+
class OkexBookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange> {
|
|
913
|
+
private readonly _canUseTickByTickChannel: boolean
|
|
914
|
+
private readonly _market: OKEX_MARKETS
|
|
915
|
+
|
|
785
916
|
constructor(
|
|
786
917
|
private readonly _exchange: Exchange,
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
918
|
+
{ market, useTickByTickChannel }: { market: OKEX_MARKETS; useTickByTickChannel: boolean }
|
|
919
|
+
) {
|
|
920
|
+
this._market = market
|
|
921
|
+
this._canUseTickByTickChannel = useTickByTickChannel
|
|
922
|
+
}
|
|
790
923
|
|
|
791
924
|
canHandle(message: OkexDataMessage) {
|
|
792
925
|
const channelSuffix = this._canUseTickByTickChannel ? 'depth_l2_tbt' : 'depth'
|
|
@@ -847,7 +980,7 @@ export class OkexBookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange>
|
|
|
847
980
|
}
|
|
848
981
|
}
|
|
849
982
|
|
|
850
|
-
|
|
983
|
+
class OkexDerivativeTickerMapper implements Mapper<'okex-futures' | 'okex-swap', DerivativeTicker> {
|
|
851
984
|
private readonly pendingTickerInfoHelper = new PendingTickerInfoHelper()
|
|
852
985
|
private _futuresChannels = ['futures/ticker', 'futures/mark_price']
|
|
853
986
|
private _swapChannels = ['swap/ticker', 'swap/mark_price', 'swap/funding_rate']
|
|
@@ -910,7 +1043,7 @@ export class OkexDerivativeTickerMapper implements Mapper<'okex-futures' | 'okex
|
|
|
910
1043
|
}
|
|
911
1044
|
}
|
|
912
1045
|
|
|
913
|
-
|
|
1046
|
+
class OkexOptionSummaryMapper implements Mapper<'okex-options', OptionSummary> {
|
|
914
1047
|
private readonly _indexPrices = new Map<string, number>()
|
|
915
1048
|
private readonly expiration_regex = /(\d{2})(\d{2})(\d{2})/
|
|
916
1049
|
|
|
@@ -1002,11 +1135,15 @@ export class OkexOptionSummaryMapper implements Mapper<'okex-options', OptionSum
|
|
|
1002
1135
|
}
|
|
1003
1136
|
}
|
|
1004
1137
|
|
|
1005
|
-
|
|
1138
|
+
class OkexLiquidationsMapper implements Mapper<OKEX_EXCHANGES, Liquidation> {
|
|
1139
|
+
private readonly _market: OKEX_MARKETS
|
|
1140
|
+
|
|
1006
1141
|
constructor(
|
|
1007
1142
|
private readonly _exchange: Exchange,
|
|
1008
|
-
|
|
1009
|
-
) {
|
|
1143
|
+
{ market }: { market: OKEX_MARKETS }
|
|
1144
|
+
) {
|
|
1145
|
+
this._market = market
|
|
1146
|
+
}
|
|
1010
1147
|
|
|
1011
1148
|
canHandle(message: OkexDataMessage) {
|
|
1012
1149
|
return message.table === `${this._market}/liquidation`
|
|
@@ -1041,11 +1178,15 @@ export class OkexLiquidationsMapper implements Mapper<OKEX_EXCHANGES, Liquidatio
|
|
|
1041
1178
|
}
|
|
1042
1179
|
}
|
|
1043
1180
|
|
|
1044
|
-
|
|
1181
|
+
class OkexBookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker> {
|
|
1182
|
+
private readonly _market: OKEX_MARKETS
|
|
1183
|
+
|
|
1045
1184
|
constructor(
|
|
1046
1185
|
private readonly _exchange: Exchange,
|
|
1047
|
-
|
|
1048
|
-
) {
|
|
1186
|
+
{ market }: { market: OKEX_MARKETS }
|
|
1187
|
+
) {
|
|
1188
|
+
this._market = market
|
|
1189
|
+
}
|
|
1049
1190
|
|
|
1050
1191
|
canHandle(message: OkexDataMessage) {
|
|
1051
1192
|
return message.table === `${this._market}/ticker`
|