tardis-dev 16.2.1 → 16.2.2
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/computable/computable.js.map +1 -1
- package/dist/handy.d.ts.map +1 -1
- package/dist/handy.js +1 -1
- package/dist/handy.js.map +1 -1
- package/dist/instrumentinfo.js +1 -1
- package/dist/instrumentinfo.js.map +1 -1
- package/dist/mappers/binance.d.ts.map +1 -1
- package/dist/mappers/binance.js.map +1 -1
- package/dist/mappers/bybit.d.ts.map +1 -1
- package/dist/mappers/bybit.js.map +1 -1
- package/dist/mappers/gateio.d.ts.map +1 -1
- package/dist/mappers/gateio.js.map +1 -1
- package/dist/mappers/gateiofutures.js.map +1 -1
- package/dist/mappers/huobi.d.ts.map +1 -1
- package/dist/mappers/huobi.js.map +1 -1
- package/dist/mappers/index.js.map +1 -1
- package/dist/mappers/kucoin.d.ts.map +1 -1
- package/dist/mappers/kucoin.js.map +1 -1
- package/dist/mappers/okex.d.ts.map +1 -1
- package/dist/mappers/okex.js.map +1 -1
- package/dist/mappers/phemex.d.ts.map +1 -1
- package/dist/mappers/phemex.js +11 -2
- package/dist/mappers/phemex.js.map +1 -1
- package/dist/realtimefeeds/bitnomial.d.ts.map +1 -1
- package/dist/realtimefeeds/bitnomial.js.map +1 -1
- package/dist/realtimefeeds/coinbase.d.ts.map +1 -1
- package/dist/realtimefeeds/coinbase.js.map +1 -1
- package/dist/realtimefeeds/hitbtc.d.ts.map +1 -1
- package/dist/realtimefeeds/hitbtc.js.map +1 -1
- package/dist/realtimefeeds/huobi.d.ts.map +1 -1
- package/dist/realtimefeeds/huobi.js.map +1 -1
- package/dist/realtimefeeds/kucoinfutures.d.ts.map +1 -1
- package/dist/realtimefeeds/kucoinfutures.js.map +1 -1
- package/dist/realtimefeeds/realtimefeed.d.ts.map +1 -1
- package/dist/realtimefeeds/realtimefeed.js.map +1 -1
- package/dist/realtimefeeds/serum.d.ts.map +1 -1
- package/dist/realtimefeeds/serum.js.map +1 -1
- package/dist/replay.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/computable/computable.ts +14 -11
- package/src/handy.ts +30 -19
- package/src/instrumentinfo.ts +1 -1
- package/src/mappers/binance.ts +16 -8
- package/src/mappers/bybit.ts +21 -16
- package/src/mappers/gateio.ts +4 -1
- package/src/mappers/gateiofutures.ts +2 -2
- package/src/mappers/huobi.ts +8 -6
- package/src/mappers/index.ts +2 -2
- package/src/mappers/kucoin.ts +4 -1
- package/src/mappers/okex.ts +24 -6
- package/src/mappers/phemex.ts +14 -4
- package/src/realtimefeeds/bitnomial.ts +14 -11
- package/src/realtimefeeds/coinbase.ts +14 -11
- package/src/realtimefeeds/hitbtc.ts +10 -7
- package/src/realtimefeeds/huobi.ts +10 -2
- package/src/realtimefeeds/kucoinfutures.ts +4 -1
- package/src/realtimefeeds/realtimefeed.ts +5 -1
- package/src/realtimefeeds/serum.ts +14 -11
- package/src/replay.ts +2 -2
package/src/mappers/okex.ts
CHANGED
|
@@ -6,7 +6,10 @@ import { Mapper, PendingTickerInfoHelper } from './mapper.ts'
|
|
|
6
6
|
// https://www.okex.com/docs-v5/en/#websocket-api-public-channel-trades-channel
|
|
7
7
|
|
|
8
8
|
export class OkexV5TradesMapper implements Mapper<OKEX_EXCHANGES, Trade> {
|
|
9
|
-
constructor(
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly _exchange: Exchange,
|
|
11
|
+
private readonly _useTradesAll: boolean
|
|
12
|
+
) {}
|
|
10
13
|
|
|
11
14
|
canHandle(message: any) {
|
|
12
15
|
if (message.event !== undefined || message.arg === undefined) {
|
|
@@ -62,7 +65,10 @@ const mapV5BookLevel = (level: OkexV5BookLevel) => {
|
|
|
62
65
|
export class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange> {
|
|
63
66
|
private _channelName: string
|
|
64
67
|
|
|
65
|
-
constructor(
|
|
68
|
+
constructor(
|
|
69
|
+
private readonly _exchange: Exchange,
|
|
70
|
+
usePublicBooksChannel: boolean
|
|
71
|
+
) {
|
|
66
72
|
this._channelName = this._getBooksChannelName(usePublicBooksChannel)
|
|
67
73
|
}
|
|
68
74
|
|
|
@@ -137,7 +143,10 @@ export class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange
|
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
export class OkexV5BookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker> {
|
|
140
|
-
constructor(
|
|
146
|
+
constructor(
|
|
147
|
+
private readonly _exchange: Exchange,
|
|
148
|
+
private readonly _useTbtTickerChannel: boolean
|
|
149
|
+
) {}
|
|
141
150
|
|
|
142
151
|
canHandle(message: any) {
|
|
143
152
|
if (message.event !== undefined || message.arg === undefined) {
|
|
@@ -726,7 +735,10 @@ type OkexV5SummaryMessage = {
|
|
|
726
735
|
// https://www.okex.com/docs/en/#ws_swap-README
|
|
727
736
|
|
|
728
737
|
export class OkexTradesMapper implements Mapper<OKEX_EXCHANGES, Trade> {
|
|
729
|
-
constructor(
|
|
738
|
+
constructor(
|
|
739
|
+
private readonly _exchange: Exchange,
|
|
740
|
+
private readonly _market: OKEX_MARKETS
|
|
741
|
+
) {}
|
|
730
742
|
|
|
731
743
|
canHandle(message: OkexDataMessage) {
|
|
732
744
|
return message.table === `${this._market}/trade`
|
|
@@ -991,7 +1003,10 @@ export class OkexOptionSummaryMapper implements Mapper<'okex-options', OptionSum
|
|
|
991
1003
|
}
|
|
992
1004
|
|
|
993
1005
|
export class OkexLiquidationsMapper implements Mapper<OKEX_EXCHANGES, Liquidation> {
|
|
994
|
-
constructor(
|
|
1006
|
+
constructor(
|
|
1007
|
+
private readonly _exchange: Exchange,
|
|
1008
|
+
private readonly _market: OKEX_MARKETS
|
|
1009
|
+
) {}
|
|
995
1010
|
|
|
996
1011
|
canHandle(message: OkexDataMessage) {
|
|
997
1012
|
return message.table === `${this._market}/liquidation`
|
|
@@ -1027,7 +1042,10 @@ export class OkexLiquidationsMapper implements Mapper<OKEX_EXCHANGES, Liquidatio
|
|
|
1027
1042
|
}
|
|
1028
1043
|
|
|
1029
1044
|
export class OkexBookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker> {
|
|
1030
|
-
constructor(
|
|
1045
|
+
constructor(
|
|
1046
|
+
private readonly _exchange: Exchange,
|
|
1047
|
+
private readonly _market: OKEX_MARKETS
|
|
1048
|
+
) {}
|
|
1031
1049
|
|
|
1032
1050
|
canHandle(message: OkexDataMessage) {
|
|
1033
1051
|
return message.table === `${this._market}/ticker`
|
package/src/mappers/phemex.ts
CHANGED
|
@@ -27,6 +27,11 @@ function getQtyScale(symbol: string) {
|
|
|
27
27
|
return 1
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function isExcludedFromNormalizedOutput(symbol: string) {
|
|
31
|
+
// Matches tardis-api metadata: Phemex spot OL/USDT uses sOLUSDT, which collides with SOLUSDT when normalized.
|
|
32
|
+
return symbol === 'sOLUSDT'
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
const COINS_STARTING_WITH_S = [
|
|
31
36
|
'SOLUSD',
|
|
32
37
|
'SUSHIUSD',
|
|
@@ -163,10 +168,13 @@ export const phemexTradesMapper: Mapper<'phemex', Trade> = {
|
|
|
163
168
|
},
|
|
164
169
|
|
|
165
170
|
*map(message: PhemexTradeMessage, localTimestamp: Date): IterableIterator<Trade> {
|
|
171
|
+
const symbol = message.symbol
|
|
172
|
+
if (isExcludedFromNormalizedOutput(symbol)) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
|
|
166
176
|
if ('trades' in message) {
|
|
167
177
|
for (const [timestamp, side, priceEp, qty] of message.trades) {
|
|
168
|
-
const symbol = message.symbol
|
|
169
|
-
|
|
170
178
|
yield {
|
|
171
179
|
type: 'trade',
|
|
172
180
|
symbol: symbol.toUpperCase(),
|
|
@@ -181,8 +189,6 @@ export const phemexTradesMapper: Mapper<'phemex', Trade> = {
|
|
|
181
189
|
}
|
|
182
190
|
} else if ('trades_p' in message) {
|
|
183
191
|
for (const [timestamp, side, price, qty] of message.trades_p) {
|
|
184
|
-
const symbol = message.symbol
|
|
185
|
-
|
|
186
192
|
yield {
|
|
187
193
|
type: 'trade',
|
|
188
194
|
symbol: symbol.toUpperCase(),
|
|
@@ -253,6 +259,10 @@ export const phemexBookChangeMapper: Mapper<'phemex', BookChange> = {
|
|
|
253
259
|
|
|
254
260
|
*map(message: PhemexBookMessage, localTimestamp: Date): IterableIterator<BookChange> {
|
|
255
261
|
const symbol = message.symbol
|
|
262
|
+
if (isExcludedFromNormalizedOutput(symbol)) {
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
|
|
256
266
|
if ('book' in message) {
|
|
257
267
|
const mapBookLevel = mapBookLevelForSymbol(symbol)
|
|
258
268
|
yield {
|
|
@@ -27,20 +27,23 @@ export class BitnomialRealTimeFeed extends RealTimeFeedBase {
|
|
|
27
27
|
product_codes: filter.symbols
|
|
28
28
|
}
|
|
29
29
|
})
|
|
30
|
-
.reduce(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
matchingExisting.product_codes.
|
|
30
|
+
.reduce(
|
|
31
|
+
(prev, current) => {
|
|
32
|
+
const matchingExisting = prev.find((c) => c.name === current.name)
|
|
33
|
+
if (matchingExisting !== undefined) {
|
|
34
|
+
for (const symbol of current.product_codes) {
|
|
35
|
+
if (matchingExisting.product_codes.includes(symbol) === false) {
|
|
36
|
+
matchingExisting.product_codes.push(symbol)
|
|
37
|
+
}
|
|
36
38
|
}
|
|
39
|
+
} else {
|
|
40
|
+
prev.push(current)
|
|
37
41
|
}
|
|
38
|
-
} else {
|
|
39
|
-
prev.push(current)
|
|
40
|
-
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
return prev
|
|
44
|
+
},
|
|
45
|
+
[] as { name: string; product_codes: string[] }[]
|
|
46
|
+
)
|
|
44
47
|
|
|
45
48
|
return [
|
|
46
49
|
{
|
|
@@ -53,20 +53,23 @@ export class CoinbaseRealTimeFeed extends RealTimeFeedBase {
|
|
|
53
53
|
product_ids: filter.symbols
|
|
54
54
|
}
|
|
55
55
|
})
|
|
56
|
-
.reduce(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
matchingExisting.product_ids.
|
|
56
|
+
.reduce(
|
|
57
|
+
(prev, current) => {
|
|
58
|
+
const matchingExisting = prev.find((c) => c.name === current.name)
|
|
59
|
+
if (matchingExisting !== undefined) {
|
|
60
|
+
for (const symbol of current.product_ids) {
|
|
61
|
+
if (matchingExisting.product_ids.includes(symbol) === false) {
|
|
62
|
+
matchingExisting.product_ids.push(symbol)
|
|
63
|
+
}
|
|
62
64
|
}
|
|
65
|
+
} else {
|
|
66
|
+
prev.push(current)
|
|
63
67
|
}
|
|
64
|
-
} else {
|
|
65
|
-
prev.push(current)
|
|
66
|
-
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
return prev
|
|
70
|
+
},
|
|
71
|
+
[] as { name: string; product_ids: string[] }[]
|
|
72
|
+
)
|
|
70
73
|
|
|
71
74
|
if (this._hasCredentials) {
|
|
72
75
|
const authParams = this.getAuthParams()
|
|
@@ -36,14 +36,17 @@ export class HitBtcRealTimeFeed extends RealTimeFeedBase {
|
|
|
36
36
|
})
|
|
37
37
|
})
|
|
38
38
|
.flatMap((s) => s)
|
|
39
|
-
.reduce(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
.reduce(
|
|
40
|
+
(prev, current) => {
|
|
41
|
+
const matchingExisting = prev.find((c) => c.method === current.method && c.symbol === current.symbol)
|
|
42
|
+
if (matchingExisting === undefined) {
|
|
43
|
+
prev.push(current)
|
|
44
|
+
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
return prev
|
|
47
|
+
},
|
|
48
|
+
[] as { method: string; symbol: string }[]
|
|
49
|
+
)
|
|
47
50
|
|
|
48
51
|
return subscriptions.map((subscription, index) => {
|
|
49
52
|
return {
|
|
@@ -271,7 +271,11 @@ class HuobiOpenInterestClient extends PoolingClientBase {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
class HuobiOptionsMarketIndexClient extends PoolingClientBase {
|
|
274
|
-
constructor(
|
|
274
|
+
constructor(
|
|
275
|
+
exchange: string,
|
|
276
|
+
private readonly _httpURL: string,
|
|
277
|
+
private readonly _instruments: string[]
|
|
278
|
+
) {
|
|
275
279
|
super(exchange, 4)
|
|
276
280
|
}
|
|
277
281
|
|
|
@@ -306,7 +310,11 @@ class HuobiOptionsMarketIndexClient extends PoolingClientBase {
|
|
|
306
310
|
}
|
|
307
311
|
|
|
308
312
|
class HuobiOptionsIndexClient extends PoolingClientBase {
|
|
309
|
-
constructor(
|
|
313
|
+
constructor(
|
|
314
|
+
exchange: string,
|
|
315
|
+
private readonly _httpURL: string,
|
|
316
|
+
private readonly _instruments: string[]
|
|
317
|
+
) {
|
|
310
318
|
super(exchange, 4)
|
|
311
319
|
}
|
|
312
320
|
|
|
@@ -109,7 +109,10 @@ export class KucoinFuturesSingleConnectionRealTimeFeed extends RealTimeFeedBase
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
class KucoinFuturesContractDetailsClient extends PoolingClientBase {
|
|
112
|
-
constructor(
|
|
112
|
+
constructor(
|
|
113
|
+
exchange: string,
|
|
114
|
+
private readonly _httpURL: string
|
|
115
|
+
) {
|
|
113
116
|
super(exchange, 6)
|
|
114
117
|
}
|
|
115
118
|
|
|
@@ -377,7 +377,11 @@ export abstract class PoolingClientBase implements RealTimeFeedIterable {
|
|
|
377
377
|
protected readonly debug: dbg.Debugger
|
|
378
378
|
private _tid: NodeJS.Timeout | undefined = undefined
|
|
379
379
|
|
|
380
|
-
constructor(
|
|
380
|
+
constructor(
|
|
381
|
+
exchange: string,
|
|
382
|
+
private readonly _poolingIntervalSeconds: number,
|
|
383
|
+
protected readonly onError?: (error: Error) => void
|
|
384
|
+
) {
|
|
381
385
|
this.debug = dbg(`tardis-dev:pooling-client:${exchange}`)
|
|
382
386
|
}
|
|
383
387
|
|
|
@@ -40,20 +40,23 @@ export class SerumRealTimeFeed extends RealTimeFeedBase {
|
|
|
40
40
|
markets: filter.symbols
|
|
41
41
|
}
|
|
42
42
|
})
|
|
43
|
-
.reduce(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
matchingExisting.markets.
|
|
43
|
+
.reduce(
|
|
44
|
+
(prev, current) => {
|
|
45
|
+
const matchingExisting = prev.find((c) => c.channel === current.channel)
|
|
46
|
+
if (matchingExisting !== undefined) {
|
|
47
|
+
for (const market of current.markets) {
|
|
48
|
+
if (matchingExisting.markets.includes(market) === false) {
|
|
49
|
+
matchingExisting.markets.push(market)
|
|
50
|
+
}
|
|
49
51
|
}
|
|
52
|
+
} else {
|
|
53
|
+
prev.push(current)
|
|
50
54
|
}
|
|
51
|
-
} else {
|
|
52
|
-
prev.push(current)
|
|
53
|
-
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
return prev
|
|
57
|
+
},
|
|
58
|
+
[] as { channel: string; markets: string[] }[]
|
|
59
|
+
)
|
|
57
60
|
|
|
58
61
|
return subs
|
|
59
62
|
}
|
package/src/replay.ts
CHANGED
|
@@ -35,8 +35,8 @@ export async function* replay<T extends Exchange, U extends boolean = false, Z e
|
|
|
35
35
|
? { localTimestamp: Buffer; message: Buffer } | undefined
|
|
36
36
|
: { localTimestamp: Date; message: any } | undefined
|
|
37
37
|
: U extends true
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
? { localTimestamp: Buffer; message: Buffer }
|
|
39
|
+
: { localTimestamp: Date; message: any }
|
|
40
40
|
> {
|
|
41
41
|
validateReplayOptions(exchange, from, to, filters)
|
|
42
42
|
|