tardis-dev 13.1.15 → 13.4.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/dist/binarysplit.d.ts +1 -0
- package/dist/binarysplit.d.ts.map +1 -1
- package/dist/consts.d.ts +4 -4
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +4 -0
- package/dist/consts.js.map +1 -1
- package/dist/mappers/huobi.js +1 -1
- package/dist/mappers/huobi.js.map +1 -1
- package/dist/mappers/index.d.ts.map +1 -1
- package/dist/mappers/index.js +12 -4
- package/dist/mappers/index.js.map +1 -1
- package/dist/mappers/okex.d.ts +24 -4
- package/dist/mappers/okex.d.ts.map +1 -1
- package/dist/mappers/okex.js +61 -16
- package/dist/mappers/okex.js.map +1 -1
- package/dist/realtimefeeds/deribit.d.ts +2 -2
- package/dist/realtimefeeds/deribit.d.ts.map +1 -1
- package/dist/realtimefeeds/deribit.js +6 -6
- package/dist/realtimefeeds/deribit.js.map +1 -1
- package/dist/realtimefeeds/huobi.d.ts +1 -0
- package/dist/realtimefeeds/huobi.d.ts.map +1 -1
- package/dist/realtimefeeds/okex.d.ts +3 -0
- package/dist/realtimefeeds/okex.d.ts.map +1 -1
- package/dist/realtimefeeds/okex.js +27 -0
- package/dist/realtimefeeds/okex.js.map +1 -1
- package/dist/realtimefeeds/realtimefeed.d.ts +2 -1
- package/dist/realtimefeeds/realtimefeed.d.ts.map +1 -1
- package/dist/realtimefeeds/realtimefeed.js +2 -2
- package/dist/realtimefeeds/realtimefeed.js.map +1 -1
- package/dist/replay.js +2 -2
- package/dist/replay.js.map +1 -1
- package/dist/worker.js +2 -2
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/src/consts.ts +4 -0
- package/src/mappers/huobi.ts +1 -1
- package/src/mappers/index.ts +13 -5
- package/src/mappers/okex.ts +81 -16
- package/src/realtimefeeds/deribit.ts +8 -7
- package/src/realtimefeeds/okex.ts +29 -0
- package/src/realtimefeeds/realtimefeed.ts +2 -2
package/src/mappers/okex.ts
CHANGED
|
@@ -51,34 +51,46 @@ const mapV5BookLevel = (level: OkexV5BookLevel) => {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange> {
|
|
54
|
-
|
|
54
|
+
private _channelName: string
|
|
55
|
+
|
|
56
|
+
constructor(private readonly _exchange: Exchange, usePublicBooksChannel: boolean) {
|
|
57
|
+
this._channelName = this._getBooksChannelName(usePublicBooksChannel)
|
|
58
|
+
}
|
|
55
59
|
|
|
56
60
|
canHandle(message: any) {
|
|
57
61
|
if (message.event !== undefined || message.arg === undefined) {
|
|
58
62
|
return false
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
return message.arg.channel === this._channelName
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private _hasCredentials = process.env.OKX_API_KEY !== undefined
|
|
69
|
+
private _hasVip5Access = process.env.OKX_API_VIP_5 !== undefined
|
|
70
|
+
|
|
71
|
+
private _getBooksChannelName(usePublicBooksChannel: boolean) {
|
|
72
|
+
if (usePublicBooksChannel === false) {
|
|
73
|
+
// historical data always uses books-l2-tbt
|
|
74
|
+
return 'books-l2-tbt'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (this._hasCredentials && this._hasVip5Access) {
|
|
78
|
+
return 'books-l2-tbt'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (this._hasCredentials) {
|
|
82
|
+
return 'books50-l2-tbt'
|
|
63
83
|
}
|
|
64
|
-
|
|
84
|
+
|
|
85
|
+
return 'books'
|
|
65
86
|
}
|
|
66
87
|
|
|
67
88
|
getFilters(symbols?: string[]) {
|
|
68
89
|
symbols = upperCaseSymbols(symbols)
|
|
69
90
|
|
|
70
|
-
if (this._usePublicBooksChannel) {
|
|
71
|
-
return [
|
|
72
|
-
{
|
|
73
|
-
channel: `books` as any,
|
|
74
|
-
symbols
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
|
|
79
91
|
return [
|
|
80
92
|
{
|
|
81
|
-
channel:
|
|
93
|
+
channel: this._channelName as any,
|
|
82
94
|
symbols
|
|
83
95
|
}
|
|
84
96
|
]
|
|
@@ -111,18 +123,31 @@ export class OkexV5BookChangeMapper implements Mapper<OKEX_EXCHANGES, BookChange
|
|
|
111
123
|
}
|
|
112
124
|
|
|
113
125
|
export class OkexV5BookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker> {
|
|
114
|
-
constructor(private readonly _exchange: Exchange) {}
|
|
126
|
+
constructor(private readonly _exchange: Exchange, private readonly _useTbtTickerChannel: boolean) {}
|
|
115
127
|
|
|
116
128
|
canHandle(message: any) {
|
|
117
129
|
if (message.event !== undefined || message.arg === undefined) {
|
|
118
130
|
return false
|
|
119
131
|
}
|
|
132
|
+
|
|
133
|
+
if (this._useTbtTickerChannel) {
|
|
134
|
+
return message.arg.channel === 'bbo-tbt'
|
|
135
|
+
}
|
|
136
|
+
|
|
120
137
|
return message.arg.channel === 'tickers'
|
|
121
138
|
}
|
|
122
139
|
|
|
123
140
|
getFilters(symbols?: string[]) {
|
|
124
141
|
symbols = upperCaseSymbols(symbols)
|
|
125
142
|
|
|
143
|
+
if (this._useTbtTickerChannel) {
|
|
144
|
+
return [
|
|
145
|
+
{
|
|
146
|
+
channel: `bbo-tbt` as const,
|
|
147
|
+
symbols
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
}
|
|
126
151
|
return [
|
|
127
152
|
{
|
|
128
153
|
channel: `tickers` as const,
|
|
@@ -131,7 +156,42 @@ export class OkexV5BookTickerMapper implements Mapper<OKEX_EXCHANGES, BookTicker
|
|
|
131
156
|
]
|
|
132
157
|
}
|
|
133
158
|
|
|
134
|
-
|
|
159
|
+
map(message: OkexV5TickerMessage | OkexBBOTbtData, localTimestamp: Date): IterableIterator<BookTicker> {
|
|
160
|
+
if (message.arg.channel === 'bbo-tbt') {
|
|
161
|
+
return this._mapFromTbtTicker(message as OkexBBOTbtData, localTimestamp)
|
|
162
|
+
} else {
|
|
163
|
+
return this._mapFromTicker(message as OkexV5TickerMessage, localTimestamp)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private *_mapFromTbtTicker(message: OkexBBOTbtData, localTimestamp: Date): IterableIterator<BookTicker> {
|
|
168
|
+
if (!message.data) {
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const tbtTicker of message.data) {
|
|
173
|
+
const bestAsk = tbtTicker.asks !== undefined && tbtTicker.asks[0] ? mapBookLevel(tbtTicker.asks[0]) : undefined
|
|
174
|
+
const bestBid = tbtTicker.bids !== undefined && tbtTicker.bids[0] ? mapBookLevel(tbtTicker.bids[0]) : undefined
|
|
175
|
+
|
|
176
|
+
const ticker: BookTicker = {
|
|
177
|
+
type: 'book_ticker',
|
|
178
|
+
symbol: message.arg.instId,
|
|
179
|
+
exchange: this._exchange,
|
|
180
|
+
|
|
181
|
+
askAmount: bestAsk?.amount,
|
|
182
|
+
askPrice: bestAsk?.price,
|
|
183
|
+
|
|
184
|
+
bidPrice: bestBid?.price,
|
|
185
|
+
bidAmount: bestBid?.amount,
|
|
186
|
+
timestamp: new Date(Number(tbtTicker.ts)),
|
|
187
|
+
localTimestamp: localTimestamp
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
yield ticker
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private *_mapFromTicker(message: OkexV5TickerMessage, localTimestamp: Date): IterableIterator<BookTicker> {
|
|
135
195
|
for (const okexTicker of message.data) {
|
|
136
196
|
const ticker: BookTicker = {
|
|
137
197
|
type: 'book_ticker',
|
|
@@ -1049,3 +1109,8 @@ type OkexOptionSummaryData = {
|
|
|
1049
1109
|
}
|
|
1050
1110
|
]
|
|
1051
1111
|
}
|
|
1112
|
+
|
|
1113
|
+
type OkexBBOTbtData = {
|
|
1114
|
+
arg: { channel: 'bbo-tbt'; instId: 'WAVES-USDT-SWAP' }
|
|
1115
|
+
data: [{ asks: [['16.083', '65', '0', '1']]; bids: [['16.082', '143', '0', '4']]; ts: '1651750920000' }]
|
|
1116
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { wait } from '../handy'
|
|
1
2
|
import { Filter, FilterForExchange } from '../types'
|
|
2
3
|
import { RealTimeFeedBase } from './realtimefeed'
|
|
3
4
|
|
|
4
5
|
export class DeribitRealTimeDataFeed extends RealTimeFeedBase {
|
|
5
6
|
protected wssURL = 'wss://www.deribit.com/ws/api/v2'
|
|
7
|
+
private _hasCredentials = process.env.DERIBIT_API_CLIENT_ID !== undefined && process.env.DERIBIT_API_CLIENT_SECRET !== undefined
|
|
6
8
|
|
|
7
9
|
protected channelsWithIntervals: FilterForExchange['deribit']['channel'][] = ['book', 'perpetual', 'trades', 'ticker']
|
|
8
10
|
|
|
9
11
|
protected mapToSubscribeMessages(filters: Filter<string>[]): any[] {
|
|
10
|
-
const hasCredentials = this.
|
|
12
|
+
const hasCredentials = this._hasCredentials
|
|
13
|
+
|
|
11
14
|
const channels = filters
|
|
12
15
|
.map((filter) => {
|
|
13
16
|
if (!filter.symbols || filter.symbols.length === 0) {
|
|
@@ -38,11 +41,7 @@ export class DeribitRealTimeDataFeed extends RealTimeFeedBase {
|
|
|
38
41
|
return message.error !== undefined
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
return process.env.DERIBIT_API_CLIENT_ID !== undefined && process.env.DERIBIT_API_CLIENT_SECRET !== undefined
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
protected onConnected() {
|
|
44
|
+
protected async onConnected() {
|
|
46
45
|
// set heartbeat so deribit won't close connection prematurely
|
|
47
46
|
// https://docs.deribit.com/v2/#public-set_heartbeat
|
|
48
47
|
|
|
@@ -55,7 +54,7 @@ export class DeribitRealTimeDataFeed extends RealTimeFeedBase {
|
|
|
55
54
|
}
|
|
56
55
|
})
|
|
57
56
|
|
|
58
|
-
if (this.
|
|
57
|
+
if (this._hasCredentials) {
|
|
59
58
|
this.send({
|
|
60
59
|
jsonrpc: '2.0',
|
|
61
60
|
method: 'public/auth',
|
|
@@ -66,6 +65,8 @@ export class DeribitRealTimeDataFeed extends RealTimeFeedBase {
|
|
|
66
65
|
client_secret: process.env.DERIBIT_API_CLIENT_SECRET
|
|
67
66
|
}
|
|
68
67
|
})
|
|
68
|
+
|
|
69
|
+
await wait(10)
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import { inflateRawSync } from 'zlib'
|
|
2
|
+
import crypto from 'crypto'
|
|
3
|
+
import { wait } from '../handy'
|
|
2
4
|
import { Filter } from '../types'
|
|
3
5
|
import { RealTimeFeedBase } from './realtimefeed'
|
|
4
6
|
|
|
5
7
|
export class OkexRealTimeFeed extends RealTimeFeedBase {
|
|
6
8
|
protected wssURL = 'wss://ws.okx.com:8443/ws/v5/public'
|
|
7
9
|
|
|
10
|
+
private _hasCredentials = process.env.OKX_API_KEY !== undefined
|
|
11
|
+
|
|
12
|
+
private secondsSinceEpoch() {
|
|
13
|
+
return Math.floor(Date.now() / 1000)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
protected async onConnected() {
|
|
17
|
+
if (this._hasCredentials) {
|
|
18
|
+
const timestamp = this.secondsSinceEpoch().toString()
|
|
19
|
+
const sign = crypto.createHmac('sha256', process.env.OKX_API_SECRET_KEY!).update(`${timestamp}GET/users/self/verify`).digest('base64')
|
|
20
|
+
|
|
21
|
+
this.send({
|
|
22
|
+
op: 'login',
|
|
23
|
+
args: [
|
|
24
|
+
{
|
|
25
|
+
apiKey: process.env.OKX_API_KEY,
|
|
26
|
+
passphrase: process.env.OKX_API_PASSPHRASE,
|
|
27
|
+
timestamp,
|
|
28
|
+
sign
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
await wait(50)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
8
37
|
protected mapToSubscribeMessages(filters: Filter<string>[]): any[] {
|
|
9
38
|
const args = filters
|
|
10
39
|
.map((filter) => {
|
|
@@ -204,7 +204,7 @@ export abstract class RealTimeFeedBase implements RealTimeFeedIterable {
|
|
|
204
204
|
|
|
205
205
|
protected onMessage(_msg: any) {}
|
|
206
206
|
|
|
207
|
-
protected onConnected() {}
|
|
207
|
+
protected async onConnected() {}
|
|
208
208
|
|
|
209
209
|
protected decompress?: (msg: any) => Buffer
|
|
210
210
|
|
|
@@ -254,7 +254,7 @@ export abstract class RealTimeFeedBase implements RealTimeFeedIterable {
|
|
|
254
254
|
return prev
|
|
255
255
|
}, new Set<string>()).size
|
|
256
256
|
|
|
257
|
-
this.onConnected()
|
|
257
|
+
await this.onConnected()
|
|
258
258
|
|
|
259
259
|
for (const message of subscribeMessages) {
|
|
260
260
|
this.send(message)
|