@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.
@@ -112,9 +112,8 @@ module.exports = class Ascendex extends ExchangeBase {
112
112
  }),
113
113
  )
114
114
  })
115
- this.ws.market.on_message((data, t_recv) => {
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(), t_recv, t_parsed }
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(), t_recv, t_parsed }
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, t_recv) => {
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(), t_recv, t_parsed }
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) {
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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(), t_recv, t_parsed }
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()
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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) {
@@ -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, t_recv) => {
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), t_recv, t_parsed }
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(), t_recv, t_parsed }
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()
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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) {
@@ -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, t_recv) => {
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]) {
@@ -122,21 +122,20 @@ module.exports = class Bitrue extends ExchangeBase {
122
122
  }),
123
123
  )
124
124
  })
125
- this.ws.market.on_message((data, t_recv) => {
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, t_recv, t_parsed }
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) {
@@ -150,10 +150,9 @@ module.exports = class Blofin extends ExchangeBase {
150
150
  }),
151
151
  )
152
152
  })
153
- this.ws.market.on_message((data, t_recv) => {
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(), t_recv, t_parsed }
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(), t_recv, t_parsed }
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()
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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()
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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, t_recv) => {
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(), t_recv, t_parsed }
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(), t_recv, t_parsed }
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(), t_recv, t_parsed }
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(), t_recv, t_parsed }
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, t_recv) => {
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(), t_recv, t_parsed }
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(), t_recv, t_parsed }
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.fix_ord.send_new_order(pair, method, price, amount, order_options, cb)
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
- this.fix_ord.send_cancel(order.pair, order.order_id, order.type, cb)
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, t_recv) => {
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(), t_recv, t_parsed }
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, t_recv) => {
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(), t_recv, t_parsed }
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, t_recv)
222
+ listener(...args)
224
223
  this.market_observable.notify()
225
224
  }
226
225
  if (this.market_socket.serviceHandlers) {
@@ -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, t_recv) => {
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(), t_recv, t_parsed }
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]) {
@@ -108,10 +108,9 @@ module.exports = class Hashkey extends ExchangeBase {
108
108
  }),
109
109
  )
110
110
  })
111
- this.ws.market.on_message((data, t_recv) => {
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, t_recv, t_parsed }
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, t_recv) => {
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(), t_recv, t_parsed }
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) {
@@ -80,9 +80,8 @@ module.exports = class Hitbtc extends ExchangeBase {
80
80
  }
81
81
  }
82
82
  })
83
- this.ws.market.on_message((data, t_recv) => {
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'
@@ -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, t_recv) => {
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(), t_recv, t_parsed }
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) {
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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, t_recv, t_parsed }
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])) {
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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, t_recv, t_parsed }
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])) {
@@ -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, t_recv) => {
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(), t_recv, t_parsed }
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) {
@@ -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, t_recv) => {
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, t_recv, t_parsed }
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] = {
@@ -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, t_recv) => {
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), t_recv, t_parsed }
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), t_recv, t_parsed }
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()
@@ -773,9 +773,8 @@ module.exports = class Phemex extends ExchangeBase {
773
773
  }),
774
774
  )
775
775
  })
776
- this.ws.market.on_message((data, t_recv) => {
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, t_recv, t_parsed }
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, t_recv, t_parsed }
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()
@@ -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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
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 = (Date.now() + 8 * 3_600_000).toString()
379
+ let timestamp = new Date().addHours(8).getTime().toString()
380
380
  let params = {
381
381
  channelId: api_key,
382
382
  timestamp,
@@ -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, t_recv) => {
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
- const t_parsed = process.hrtime()
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) {
@@ -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, t_recv) => {
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(), t_recv, t_parsed }
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.43",
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.60",
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",