hedgequantx 2.6.33 → 2.6.35
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
|
@@ -117,11 +117,14 @@ class RithmicConnection extends EventEmitter {
|
|
|
117
117
|
* Fast send - bypasses some ws overhead for hot path
|
|
118
118
|
* Use for time-critical order messages
|
|
119
119
|
* @param {Buffer} buffer - Pre-encoded protobuf buffer
|
|
120
|
+
* @returns {boolean} true if sent, false if connection not open
|
|
120
121
|
*/
|
|
121
122
|
fastSend(buffer) {
|
|
122
123
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
123
124
|
this.ws.send(buffer);
|
|
125
|
+
return true;
|
|
124
126
|
}
|
|
127
|
+
return false;
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
/**
|
|
@@ -523,6 +523,8 @@ const handleOrderNotification = (service, data) => {
|
|
|
523
523
|
|
|
524
524
|
// Emit fill event if this is a fill
|
|
525
525
|
if (isFill) {
|
|
526
|
+
console.log(`[FILL] Received: ${orderTag} | ${fillInfo.transactionType === 1 ? 'BUY' : 'SELL'} ${fillQty}x @ ${fillInfo.avgFillPrice} | latency=${roundTripLatency}ms`);
|
|
527
|
+
|
|
526
528
|
debug('ORDER FILLED:', {
|
|
527
529
|
orderTag,
|
|
528
530
|
side: fillInfo.transactionType === 1 ? 'BUY' : 'SELL',
|
|
@@ -533,6 +535,8 @@ const handleOrderNotification = (service, data) => {
|
|
|
533
535
|
|
|
534
536
|
// Clone for fill event (async handlers may need to keep the data)
|
|
535
537
|
service.emit('orderFilled', FillInfoPool.clone(fillInfo));
|
|
538
|
+
} else {
|
|
539
|
+
console.log(`[ORDER STATUS] ${orderTag} | status=${fillInfo.status} text=${fillInfo.text || 'N/A'}`);
|
|
536
540
|
}
|
|
537
541
|
} catch (e) {
|
|
538
542
|
debug('Error decoding order notification:', e.message);
|
|
@@ -48,7 +48,7 @@ const OrderPool = {
|
|
|
48
48
|
quantity: 0,
|
|
49
49
|
transactionType: 1,
|
|
50
50
|
duration: 1,
|
|
51
|
-
orderType: 1
|
|
51
|
+
priceType: 2, // FIXED: was 'orderType: 1' - priceType 2 = MARKET order
|
|
52
52
|
manualOrAuto: 2,
|
|
53
53
|
},
|
|
54
54
|
|
|
@@ -102,8 +102,20 @@ const fastEntry = (service, orderData) => {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
try {
|
|
105
|
+
// FIXED: Use account-specific fcmId/ibId if available (some prop firms have different IDs per account)
|
|
106
|
+
const account = service.accounts?.find(a =>
|
|
107
|
+
a.accountId === orderData.accountId || a.rithmicAccountId === orderData.accountId
|
|
108
|
+
);
|
|
109
|
+
const effectiveLoginInfo = {
|
|
110
|
+
fcmId: account?.fcmId || service.loginInfo.fcmId,
|
|
111
|
+
ibId: account?.ibId || service.loginInfo.ibId,
|
|
112
|
+
};
|
|
113
|
+
|
|
105
114
|
// OPTIMIZED: Use pre-allocated order object
|
|
106
|
-
const order = OrderPool.fill(orderTag,
|
|
115
|
+
const order = OrderPool.fill(orderTag, effectiveLoginInfo, orderData);
|
|
116
|
+
|
|
117
|
+
// DEBUG: Log order details
|
|
118
|
+
console.log(`[ORDER] Sending: ${orderTag} | ${orderData.side === 0 ? 'BUY' : 'SELL'} ${orderData.size}x ${orderData.symbol} | acct=${orderData.accountId} | fcm=${effectiveLoginInfo.fcmId} ib=${effectiveLoginInfo.ibId}`);
|
|
107
119
|
|
|
108
120
|
// OPTIMIZED: Use fastEncode with cached type
|
|
109
121
|
const buffer = proto.fastEncode('RequestNewOrder', order);
|
|
@@ -117,6 +129,8 @@ const fastEntry = (service, orderData) => {
|
|
|
117
129
|
service.orderConn.fastSend(buffer);
|
|
118
130
|
}
|
|
119
131
|
|
|
132
|
+
console.log(`[ORDER] Sent to Rithmic: ${orderTag} | buffer=${buffer.length} bytes`);
|
|
133
|
+
|
|
120
134
|
// Track for round-trip latency measurement
|
|
121
135
|
LatencyTracker.recordEntry(orderTag, entryTime);
|
|
122
136
|
|
|
@@ -162,8 +176,17 @@ const fastExit = (service, orderData) => {
|
|
|
162
176
|
}
|
|
163
177
|
|
|
164
178
|
try {
|
|
179
|
+
// FIXED: Use account-specific fcmId/ibId if available
|
|
180
|
+
const account = service.accounts?.find(a =>
|
|
181
|
+
a.accountId === orderData.accountId || a.rithmicAccountId === orderData.accountId
|
|
182
|
+
);
|
|
183
|
+
const effectiveLoginInfo = {
|
|
184
|
+
fcmId: account?.fcmId || service.loginInfo.fcmId,
|
|
185
|
+
ibId: account?.ibId || service.loginInfo.ibId,
|
|
186
|
+
};
|
|
187
|
+
|
|
165
188
|
// OPTIMIZED: Use pre-allocated order object
|
|
166
|
-
const order = OrderPool.fill(orderTag,
|
|
189
|
+
const order = OrderPool.fill(orderTag, effectiveLoginInfo, orderData);
|
|
167
190
|
|
|
168
191
|
// OPTIMIZED: Use fastEncode with cached type
|
|
169
192
|
const buffer = proto.fastEncode('RequestNewOrder', order);
|
|
@@ -205,18 +228,23 @@ const placeOrder = async (service, orderData) => {
|
|
|
205
228
|
}
|
|
206
229
|
|
|
207
230
|
try {
|
|
231
|
+
// FIXED: Use account-specific fcmId/ibId if available
|
|
232
|
+
const account = service.accounts?.find(a =>
|
|
233
|
+
a.accountId === orderData.accountId || a.rithmicAccountId === orderData.accountId
|
|
234
|
+
);
|
|
235
|
+
|
|
208
236
|
service.orderConn.send('RequestNewOrder', {
|
|
209
237
|
templateId: REQ.NEW_ORDER,
|
|
210
238
|
userMsg: ['HQX'],
|
|
211
|
-
fcmId: service.loginInfo.fcmId,
|
|
212
|
-
ibId: service.loginInfo.ibId,
|
|
239
|
+
fcmId: account?.fcmId || service.loginInfo.fcmId,
|
|
240
|
+
ibId: account?.ibId || service.loginInfo.ibId,
|
|
213
241
|
accountId: orderData.accountId,
|
|
214
242
|
symbol: orderData.symbol,
|
|
215
243
|
exchange: orderData.exchange || 'CME',
|
|
216
244
|
quantity: orderData.size,
|
|
217
245
|
transactionType: orderData.side === 0 ? 1 : 2, // 1=Buy, 2=Sell
|
|
218
246
|
duration: 1, // DAY
|
|
219
|
-
|
|
247
|
+
priceType: orderData.type === 2 ? 2 : 1, // FIXED: was 'orderType' with inverted logic. priceType: 1=Limit, 2=Market
|
|
220
248
|
price: orderData.price || 0,
|
|
221
249
|
});
|
|
222
250
|
|