hedgequantx 2.9.186 → 2.9.187
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
|
@@ -213,44 +213,18 @@ const fetchAllFrontMonths = (service) => {
|
|
|
213
213
|
throw new Error('TICKER_PLANT not connected');
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
const tickerState = service.tickerConn.connectionState;
|
|
217
|
-
const tickerConnected = service.tickerConn.isConnected;
|
|
218
|
-
|
|
219
|
-
// Direct console.log for daemon broker.log (always visible)
|
|
220
|
-
const brokerLog = (msg, data) => console.log(`[CONTRACTS] ${msg}`, JSON.stringify(data));
|
|
221
|
-
|
|
222
|
-
brokerLog('fetchAllFrontMonths starting', { tickerState, tickerConnected });
|
|
223
|
-
|
|
224
216
|
return new Promise((resolve) => {
|
|
225
217
|
const contracts = new Map();
|
|
226
218
|
const productsToCheck = new Map();
|
|
227
|
-
let msgCount = 0;
|
|
228
|
-
let productMsgCount = 0;
|
|
229
219
|
|
|
230
220
|
// Handler for ProductCodes responses
|
|
231
|
-
const sampleProducts = [];
|
|
232
|
-
let decodeErrors = 0;
|
|
233
|
-
let firstError = null;
|
|
234
221
|
const productHandler = (msg) => {
|
|
235
|
-
msgCount++;
|
|
236
222
|
if (msg.templateId !== 112) return;
|
|
237
|
-
productMsgCount++;
|
|
238
223
|
|
|
239
|
-
// Use official protobuf decoder instead of manual parsing
|
|
240
224
|
let decoded;
|
|
241
225
|
try {
|
|
242
226
|
decoded = proto.decode('ResponseProductCodes', msg.data);
|
|
243
227
|
} catch (e) {
|
|
244
|
-
decodeErrors++;
|
|
245
|
-
if (!firstError) {
|
|
246
|
-
firstError = e.message;
|
|
247
|
-
// Log raw buffer info for debugging
|
|
248
|
-
brokerLog('First decode error', {
|
|
249
|
-
error: e.message,
|
|
250
|
-
bufferLen: msg.data?.length,
|
|
251
|
-
first20bytes: msg.data?.slice(0, 20)?.toString('hex')
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
228
|
return;
|
|
255
229
|
}
|
|
256
230
|
|
|
@@ -258,17 +232,6 @@ const fetchAllFrontMonths = (service) => {
|
|
|
258
232
|
const exchange = decoded.exchange;
|
|
259
233
|
const productName = decoded.productName;
|
|
260
234
|
|
|
261
|
-
// Log first 5 raw decoded messages to see field names
|
|
262
|
-
if (sampleProducts.length < 5) {
|
|
263
|
-
const keys = Object.keys(decoded.toJSON ? decoded.toJSON() : decoded);
|
|
264
|
-
sampleProducts.push({
|
|
265
|
-
code: productCode || 'NONE',
|
|
266
|
-
exchange: exchange || 'NONE',
|
|
267
|
-
name: productName?.substring(0, 30) || 'NONE',
|
|
268
|
-
fields: keys.slice(0, 10)
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
235
|
if (!productCode || !exchange) return;
|
|
273
236
|
|
|
274
237
|
const validExchanges = ['CME', 'CBOT', 'NYMEX', 'COMEX', 'NYBOT', 'CFE'];
|
|
@@ -288,46 +251,16 @@ const fetchAllFrontMonths = (service) => {
|
|
|
288
251
|
};
|
|
289
252
|
|
|
290
253
|
// Handler for FrontMonth responses
|
|
291
|
-
let frontMonthMsgCount = 0;
|
|
292
|
-
let template114Count = 0;
|
|
293
|
-
const templateIdsSeen = new Map();
|
|
294
|
-
const rawResponses = [];
|
|
295
254
|
const frontMonthHandler = (msg) => {
|
|
296
|
-
msgCount++;
|
|
297
|
-
frontMonthMsgCount++;
|
|
298
|
-
|
|
299
|
-
// Track all templateIds seen
|
|
300
|
-
const tid = msg.templateId;
|
|
301
|
-
templateIdsSeen.set(tid, (templateIdsSeen.get(tid) || 0) + 1);
|
|
302
|
-
|
|
303
|
-
// Log first few non-112 messages to see what we're getting
|
|
304
|
-
if (tid !== 112 && rawResponses.length < 5) {
|
|
305
|
-
rawResponses.push({ templateId: tid, dataLen: msg.data?.length });
|
|
306
|
-
}
|
|
307
|
-
|
|
308
255
|
if (msg.templateId !== 114) return;
|
|
309
|
-
template114Count++;
|
|
310
256
|
|
|
311
|
-
// Use official protobuf decoder
|
|
312
257
|
let decoded;
|
|
313
258
|
try {
|
|
314
259
|
decoded = proto.decode('ResponseFrontMonthContract', msg.data);
|
|
315
260
|
} catch (e) {
|
|
316
|
-
brokerLog('FrontMonth decode error', { error: e.message });
|
|
317
261
|
return;
|
|
318
262
|
}
|
|
319
263
|
|
|
320
|
-
// Log first few responses to diagnose
|
|
321
|
-
if (template114Count <= 5) {
|
|
322
|
-
brokerLog('FrontMonth response', {
|
|
323
|
-
template114Count,
|
|
324
|
-
rpCode: decoded.rpCode,
|
|
325
|
-
tradingSymbol: decoded.tradingSymbol,
|
|
326
|
-
userMsg: decoded.userMsg,
|
|
327
|
-
exchange: decoded.exchange
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
264
|
if (decoded.rpCode && decoded.rpCode[0] === '0' && decoded.tradingSymbol) {
|
|
332
265
|
const baseSymbol = decoded.userMsg?.[0] || decoded.symbol;
|
|
333
266
|
contracts.set(baseSymbol, {
|
|
@@ -342,77 +275,46 @@ const fetchAllFrontMonths = (service) => {
|
|
|
342
275
|
service.tickerConn.on('message', frontMonthHandler);
|
|
343
276
|
|
|
344
277
|
// Request all product codes
|
|
345
|
-
brokerLog('Sending RequestProductCodes', { templateId: 111 });
|
|
346
278
|
try {
|
|
347
279
|
service.tickerConn.send('RequestProductCodes', {
|
|
348
280
|
templateId: 111,
|
|
349
281
|
userMsg: ['get-products'],
|
|
350
282
|
});
|
|
351
|
-
brokerLog('RequestProductCodes sent OK', {});
|
|
352
283
|
} catch (err) {
|
|
353
|
-
|
|
284
|
+
log.warn('Failed to send RequestProductCodes', { error: err.message });
|
|
354
285
|
}
|
|
355
286
|
|
|
356
287
|
// After timeout, request front months
|
|
357
288
|
setTimeout(() => {
|
|
358
289
|
service.tickerConn.removeListener('message', productHandler);
|
|
359
|
-
brokerLog('ProductCodes phase complete', {
|
|
360
|
-
productsFound: productsToCheck.size,
|
|
361
|
-
totalMsgs: msgCount,
|
|
362
|
-
productMsgs: productMsgCount,
|
|
363
|
-
decodeErrors: decodeErrors,
|
|
364
|
-
firstError: firstError,
|
|
365
|
-
sampleProducts: sampleProducts
|
|
366
|
-
});
|
|
367
290
|
|
|
368
|
-
|
|
369
|
-
brokerLog('WARNING: No products collected - TICKER may not be responding', {});
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
let sentCount = 0;
|
|
373
|
-
let sendErrors = [];
|
|
374
|
-
|
|
375
|
-
// Prioritize CME products (ES, NQ, MNQ, MES, etc.) - most used by traders
|
|
291
|
+
// Prioritize CME products (ES, NQ, MNQ, MES, etc.)
|
|
376
292
|
const productsArray = Array.from(productsToCheck.values());
|
|
377
293
|
const prioritySymbols = ['ES', 'NQ', 'MNQ', 'MES', 'RTY', 'M2K', 'YM', 'MYM', 'CL', 'MCL', 'GC', 'MGC', 'SI', 'HG', 'NG', 'ZB', 'ZN', 'ZF', 'ZT', '6E', '6J', '6B', '6A', '6C', '6S', 'ZC', 'ZS', 'ZW', 'ZM', 'ZL', 'HE', 'LE', 'GF'];
|
|
378
294
|
|
|
379
|
-
// Sort: priority symbols first (CME), then others
|
|
380
295
|
productsArray.sort((a, b) => {
|
|
381
296
|
const aPriority = prioritySymbols.includes(a.productCode) ? 0 : 1;
|
|
382
297
|
const bPriority = prioritySymbols.includes(b.productCode) ? 0 : 1;
|
|
383
298
|
if (aPriority !== bPriority) return aPriority - bPriority;
|
|
384
|
-
// Within same priority, prefer CME/CBOT
|
|
385
299
|
const aExchange = (a.exchange === 'CME' || a.exchange === 'CBOT') ? 0 : 1;
|
|
386
300
|
const bExchange = (b.exchange === 'CME' || b.exchange === 'CBOT') ? 0 : 1;
|
|
387
301
|
return aExchange - bExchange;
|
|
388
302
|
});
|
|
389
303
|
|
|
390
|
-
const testProducts = productsArray.slice(0, 60);
|
|
304
|
+
const testProducts = productsArray.slice(0, 60);
|
|
391
305
|
|
|
392
306
|
for (const product of testProducts) {
|
|
393
307
|
try {
|
|
394
|
-
|
|
308
|
+
service.tickerConn.send('RequestFrontMonthContract', {
|
|
395
309
|
templateId: 113,
|
|
396
310
|
userMsg: [product.productCode],
|
|
397
311
|
symbol: product.productCode,
|
|
398
312
|
exchange: product.exchange,
|
|
399
|
-
};
|
|
400
|
-
// Log first request
|
|
401
|
-
if (sentCount === 0) {
|
|
402
|
-
brokerLog('First RequestFrontMonthContract', reqData);
|
|
403
|
-
}
|
|
404
|
-
service.tickerConn.send('RequestFrontMonthContract', reqData);
|
|
405
|
-
sentCount++;
|
|
313
|
+
});
|
|
406
314
|
} catch (err) {
|
|
407
|
-
|
|
315
|
+
// Ignore send errors
|
|
408
316
|
}
|
|
409
317
|
}
|
|
410
|
-
brokerLog('RequestFrontMonthContract sent', {
|
|
411
|
-
sentCount,
|
|
412
|
-
totalProducts: productsToCheck.size,
|
|
413
|
-
limitedTo: testProducts.length,
|
|
414
|
-
errors: sendErrors.length > 0 ? sendErrors.slice(0, 3) : 'none'
|
|
415
|
-
});
|
|
416
318
|
|
|
417
319
|
// Collect results after timeout
|
|
418
320
|
setTimeout(() => {
|
|
@@ -422,10 +324,8 @@ const fetchAllFrontMonths = (service) => {
|
|
|
422
324
|
for (const [baseSymbol, contract] of contracts) {
|
|
423
325
|
const productKey = `${baseSymbol}:${contract.exchange}`;
|
|
424
326
|
const product = productsToCheck.get(productKey);
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const apiName = product?.productName || baseSymbol;
|
|
428
|
-
const displayName = getContractDescription(baseSymbol) || apiName;
|
|
327
|
+
const displayName = getContractDescription(baseSymbol) || product?.productName || baseSymbol;
|
|
328
|
+
|
|
429
329
|
results.push({
|
|
430
330
|
symbol: contract.symbol,
|
|
431
331
|
baseSymbol,
|
|
@@ -435,22 +335,7 @@ const fetchAllFrontMonths = (service) => {
|
|
|
435
335
|
});
|
|
436
336
|
}
|
|
437
337
|
|
|
438
|
-
// Sort alphabetically by base symbol
|
|
439
338
|
results.sort((a, b) => a.baseSymbol.localeCompare(b.baseSymbol));
|
|
440
|
-
|
|
441
|
-
// Convert Map to object for logging
|
|
442
|
-
const templateStats = {};
|
|
443
|
-
for (const [tid, count] of templateIdsSeen) {
|
|
444
|
-
templateStats[`t${tid}`] = count;
|
|
445
|
-
}
|
|
446
|
-
brokerLog('FrontMonth phase complete', {
|
|
447
|
-
contractsFound: results.length,
|
|
448
|
-
totalMsgs: msgCount,
|
|
449
|
-
frontMonthMsgs: frontMonthMsgCount,
|
|
450
|
-
template114Received: template114Count,
|
|
451
|
-
templateIds: templateStats,
|
|
452
|
-
nonProductMsgs: rawResponses
|
|
453
|
-
});
|
|
454
339
|
resolve(results);
|
|
455
340
|
}, TIMEOUTS.RITHMIC_PRODUCTS);
|
|
456
341
|
}, TIMEOUTS.RITHMIC_CONTRACTS);
|