@icgio/icg-exchanges-wrapper 1.14.229 → 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 -42
- 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,11 +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);
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_all_orders_exchange_pair_order ON all_orders(exchange, pair, order_id);
|
|
74
76
|
`
|
|
75
77
|
|
|
76
78
|
const client = await this.pool.connect()
|
|
@@ -87,7 +89,7 @@ class OpenOrdersStore {
|
|
|
87
89
|
|
|
88
90
|
this.flush_interval = setInterval(() => {
|
|
89
91
|
this.flush().catch((err) => {
|
|
90
|
-
console.error('
|
|
92
|
+
console.error('AllOrdersStore flush error:', err.message)
|
|
91
93
|
})
|
|
92
94
|
}, this.flush_interval_ms)
|
|
93
95
|
}
|
|
@@ -121,6 +123,7 @@ class OpenOrdersStore {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
const record = {
|
|
126
|
+
id: data.id,
|
|
124
127
|
exchange,
|
|
125
128
|
pair,
|
|
126
129
|
type,
|
|
@@ -154,13 +157,14 @@ class OpenOrdersStore {
|
|
|
154
157
|
|
|
155
158
|
const batch = this.queue.splice(0, 100) // Process up to 100 at a time
|
|
156
159
|
|
|
157
|
-
const
|
|
158
|
-
INSERT INTO
|
|
159
|
-
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,
|
|
160
163
|
price, amount, f_amount, f_percentage, t_amount,
|
|
161
|
-
fees, open_time, close_time, note, updated_at
|
|
162
|
-
) 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'))
|
|
163
166
|
ON CONFLICT (exchange, pair, type, order_id) DO UPDATE SET
|
|
167
|
+
id = EXCLUDED.id,
|
|
164
168
|
order_type = EXCLUDED.order_type,
|
|
165
169
|
status = EXCLUDED.status,
|
|
166
170
|
price = EXCLUDED.price,
|
|
@@ -175,35 +179,28 @@ class OpenOrdersStore {
|
|
|
175
179
|
updated_at = (NOW() AT TIME ZONE 'UTC')
|
|
176
180
|
`
|
|
177
181
|
|
|
178
|
-
const delete_query = `
|
|
179
|
-
DELETE FROM open_orders
|
|
180
|
-
WHERE exchange = $1 AND pair = $2 AND type = $3 AND order_id = $4
|
|
181
|
-
`
|
|
182
|
-
|
|
183
182
|
const client = await this.pool.connect()
|
|
184
183
|
try {
|
|
185
184
|
for (const record of batch) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
])
|
|
206
|
-
}
|
|
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
|
+
])
|
|
207
204
|
}
|
|
208
205
|
} catch (err) {
|
|
209
206
|
// Re-queue failed records
|
|
@@ -220,7 +217,7 @@ class OpenOrdersStore {
|
|
|
220
217
|
try {
|
|
221
218
|
await this.flush()
|
|
222
219
|
} catch (err) {
|
|
223
|
-
console.error('
|
|
220
|
+
console.error('AllOrdersStore final flush error:', err.message)
|
|
224
221
|
}
|
|
225
222
|
}
|
|
226
223
|
if (this.pool) {
|
|
@@ -230,4 +227,4 @@ class OpenOrdersStore {
|
|
|
230
227
|
}
|
|
231
228
|
}
|
|
232
229
|
|
|
233
|
-
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) => {
|