@icgio/icg-exchanges-wrapper 1.17.21 → 1.17.23
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/middleware/orders.js +212 -66
- package/package.json +2 -2
package/middleware/orders.js
CHANGED
|
@@ -73,6 +73,7 @@ const MARKET_HISTORY_DEFAULT_MS = 10 * 60 * 1000
|
|
|
73
73
|
const TRADES_DEFAULT_MS = 7 * 24 * 60 * 60 * 1000
|
|
74
74
|
const NO_CALLBACK_TIMEOUT_MS = 2 * 60 * 1000
|
|
75
75
|
const PROCESS_RATES_THROTTLE_MS = 75
|
|
76
|
+
const MAX_ORDER_TRACE_ENTRIES = 20
|
|
76
77
|
const ORDER_TYPE_PRIORITY = {
|
|
77
78
|
self: 2,
|
|
78
79
|
maker_1: 3,
|
|
@@ -89,6 +90,36 @@ const getOrderPriority = (order_type, is_cancel = false) => {
|
|
|
89
90
|
return is_cancel ? priority - 0.5 : priority
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
const hrtime_diff = (start, end) => {
|
|
94
|
+
if (!Array.isArray(start) || !Array.isArray(end)) {
|
|
95
|
+
return undefined
|
|
96
|
+
}
|
|
97
|
+
return (end[0] - start[0]) * 1e9 + (end[1] - start[1])
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const is_finite_number = (value) => value != null && Number.isFinite(Number(value))
|
|
101
|
+
|
|
102
|
+
const normalize_market_ts = (raw_market_ts) => {
|
|
103
|
+
if (!raw_market_ts || typeof raw_market_ts !== 'object') {
|
|
104
|
+
return {}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
ts_ms_venue_event: is_finite_number(raw_market_ts.ts_ms_venue_event) ? Number(raw_market_ts.ts_ms_venue_event) : null,
|
|
108
|
+
ts_ms_venue_send: is_finite_number(raw_market_ts.ts_ms_venue_send) ? Number(raw_market_ts.ts_ms_venue_send) : null,
|
|
109
|
+
ts_ms_local_received: is_finite_number(raw_market_ts.ts_ms_local_received) ? Number(raw_market_ts.ts_ms_local_received) : null,
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const public_decision_context = (decision_context) => {
|
|
114
|
+
if (!decision_context || typeof decision_context !== 'object') {
|
|
115
|
+
return null
|
|
116
|
+
}
|
|
117
|
+
const public_context = _.cloneDeep(decision_context)
|
|
118
|
+
delete public_context.hr_rate_root
|
|
119
|
+
delete public_context.hr_decision
|
|
120
|
+
return public_context
|
|
121
|
+
}
|
|
122
|
+
|
|
92
123
|
module.exports = class Orders {
|
|
93
124
|
constructor(exchange_cur_quote_cur_dict, cd, settings) {
|
|
94
125
|
let { exchange_cur_quote_cur, exchange_cur_quote_cur_rates_only, pair_map_rates_only } = exchange_cur_quote_cur_dict
|
|
@@ -272,60 +303,124 @@ module.exports = class Orders {
|
|
|
272
303
|
ws_client.set_order_info_ref(this.order_info)
|
|
273
304
|
}
|
|
274
305
|
}
|
|
306
|
+
build_trace_entry(order, note) {
|
|
307
|
+
return {
|
|
308
|
+
ts: Date.now(),
|
|
309
|
+
status: order.status,
|
|
310
|
+
note,
|
|
311
|
+
f_amount: order.f_amount,
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
append_trace(order, note) {
|
|
315
|
+
if (!note || !order) return
|
|
316
|
+
if (!Array.isArray(order.trace)) {
|
|
317
|
+
order.trace = []
|
|
318
|
+
}
|
|
319
|
+
order.trace.push(this.build_trace_entry(order, note))
|
|
320
|
+
if (order.trace.length > MAX_ORDER_TRACE_ENTRIES) {
|
|
321
|
+
order.trace.splice(0, order.trace.length - MAX_ORDER_TRACE_ENTRIES)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
move_order_info_key(exchange, pair, type, from_order_id, to_order_id) {
|
|
325
|
+
if (!from_order_id || !to_order_id || from_order_id === to_order_id) {
|
|
326
|
+
return
|
|
327
|
+
}
|
|
328
|
+
const from_bucket = this.order_info?.[exchange]?.[pair]?.[type]
|
|
329
|
+
if (!from_bucket || !from_bucket[from_order_id]) {
|
|
330
|
+
return
|
|
331
|
+
}
|
|
332
|
+
const order = from_bucket[from_order_id]
|
|
333
|
+
from_bucket[to_order_id] = order
|
|
334
|
+
delete from_bucket[from_order_id]
|
|
335
|
+
if (order.order_type) {
|
|
336
|
+
const by_type = this.order_info_by_type?.[order.order_type]?.[exchange]?.[pair]?.[type]
|
|
337
|
+
if (by_type) {
|
|
338
|
+
by_type[to_order_id] = order
|
|
339
|
+
delete by_type[from_order_id]
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
275
343
|
init_account(balances, benchmarks) {
|
|
276
344
|
this.account = new Account(balances, benchmarks)
|
|
277
345
|
}
|
|
278
346
|
update_non_initial_from_balances(balances) {
|
|
279
347
|
this.account?.update_non_initial_from_balances(balances)
|
|
280
348
|
}
|
|
281
|
-
limit_trade(exchange, pair, method, price, amount, id = uuid(), order_type = '', limiter_on = true, api_key_index, order_options = {}) {
|
|
349
|
+
limit_trade(exchange, pair, method, price, amount, id = uuid(), order_type = '', limiter_on = true, api_key_index, order_options = {}, decision_context = null) {
|
|
282
350
|
price = round_price(exchange, pair, price)
|
|
283
351
|
amount = round_amount(exchange, pair, amount)
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
status
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
exchange,
|
|
311
|
-
pair,
|
|
312
|
-
method,
|
|
313
|
-
id,
|
|
314
|
-
{
|
|
315
|
-
status: 'N-OPENED-TIMEOUT',
|
|
316
|
-
},
|
|
317
|
-
order_type + ' n-opened-timeout-init',
|
|
318
|
-
)
|
|
352
|
+
const internal_id = id
|
|
353
|
+
let no_callback_timeout = null
|
|
354
|
+
let init_emitted = false
|
|
355
|
+
const start_no_callback_timeout = () => {
|
|
356
|
+
if (no_callback_timeout) {
|
|
357
|
+
clearTimeout(no_callback_timeout)
|
|
358
|
+
}
|
|
359
|
+
no_callback_timeout = setTimeout(() => {
|
|
360
|
+
if (_.get(this.order_info, [exchange, pair, method, internal_id, 'status']) === 'INIT') {
|
|
361
|
+
console.log('no callback: %s %s %s %s %s', exchange, pair, method, internal_id, order_type)
|
|
362
|
+
this.update_order_info(
|
|
363
|
+
exchange,
|
|
364
|
+
pair,
|
|
365
|
+
method,
|
|
366
|
+
internal_id,
|
|
367
|
+
{
|
|
368
|
+
status: 'N-OPENED-TIMEOUT',
|
|
369
|
+
},
|
|
370
|
+
order_type + ' n-opened-timeout-init',
|
|
371
|
+
)
|
|
372
|
+
}
|
|
373
|
+
}, NO_CALLBACK_TIMEOUT_MS)
|
|
374
|
+
}
|
|
375
|
+
const emit_init = ({ t_order_sent } = {}) => {
|
|
376
|
+
if (init_emitted) {
|
|
377
|
+
return
|
|
319
378
|
}
|
|
320
|
-
|
|
379
|
+
init_emitted = true
|
|
380
|
+
const init_decision_context = public_decision_context(decision_context)
|
|
381
|
+
const du_ns_decision_to_send = hrtime_diff(decision_context?.hr_decision, t_order_sent)
|
|
382
|
+
const du_ns_rate_to_send = hrtime_diff(decision_context?.hr_rate_root, t_order_sent)
|
|
383
|
+
this.update_order_info(
|
|
384
|
+
exchange,
|
|
385
|
+
pair,
|
|
386
|
+
method,
|
|
387
|
+
internal_id,
|
|
388
|
+
{
|
|
389
|
+
order_type,
|
|
390
|
+
status: 'INIT',
|
|
391
|
+
id: internal_id,
|
|
392
|
+
internal_id,
|
|
393
|
+
order_id: null,
|
|
394
|
+
type: method,
|
|
395
|
+
price,
|
|
396
|
+
amount,
|
|
397
|
+
f_amount: 0,
|
|
398
|
+
f_percentage: 0,
|
|
399
|
+
t_amount: amount,
|
|
400
|
+
open_time: Date.now(),
|
|
401
|
+
close_time: null,
|
|
402
|
+
decision_context: init_decision_context,
|
|
403
|
+
du_ns_decision_to_send,
|
|
404
|
+
du_ns_rate_to_send,
|
|
405
|
+
event_hrtime: t_order_sent,
|
|
406
|
+
},
|
|
407
|
+
order_type + ' init',
|
|
408
|
+
)
|
|
409
|
+
start_no_callback_timeout()
|
|
410
|
+
}
|
|
321
411
|
let limit_trade = (cb) => {
|
|
412
|
+
const order_options_with_meta = Object.assign({}, order_options, {
|
|
413
|
+
on_sent: ({ t_order_sent }) => {
|
|
414
|
+
emit_init({ t_order_sent })
|
|
415
|
+
},
|
|
416
|
+
})
|
|
322
417
|
if (limiter_on) {
|
|
323
418
|
if (this.Exchanges[exchange].private_limiter) {
|
|
324
419
|
this.Exchanges[exchange].private_limiter.priority = getOrderPriority(order_type)
|
|
325
420
|
}
|
|
326
|
-
this.Exchanges[exchange].limit_trade(pair, method, price, amount,
|
|
421
|
+
this.Exchanges[exchange].limit_trade(pair, method, price, amount, order_options_with_meta, cb)
|
|
327
422
|
} else {
|
|
328
|
-
this.Exchanges[exchange].limit_trade_base(pair, method, price, amount,
|
|
423
|
+
this.Exchanges[exchange].limit_trade_base(pair, method, price, amount, order_options_with_meta, cb)
|
|
329
424
|
}
|
|
330
425
|
}
|
|
331
426
|
if (api_key_index) {
|
|
@@ -334,7 +429,8 @@ module.exports = class Orders {
|
|
|
334
429
|
limit_trade((res) => {
|
|
335
430
|
if (res.success) {
|
|
336
431
|
let order_id = res.body
|
|
337
|
-
|
|
432
|
+
emit_init(res.meta || {})
|
|
433
|
+
this.move_order_info_key(exchange, pair, method, internal_id, order_id)
|
|
338
434
|
this.update_order_info(
|
|
339
435
|
exchange,
|
|
340
436
|
pair,
|
|
@@ -343,7 +439,8 @@ module.exports = class Orders {
|
|
|
343
439
|
{
|
|
344
440
|
order_type,
|
|
345
441
|
status: 'N-FILLED',
|
|
346
|
-
id,
|
|
442
|
+
id: internal_id,
|
|
443
|
+
internal_id,
|
|
347
444
|
order_id,
|
|
348
445
|
type: method,
|
|
349
446
|
price,
|
|
@@ -351,33 +448,38 @@ module.exports = class Orders {
|
|
|
351
448
|
f_amount: 0,
|
|
352
449
|
f_percentage: 0,
|
|
353
450
|
t_amount: amount,
|
|
354
|
-
open_time: new Date(),
|
|
355
451
|
close_time: null,
|
|
452
|
+
du_ns_rate_to_ack: hrtime_diff(decision_context?.hr_rate_root, _.get(res, ['meta', 't_ack_recv'])),
|
|
453
|
+
du_ns_order_rtt: hrtime_diff(_.get(res, ['meta', 't_order_sent']), _.get(res, ['meta', 't_ack_recv'])),
|
|
454
|
+
event_hrtime: _.get(res, ['meta', 't_ack_recv']),
|
|
356
455
|
},
|
|
357
456
|
order_type + ' n-filled',
|
|
358
457
|
)
|
|
359
458
|
} else if (res.error === 'amount-too-small' || res.error === 'insufficient-funds') {
|
|
360
|
-
this.delete_order_info(exchange, pair, method,
|
|
459
|
+
this.delete_order_info(exchange, pair, method, internal_id, order_type + ' limit-trade-' + res.error)
|
|
361
460
|
} else if (res.error === 'connection-error') {
|
|
362
461
|
setTimeout(() => {
|
|
363
|
-
this.delete_order_info(exchange, pair, method,
|
|
462
|
+
this.delete_order_info(exchange, pair, method, internal_id, order_type + ' limit-trade-' + res.error)
|
|
364
463
|
}, this.delete_connection_error_orders_timeout)
|
|
365
464
|
} else {
|
|
366
465
|
if (order_type.startsWith('self') || order_type.startsWith('maker_2')) {
|
|
367
|
-
this.delete_order_info(exchange, pair, method,
|
|
466
|
+
this.delete_order_info(exchange, pair, method, internal_id, order_type + ' limit-trade-timeout')
|
|
368
467
|
}
|
|
369
468
|
// else if (_.get(this.order_info, [exchange, pair, method, id, 'status']) === 'INIT') { // make sure no_callback_timeout is NOT running zero
|
|
370
469
|
// this.update_order_info(exchange, pair, method, id, {
|
|
371
470
|
// status: 'N-OPENED-TIMEOUT'
|
|
372
471
|
// }, order_type + ' n-opened-timeout-callback')
|
|
373
472
|
// }
|
|
374
|
-
console.error('limit trade error: %s %s %s %s %s %s %s %j', order_type,
|
|
473
|
+
console.error('limit trade error: %s %s %s %s %s %s %s %j', order_type, internal_id, exchange, pair, method, price, amount, res)
|
|
474
|
+
}
|
|
475
|
+
if (no_callback_timeout) {
|
|
476
|
+
clearTimeout(no_callback_timeout)
|
|
375
477
|
}
|
|
376
|
-
clearTimeout(no_callback_timeout)
|
|
377
478
|
})
|
|
378
479
|
}
|
|
379
|
-
cancel_order(exchange, pair, order) {
|
|
480
|
+
cancel_order(exchange, pair, order, decision_context = null) {
|
|
380
481
|
let original_status = order.status
|
|
482
|
+
const cancel_decision_context = public_decision_context(decision_context) || _.cloneDeep(order.decision_context) || null
|
|
381
483
|
this.update_order_info(
|
|
382
484
|
exchange,
|
|
383
485
|
pair,
|
|
@@ -385,6 +487,7 @@ module.exports = class Orders {
|
|
|
385
487
|
order.order_id,
|
|
386
488
|
{
|
|
387
489
|
status: 'CANCELING',
|
|
490
|
+
decision_context: cancel_decision_context,
|
|
388
491
|
},
|
|
389
492
|
order.order_type + ' canceling',
|
|
390
493
|
)
|
|
@@ -401,7 +504,11 @@ module.exports = class Orders {
|
|
|
401
504
|
order.order_id,
|
|
402
505
|
{
|
|
403
506
|
status: 'CANCELED',
|
|
404
|
-
close_time:
|
|
507
|
+
close_time: Date.now(),
|
|
508
|
+
decision_context: cancel_decision_context,
|
|
509
|
+
du_ns_cancel_latency: hrtime_diff(_.get(res, ['meta', 't_cancel_sent']), _.get(res, ['meta', 't_cancel_ack'])),
|
|
510
|
+
du_ns_rate_to_cancel_ack: hrtime_diff(decision_context?.hr_rate_root, _.get(res, ['meta', 't_cancel_ack'])),
|
|
511
|
+
event_hrtime: _.get(res, ['meta', 't_cancel_ack']),
|
|
405
512
|
},
|
|
406
513
|
order.order_type + ' canceled',
|
|
407
514
|
)
|
|
@@ -420,7 +527,7 @@ module.exports = class Orders {
|
|
|
420
527
|
amount: 0,
|
|
421
528
|
f_amount: order.amount,
|
|
422
529
|
f_percentage: 1,
|
|
423
|
-
close_time:
|
|
530
|
+
close_time: Date.now(),
|
|
424
531
|
},
|
|
425
532
|
order.order_type + ' cannot-be-canceled',
|
|
426
533
|
)
|
|
@@ -552,8 +659,9 @@ module.exports = class Orders {
|
|
|
552
659
|
amount: 0,
|
|
553
660
|
f_amount: trade_amount,
|
|
554
661
|
f_percentage: trade_amount / order_info.t_amount,
|
|
555
|
-
close_time: trade.close_time
|
|
662
|
+
close_time: trade.close_time ? new Date(trade.close_time).getTime() : Date.now(),
|
|
556
663
|
fees: trade.fees,
|
|
664
|
+
event_hrtime: process.hrtime(),
|
|
557
665
|
},
|
|
558
666
|
order_info.order_type + ' canceled-order-filled(-more)',
|
|
559
667
|
)
|
|
@@ -592,8 +700,9 @@ module.exports = class Orders {
|
|
|
592
700
|
amount: order_info.t_amount - trade_amount,
|
|
593
701
|
f_amount: trade.amount,
|
|
594
702
|
f_percentage: trade_amount / order_info.t_amount,
|
|
595
|
-
close_time: trade.close_time
|
|
703
|
+
close_time: trade.close_time ? new Date(trade.close_time).getTime() : Date.now(),
|
|
596
704
|
fees: trade.fees,
|
|
705
|
+
event_hrtime: process.hrtime(),
|
|
597
706
|
},
|
|
598
707
|
order_info.order_type + ' order-f-filled-1',
|
|
599
708
|
)
|
|
@@ -678,7 +787,8 @@ module.exports = class Orders {
|
|
|
678
787
|
amount: 0,
|
|
679
788
|
f_amount: order_info_order.t_amount,
|
|
680
789
|
f_percentage: 1,
|
|
681
|
-
close_time:
|
|
790
|
+
close_time: Date.now(),
|
|
791
|
+
event_hrtime: process.hrtime(),
|
|
682
792
|
},
|
|
683
793
|
order_info_order.order_type + ' order-f-filled-2',
|
|
684
794
|
)
|
|
@@ -713,7 +823,8 @@ module.exports = class Orders {
|
|
|
713
823
|
amount: order.amount,
|
|
714
824
|
f_amount: order_f_amount,
|
|
715
825
|
f_percentage: order_f_amount / order_info.t_amount,
|
|
716
|
-
close_time: order.close_time
|
|
826
|
+
close_time: order.close_time ? new Date(order.close_time).getTime() : Date.now(),
|
|
827
|
+
event_hrtime: process.hrtime(),
|
|
717
828
|
},
|
|
718
829
|
order_info.order_type + ' order-f-filled-3',
|
|
719
830
|
)
|
|
@@ -744,8 +855,8 @@ module.exports = class Orders {
|
|
|
744
855
|
this.get_order_info_status_all(exchange, pair, 'both', 'INIT').map((init_order) => {
|
|
745
856
|
let init_order_price = round_price(exchange, pair, init_order.price)
|
|
746
857
|
let order_price = round_price(exchange, pair, order.price)
|
|
747
|
-
let init_order_time = init_order.open_time.getTime()
|
|
748
|
-
let order_time = order.open_time.getTime()
|
|
858
|
+
let init_order_time = typeof init_order.open_time === 'number' ? init_order.open_time : new Date(init_order.open_time).getTime()
|
|
859
|
+
let order_time = typeof order.open_time === 'number' ? order.open_time : new Date(order.open_time).getTime()
|
|
749
860
|
if (
|
|
750
861
|
init_order.type === order.type &&
|
|
751
862
|
init_order_price === order_price &&
|
|
@@ -753,7 +864,7 @@ module.exports = class Orders {
|
|
|
753
864
|
order_time - init_order_time < this.check_init_order_opened_timeout
|
|
754
865
|
) {
|
|
755
866
|
// console.log('ORDERS: %s %s %s %s INIT ORDER OPENED', init_order.order_id, order.order_id, exchange, pair)
|
|
756
|
-
this.
|
|
867
|
+
this.move_order_info_key(exchange, pair, init_order.type, init_order.internal_id || init_order.id, order.order_id)
|
|
757
868
|
this.update_order_info(
|
|
758
869
|
exchange,
|
|
759
870
|
pair,
|
|
@@ -767,8 +878,9 @@ module.exports = class Orders {
|
|
|
767
878
|
amount: order.amount,
|
|
768
879
|
f_amount: 0,
|
|
769
880
|
t_amount: order.amount,
|
|
770
|
-
open_time: order.open_time
|
|
881
|
+
open_time: order.open_time ? new Date(order.open_time).getTime() : Date.now(),
|
|
771
882
|
close_time: null,
|
|
883
|
+
event_hrtime: process.hrtime(),
|
|
772
884
|
},
|
|
773
885
|
init_order.order_type + ' init-order-opened',
|
|
774
886
|
)
|
|
@@ -788,7 +900,8 @@ module.exports = class Orders {
|
|
|
788
900
|
order_info.order_id,
|
|
789
901
|
{
|
|
790
902
|
status: 'CANCELED',
|
|
791
|
-
close_time:
|
|
903
|
+
close_time: Date.now(),
|
|
904
|
+
event_hrtime: process.hrtime(),
|
|
792
905
|
},
|
|
793
906
|
(order_info.order_type || '') + ' canceling-canceled-from-open-orders',
|
|
794
907
|
)
|
|
@@ -809,6 +922,8 @@ module.exports = class Orders {
|
|
|
809
922
|
const existing = this.order_info[exchange]?.[pair]?.[type]?.[order_id]
|
|
810
923
|
const old_status = existing && existing.status
|
|
811
924
|
const old_order_type = existing && existing.order_type
|
|
925
|
+
const event_hrtime = dict.event_hrtime
|
|
926
|
+
delete dict.event_hrtime
|
|
812
927
|
|
|
813
928
|
for (let key in dict) {
|
|
814
929
|
if (key === 'f_percentage') {
|
|
@@ -822,7 +937,15 @@ module.exports = class Orders {
|
|
|
822
937
|
}
|
|
823
938
|
|
|
824
939
|
const order = this.order_info[exchange][pair][type][order_id]
|
|
940
|
+
if (order.internal_id == null && order.id != null) {
|
|
941
|
+
order.internal_id = order.id
|
|
942
|
+
}
|
|
943
|
+
if (order.trace == null) {
|
|
944
|
+
order.trace = []
|
|
945
|
+
}
|
|
946
|
+
order.lifecycle_seq = existing && Number.isFinite(existing.lifecycle_seq) ? existing.lifecycle_seq + 1 : dict.lifecycle_seq || 1
|
|
825
947
|
order.last_update_ts = Date.now()
|
|
948
|
+
this.append_trace(order, note)
|
|
826
949
|
|
|
827
950
|
const new_status = order.status
|
|
828
951
|
if (old_status !== new_status) {
|
|
@@ -879,14 +1002,16 @@ module.exports = class Orders {
|
|
|
879
1002
|
|
|
880
1003
|
// Send order update via WebSocket to dashboard backend
|
|
881
1004
|
const order_data = _.get(this.order_info, [exchange, pair, type, order_id], {})
|
|
882
|
-
|
|
883
|
-
if (dict.status !== 'INIT' && order_data.status !== 'INIT' && ws_client) {
|
|
1005
|
+
if (ws_client) {
|
|
884
1006
|
ws_client.send_order({
|
|
885
1007
|
action: 'update',
|
|
886
1008
|
exchange,
|
|
887
1009
|
pair,
|
|
888
1010
|
side: type,
|
|
889
1011
|
order_id,
|
|
1012
|
+
internal_id: order_data.internal_id,
|
|
1013
|
+
lifecycle_seq: order_data.lifecycle_seq,
|
|
1014
|
+
event_hrtime,
|
|
890
1015
|
data: order_data,
|
|
891
1016
|
note,
|
|
892
1017
|
})
|
|
@@ -909,14 +1034,16 @@ module.exports = class Orders {
|
|
|
909
1034
|
}
|
|
910
1035
|
console.log('DELETE %s: %s %s %s %s', note, exchange, pair, type, order_id)
|
|
911
1036
|
|
|
912
|
-
|
|
913
|
-
if (order_data.status !== 'INIT' && ws_client) {
|
|
1037
|
+
if (ws_client && order_data.internal_id) {
|
|
914
1038
|
ws_client.send_order({
|
|
915
1039
|
action: 'delete',
|
|
916
1040
|
exchange,
|
|
917
1041
|
pair,
|
|
918
1042
|
side: type,
|
|
919
1043
|
order_id,
|
|
1044
|
+
internal_id: order_data.internal_id,
|
|
1045
|
+
lifecycle_seq: (order_data.lifecycle_seq || 0) + 1,
|
|
1046
|
+
event_hrtime: process.hrtime(),
|
|
920
1047
|
data: order_data,
|
|
921
1048
|
note,
|
|
922
1049
|
})
|
|
@@ -1331,7 +1458,7 @@ module.exports = class Orders {
|
|
|
1331
1458
|
for (let order_id in order_info[type]) {
|
|
1332
1459
|
let { open_time } = order_info[type][order_id]
|
|
1333
1460
|
// console.log(order_id, open_time, open_time < new Date() - 30 * 60 * 1000)
|
|
1334
|
-
if (open_time <
|
|
1461
|
+
if (open_time < Date.now() - QUERY_ORDER_TIME_IN_MS) {
|
|
1335
1462
|
// console.log('query_order_maker_1: %s %s %s', exchange, pair, order_id)
|
|
1336
1463
|
Exchanges[exchange].query_order(pair, order_id, (res) => {
|
|
1337
1464
|
count++
|
|
@@ -1406,10 +1533,29 @@ module.exports = class Orders {
|
|
|
1406
1533
|
const throttled_process_rates = _.throttle(process_rates, PROCESS_RATES_THROTTLE_MS, { leading: true, trailing: true })
|
|
1407
1534
|
let rates_handler = (exchange, pair, res) => {
|
|
1408
1535
|
if (res.success) {
|
|
1409
|
-
|
|
1536
|
+
const hr_rate_root = process.hrtime()
|
|
1537
|
+
const ts_ms_local_rate_root = Date.now()
|
|
1538
|
+
let { asks, bids, market_ts } = res.body
|
|
1539
|
+
const raw_market_ts = market_ts && typeof market_ts === 'object' ? market_ts : null
|
|
1540
|
+
const normalized_market_ts = normalize_market_ts(raw_market_ts)
|
|
1541
|
+
const prev_local_received = _.get(this.rates, [exchange, pair, 'market_ts', 'ts_ms_local_received'])
|
|
1542
|
+
const du_ms_interarrival_local_received =
|
|
1543
|
+
is_finite_number(prev_local_received) && is_finite_number(normalized_market_ts.ts_ms_local_received)
|
|
1544
|
+
? Number(normalized_market_ts.ts_ms_local_received) - Number(prev_local_received)
|
|
1545
|
+
: null
|
|
1410
1546
|
asks = asks.slice(0, RATES_LENGTH_MAX)
|
|
1411
1547
|
bids = bids.slice(0, RATES_LENGTH_MAX)
|
|
1412
|
-
_.set(this.rates, [exchange, pair], {
|
|
1548
|
+
_.set(this.rates, [exchange, pair], {
|
|
1549
|
+
asks,
|
|
1550
|
+
bids,
|
|
1551
|
+
market_ts: normalized_market_ts,
|
|
1552
|
+
hr_rate_root,
|
|
1553
|
+
hr_recv: Array.isArray(raw_market_ts?.hr_recv) ? raw_market_ts.hr_recv : null,
|
|
1554
|
+
hr_parsed: Array.isArray(raw_market_ts?.hr_parsed) ? raw_market_ts.hr_parsed : null,
|
|
1555
|
+
ts_ms_local_rate_root,
|
|
1556
|
+
du_ms_interarrival_local_received,
|
|
1557
|
+
update_time: new Date(),
|
|
1558
|
+
})
|
|
1413
1559
|
/*
|
|
1414
1560
|
* throttle to 20ms
|
|
1415
1561
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@icgio/icg-exchanges-wrapper",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.23",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"homepage": "https://github.com/icgio/icg-exchanges-wrapper#readme",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@icgio/icg-exchanges": "^1.40.
|
|
20
|
+
"@icgio/icg-exchanges": "^1.40.46",
|
|
21
21
|
"@icgio/icg-utils": "^1.9.61",
|
|
22
22
|
"lodash": "^4.17.23",
|
|
23
23
|
"pg": "^8.17.2"
|