hedgequantx 2.7.10 → 2.7.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.7.10",
3
+ "version": "2.7.11",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -124,39 +124,48 @@ const getOrders = async (service) => {
124
124
  * @returns {Promise<{success: boolean, dates: string[]}>}
125
125
  */
126
126
  const getOrderHistoryDates = async (service) => {
127
- if (!service.orderConn || !service.loginInfo) {
127
+ if (!service.orderConn || !service.loginInfo || service.accounts.length === 0) {
128
128
  return { success: false, dates: [] };
129
129
  }
130
130
 
131
131
  return new Promise((resolve) => {
132
132
  const dates = [];
133
133
  const timeout = setTimeout(() => {
134
+ service.orderConn.removeListener('message', handler);
134
135
  resolve({ success: true, dates });
135
136
  }, 5000);
136
137
 
137
138
  const handler = (msg) => {
138
- if (msg.templateId === 319 && msg.date) {
139
- // ResponseShowOrderHistoryDates returns dates array
140
- if (Array.isArray(msg.date)) {
141
- dates.push(...msg.date);
142
- } else {
143
- dates.push(msg.date);
139
+ if (msg.templateId === 319) {
140
+ // ResponseShowOrderHistoryDates returns dates
141
+ if (msg.date) {
142
+ if (Array.isArray(msg.date)) {
143
+ dates.push(...msg.date);
144
+ } else {
145
+ dates.push(msg.date);
146
+ }
147
+ }
148
+ if (msg.rpCode && msg.rpCode[0] === '0') {
149
+ clearTimeout(timeout);
150
+ service.orderConn.removeListener('message', handler);
151
+ resolve({ success: true, dates });
144
152
  }
145
- }
146
- if (msg.templateId === 319 && msg.rpCode && msg.rpCode[0] === '0') {
147
- clearTimeout(timeout);
148
- service.orderConn.removeListener('message', handler);
149
- resolve({ success: true, dates });
150
153
  }
151
154
  };
152
155
 
153
156
  service.orderConn.on('message', handler);
154
157
 
155
158
  try {
156
- service.orderConn.send('RequestShowOrderHistoryDates', {
157
- templateId: REQ.SHOW_ORDER_HISTORY_DATES,
158
- userMsg: ['HQX'],
159
- });
159
+ // Send for each account
160
+ for (const acc of service.accounts) {
161
+ service.orderConn.send('RequestShowOrderHistoryDates', {
162
+ templateId: REQ.SHOW_ORDER_HISTORY_DATES,
163
+ userMsg: ['HQX'],
164
+ fcmId: acc.fcmId || service.loginInfo.fcmId,
165
+ ibId: acc.ibId || service.loginInfo.ibId,
166
+ accountId: acc.accountId,
167
+ });
168
+ }
160
169
  } catch (e) {
161
170
  clearTimeout(timeout);
162
171
  service.orderConn.removeListener('message', handler);
@@ -166,7 +175,7 @@ const getOrderHistoryDates = async (service) => {
166
175
  };
167
176
 
168
177
  /**
169
- * Get order history for a specific date
178
+ * Get order history for a specific date using show_order_history_summary
170
179
  * @param {RithmicService} service - The Rithmic service instance
171
180
  * @param {string} date - Date in YYYYMMDD format
172
181
  * @returns {Promise<{success: boolean, orders: Array}>}
@@ -180,47 +189,53 @@ const getOrderHistory = async (service, date) => {
180
189
 
181
190
  return new Promise((resolve) => {
182
191
  const orders = [];
192
+ let receivedEnd = false;
193
+
183
194
  const timeout = setTimeout(() => {
184
- service.orderConn.removeListener('message', handler);
195
+ service.removeListener('exchangeNotification', handler);
185
196
  resolve({ success: true, orders });
186
197
  }, 10000);
187
198
 
188
- const handler = (msg) => {
189
- // ExchangeOrderNotification (352) contains order/fill details
190
- if (msg.templateId === 352 && msg.data) {
191
- try {
192
- const notification = service.orderConn.proto.decode('ExchangeOrderNotification', msg.data);
193
- if (notification && notification.symbol) {
194
- orders.push({
195
- id: notification.fillId || notification.basketId || `${Date.now()}`,
196
- accountId: notification.accountId,
197
- symbol: notification.symbol,
198
- exchange: notification.exchange || 'CME',
199
- side: notification.transactionType, // 1=BUY, 2=SELL
200
- quantity: notification.quantity,
201
- price: notification.price,
202
- fillPrice: notification.fillPrice,
203
- fillSize: notification.fillSize,
204
- fillTime: notification.fillTime,
205
- fillDate: notification.fillDate,
206
- avgFillPrice: notification.avgFillPrice,
207
- totalFillSize: notification.totalFillSize,
208
- status: notification.status,
209
- notifyType: notification.notifyType,
210
- isSnapshot: notification.isSnapshot,
211
- });
212
- }
213
- } catch (e) {
214
- // Ignore decode errors
215
- }
199
+ const handler = (notification) => {
200
+ // ExchangeOrderNotification with isSnapshot=true contains history
201
+ if (notification && notification.symbol) {
202
+ orders.push({
203
+ id: notification.fillId || notification.basketId || `${Date.now()}`,
204
+ accountId: notification.accountId,
205
+ symbol: notification.symbol,
206
+ exchange: notification.exchange || 'CME',
207
+ side: notification.transactionType, // 1=BUY, 2=SELL
208
+ quantity: parseInt(notification.quantity) || 0,
209
+ price: parseFloat(notification.price) || 0,
210
+ fillPrice: parseFloat(notification.fillPrice) || 0,
211
+ fillSize: parseInt(notification.fillSize) || 0,
212
+ fillTime: notification.fillTime,
213
+ fillDate: notification.fillDate,
214
+ avgFillPrice: parseFloat(notification.avgFillPrice) || 0,
215
+ totalFillSize: parseInt(notification.totalFillSize) || 0,
216
+ status: notification.status,
217
+ notifyType: notification.notifyType,
218
+ isSnapshot: notification.isSnapshot,
219
+ profitAndLoss: 0, // Will be calculated from fills
220
+ pnl: 0,
221
+ });
222
+ }
223
+
224
+ // Check for end of snapshot (rpCode = '0')
225
+ if (notification && notification.rpCode && notification.rpCode[0] === '0') {
226
+ receivedEnd = true;
227
+ clearTimeout(timeout);
228
+ service.removeListener('exchangeNotification', handler);
229
+ resolve({ success: true, orders });
216
230
  }
217
231
  };
218
232
 
219
- service.orderConn.on('message', handler);
233
+ service.on('exchangeNotification', handler);
220
234
 
221
235
  try {
236
+ // Use template 324 (RequestShowOrderHistorySummary)
222
237
  for (const acc of service.accounts) {
223
- service.orderConn.send('RequestShowOrderHistory', {
238
+ service.orderConn.send('RequestShowOrderHistorySummary', {
224
239
  templateId: REQ.SHOW_ORDER_HISTORY,
225
240
  userMsg: ['HQX'],
226
241
  fcmId: acc.fcmId || service.loginInfo.fcmId,
@@ -232,13 +247,15 @@ const getOrderHistory = async (service, date) => {
232
247
 
233
248
  // Wait for responses
234
249
  setTimeout(() => {
235
- clearTimeout(timeout);
236
- service.orderConn.removeListener('message', handler);
237
- resolve({ success: true, orders });
250
+ if (!receivedEnd) {
251
+ clearTimeout(timeout);
252
+ service.removeListener('exchangeNotification', handler);
253
+ resolve({ success: true, orders });
254
+ }
238
255
  }, 5000);
239
256
  } catch (e) {
240
257
  clearTimeout(timeout);
241
- service.orderConn.removeListener('message', handler);
258
+ service.removeListener('exchangeNotification', handler);
242
259
  resolve({ success: false, error: e.message, orders: [] });
243
260
  }
244
261
  });