hedgequantx 2.6.46 → 2.6.48

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.6.46",
3
+ "version": "2.6.48",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -438,11 +438,13 @@ const launchAlgo = async (service, account, contract, config) => {
438
438
  // pos.openPnl comes from INSTRUMENT_PNL_UPDATE (450) - this is the unrealized P&L
439
439
  if (pos.openPnl !== undefined && pos.openPnl !== null) {
440
440
  stats.openPnl = pos.openPnl;
441
- }
442
- // Update day P&L if available
443
- if (pos.dayPnl !== undefined && pos.dayPnl !== null) {
441
+ // Recalculate total P&L whenever Open P&L changes
444
442
  // Total P&L = openPnl + closedPnl (same formula as R Trader)
445
443
  stats.pnl = (stats.openPnl || 0) + (stats.closedPnl || 0);
444
+ // Also update Net Liquidation (balance + openPnl)
445
+ if (stats.balance !== null) {
446
+ stats.netLiquidation = stats.balance + stats.openPnl;
447
+ }
446
448
  }
447
449
  });
448
450
 
@@ -359,6 +359,8 @@ const handleAccountPnLUpdate = (service, data) => {
359
359
 
360
360
  /**
361
361
  * Handle instrument PnL update (positions)
362
+ * INSTRUMENT_PNL_UPDATE (450) - Real-time position and P&L per instrument
363
+ * This is the PRIMARY source for unrealized P&L (same as R Trader Positions panel)
362
364
  */
363
365
  const handleInstrumentPnLUpdate = (service, data) => {
364
366
  try {
@@ -367,26 +369,33 @@ const handleInstrumentPnLUpdate = (service, data) => {
367
369
  const key = `${pos.accountId}:${pos.symbol}:${pos.exchange}`;
368
370
  const netQty = pos.netQuantity || pos.openPositionQuantity || ((pos.buyQty || 0) - (pos.sellQty || 0));
369
371
 
372
+ // Build position data - ALWAYS emit, even when FLAT (netQty === 0)
373
+ // This ensures Open P&L resets to 0 when position closes (like R Trader)
374
+ const positionData = {
375
+ accountId: pos.accountId,
376
+ symbol: pos.symbol,
377
+ exchange: pos.exchange || 'CME',
378
+ quantity: netQty,
379
+ averagePrice: netQty !== 0 ? (pos.avgOpenFillPrice || 0) : 0,
380
+ // Open P&L from API - this is the real-time unrealized P&L (same as R Trader)
381
+ openPnl: parseFloat(pos.openPositionPnl || pos.dayOpenPnl || 0),
382
+ closedPnl: parseFloat(pos.closedPositionPnl || pos.dayClosedPnl || 0),
383
+ dayPnl: parseFloat(pos.dayPnl || 0),
384
+ isSnapshot: pos.isSnapshot || false,
385
+ };
386
+
370
387
  if (netQty !== 0) {
371
- service.positions.set(key, {
372
- accountId: pos.accountId,
373
- symbol: pos.symbol,
374
- exchange: pos.exchange || 'CME',
375
- quantity: netQty,
376
- averagePrice: pos.avgOpenFillPrice || 0,
377
- openPnl: parseFloat(pos.openPositionPnl || pos.dayOpenPnl || 0),
378
- closedPnl: parseFloat(pos.closedPositionPnl || pos.dayClosedPnl || 0),
379
- dayPnl: parseFloat(pos.dayPnl || 0),
380
- isSnapshot: pos.isSnapshot || false,
381
- });
388
+ service.positions.set(key, positionData);
382
389
  } else {
383
390
  service.positions.delete(key);
384
391
  }
385
392
 
386
- service.emit('positionUpdate', service.positions.get(key));
393
+ // ALWAYS emit positionUpdate - even when FLAT
394
+ // This ensures UI updates Open P&L to 0 when position closes
395
+ service.emit('positionUpdate', positionData);
387
396
  }
388
397
  } catch (e) {
389
- // Ignore decode errors
398
+ debug('Error decoding Instrument PNL:', e.message);
390
399
  }
391
400
  };
392
401
 
@@ -17,6 +17,10 @@ const { proto } = require('./protobuf');
17
17
  const { LatencyTracker } = require('./handlers');
18
18
  const { performance } = require('perf_hooks');
19
19
 
20
+ // Debug mode - use no-op function when disabled for zero overhead
21
+ const DEBUG = process.env.HQX_DEBUG === '1';
22
+ const debug = DEBUG ? (...args) => console.log('[Rithmic:Orders]', ...args) : () => {};
23
+
20
24
  // ==================== FAST ORDER TAG ====================
21
25
  // Pre-generate prefix once at module load (not per-order)
22
26
  const ORDER_TAG_PREFIX = `HQX${process.pid}-`;