@icgio/icg-exchanges-wrapper 1.21.28 → 1.21.29
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 +89 -57
- package/package.json +1 -1
package/middleware/orders.js
CHANGED
|
@@ -72,6 +72,7 @@ const PROCESS_OPEN_ORDERS_TRADERS_INTERVAL_MS = 500
|
|
|
72
72
|
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
|
+
const STALE_QUERY_ORDER_THRESHOLD_MS = 12 * 60 * 60 * 1000
|
|
75
76
|
const PROCESS_RATES_THROTTLE_MS = 75
|
|
76
77
|
const MAX_ORDER_TRACE_ENTRIES = 20
|
|
77
78
|
const ORDER_TYPE_PRIORITY = {
|
|
@@ -248,6 +249,7 @@ module.exports = class Orders {
|
|
|
248
249
|
open_orders_check: true,
|
|
249
250
|
trades_check: true,
|
|
250
251
|
query_order_check_maker_1_self: false,
|
|
252
|
+
query_order_check_stale_maker_2_3: false,
|
|
251
253
|
query_order_check_exchange: {},
|
|
252
254
|
rates_check: true,
|
|
253
255
|
market_history_check: true,
|
|
@@ -267,10 +269,10 @@ module.exports = class Orders {
|
|
|
267
269
|
this.trades_amount_past_hour = {}
|
|
268
270
|
this.check_trades()
|
|
269
271
|
}
|
|
270
|
-
if (this.function_enabled.query_order_check_maker_1_self) {
|
|
272
|
+
if (this.function_enabled.query_order_check_maker_1_self || this.function_enabled.query_order_check_stale_maker_2_3) {
|
|
271
273
|
for (let exchange in this.Exchanges) {
|
|
272
274
|
if (this.function_enabled.query_order_check_exchange[exchange]) {
|
|
273
|
-
this.check_query_order(exchange
|
|
275
|
+
this.check_query_order(exchange)
|
|
274
276
|
}
|
|
275
277
|
}
|
|
276
278
|
}
|
|
@@ -292,7 +294,7 @@ module.exports = class Orders {
|
|
|
292
294
|
this.process_open_orders(this.open_orders)
|
|
293
295
|
}, PROCESS_OPEN_ORDERS_TRADERS_INTERVAL_MS)
|
|
294
296
|
}
|
|
295
|
-
if (this.function_enabled.query_order_check_maker_1_self) {
|
|
297
|
+
if (this.function_enabled.query_order_check_maker_1_self || this.function_enabled.query_order_check_stale_maker_2_3) {
|
|
296
298
|
setInterval(() => {
|
|
297
299
|
this.process_query_order(this.query_order)
|
|
298
300
|
}, PROCESS_OPEN_ORDERS_TRADERS_INTERVAL_MS)
|
|
@@ -770,9 +772,8 @@ module.exports = class Orders {
|
|
|
770
772
|
const local_filled_amount = round_amount(exchange, pair, local_order.f_amount || 0)
|
|
771
773
|
const polled_filled_amount = round_amount(exchange, pair, polled_order.f_amount || 0)
|
|
772
774
|
const compare_total = round_amount(exchange, pair, local_order.t_amount || polled_order.t_amount || 0)
|
|
773
|
-
const both_effectively_filled =
|
|
774
|
-
local_filled_amount / compare_total > this.f_filled_threshold &&
|
|
775
|
-
polled_filled_amount / compare_total > this.f_filled_threshold
|
|
775
|
+
const both_effectively_filled =
|
|
776
|
+
compare_total > 0 && local_filled_amount / compare_total > this.f_filled_threshold && polled_filled_amount / compare_total > this.f_filled_threshold
|
|
776
777
|
if (local_order.status === exchange_status && (local_filled_amount === polled_filled_amount || both_effectively_filled)) continue
|
|
777
778
|
this.log_terminal_divergence('query_order', exchange, pair, polled_order.order_id, local_order.status, exchange_status)
|
|
778
779
|
if (local_order.status === 'F-FILLED' && exchange_status === 'P-FILLED') continue
|
|
@@ -1492,10 +1493,62 @@ module.exports = class Orders {
|
|
|
1492
1493
|
}
|
|
1493
1494
|
get_trades_all(this.Exchanges, this.exchange_pairs, this.interval_dict)
|
|
1494
1495
|
}
|
|
1495
|
-
check_query_order(exchange
|
|
1496
|
+
check_query_order(exchange) {
|
|
1497
|
+
// Per pair, periodically collect the set of orders to query and dispatch them.
|
|
1498
|
+
// Targets come from two sources, each gated by its own flag:
|
|
1499
|
+
// 1. maker_1_self: every maker_1/self order older than QUERY_ORDER_TIME_IN_MS
|
|
1500
|
+
// 2. stale_maker_2_3: oldest maker_2/maker_3 per axis that's missing from the
|
|
1501
|
+
// latest open_orders snapshot and older than STALE_QUERY_ORDER_THRESHOLD_MS
|
|
1502
|
+
// Both sources share the same dispatch loop, per-order in_flight dedup, aggregate
|
|
1503
|
+
// settlement, and downstream reconciliation via process_query_order.
|
|
1504
|
+
if (!this.function_enabled.query_order_check_exchange[exchange]) return
|
|
1505
|
+
if (!this.Exchanges[exchange] || !this.Exchanges[exchange].query_order) return
|
|
1496
1506
|
const QUERY_ORDER_TIME_IN_MS = 5 * 1000
|
|
1497
|
-
const
|
|
1498
|
-
|
|
1507
|
+
const collect_targets = (pair) => {
|
|
1508
|
+
const targets = []
|
|
1509
|
+
if (this.function_enabled.query_order_check_maker_1_self) {
|
|
1510
|
+
const order_info_by_type = _.get(this.get_order_info_by_order_type(['maker_1', 'self']), [exchange, pair], {})
|
|
1511
|
+
const cutoff = Date.now() - QUERY_ORDER_TIME_IN_MS
|
|
1512
|
+
for (const type of ['buy', 'sell']) {
|
|
1513
|
+
let oldest = null
|
|
1514
|
+
let oldest_open_time_ms = Infinity
|
|
1515
|
+
for (const order_id in order_info_by_type[type] || {}) {
|
|
1516
|
+
const o = order_info_by_type[type][order_id]
|
|
1517
|
+
if (!o || !o.order_id) continue
|
|
1518
|
+
const open_time_ms = typeof o.open_time === 'number' ? o.open_time : new Date(o.open_time).getTime()
|
|
1519
|
+
if (!open_time_ms || open_time_ms > cutoff) continue
|
|
1520
|
+
if (open_time_ms < oldest_open_time_ms) {
|
|
1521
|
+
oldest = o
|
|
1522
|
+
oldest_open_time_ms = open_time_ms
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
if (oldest) targets.push({ type, order_id: oldest.order_id })
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
if (this.function_enabled.query_order_check_stale_maker_2_3) {
|
|
1529
|
+
const live_ids = new Set(_.get(this.open_orders, [exchange, pair, 'open_orders'], []).map((o) => o.order_id))
|
|
1530
|
+
const cutoff = Date.now() - STALE_QUERY_ORDER_THRESHOLD_MS
|
|
1531
|
+
for (const type of ['buy', 'sell']) {
|
|
1532
|
+
let oldest = null
|
|
1533
|
+
let oldest_open_time_ms = Infinity
|
|
1534
|
+
for (const order_id in _.get(this.order_info, [exchange, pair, type], {})) {
|
|
1535
|
+
const o = this.order_info[exchange][pair][type][order_id]
|
|
1536
|
+
if (!o || !o.order_id || live_ids.has(o.order_id)) continue
|
|
1537
|
+
if (!['maker_2', 'maker_3'].includes(o.order_type)) continue
|
|
1538
|
+
if (!['N-FILLED', 'P-FILLED'].includes(o.status)) continue
|
|
1539
|
+
const open_time_ms = typeof o.open_time === 'number' ? o.open_time : new Date(o.open_time).getTime()
|
|
1540
|
+
if (!open_time_ms || open_time_ms > cutoff) continue
|
|
1541
|
+
if (open_time_ms < oldest_open_time_ms) {
|
|
1542
|
+
oldest = o
|
|
1543
|
+
oldest_open_time_ms = open_time_ms
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
if (oldest) targets.push({ type, order_id: oldest.order_id })
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
return targets
|
|
1550
|
+
}
|
|
1551
|
+
const query_order_handler = (exchange, pair, res) => {
|
|
1499
1552
|
if (res.success) {
|
|
1500
1553
|
_.set(this.query_order, [exchange, pair], { query_order: res.body, update_time: new Date() })
|
|
1501
1554
|
} else if (_.get(this.query_order, [exchange, pair, 'update_time']) < Date.now() - this.interval_dict[exchange].query_order) {
|
|
@@ -1506,58 +1559,37 @@ module.exports = class Orders {
|
|
|
1506
1559
|
}
|
|
1507
1560
|
}
|
|
1508
1561
|
const in_flight = new Set()
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
clearTimeout(timeout)
|
|
1521
|
-
setTimeout(() => {
|
|
1522
|
-
query_order(exchange, pair)
|
|
1523
|
-
}, interval_dict[exchange].query_order)
|
|
1524
|
-
}
|
|
1525
|
-
if (order_number === 0) {
|
|
1526
|
-
return
|
|
1527
|
-
}
|
|
1528
|
-
for (let type in order_info) {
|
|
1529
|
-
for (let order_id in order_info[type]) {
|
|
1530
|
-
let { open_time } = order_info[type][order_id]
|
|
1531
|
-
const key = `${exchange}:${pair}:${type}:${order_id}`
|
|
1532
|
-
if (in_flight.has(key)) {
|
|
1533
|
-
count++
|
|
1534
|
-
if (count === order_number) settle()
|
|
1535
|
-
continue
|
|
1536
|
-
}
|
|
1537
|
-
if (open_time < Date.now() - QUERY_ORDER_TIME_IN_MS) {
|
|
1538
|
-
in_flight.add(key)
|
|
1539
|
-
Exchanges[exchange].query_order(pair, order_id, (res) => {
|
|
1540
|
-
in_flight.delete(key)
|
|
1541
|
-
count++
|
|
1542
|
-
if (res.success) {
|
|
1543
|
-
result.push(res.body)
|
|
1544
|
-
}
|
|
1545
|
-
if (count === order_number) settle()
|
|
1546
|
-
})
|
|
1547
|
-
} else {
|
|
1548
|
-
count++
|
|
1549
|
-
if (count === order_number) settle()
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1562
|
+
const query_order_loop = (pair) => {
|
|
1563
|
+
const targets = collect_targets(pair)
|
|
1564
|
+
let timeout = setTimeout(() => query_order_loop(pair), this.interval_dict[exchange].query_order)
|
|
1565
|
+
const order_number = targets.length
|
|
1566
|
+
if (order_number === 0) return
|
|
1567
|
+
let count = 0
|
|
1568
|
+
const result = []
|
|
1569
|
+
const settle = () => {
|
|
1570
|
+
query_order_handler(exchange, pair, { success: true, body: result })
|
|
1571
|
+
clearTimeout(timeout)
|
|
1572
|
+
setTimeout(() => query_order_loop(pair), this.interval_dict[exchange].query_order)
|
|
1553
1573
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1574
|
+
for (const { type, order_id } of targets) {
|
|
1575
|
+
const key = `${exchange}:${pair}:${type}:${order_id}`
|
|
1576
|
+
if (in_flight.has(key)) {
|
|
1577
|
+
count++
|
|
1578
|
+
if (count === order_number) settle()
|
|
1579
|
+
continue
|
|
1557
1580
|
}
|
|
1581
|
+
in_flight.add(key)
|
|
1582
|
+
this.Exchanges[exchange].query_order(pair, order_id, (res) => {
|
|
1583
|
+
in_flight.delete(key)
|
|
1584
|
+
count++
|
|
1585
|
+
if (res.success) result.push(res.body)
|
|
1586
|
+
if (count === order_number) settle()
|
|
1587
|
+
})
|
|
1558
1588
|
}
|
|
1559
1589
|
}
|
|
1560
|
-
|
|
1590
|
+
for (const pair of this.exchange_pairs[exchange]) {
|
|
1591
|
+
query_order_loop(pair)
|
|
1592
|
+
}
|
|
1561
1593
|
}
|
|
1562
1594
|
check_rates() {
|
|
1563
1595
|
const pending_rate_updates = new Map()
|