@icgio/icg-exchanges-wrapper 1.14.230 → 1.14.232

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.
@@ -1,10 +1,10 @@
1
1
  const { Pool } = require('pg')
2
2
 
3
3
  /**
4
- * Async PostgreSQL store for open orders
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 OpenOrdersStore {
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('OpenOrdersStore pool error:', err.message)
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('OpenOrdersStore initialized successfully')
44
+ console.log('AllOrdersStore initialized successfully')
45
45
  } catch (err) {
46
- console.error('OpenOrdersStore init failed:', err.message)
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
- CREATE TABLE IF NOT EXISTS open_orders (
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 idx_open_orders_status ON open_orders(status);
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()
@@ -83,12 +84,27 @@ class OpenOrdersStore {
83
84
  }
84
85
  }
85
86
 
87
+ /**
88
+ * Remove all rows for a specific exchange/pair (fresh start).
89
+ * @param {string} exchange
90
+ * @param {string} pair
91
+ */
92
+ async clear_orders(exchange, pair) {
93
+ if (!this.enabled || !this.table_ready) return
94
+ const client = await this.pool.connect()
95
+ try {
96
+ await client.query('DELETE FROM all_orders WHERE exchange = $1 AND pair = $2', [exchange, pair])
97
+ } finally {
98
+ client.release()
99
+ }
100
+ }
101
+
86
102
  start_flush_interval() {
87
103
  if (this.flush_interval) return
88
104
 
89
105
  this.flush_interval = setInterval(() => {
90
106
  this.flush().catch((err) => {
91
- console.error('OpenOrdersStore flush error:', err.message)
107
+ console.error('AllOrdersStore flush error:', err.message)
92
108
  })
93
109
  }, this.flush_interval_ms)
94
110
  }
@@ -122,6 +138,7 @@ class OpenOrdersStore {
122
138
  }
123
139
 
124
140
  const record = {
141
+ id: data.id,
125
142
  exchange,
126
143
  pair,
127
144
  type,
@@ -155,13 +172,14 @@ class OpenOrdersStore {
155
172
 
156
173
  const batch = this.queue.splice(0, 100) // Process up to 100 at a time
157
174
 
158
- const upsert_query = `
159
- INSERT INTO open_orders (
160
- exchange, pair, type, order_id, order_type, status,
175
+ const upsert_all_orders_query = `
176
+ INSERT INTO all_orders (
177
+ id, exchange, pair, type, order_id, order_type, status,
161
178
  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'))
179
+ fees, open_time, close_time, note, created_at, updated_at
180
+ ) 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
181
  ON CONFLICT (exchange, pair, type, order_id) DO UPDATE SET
182
+ id = EXCLUDED.id,
165
183
  order_type = EXCLUDED.order_type,
166
184
  status = EXCLUDED.status,
167
185
  price = EXCLUDED.price,
@@ -176,8 +194,8 @@ class OpenOrdersStore {
176
194
  updated_at = (NOW() AT TIME ZONE 'UTC')
177
195
  `
178
196
 
179
- const delete_query = `
180
- DELETE FROM open_orders
197
+ const delete_all_orders_query = `
198
+ DELETE FROM all_orders
181
199
  WHERE exchange = $1 AND pair = $2 AND type = $3 AND order_id = $4
182
200
  `
183
201
 
@@ -185,9 +203,12 @@ class OpenOrdersStore {
185
203
  try {
186
204
  for (const record of batch) {
187
205
  if (record.status === 'DELETED') {
188
- await client.query(delete_query, [record.exchange, record.pair, record.type, record.order_id])
206
+ // Physically delete rows for deleted orders to limit DB size
207
+ await client.query(delete_all_orders_query, [record.exchange, record.pair, record.type, record.order_id])
189
208
  } else {
190
- await client.query(upsert_query, [
209
+ // Upsert active / updated orders
210
+ await client.query(upsert_all_orders_query, [
211
+ record.id,
191
212
  record.exchange,
192
213
  record.pair,
193
214
  record.type,
@@ -221,7 +242,7 @@ class OpenOrdersStore {
221
242
  try {
222
243
  await this.flush()
223
244
  } catch (err) {
224
- console.error('OpenOrdersStore final flush error:', err.message)
245
+ console.error('AllOrdersStore final flush error:', err.message)
225
246
  }
226
247
  }
227
248
  if (this.pool) {
@@ -231,4 +252,4 @@ class OpenOrdersStore {
231
252
  }
232
253
  }
233
254
 
234
- module.exports = OpenOrdersStore
255
+ module.exports = AllOrdersStore
@@ -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 OpenOrdersStore = require('../lib/order-status-store.js')
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 order status store for PostgreSQL persistence (async, non-blocking)
129
- this.order_status_store = new OpenOrdersStore(cd.order_status_store_connection_string)
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.order_status_store.store(exchange, pair, type, order_id, order_data, note)
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.order_status_store.store(exchange, pair, type, order_id, { ...order_data, status: 'DELETED' }, note)
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) => {
@@ -886,6 +886,8 @@ module.exports = class Orders {
886
886
  }
887
887
  // cancel previous orders
888
888
  else if (this.cancel_previous_orders && !this.previous_orders_canceled) {
889
+ // remove all previous orders for this exchange/pair from all_orders (fire-and-forget)
890
+ this.all_orders_store.clear_orders(exchange, pair).catch((err) => console.error('clear_all_orders error', exchange, pair, err.message))
889
891
  if (this.cancel_previous_orders_with_delay) {
890
892
  setTimeout(() => {
891
893
  orders.map((order) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icgio/icg-exchanges-wrapper",
3
- "version": "1.14.230",
3
+ "version": "1.14.232",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {