@icgio/icg-exchanges 1.40.43 → 1.40.45
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/lib/exchanges/ascendex.js +3 -4
- package/lib/exchanges/biconomy.js +2 -3
- package/lib/exchanges/binance.js +3 -4
- package/lib/exchanges/bingx.js +2 -3
- package/lib/exchanges/bitget.js +3 -4
- package/lib/exchanges/bitmart.js +2 -3
- package/lib/exchanges/bitmex.js +1 -2
- package/lib/exchanges/bitrue.js +2 -3
- package/lib/exchanges/blofin.js +3 -4
- package/lib/exchanges/btse.js +2 -3
- package/lib/exchanges/bybit.js +2 -3
- package/lib/exchanges/coinbase.js +30 -13
- package/lib/exchanges/coinstore.js +2 -3
- package/lib/exchanges/cryptocom.js +2 -3
- package/lib/exchanges/exchange-base.js +94 -2
- package/lib/exchanges/exchange-ws.js +1 -2
- package/lib/exchanges/gate.js +2 -4
- package/lib/exchanges/hashkey.js +2 -3
- package/lib/exchanges/hashkeyglobal.js +2 -3
- package/lib/exchanges/hitbtc.js +1 -2
- package/lib/exchanges/hkbitex.js +2 -3
- package/lib/exchanges/htx.js +3 -4
- package/lib/exchanges/kucoin.js +3 -4
- package/lib/exchanges/lbank.js +2 -3
- package/lib/exchanges/mexc.js +2 -3
- package/lib/exchanges/okx.js +3 -4
- package/lib/exchanges/phemex.js +3 -4
- package/lib/exchanges/swft.js +9 -9
- package/lib/exchanges/upbit.js +2 -3
- package/lib/exchanges/xt.js +2 -3
- package/package.json +2 -2
|
@@ -112,9 +112,8 @@ module.exports = class Ascendex extends ExchangeBase {
|
|
|
112
112
|
}),
|
|
113
113
|
)
|
|
114
114
|
})
|
|
115
|
-
this.ws.market.on_message((data
|
|
115
|
+
this.ws.market.on_message((data) => {
|
|
116
116
|
data = JSON.parse(data)
|
|
117
|
-
const t_parsed = process.hrtime()
|
|
118
117
|
if (data.op === 'pong') {
|
|
119
118
|
this.ws.market.last_pong = new Date()
|
|
120
119
|
} else {
|
|
@@ -127,7 +126,7 @@ module.exports = class Ascendex extends ExchangeBase {
|
|
|
127
126
|
for (let bid of data.data.bids) {
|
|
128
127
|
this.ws.market.bids_dict[pair].insert(bid[0], bid[1])
|
|
129
128
|
}
|
|
130
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
129
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
131
130
|
const asks_s = this.ws.market.asks_dict[pair].entries()
|
|
132
131
|
const bids_s = this.ws.market.bids_dict[pair].entries()
|
|
133
132
|
if (asks_s.length > 0 && bids_s.length > 0) {
|
|
@@ -153,7 +152,7 @@ module.exports = class Ascendex extends ExchangeBase {
|
|
|
153
152
|
this.ws.market.bids_dict[pair].insert(parseFloat(bid[0]), parseFloat(bid[1]))
|
|
154
153
|
}
|
|
155
154
|
}
|
|
156
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
155
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
157
156
|
const asks_u = this.ws.market.asks_dict[pair].entries()
|
|
158
157
|
const bids_u = this.ws.market.bids_dict[pair].entries()
|
|
159
158
|
if (asks_u.length > 0 && bids_u.length > 0) {
|
|
@@ -109,9 +109,8 @@ module.exports = class Biconomy extends ExchangeBase {
|
|
|
109
109
|
}),
|
|
110
110
|
)
|
|
111
111
|
})
|
|
112
|
-
this.ws.market.on_message((data
|
|
112
|
+
this.ws.market.on_message((data) => {
|
|
113
113
|
data = JSON.parse(data)
|
|
114
|
-
const t_parsed = process.hrtime()
|
|
115
114
|
if (data && data.method === 'depth.update') {
|
|
116
115
|
let pair = post_process_pair(data.params[2])
|
|
117
116
|
this.ws.market.pair_status[pair] = 'opened'
|
|
@@ -148,7 +147,7 @@ module.exports = class Biconomy extends ExchangeBase {
|
|
|
148
147
|
}
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
150
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
152
151
|
const asks_e = this.ws.market.asks_dict[pair].entries()
|
|
153
152
|
const bids_e = this.ws.market.bids_dict[pair].entries()
|
|
154
153
|
if (asks_e.length > 0 && bids_e.length > 0) {
|
package/lib/exchanges/binance.js
CHANGED
|
@@ -73,9 +73,8 @@ module.exports = class Binance extends ExchangeBase {
|
|
|
73
73
|
;((this.rate_last_id = {}), (this.first_rate = {}))
|
|
74
74
|
this.ws.market_socket = new websocket('wss://stream.binance.com:9443/stream?streams=' + streams.slice(0, -1))
|
|
75
75
|
this.ws.market.on_open(() => {})
|
|
76
|
-
this.ws.market.on_message((data
|
|
76
|
+
this.ws.market.on_message((data) => {
|
|
77
77
|
data = JSON.parse(data).data
|
|
78
|
-
const t_parsed = process.hrtime()
|
|
79
78
|
if (data.e === 'depthUpdate') {
|
|
80
79
|
let pair = post_process_pair(data.s, true)
|
|
81
80
|
this.ws.market.pair_status[pair] = 'opened'
|
|
@@ -104,7 +103,7 @@ module.exports = class Binance extends ExchangeBase {
|
|
|
104
103
|
this.ws.market.bids_dict[pair].insert(parseFloat(bid[0]), parseFloat(bid[1]))
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.E
|
|
106
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.E }
|
|
108
107
|
} else if (this.first_rate[pair] && data.U > lastu[pair] + 1) {
|
|
109
108
|
this.first_rate[pair] = false
|
|
110
109
|
}
|
|
@@ -135,7 +134,7 @@ module.exports = class Binance extends ExchangeBase {
|
|
|
135
134
|
if (options.depth === false) {
|
|
136
135
|
this.ws.market.asks_dict[pair] = [[parseFloat(data.a), parseFloat(data.A)]]
|
|
137
136
|
this.ws.market.bids_dict[pair] = [[parseFloat(data.b), parseFloat(data.B)]]
|
|
138
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.E || Date.now()
|
|
137
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.E || Date.now() }
|
|
139
138
|
this.ws.market.pair_status[pair] = 'opened'
|
|
140
139
|
}
|
|
141
140
|
this.ws.bbo_observable.notify()
|
package/lib/exchanges/bingx.js
CHANGED
|
@@ -136,21 +136,20 @@ module.exports = class Bingx extends ExchangeBase {
|
|
|
136
136
|
this.ws.market.bids_dict[pair] = utils.ordered_dict(false)
|
|
137
137
|
})
|
|
138
138
|
})
|
|
139
|
-
this.ws.market.on_message((data
|
|
139
|
+
this.ws.market.on_message((data) => {
|
|
140
140
|
zlib.gunzip(data, (err, decompressedData) => {
|
|
141
141
|
if (err) {
|
|
142
142
|
console.error('Error decompressing data:', err)
|
|
143
143
|
} else {
|
|
144
144
|
let data = decompressedData.toString('utf8')
|
|
145
145
|
data = JSON.parse(data)
|
|
146
|
-
const t_parsed = process.hrtime()
|
|
147
146
|
if (data && _.includes(data.dataType, 'depth')) {
|
|
148
147
|
let parts = data.dataType.split('@')
|
|
149
148
|
let pair = post_process_pair(parts[0])
|
|
150
149
|
this.ws.market.pair_status[pair] = 'opened'
|
|
151
150
|
this.ws.market.asks_dict[pair] = data.data.asks.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])]).reverse()
|
|
152
151
|
this.ws.market.bids_dict[pair] = data.data.bids.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
153
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp
|
|
152
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp }
|
|
154
153
|
const asks = this.ws.market.asks_dict[pair]
|
|
155
154
|
const bids = this.ws.market.bids_dict[pair]
|
|
156
155
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/bitget.js
CHANGED
|
@@ -147,19 +147,18 @@ module.exports = class Bitget extends ExchangeBase {
|
|
|
147
147
|
})
|
|
148
148
|
this.ws.market.ping('ping')
|
|
149
149
|
})
|
|
150
|
-
this.ws.market.on_message((data
|
|
150
|
+
this.ws.market.on_message((data) => {
|
|
151
151
|
if (data.toString() === 'pong') {
|
|
152
152
|
this.ws.market.last_pong = new Date()
|
|
153
153
|
} else {
|
|
154
154
|
data = JSON.parse(data)
|
|
155
|
-
const t_parsed = process.hrtime()
|
|
156
155
|
let book = data.data
|
|
157
156
|
if (data && data.arg && data.arg.channel === depth_val && Array.isArray(book) && book) {
|
|
158
157
|
let pair = data.arg.instId
|
|
159
158
|
this.ws.market.pair_status[pair] = 'opened'
|
|
160
159
|
this.ws.market.asks_dict[pair] = book[0].asks.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
161
160
|
this.ws.market.bids_dict[pair] = book[0].bids.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
162
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(book[0].ts)
|
|
161
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(book[0].ts) }
|
|
163
162
|
} else if (data && data.arg && data.arg.channel === ticker_val && Array.isArray(book) && book) {
|
|
164
163
|
let pair = data.arg.instId
|
|
165
164
|
let t = book[0]
|
|
@@ -176,7 +175,7 @@ module.exports = class Bitget extends ExchangeBase {
|
|
|
176
175
|
if (options.depth === false) {
|
|
177
176
|
this.ws.market.asks_dict[pair] = [[ask_1_price, ask_1_amount]]
|
|
178
177
|
this.ws.market.bids_dict[pair] = [[bid_1_price, bid_1_amount]]
|
|
179
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(t.ts || data.ts) || Date.now()
|
|
178
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(t.ts || data.ts) || Date.now() }
|
|
180
179
|
this.ws.market.pair_status[pair] = 'opened'
|
|
181
180
|
}
|
|
182
181
|
this.ws.bbo_observable.notify()
|
package/lib/exchanges/bitmart.js
CHANGED
|
@@ -165,12 +165,11 @@ module.exports = class Bitmart extends ExchangeBase {
|
|
|
165
165
|
})
|
|
166
166
|
this.ws.market.ping('ping')
|
|
167
167
|
})
|
|
168
|
-
this.ws.market.on_message((data
|
|
168
|
+
this.ws.market.on_message((data) => {
|
|
169
169
|
if (data.toString() === 'pong') {
|
|
170
170
|
this.ws.market.last_pong = new Date()
|
|
171
171
|
} else {
|
|
172
172
|
data = JSON.parse(data)
|
|
173
|
-
const t_parsed = process.hrtime()
|
|
174
173
|
let book = data.data
|
|
175
174
|
// Get the pair from the message's symbol field
|
|
176
175
|
const msg_symbol = data.symbol
|
|
@@ -179,7 +178,7 @@ module.exports = class Bitmart extends ExchangeBase {
|
|
|
179
178
|
this.ws.market.pair_status[target_pair] = 'opened'
|
|
180
179
|
this.ws.market.asks_dict[target_pair] = book.sells.map((ask) => [parseFloat(ask.price), parseFloat(ask.amount)])
|
|
181
180
|
this.ws.market.bids_dict[target_pair] = book.buys.map((bid) => [parseFloat(bid.price), parseFloat(bid.amount)])
|
|
182
|
-
this.ws.market.ts_dict[target_pair] = { received_ts: Date.now(), event_ts: parseInt(data.timeStamp) || undefined
|
|
181
|
+
this.ws.market.ts_dict[target_pair] = { received_ts: Date.now(), event_ts: parseInt(data.timeStamp) || undefined }
|
|
183
182
|
const asks = this.ws.market.asks_dict[target_pair]
|
|
184
183
|
const bids = this.ws.market.bids_dict[target_pair]
|
|
185
184
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/bitmex.js
CHANGED
|
@@ -141,9 +141,8 @@ module.exports = class Bitmex extends ExchangeBase {
|
|
|
141
141
|
this.ws.market.bids_dict[pair] = utils.ordered_dict(false)
|
|
142
142
|
}
|
|
143
143
|
})
|
|
144
|
-
this.ws.market.on_message((data
|
|
144
|
+
this.ws.market.on_message((data) => {
|
|
145
145
|
data = JSON.parse(data)
|
|
146
|
-
const t_parsed = process.hrtime()
|
|
147
146
|
if (data.table === 'orderBookL2') {
|
|
148
147
|
if (data.action === 'partial') {
|
|
149
148
|
if (!data.data[0]) {
|
package/lib/exchanges/bitrue.js
CHANGED
|
@@ -122,21 +122,20 @@ module.exports = class Bitrue extends ExchangeBase {
|
|
|
122
122
|
}),
|
|
123
123
|
)
|
|
124
124
|
})
|
|
125
|
-
this.ws.market.on_message((data
|
|
125
|
+
this.ws.market.on_message((data) => {
|
|
126
126
|
zlib.gunzip(data, (err, decompressedData) => {
|
|
127
127
|
if (err) {
|
|
128
128
|
console.error('Error decompressing data:', err)
|
|
129
129
|
} else {
|
|
130
130
|
let data = decompressedData.toString('utf8')
|
|
131
131
|
data = JSON.parse(data)
|
|
132
|
-
const t_parsed = process.hrtime()
|
|
133
132
|
if (data && _.includes(data.channel, 'depth_step0') && data.tick) {
|
|
134
133
|
let parts = data.channel.split('_')
|
|
135
134
|
let pair = post_process_pair(parts[1])
|
|
136
135
|
this.ws.market.pair_status[pair] = 'opened'
|
|
137
136
|
this.ws.market.asks_dict[pair] = data.tick.asks.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
138
137
|
this.ws.market.bids_dict[pair] = data.tick.buys.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
139
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts
|
|
138
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts }
|
|
140
139
|
const asks = this.ws.market.asks_dict[pair]
|
|
141
140
|
const bids = this.ws.market.bids_dict[pair]
|
|
142
141
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/blofin.js
CHANGED
|
@@ -150,10 +150,9 @@ module.exports = class Blofin extends ExchangeBase {
|
|
|
150
150
|
}),
|
|
151
151
|
)
|
|
152
152
|
})
|
|
153
|
-
this.ws.market.on_message((data
|
|
153
|
+
this.ws.market.on_message((data) => {
|
|
154
154
|
try {
|
|
155
155
|
data = JSON.parse(data)
|
|
156
|
-
const t_parsed = process.hrtime()
|
|
157
156
|
if (data.channel === 'DEPTH') {
|
|
158
157
|
const action = data.data_type
|
|
159
158
|
const pair = post_process_pair(data.symbol)
|
|
@@ -169,7 +168,7 @@ module.exports = class Blofin extends ExchangeBase {
|
|
|
169
168
|
const [price, size] = bid
|
|
170
169
|
this.ws.market.bids_dict[pair].insert(parseFloat(price), parseFloat(size))
|
|
171
170
|
}
|
|
172
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
171
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
173
172
|
{
|
|
174
173
|
const _asks = this.ws.market.asks_dict[pair].entries()
|
|
175
174
|
const _bids = this.ws.market.bids_dict[pair].entries()
|
|
@@ -198,7 +197,7 @@ module.exports = class Blofin extends ExchangeBase {
|
|
|
198
197
|
this.ws.market.bids_dict[pair].insert(parseFloat(price), parseFloat(size))
|
|
199
198
|
}
|
|
200
199
|
}
|
|
201
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
200
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
202
201
|
{
|
|
203
202
|
const _asks = this.ws.market.asks_dict[pair].entries()
|
|
204
203
|
const _bids = this.ws.market.bids_dict[pair].entries()
|
package/lib/exchanges/btse.js
CHANGED
|
@@ -96,12 +96,11 @@ module.exports = class Btse extends ExchangeBase {
|
|
|
96
96
|
})
|
|
97
97
|
this.ws.market.ping('ping')
|
|
98
98
|
})
|
|
99
|
-
this.ws.market.on_message((data
|
|
99
|
+
this.ws.market.on_message((data) => {
|
|
100
100
|
if (data.toString() === 'pong') {
|
|
101
101
|
this.ws.market.last_pong = new Date()
|
|
102
102
|
} else {
|
|
103
103
|
data = JSON.parse(data)
|
|
104
|
-
const t_parsed = process.hrtime()
|
|
105
104
|
if (data && data.topic && data.topic.includes('snapshot:' || 'update:') && data.data) {
|
|
106
105
|
let pair = post_process_pair(data.data.symbol)
|
|
107
106
|
let current_timestamp = new Date().getTime()
|
|
@@ -133,7 +132,7 @@ module.exports = class Btse extends ExchangeBase {
|
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
134
|
}
|
|
136
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: book.timestamp
|
|
135
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: book.timestamp }
|
|
137
136
|
{
|
|
138
137
|
const _asks = this.ws.market.asks_dict[pair].entries()
|
|
139
138
|
const _bids = this.ws.market.bids_dict[pair].entries()
|
package/lib/exchanges/bybit.js
CHANGED
|
@@ -90,10 +90,9 @@ module.exports = class Bybit extends ExchangeBase {
|
|
|
90
90
|
})
|
|
91
91
|
this.ws.market.ping(JSON.stringify({ op: 'ping' }))
|
|
92
92
|
})
|
|
93
|
-
this.ws.market.on_message((data
|
|
93
|
+
this.ws.market.on_message((data) => {
|
|
94
94
|
try {
|
|
95
95
|
data = JSON.parse(data)
|
|
96
|
-
const t_parsed = process.hrtime()
|
|
97
96
|
if (data.success && data.ret_msg === 'pong') {
|
|
98
97
|
this.ws.market.last_pong = new Date()
|
|
99
98
|
} else {
|
|
@@ -132,7 +131,7 @@ module.exports = class Bybit extends ExchangeBase {
|
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts
|
|
134
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts }
|
|
136
135
|
// Populate BBO from orderbook data
|
|
137
136
|
if (options.bbo !== false && data.data.a && data.data.a.length > 0 && data.data.b && data.data.b.length > 0) {
|
|
138
137
|
const best_ask = data.data.a[0]
|
|
@@ -219,14 +219,13 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
219
219
|
}))
|
|
220
220
|
console.log('coinbase ws-direct: subscribed channels:', channels.join(', '))
|
|
221
221
|
})
|
|
222
|
-
this.ws.market.on_message((data
|
|
222
|
+
this.ws.market.on_message((data) => {
|
|
223
223
|
try {
|
|
224
224
|
data = JSON.parse(data)
|
|
225
225
|
} catch (err) {
|
|
226
226
|
console.error('coinbase', 'ws-direct', 'JSON parse error:', err.message)
|
|
227
227
|
return
|
|
228
228
|
}
|
|
229
|
-
const t_parsed = process.hrtime()
|
|
230
229
|
if (data.type === 'snapshot') {
|
|
231
230
|
const pair = post_process_pair(data.product_id)
|
|
232
231
|
if (!this.ws.market.asks_dict[pair]) return
|
|
@@ -253,7 +252,7 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
253
252
|
if (price >= lo && price <= hi) this.ws.market.asks_dict[pair].insert(price, qty)
|
|
254
253
|
}
|
|
255
254
|
this.ws.market.pair_status[pair] = 'opened'
|
|
256
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: Date.now()
|
|
255
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: Date.now() }
|
|
257
256
|
const top_bid = this.ws.market.bids_dict[pair].top()
|
|
258
257
|
const top_ask = this.ws.market.asks_dict[pair].top()
|
|
259
258
|
if (top_bid != null && top_ask != null) {
|
|
@@ -284,7 +283,7 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
284
283
|
}
|
|
285
284
|
}
|
|
286
285
|
}
|
|
287
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.time) || Date.now()
|
|
286
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.time) || Date.now() }
|
|
288
287
|
{
|
|
289
288
|
const top_bid = this.ws.market.bids_dict[pair].top()
|
|
290
289
|
const top_ask = this.ws.market.asks_dict[pair].top()
|
|
@@ -307,7 +306,7 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
307
306
|
if (options.depth === false) {
|
|
308
307
|
this.ws.market.asks_dict[pair] = [[best_ask, best_ask_qty]]
|
|
309
308
|
this.ws.market.bids_dict[pair] = [[best_bid, best_bid_qty]]
|
|
310
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.time) || Date.now()
|
|
309
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.time) || Date.now() }
|
|
311
310
|
this.ws.market.pair_status[pair] = 'opened'
|
|
312
311
|
} else {
|
|
313
312
|
const bids = this.ws.market.bids_dict[pair]
|
|
@@ -324,7 +323,7 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
324
323
|
for (const k of prune_bids) bids.del(k)
|
|
325
324
|
const prune_asks = asks.keys().filter((k) => k > hi)
|
|
326
325
|
for (const k of prune_asks) asks.del(k)
|
|
327
|
-
if (bbo_changed) this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.time) || Date.now()
|
|
326
|
+
if (bbo_changed) this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.time) || Date.now() }
|
|
328
327
|
}
|
|
329
328
|
if (bbo_changed) this.ws.bbo_observable.notify()
|
|
330
329
|
} else if (data.type === 'match' || data.type === 'last_match') {
|
|
@@ -407,14 +406,13 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
407
406
|
this.ws.market.send(JSON.stringify({ type: 'subscribe', product_ids, channel: 'market_trades' }))
|
|
408
407
|
}
|
|
409
408
|
})
|
|
410
|
-
this.ws.market.on_message((data
|
|
409
|
+
this.ws.market.on_message((data) => {
|
|
411
410
|
try {
|
|
412
411
|
data = JSON.parse(data)
|
|
413
412
|
} catch (err) {
|
|
414
413
|
console.error('coinbase', 'websocket', 'JSON parse error:', err.message)
|
|
415
414
|
return
|
|
416
415
|
}
|
|
417
|
-
const t_parsed = process.hrtime()
|
|
418
416
|
const seq = data.sequence_num
|
|
419
417
|
if (seq !== undefined) {
|
|
420
418
|
const gap = (this._ws_last_seq !== undefined && seq > this._ws_last_seq + 1) ? seq - this._ws_last_seq - 1 : 0
|
|
@@ -488,7 +486,6 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
488
486
|
this.ws.market.ts_dict[pair] = {
|
|
489
487
|
received_ts: Date.now(),
|
|
490
488
|
event_ts: parse_event_ts_ms(data.timestamp) || Date.now(),
|
|
491
|
-
t_recv, t_parsed,
|
|
492
489
|
}
|
|
493
490
|
{
|
|
494
491
|
const top_bid = this.ws.market.bids_dict[pair].top()
|
|
@@ -535,7 +532,7 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
535
532
|
if (options.depth === false) {
|
|
536
533
|
this.ws.market.asks_dict[pair] = [[best_ask, best_ask_qty]]
|
|
537
534
|
this.ws.market.bids_dict[pair] = [[best_bid, best_bid_qty]]
|
|
538
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.timestamp) || Date.now()
|
|
535
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.timestamp) || Date.now() }
|
|
539
536
|
this.ws.market.pair_status[pair] = 'opened'
|
|
540
537
|
} else {
|
|
541
538
|
const bids = this.ws.market.bids_dict[pair]
|
|
@@ -553,7 +550,7 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
553
550
|
for (const k of prune_bids) bids.del(k)
|
|
554
551
|
const prune_asks = asks.keys().filter((k) => k > hi)
|
|
555
552
|
for (const k of prune_asks) asks.del(k)
|
|
556
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.timestamp) || Date.now()
|
|
553
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parse_event_ts_ms(data.timestamp) || Date.now() }
|
|
557
554
|
}
|
|
558
555
|
this.ws.bbo_observable.notify()
|
|
559
556
|
}
|
|
@@ -1156,7 +1153,19 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
1156
1153
|
return
|
|
1157
1154
|
}
|
|
1158
1155
|
if (this.fix_ord && this.fix_ord.is_ready()) {
|
|
1159
|
-
this.
|
|
1156
|
+
const normalized = this.normalize_order_options(order_options)
|
|
1157
|
+
const t_order_sent = process.hrtime()
|
|
1158
|
+
if (normalized.on_sent) {
|
|
1159
|
+
normalized.on_sent({ t_order_sent })
|
|
1160
|
+
}
|
|
1161
|
+
this.fix_ord.send_new_order(pair, method, price, amount, normalized.order_options, (res = {}) => {
|
|
1162
|
+
res.meta = {
|
|
1163
|
+
...(res.meta || {}),
|
|
1164
|
+
t_order_sent,
|
|
1165
|
+
t_ack_recv: process.hrtime(),
|
|
1166
|
+
}
|
|
1167
|
+
cb(res)
|
|
1168
|
+
})
|
|
1160
1169
|
return
|
|
1161
1170
|
}
|
|
1162
1171
|
this.private_limiter.process(this.limit_trade_base.bind(this), pair, method, price, amount, order_options, cb)
|
|
@@ -1201,7 +1210,15 @@ module.exports = class Coinbase extends ExchangeBase {
|
|
|
1201
1210
|
}
|
|
1202
1211
|
cancel_order_by_order(order, cb) {
|
|
1203
1212
|
if (this.fix_ord && this.fix_ord.is_ready()) {
|
|
1204
|
-
|
|
1213
|
+
const t_cancel_sent = process.hrtime()
|
|
1214
|
+
this.fix_ord.send_cancel(order.pair, order.order_id, order.type, (res = {}) => {
|
|
1215
|
+
res.meta = {
|
|
1216
|
+
...(res.meta || {}),
|
|
1217
|
+
t_cancel_sent,
|
|
1218
|
+
t_cancel_ack: process.hrtime(),
|
|
1219
|
+
}
|
|
1220
|
+
cb(res)
|
|
1221
|
+
})
|
|
1205
1222
|
return
|
|
1206
1223
|
}
|
|
1207
1224
|
this.cancel_order(order.pair, order.order_id, cb)
|
|
@@ -135,15 +135,14 @@ module.exports = class Coinstore extends ExchangeBase {
|
|
|
135
135
|
false,
|
|
136
136
|
)
|
|
137
137
|
})
|
|
138
|
-
this.ws.market.on_message((data
|
|
138
|
+
this.ws.market.on_message((data) => {
|
|
139
139
|
data = JSON.parse(data)
|
|
140
|
-
const t_parsed = process.hrtime()
|
|
141
140
|
if (data && data.T === 'depth') {
|
|
142
141
|
let pair = post_process_pair(data.symbol)
|
|
143
142
|
this.ws.market.pair_status[pair] = 'opened'
|
|
144
143
|
this.ws.market.asks_dict[pair] = data.a.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
145
144
|
this.ws.market.bids_dict[pair] = data.b.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
146
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
145
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
147
146
|
const asks = this.ws.market.asks_dict[pair]
|
|
148
147
|
const bids = this.ws.market.bids_dict[pair]
|
|
149
148
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
|
@@ -109,7 +109,7 @@ module.exports = class Cryptocom extends ExchangeBase {
|
|
|
109
109
|
)
|
|
110
110
|
}
|
|
111
111
|
})
|
|
112
|
-
this.ws.market.on_message((data
|
|
112
|
+
this.ws.market.on_message((data) => {
|
|
113
113
|
let parsed
|
|
114
114
|
try {
|
|
115
115
|
parsed = JSON.parse(data)
|
|
@@ -125,13 +125,12 @@ module.exports = class Cryptocom extends ExchangeBase {
|
|
|
125
125
|
)
|
|
126
126
|
return
|
|
127
127
|
}
|
|
128
|
-
const t_parsed = process.hrtime()
|
|
129
128
|
let result = parsed.result
|
|
130
129
|
if (result) {
|
|
131
130
|
let pair = post_process_pair(result.instrument_name, true)
|
|
132
131
|
if (result.channel === 'book') {
|
|
133
132
|
this.ws.market.pair_status[pair] = 'opened'
|
|
134
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
133
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
135
134
|
let { asks, bids } = result.data[0]
|
|
136
135
|
this.ws.market.asks_dict[pair] = asks.map((e) => [parseFloat(e[0]), parseFloat(e[1])])
|
|
137
136
|
this.ws.market.bids_dict[pair] = bids.map((e) => [parseFloat(e[0]), parseFloat(e[1])])
|
|
@@ -154,6 +154,59 @@ class ExchangeBase {
|
|
|
154
154
|
}
|
|
155
155
|
/** @type {boolean} Whether deposits/withdrawals go directly to the spot account */
|
|
156
156
|
this.deposits_to_spot = true
|
|
157
|
+
this._wrap_transport_methods()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_wrap_transport_methods() {
|
|
161
|
+
if (typeof this.limit_trade_base === 'function') {
|
|
162
|
+
const original_limit_trade_base = this.limit_trade_base.bind(this)
|
|
163
|
+
this.limit_trade_base = (pair, method, price, amount, order_options, cb) => {
|
|
164
|
+
if (typeof order_options === 'function') {
|
|
165
|
+
cb = order_options
|
|
166
|
+
order_options = {}
|
|
167
|
+
}
|
|
168
|
+
const normalized = this.normalize_order_options(order_options)
|
|
169
|
+
if (parseFloat(amount) === 0) {
|
|
170
|
+
return original_limit_trade_base(pair, method, price, amount, normalized.order_options, cb)
|
|
171
|
+
}
|
|
172
|
+
const t_order_sent = process.hrtime()
|
|
173
|
+
if (normalized.on_sent) {
|
|
174
|
+
normalized.on_sent({ t_order_sent })
|
|
175
|
+
}
|
|
176
|
+
return original_limit_trade_base(pair, method, price, amount, normalized.order_options, (res = {}) => {
|
|
177
|
+
res.meta = {
|
|
178
|
+
...(res.meta || {}),
|
|
179
|
+
t_order_sent,
|
|
180
|
+
t_ack_recv: process.hrtime(),
|
|
181
|
+
}
|
|
182
|
+
cb(res)
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (typeof this.cancel_order === 'function' && this.cancel_order !== ExchangeBase.prototype.cancel_order) {
|
|
188
|
+
const original_cancel_order = this.cancel_order.bind(this)
|
|
189
|
+
this.cancel_order = (pair, order_id, cb) => {
|
|
190
|
+
const t_cancel_sent = process.hrtime()
|
|
191
|
+
return original_cancel_order(pair, order_id, (res = {}) => {
|
|
192
|
+
res.meta = {
|
|
193
|
+
...(res.meta || {}),
|
|
194
|
+
t_cancel_sent,
|
|
195
|
+
t_cancel_ack: process.hrtime(),
|
|
196
|
+
}
|
|
197
|
+
cb(res)
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (typeof this.rate_ws === 'function' && this.rate_ws !== ExchangeBase.prototype.rate_ws) {
|
|
203
|
+
const original_rate_ws = this.rate_ws.bind(this)
|
|
204
|
+
this.rate_ws = (pair, cb) => {
|
|
205
|
+
original_rate_ws(pair, (res) => {
|
|
206
|
+
cb(this.attach_market_ts(pair, res))
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
}
|
|
157
210
|
}
|
|
158
211
|
|
|
159
212
|
get api_secret_key() {
|
|
@@ -165,6 +218,45 @@ class ExchangeBase {
|
|
|
165
218
|
return key
|
|
166
219
|
}
|
|
167
220
|
|
|
221
|
+
normalize_order_options(order_options) {
|
|
222
|
+
if (!order_options || typeof order_options !== 'object') {
|
|
223
|
+
return { order_options: {}, on_sent: null }
|
|
224
|
+
}
|
|
225
|
+
const normalized = { ...order_options }
|
|
226
|
+
const on_sent = typeof normalized.on_sent === 'function' ? normalized.on_sent : null
|
|
227
|
+
delete normalized.on_sent
|
|
228
|
+
return { order_options: normalized, on_sent }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
snapshot_market_ts(pair) {
|
|
232
|
+
const ticker_ts = _.get(this, ['ws', 'market', 'tickers', pair, '_ts'])
|
|
233
|
+
if (ticker_ts && typeof ticker_ts === 'object') {
|
|
234
|
+
return { ...ticker_ts }
|
|
235
|
+
}
|
|
236
|
+
const ts = _.get(this, ['ws', 'market', 'ts_dict', pair])
|
|
237
|
+
if (ts && typeof ts === 'object') {
|
|
238
|
+
return { ...ts }
|
|
239
|
+
}
|
|
240
|
+
return undefined
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
attach_market_ts(pair, res) {
|
|
244
|
+
if (!res || !res.success || !res.body || typeof res.body !== 'object') {
|
|
245
|
+
return res
|
|
246
|
+
}
|
|
247
|
+
const market_ts = this.snapshot_market_ts(pair)
|
|
248
|
+
if (!market_ts) {
|
|
249
|
+
return res
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
...res,
|
|
253
|
+
body: {
|
|
254
|
+
...res.body,
|
|
255
|
+
_ts: res.body._ts && typeof res.body._ts === 'object' ? { ...res.body._ts } : market_ts,
|
|
256
|
+
},
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
168
260
|
/**
|
|
169
261
|
* Normalize a timestamp-like exchange value into a valid Date instance.
|
|
170
262
|
* @param {Date|string|number|null|undefined} value
|
|
@@ -520,12 +612,12 @@ class ExchangeBase {
|
|
|
520
612
|
bbo_ws(pair, cb) {
|
|
521
613
|
const t = this.ws.market.tickers[pair]
|
|
522
614
|
if (t && t.bid > 0 && t.ask > 0) {
|
|
523
|
-
cb({ success: true, body: { asks: [[t.ask, t.ask_size]], bids: [[t.bid, t.bid_size]] } })
|
|
615
|
+
cb({ success: true, body: { asks: [[t.ask, t.ask_size]], bids: [[t.bid, t.bid_size]], _ts: t._ts || this.snapshot_market_ts(pair) } })
|
|
524
616
|
} else {
|
|
525
617
|
// Fallback: derive from full orderbook
|
|
526
618
|
this.rate_ws(pair, (res) => {
|
|
527
619
|
if (res.success && res.body.bids.length > 0 && res.body.asks.length > 0) {
|
|
528
|
-
cb({ success: true, body: { asks: [res.body.asks[0]], bids: [res.body.bids[0]] } })
|
|
620
|
+
cb({ success: true, body: { asks: [res.body.asks[0]], bids: [res.body.bids[0]], _ts: res.body._ts || this.snapshot_market_ts(pair) } })
|
|
529
621
|
} else {
|
|
530
622
|
cb(res)
|
|
531
623
|
}
|
|
@@ -218,9 +218,8 @@ module.exports = class ExchangeWs {
|
|
|
218
218
|
const boundSocket = this.market_socket
|
|
219
219
|
let message_handler = (...args) => {
|
|
220
220
|
if (boundSocket !== this.market_socket) return
|
|
221
|
-
const t_recv = process.hrtime()
|
|
222
221
|
this.market.last_message_time = Date.now()
|
|
223
|
-
listener(...args
|
|
222
|
+
listener(...args)
|
|
224
223
|
this.market_observable.notify()
|
|
225
224
|
}
|
|
226
225
|
if (this.market_socket.serviceHandlers) {
|
package/lib/exchanges/gate.js
CHANGED
|
@@ -159,9 +159,8 @@ module.exports = class Gate extends ExchangeBase {
|
|
|
159
159
|
}),
|
|
160
160
|
)
|
|
161
161
|
const last_update_dict = {}
|
|
162
|
-
this.ws.market.on_message((data
|
|
162
|
+
this.ws.market.on_message((data) => {
|
|
163
163
|
data = JSON.parse(data)
|
|
164
|
-
const t_parsed = process.hrtime()
|
|
165
164
|
if (data && data.channel === 'spot.pong') {
|
|
166
165
|
this.ws.market.last_pong = new Date()
|
|
167
166
|
} else if (data && data.channel === 'spot.order_book' && data.result && data.result.s && data.result.bids && data.result.asks) {
|
|
@@ -175,7 +174,6 @@ module.exports = class Gate extends ExchangeBase {
|
|
|
175
174
|
this.ws.market.ts_dict[pair] = {
|
|
176
175
|
received_ts: Date.now(),
|
|
177
176
|
event_ts: parseInt(t),
|
|
178
|
-
t_recv, t_parsed,
|
|
179
177
|
}
|
|
180
178
|
last_update_dict[pair] = lastUpdateId
|
|
181
179
|
}
|
|
@@ -191,7 +189,7 @@ module.exports = class Gate extends ExchangeBase {
|
|
|
191
189
|
if (options.depth === false) {
|
|
192
190
|
this.ws.market.asks_dict[pair] = [[parseFloat(ask_1_price), parseFloat(ask_1_amount)]]
|
|
193
191
|
this.ws.market.bids_dict[pair] = [[parseFloat(bid_1_price), parseFloat(bid_1_amount)]]
|
|
194
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(data.result.t) || Date.now()
|
|
192
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(data.result.t) || Date.now() }
|
|
195
193
|
this.ws.market.pair_status[pair] = 'opened'
|
|
196
194
|
} else {
|
|
197
195
|
if (!this.ws.market.asks_dict[pair] || !this.ws.market.bids_dict[pair]) {
|
package/lib/exchanges/hashkey.js
CHANGED
|
@@ -108,10 +108,9 @@ module.exports = class Hashkey extends ExchangeBase {
|
|
|
108
108
|
}),
|
|
109
109
|
)
|
|
110
110
|
})
|
|
111
|
-
this.ws.market.on_message((data
|
|
111
|
+
this.ws.market.on_message((data) => {
|
|
112
112
|
try {
|
|
113
113
|
data = JSON.parse(data)
|
|
114
|
-
const t_parsed = process.hrtime()
|
|
115
114
|
if (data.pong) {
|
|
116
115
|
this.ws.market.last_pong = new Date()
|
|
117
116
|
} else {
|
|
@@ -121,7 +120,7 @@ module.exports = class Hashkey extends ExchangeBase {
|
|
|
121
120
|
const { a, b } = data.data
|
|
122
121
|
this.ws.market.asks_dict[pair] = a.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
123
122
|
this.ws.market.bids_dict[pair] = b.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
124
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseFloat(data.data.t) || undefined, send_ts: parseFloat(data.sendTime) || undefined
|
|
123
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseFloat(data.data.t) || undefined, send_ts: parseFloat(data.sendTime) || undefined }
|
|
125
124
|
const asks = this.ws.market.asks_dict[pair]
|
|
126
125
|
const bids = this.ws.market.bids_dict[pair]
|
|
127
126
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
|
@@ -110,9 +110,8 @@ module.exports = class Hashkeyglobal extends ExchangeBase {
|
|
|
110
110
|
})
|
|
111
111
|
this.ws.market.ping('ping')
|
|
112
112
|
})
|
|
113
|
-
this.ws.market.on_message((data
|
|
113
|
+
this.ws.market.on_message((data) => {
|
|
114
114
|
data = JSON.parse(data)
|
|
115
|
-
const t_parsed = process.hrtime()
|
|
116
115
|
if (data.pong) {
|
|
117
116
|
this.ws.market.last_pong = new Date()
|
|
118
117
|
} else {
|
|
@@ -122,7 +121,7 @@ module.exports = class Hashkeyglobal extends ExchangeBase {
|
|
|
122
121
|
this.ws.market.pair_status[pair] = 'opened'
|
|
123
122
|
this.ws.market.asks_dict[pair] = book[0].a.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
124
123
|
this.ws.market.bids_dict[pair] = book[0].b.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
125
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
124
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
126
125
|
const asks = this.ws.market.asks_dict[pair]
|
|
127
126
|
const bids = this.ws.market.bids_dict[pair]
|
|
128
127
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/hitbtc.js
CHANGED
|
@@ -80,9 +80,8 @@ module.exports = class Hitbtc extends ExchangeBase {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
})
|
|
83
|
-
this.ws.market.on_message((data
|
|
83
|
+
this.ws.market.on_message((data) => {
|
|
84
84
|
data = JSON.parse(data)
|
|
85
|
-
const t_parsed = process.hrtime()
|
|
86
85
|
if (data.method === 'snapshotOrderbook') {
|
|
87
86
|
let pair = post_process_pair(data.params.symbol)
|
|
88
87
|
this.ws.market.pair_status[pair] = 'opened'
|
package/lib/exchanges/hkbitex.js
CHANGED
|
@@ -142,12 +142,11 @@ module.exports = class Hkbitex extends ExchangeBase {
|
|
|
142
142
|
}, 60 * 1000)
|
|
143
143
|
this.ws.market.ping('ping')
|
|
144
144
|
})
|
|
145
|
-
this.ws.market.on_message((data
|
|
145
|
+
this.ws.market.on_message((data) => {
|
|
146
146
|
if (data.toString() === 'pong') {
|
|
147
147
|
this.ws.market.last_pong = new Date()
|
|
148
148
|
} else {
|
|
149
149
|
data = JSON.parse(data)
|
|
150
|
-
const t_parsed = process.hrtime()
|
|
151
150
|
if (data && data.data && data.data.e === 8) {
|
|
152
151
|
let book = data.data
|
|
153
152
|
let pair = post_process_pair(book.s)
|
|
@@ -158,7 +157,7 @@ module.exports = class Hkbitex extends ExchangeBase {
|
|
|
158
157
|
if (book.d && book.d.b) {
|
|
159
158
|
this.ws.market.bids_dict[pair] = book.d.b.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
160
159
|
}
|
|
161
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
160
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
162
161
|
const asks = this.ws.market.asks_dict[pair]
|
|
163
162
|
const bids = this.ws.market.bids_dict[pair]
|
|
164
163
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/htx.js
CHANGED
|
@@ -120,13 +120,12 @@ module.exports = class Htx extends ExchangeBase {
|
|
|
120
120
|
let depth_re = new RegExp('market.(.+).depth.step0'),
|
|
121
121
|
bbo_re = new RegExp('market.(.+).bbo'),
|
|
122
122
|
trade_re = new RegExp('market.(.+).trade.detail')
|
|
123
|
-
this.ws.market.on_message((data
|
|
123
|
+
this.ws.market.on_message((data) => {
|
|
124
124
|
data = parse_body(pako.inflate(new Uint8Array(data), { to: 'string' }))
|
|
125
|
-
const t_parsed = process.hrtime()
|
|
126
125
|
if (data.ch && depth_re.exec(data.ch)) {
|
|
127
126
|
let pair = post_process_pair(depth_re.exec(data.ch)[1])
|
|
128
127
|
this.ws.market.pair_status[pair] = 'opened'
|
|
129
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts
|
|
128
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts }
|
|
130
129
|
this.ws.market.asks_dict[pair] = data.tick.asks
|
|
131
130
|
this.ws.market.bids_dict[pair] = data.tick.bids
|
|
132
131
|
} else if (data.ch && bbo_re.exec(data.ch)) {
|
|
@@ -141,7 +140,7 @@ module.exports = class Htx extends ExchangeBase {
|
|
|
141
140
|
if (options.depth === false) {
|
|
142
141
|
this.ws.market.asks_dict[pair] = [[parseFloat(ask_1_price), parseFloat(ask_1_amount)]]
|
|
143
142
|
this.ws.market.bids_dict[pair] = [[parseFloat(bid_1_price), parseFloat(bid_1_amount)]]
|
|
144
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts
|
|
143
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.ts }
|
|
145
144
|
this.ws.market.pair_status[pair] = 'opened'
|
|
146
145
|
} else {
|
|
147
146
|
if (!Array.isArray(this.ws.market.asks_dict[pair]) || !Array.isArray(this.ws.market.bids_dict[pair])) {
|
package/lib/exchanges/kucoin.js
CHANGED
|
@@ -121,9 +121,8 @@ module.exports = class Kucoin extends ExchangeBase {
|
|
|
121
121
|
type: 'ping',
|
|
122
122
|
}),
|
|
123
123
|
)
|
|
124
|
-
this.ws.market.on_message((data
|
|
124
|
+
this.ws.market.on_message((data) => {
|
|
125
125
|
data = JSON.parse(data)
|
|
126
|
-
const t_parsed = process.hrtime()
|
|
127
126
|
let book = data.data
|
|
128
127
|
if (data.type === 'pong') {
|
|
129
128
|
this.ws.market.last_pong = new Date()
|
|
@@ -133,7 +132,7 @@ module.exports = class Kucoin extends ExchangeBase {
|
|
|
133
132
|
this.ws.market.pair_status[pair] = 'opened'
|
|
134
133
|
this.ws.market.asks_dict[pair] = book.asks.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
135
134
|
this.ws.market.bids_dict[pair] = book.bids.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
136
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: book.timestamp
|
|
135
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: book.timestamp }
|
|
137
136
|
} else if (data && data.type === 'message' && data.topic && data.subject === 'level1' && book && book.timestamp && book.bids && book.asks) {
|
|
138
137
|
let val = data.topic.split(':')
|
|
139
138
|
let pair = post_process_pair(val[1])
|
|
@@ -149,7 +148,7 @@ module.exports = class Kucoin extends ExchangeBase {
|
|
|
149
148
|
if (options.depth === false) {
|
|
150
149
|
this.ws.market.asks_dict[pair] = [[parseFloat(ask_1_price), parseFloat(ask_1_amount)]]
|
|
151
150
|
this.ws.market.bids_dict[pair] = [[parseFloat(bid_1_price), parseFloat(bid_1_amount)]]
|
|
152
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: book.timestamp
|
|
151
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: book.timestamp }
|
|
153
152
|
this.ws.market.pair_status[pair] = 'opened'
|
|
154
153
|
} else {
|
|
155
154
|
if (!Array.isArray(this.ws.market.asks_dict[pair]) || !Array.isArray(this.ws.market.bids_dict[pair])) {
|
package/lib/exchanges/lbank.js
CHANGED
|
@@ -157,9 +157,8 @@ module.exports = class Lbank extends ExchangeBase {
|
|
|
157
157
|
})
|
|
158
158
|
this.ws.market.ping(JSON.stringify({ action: 'ping', ping: 'keepalive' }))
|
|
159
159
|
})
|
|
160
|
-
this.ws.market.on_message((data
|
|
160
|
+
this.ws.market.on_message((data) => {
|
|
161
161
|
data = JSON.parse(data)
|
|
162
|
-
const t_parsed = process.hrtime()
|
|
163
162
|
if (data.action === 'ping') {
|
|
164
163
|
this.ws.market.send(
|
|
165
164
|
JSON.stringify({
|
|
@@ -182,7 +181,7 @@ module.exports = class Lbank extends ExchangeBase {
|
|
|
182
181
|
this.ws.market.pair_status[pair] = 'opened'
|
|
183
182
|
this.ws.market.asks_dict[pair] = data.depth.asks.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
184
183
|
this.ws.market.bids_dict[pair] = data.depth.bids.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
185
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
184
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
186
185
|
const asks = this.ws.market.asks_dict[pair]
|
|
187
186
|
const bids = this.ws.market.bids_dict[pair]
|
|
188
187
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/mexc.js
CHANGED
|
@@ -131,7 +131,7 @@ module.exports = class Mexc extends ExchangeBase {
|
|
|
131
131
|
return false
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
this.ws.market.on_message((data
|
|
134
|
+
this.ws.market.on_message((data) => {
|
|
135
135
|
if (is_json(data)) {
|
|
136
136
|
try {
|
|
137
137
|
const json = JSON.parse(data.toString())
|
|
@@ -152,7 +152,6 @@ module.exports = class Mexc extends ExchangeBase {
|
|
|
152
152
|
try {
|
|
153
153
|
const message = PushDataV3ApiWrapper.decode(data)
|
|
154
154
|
const obj = PushDataV3ApiWrapper.toObject(message, { enums: String, longs: String })
|
|
155
|
-
const t_parsed = process.hrtime()
|
|
156
155
|
const pair = post_process_pair(obj.symbol)
|
|
157
156
|
const channel = obj.channel
|
|
158
157
|
if (channel.startsWith('spot@public.limit.depth.v3.api.pb@')) {
|
|
@@ -160,7 +159,7 @@ module.exports = class Mexc extends ExchangeBase {
|
|
|
160
159
|
this.ws.market.pair_status[pair] = 'opened'
|
|
161
160
|
this.ws.market.asks_dict[pair] = asks.map((ask) => [parseFloat(ask.price), parseFloat(ask.quantity)])
|
|
162
161
|
this.ws.market.bids_dict[pair] = bids.map((bid) => [parseFloat(bid.price), parseFloat(bid.quantity)])
|
|
163
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(obj.sendTime) || undefined
|
|
162
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(obj.sendTime) || undefined }
|
|
164
163
|
// Derive BBO from depth data
|
|
165
164
|
if (options.bbo !== false && this.ws.market.asks_dict[pair].length > 0 && this.ws.market.bids_dict[pair].length > 0) {
|
|
166
165
|
this.ws.market.tickers[pair] = {
|
package/lib/exchanges/okx.js
CHANGED
|
@@ -217,14 +217,13 @@ module.exports = class Okx extends ExchangeBase {
|
|
|
217
217
|
this.ws.market.ping('ping')
|
|
218
218
|
start_market_history_socket()
|
|
219
219
|
})
|
|
220
|
-
this.ws.market.on_message((data
|
|
220
|
+
this.ws.market.on_message((data) => {
|
|
221
221
|
if (data.toString() === 'pong') {
|
|
222
222
|
this.ws.market.last_pong = new Date()
|
|
223
223
|
}
|
|
224
224
|
if (data.toString() !== 'pong') {
|
|
225
225
|
try {
|
|
226
226
|
data = JSON.parse(data)
|
|
227
|
-
const t_parsed = process.hrtime()
|
|
228
227
|
if (data && data.arg && data.arg.channel === 'books' && data.data && data.data[0]) {
|
|
229
228
|
const action = data.action
|
|
230
229
|
const pair = post_process_pair(data.arg.instId, true)
|
|
@@ -263,7 +262,7 @@ module.exports = class Okx extends ExchangeBase {
|
|
|
263
262
|
} else {
|
|
264
263
|
}
|
|
265
264
|
}
|
|
266
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(data.data[0].ts)
|
|
265
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(data.data[0].ts) }
|
|
267
266
|
} else if (data && data.data && data.arg && (data.arg.channel === 'trades' || data.arg.channel === 'trades-all')) {
|
|
268
267
|
for (let datum of data.data) {
|
|
269
268
|
let pair = post_process_pair(datum.instId)
|
|
@@ -300,7 +299,7 @@ module.exports = class Okx extends ExchangeBase {
|
|
|
300
299
|
if (options.depth === false) {
|
|
301
300
|
this.ws.market.asks_dict[pair] = [[askPrice, askSize]]
|
|
302
301
|
this.ws.market.bids_dict[pair] = [[bidPrice, bidSize]]
|
|
303
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(bbo.ts)
|
|
302
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: parseInt(bbo.ts) }
|
|
304
303
|
this.ws.market.pair_status[pair] = 'opened'
|
|
305
304
|
}
|
|
306
305
|
this.ws.bbo_observable.notify()
|
package/lib/exchanges/phemex.js
CHANGED
|
@@ -773,9 +773,8 @@ module.exports = class Phemex extends ExchangeBase {
|
|
|
773
773
|
}),
|
|
774
774
|
)
|
|
775
775
|
})
|
|
776
|
-
this.ws.market.on_message((data
|
|
776
|
+
this.ws.market.on_message((data) => {
|
|
777
777
|
data = JSON.parse(data)
|
|
778
|
-
const t_parsed = process.hrtime()
|
|
779
778
|
if (data && data.book && data.type === 'snapshot') {
|
|
780
779
|
let pair = post_process_pair(data.symbol)
|
|
781
780
|
this.ws.market.pair_status[pair] = 'opened'
|
|
@@ -785,7 +784,7 @@ module.exports = class Phemex extends ExchangeBase {
|
|
|
785
784
|
for (let bid of data.book.bids) {
|
|
786
785
|
this.ws.market.bids_dict[pair].insert(bid[0], bid[1])
|
|
787
786
|
}
|
|
788
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp ? Math.floor(data.timestamp / 1e6) : undefined
|
|
787
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp ? Math.floor(data.timestamp / 1e6) : undefined }
|
|
789
788
|
{
|
|
790
789
|
const _asks = this.ws.market.asks_dict[pair].entries()
|
|
791
790
|
const _bids = this.ws.market.bids_dict[pair].entries()
|
|
@@ -813,7 +812,7 @@ module.exports = class Phemex extends ExchangeBase {
|
|
|
813
812
|
this.ws.market.bids_dict[pair].insert(parseFloat(bid[0]), parseFloat(bid[1]))
|
|
814
813
|
}
|
|
815
814
|
}
|
|
816
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp ? Math.floor(data.timestamp / 1e6) : undefined
|
|
815
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp ? Math.floor(data.timestamp / 1e6) : undefined }
|
|
817
816
|
{
|
|
818
817
|
const _asks = this.ws.market.asks_dict[pair].entries()
|
|
819
818
|
const _bids = this.ws.market.bids_dict[pair].entries()
|
package/lib/exchanges/swft.js
CHANGED
|
@@ -81,7 +81,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
81
81
|
// }
|
|
82
82
|
rate(pair, orderbook_depth, cb) {
|
|
83
83
|
let [api_key, secret_key] = this.public_api_secret_key
|
|
84
|
-
let timestamp = (
|
|
84
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
85
85
|
let params = {
|
|
86
86
|
channelId: api_key,
|
|
87
87
|
depth: '1',
|
|
@@ -110,7 +110,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
110
110
|
}
|
|
111
111
|
market_history(pair, timeframe_in_ms, cb) {
|
|
112
112
|
let [api_key, secret_key] = this.public_api_secret_key
|
|
113
|
-
let timestamp = (
|
|
113
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
114
114
|
let params = {
|
|
115
115
|
channelId: api_key,
|
|
116
116
|
symbol: pre_process_pair(pair),
|
|
@@ -166,7 +166,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
166
166
|
return filled_data
|
|
167
167
|
}
|
|
168
168
|
let [api_key, secret_key] = this.public_api_secret_key
|
|
169
|
-
let timestamp = (
|
|
169
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
170
170
|
let params = {
|
|
171
171
|
channelId: api_key,
|
|
172
172
|
period: '60min',
|
|
@@ -206,7 +206,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
206
206
|
return
|
|
207
207
|
}
|
|
208
208
|
let [api_key, secret_key] = this.api_secret_key
|
|
209
|
-
let timestamp = (
|
|
209
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
210
210
|
let params = {
|
|
211
211
|
amount,
|
|
212
212
|
channelId: api_key,
|
|
@@ -241,7 +241,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
241
241
|
}
|
|
242
242
|
balance(cb) {
|
|
243
243
|
let [api_key, secret_key] = this.api_secret_key
|
|
244
|
-
let timestamp = (
|
|
244
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
245
245
|
let params = {
|
|
246
246
|
channelId: api_key,
|
|
247
247
|
timestamp,
|
|
@@ -272,7 +272,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
272
272
|
get_open_orders(pair, cb) {
|
|
273
273
|
let get_open_orders_base = (pair, cb) => {
|
|
274
274
|
let [api_key, secret_key] = this.api_secret_key
|
|
275
|
-
let timestamp = (
|
|
275
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
276
276
|
let params = {
|
|
277
277
|
channelId: api_key,
|
|
278
278
|
timestamp,
|
|
@@ -304,7 +304,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
304
304
|
}
|
|
305
305
|
cancel_order(pair, id, cb) {
|
|
306
306
|
let [api_key, secret_key] = this.api_secret_key
|
|
307
|
-
let timestamp = (
|
|
307
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
308
308
|
let params = {
|
|
309
309
|
channelId: api_key,
|
|
310
310
|
orderId: id,
|
|
@@ -329,7 +329,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
329
329
|
}
|
|
330
330
|
query_order_base(pair, order_id, cb) {
|
|
331
331
|
let [api_key, secret_key] = this.api_secret_key
|
|
332
|
-
let timestamp = (
|
|
332
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
333
333
|
let params = {
|
|
334
334
|
channelId: api_key,
|
|
335
335
|
orderId: order_id,
|
|
@@ -376,7 +376,7 @@ module.exports = class Swft extends ExchangeBase {
|
|
|
376
376
|
get_trades(pair, timeframe_in_ms, cb) {
|
|
377
377
|
let get_trades_base = (pair, timeframe_in_ms, cb) => {
|
|
378
378
|
let [api_key, secret_key] = this.api_secret_key
|
|
379
|
-
let timestamp = (
|
|
379
|
+
let timestamp = new Date().addHours(8).getTime().toString()
|
|
380
380
|
let params = {
|
|
381
381
|
channelId: api_key,
|
|
382
382
|
timestamp,
|
package/lib/exchanges/upbit.js
CHANGED
|
@@ -97,7 +97,7 @@ module.exports = class Upbit extends ExchangeBase {
|
|
|
97
97
|
let message = JSON.stringify([JSON.stringify(sub_channels).toString()])
|
|
98
98
|
this.ws.market.send(message)
|
|
99
99
|
})
|
|
100
|
-
this.ws.market.on_message((data
|
|
100
|
+
this.ws.market.on_message((data) => {
|
|
101
101
|
if (data.startsWith('a')) {
|
|
102
102
|
data = _.trim(data, 'a')
|
|
103
103
|
data = JSON.parse(JSON.parse(data)[0])
|
|
@@ -107,8 +107,7 @@ module.exports = class Upbit extends ExchangeBase {
|
|
|
107
107
|
this.ws.market.pair_status[pair] = 'opened'
|
|
108
108
|
this.ws.market.asks_dict[pair] = data.orderbookUnits.map((o) => [parseFloat(o.askPrice), parseFloat(o.askSize)])
|
|
109
109
|
this.ws.market.bids_dict[pair] = data.orderbookUnits.map((o) => [parseFloat(o.bidPrice), parseFloat(o.bidSize)])
|
|
110
|
-
|
|
111
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp, t_recv, t_parsed }
|
|
110
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now(), event_ts: data.timestamp }
|
|
112
111
|
const asks = this.ws.market.asks_dict[pair]
|
|
113
112
|
const bids = this.ws.market.bids_dict[pair]
|
|
114
113
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/lib/exchanges/xt.js
CHANGED
|
@@ -122,7 +122,7 @@ module.exports = class Xt extends ExchangeBase {
|
|
|
122
122
|
})
|
|
123
123
|
this.ws.market.ping('ping')
|
|
124
124
|
})
|
|
125
|
-
this.ws.market.on_message((data
|
|
125
|
+
this.ws.market.on_message((data) => {
|
|
126
126
|
if (data.toString() === 'pong') {
|
|
127
127
|
this.ws.market.last_pong = new Date()
|
|
128
128
|
} else {
|
|
@@ -131,14 +131,13 @@ module.exports = class Xt extends ExchangeBase {
|
|
|
131
131
|
} catch (err) {
|
|
132
132
|
console.error('xt websocket', data.toString(), err)
|
|
133
133
|
}
|
|
134
|
-
const t_parsed = process.hrtime()
|
|
135
134
|
let book = data.data
|
|
136
135
|
if (data && data.topic === 'depth' && book) {
|
|
137
136
|
let pair = post_process_pair(data.data.s)
|
|
138
137
|
this.ws.market.pair_status[pair] = 'opened'
|
|
139
138
|
this.ws.market.asks_dict[pair] = data.data.a.map((ask) => [parseFloat(ask[0]), parseFloat(ask[1])])
|
|
140
139
|
this.ws.market.bids_dict[pair] = data.data.b.map((bid) => [parseFloat(bid[0]), parseFloat(bid[1])])
|
|
141
|
-
this.ws.market.ts_dict[pair] = { received_ts: Date.now()
|
|
140
|
+
this.ws.market.ts_dict[pair] = { received_ts: Date.now() }
|
|
142
141
|
const asks = this.ws.market.asks_dict[pair]
|
|
143
142
|
const bids = this.ws.market.bids_dict[pair]
|
|
144
143
|
if (asks && asks.length > 0 && bids && bids.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@icgio/icg-exchanges",
|
|
3
|
-
"version": "1.40.
|
|
3
|
+
"version": "1.40.45",
|
|
4
4
|
"description": "icgio exchanges package",
|
|
5
5
|
"main": "./exchanges.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://github.com/icgio/icg-exchanges#readme",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@icgio/icg-utils": "^1.9.
|
|
21
|
+
"@icgio/icg-utils": "^1.9.58",
|
|
22
22
|
"json-bigint": "^1.0.0",
|
|
23
23
|
"jsonwebtoken": "^9.0.3",
|
|
24
24
|
"lodash": "^4.17.20",
|