@icgio/icg-exchanges-wrapper 1.14.230 → 1.14.231
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/order-status-store.js +39 -43
- package/middleware/orders.js +5 -5
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const { Pool } = require('pg')
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Async PostgreSQL store for
|
|
4
|
+
* Async PostgreSQL store for all orders
|
|
5
5
|
* Non-blocking: all writes are fire-and-forget to avoid blocking the main process
|
|
6
6
|
*/
|
|
7
|
-
class
|
|
7
|
+
class AllOrdersStore {
|
|
8
8
|
constructor(connection_string) {
|
|
9
9
|
this.enabled = true
|
|
10
10
|
this.pool = null
|
|
@@ -30,7 +30,7 @@ class OpenOrdersStore {
|
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
this.pool.on('error', (err) => {
|
|
33
|
-
console.error('
|
|
33
|
+
console.error('AllOrdersStore pool error:', err.message)
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
// Set timezone to UTC for all connections
|
|
@@ -41,16 +41,18 @@ class OpenOrdersStore {
|
|
|
41
41
|
await this.ensure_table()
|
|
42
42
|
this.enabled = true
|
|
43
43
|
this.start_flush_interval()
|
|
44
|
-
console.log('
|
|
44
|
+
console.log('AllOrdersStore initialized successfully')
|
|
45
45
|
} catch (err) {
|
|
46
|
-
console.error('
|
|
46
|
+
console.error('AllOrdersStore init failed:', err.message)
|
|
47
47
|
this.enabled = false
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async ensure_table() {
|
|
52
52
|
const create_table_query = `
|
|
53
|
-
|
|
53
|
+
-- All orders (persistent mapping of id/order_id to order_type & status)
|
|
54
|
+
CREATE TABLE IF NOT EXISTS all_orders (
|
|
55
|
+
id VARCHAR(128),
|
|
54
56
|
exchange VARCHAR(64) NOT NULL,
|
|
55
57
|
pair VARCHAR(32) NOT NULL,
|
|
56
58
|
order_type VARCHAR(64),
|
|
@@ -66,12 +68,11 @@ class OpenOrdersStore {
|
|
|
66
68
|
open_time TIMESTAMPTZ,
|
|
67
69
|
close_time TIMESTAMPTZ,
|
|
68
70
|
note VARCHAR(256),
|
|
71
|
+
created_at TIMESTAMPTZ DEFAULT (NOW() AT TIME ZONE 'UTC'),
|
|
69
72
|
updated_at TIMESTAMPTZ DEFAULT (NOW() AT TIME ZONE 'UTC'),
|
|
70
73
|
PRIMARY KEY (exchange, pair, type, order_id)
|
|
71
74
|
);
|
|
72
|
-
CREATE INDEX IF NOT EXISTS
|
|
73
|
-
CREATE INDEX IF NOT EXISTS idx_open_orders_exchange ON open_orders(exchange);
|
|
74
|
-
CREATE INDEX IF NOT EXISTS idx_open_orders_ex_pair_order ON open_orders(exchange, pair, order_id);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_all_orders_exchange_pair_order ON all_orders(exchange, pair, order_id);
|
|
75
76
|
`
|
|
76
77
|
|
|
77
78
|
const client = await this.pool.connect()
|
|
@@ -88,7 +89,7 @@ class OpenOrdersStore {
|
|
|
88
89
|
|
|
89
90
|
this.flush_interval = setInterval(() => {
|
|
90
91
|
this.flush().catch((err) => {
|
|
91
|
-
console.error('
|
|
92
|
+
console.error('AllOrdersStore flush error:', err.message)
|
|
92
93
|
})
|
|
93
94
|
}, this.flush_interval_ms)
|
|
94
95
|
}
|
|
@@ -122,6 +123,7 @@ class OpenOrdersStore {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
const record = {
|
|
126
|
+
id: data.id,
|
|
125
127
|
exchange,
|
|
126
128
|
pair,
|
|
127
129
|
type,
|
|
@@ -155,13 +157,14 @@ class OpenOrdersStore {
|
|
|
155
157
|
|
|
156
158
|
const batch = this.queue.splice(0, 100) // Process up to 100 at a time
|
|
157
159
|
|
|
158
|
-
const
|
|
159
|
-
INSERT INTO
|
|
160
|
-
exchange, pair, type, order_id, order_type, status,
|
|
160
|
+
const upsert_all_orders_query = `
|
|
161
|
+
INSERT INTO all_orders (
|
|
162
|
+
id, exchange, pair, type, order_id, order_type, status,
|
|
161
163
|
price, amount, f_amount, f_percentage, t_amount,
|
|
162
|
-
fees, open_time, close_time, note, updated_at
|
|
163
|
-
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, (NOW() AT TIME ZONE 'UTC'))
|
|
164
|
+
fees, open_time, close_time, note, created_at, updated_at
|
|
165
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, (NOW() AT TIME ZONE 'UTC'), (NOW() AT TIME ZONE 'UTC'))
|
|
164
166
|
ON CONFLICT (exchange, pair, type, order_id) DO UPDATE SET
|
|
167
|
+
id = EXCLUDED.id,
|
|
165
168
|
order_type = EXCLUDED.order_type,
|
|
166
169
|
status = EXCLUDED.status,
|
|
167
170
|
price = EXCLUDED.price,
|
|
@@ -176,35 +179,28 @@ class OpenOrdersStore {
|
|
|
176
179
|
updated_at = (NOW() AT TIME ZONE 'UTC')
|
|
177
180
|
`
|
|
178
181
|
|
|
179
|
-
const delete_query = `
|
|
180
|
-
DELETE FROM open_orders
|
|
181
|
-
WHERE exchange = $1 AND pair = $2 AND type = $3 AND order_id = $4
|
|
182
|
-
`
|
|
183
|
-
|
|
184
182
|
const client = await this.pool.connect()
|
|
185
183
|
try {
|
|
186
184
|
for (const record of batch) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
])
|
|
207
|
-
}
|
|
185
|
+
// Always persist in all_orders
|
|
186
|
+
await client.query(upsert_all_orders_query, [
|
|
187
|
+
record.id,
|
|
188
|
+
record.exchange,
|
|
189
|
+
record.pair,
|
|
190
|
+
record.type,
|
|
191
|
+
record.order_id,
|
|
192
|
+
record.order_type,
|
|
193
|
+
record.status,
|
|
194
|
+
record.price,
|
|
195
|
+
record.amount,
|
|
196
|
+
record.f_amount,
|
|
197
|
+
record.f_percentage,
|
|
198
|
+
record.t_amount,
|
|
199
|
+
record.fees,
|
|
200
|
+
record.open_time,
|
|
201
|
+
record.close_time,
|
|
202
|
+
record.note,
|
|
203
|
+
])
|
|
208
204
|
}
|
|
209
205
|
} catch (err) {
|
|
210
206
|
// Re-queue failed records
|
|
@@ -221,7 +217,7 @@ class OpenOrdersStore {
|
|
|
221
217
|
try {
|
|
222
218
|
await this.flush()
|
|
223
219
|
} catch (err) {
|
|
224
|
-
console.error('
|
|
220
|
+
console.error('AllOrdersStore final flush error:', err.message)
|
|
225
221
|
}
|
|
226
222
|
}
|
|
227
223
|
if (this.pool) {
|
|
@@ -231,4 +227,4 @@ class OpenOrdersStore {
|
|
|
231
227
|
}
|
|
232
228
|
}
|
|
233
229
|
|
|
234
|
-
module.exports =
|
|
230
|
+
module.exports = AllOrdersStore
|
package/middleware/orders.js
CHANGED
|
@@ -7,7 +7,7 @@ const utils = require('@icgio/icg-utils').utils
|
|
|
7
7
|
const { coinmarketcap: get_coinmarketcap_rates, observable: Observable } = require('@icgio/icg-utils')
|
|
8
8
|
|
|
9
9
|
const Account = require('./account.js')
|
|
10
|
-
const
|
|
10
|
+
const AllOrdersStore = require('../lib/order-status-store.js')
|
|
11
11
|
|
|
12
12
|
// Default precision functions - will be overridden if provided in settings
|
|
13
13
|
let round_price = (exchange, pair, price) => price
|
|
@@ -125,8 +125,8 @@ module.exports = class Orders {
|
|
|
125
125
|
this.accounting_benchmark = settings.accounting_benchmark
|
|
126
126
|
this.balance_benchmark = settings.balance_benchmark || {}
|
|
127
127
|
this.min_reserve_balance = settings.min_reserve_balance || {}
|
|
128
|
-
// Initialize
|
|
129
|
-
this.
|
|
128
|
+
// Initialize all orders store for PostgreSQL persistence (async, non-blocking)
|
|
129
|
+
this.all_orders_store = new AllOrdersStore(cd.all_orders_store_connection_string)
|
|
130
130
|
for (let exchange in exchange_pairs) {
|
|
131
131
|
let api_key_temp = cd[exchange]['api_keys'] || cd[exchange]['api_key'],
|
|
132
132
|
secret_key_temp = cd[exchange]['secret_keys'] || cd[exchange]['secret_key'],
|
|
@@ -758,14 +758,14 @@ module.exports = class Orders {
|
|
|
758
758
|
// end: log every f-filled trade for future analysis
|
|
759
759
|
// Store order status to PostgreSQL asynchronously (non-blocking)
|
|
760
760
|
const order_data = _.get(this.order_info, [exchange, pair, type, order_id], {})
|
|
761
|
-
this.
|
|
761
|
+
this.all_orders_store.store(exchange, pair, type, order_id, order_data, note)
|
|
762
762
|
}
|
|
763
763
|
delete_order_info(exchange, pair, type, order_id, note) {
|
|
764
764
|
const order_data = _.get(this.order_info, [exchange, pair, type, order_id], {})
|
|
765
765
|
this.order_info[exchange][pair][type] = _.omit(this.order_info[exchange][pair][type], [order_id])
|
|
766
766
|
console.log('DELETE %s: %s %s %s %s', note, exchange, pair, type, order_id)
|
|
767
767
|
// Store deletion to PostgreSQL (non-blocking)
|
|
768
|
-
this.
|
|
768
|
+
this.all_orders_store.store(exchange, pair, type, order_id, { ...order_data, status: 'DELETED' }, note)
|
|
769
769
|
}
|
|
770
770
|
check_balances() {
|
|
771
771
|
let balances_handler = (exchange, res) => {
|