hedgequantx 2.6.137 → 2.6.139

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.137",
3
+ "version": "2.6.139",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -1416,11 +1416,13 @@ const launchMultiSymbolRithmic = async (service, account, contracts, config) =>
1416
1416
  : 'HQX *****';
1417
1417
  const rithmicAccountId = account.rithmicAccountId || account.accountId;
1418
1418
 
1419
- // Build symbols string for UI (with quantities)
1419
+ // Build symbols string for UI (clean names without X1 suffix, show qty only if > 1)
1420
1420
  const symbolsDisplay = contracts.map(c => {
1421
- const name = c.name || c.symbol;
1421
+ let name = c.name || c.symbol;
1422
+ // Remove X1, X2 suffix (Rithmic internal suffixes)
1423
+ name = name.replace(/X\d+$/, '');
1422
1424
  const qty = c.qty || 1;
1423
- return `${name}x${qty}`;
1425
+ return qty > 1 ? `${name}x${qty}` : name;
1424
1426
  }).join(', ');
1425
1427
 
1426
1428
  const ui = new AlgoUI({
@@ -1502,6 +1504,22 @@ const launchMultiSymbolRithmic = async (service, account, contracts, config) =>
1502
1504
  };
1503
1505
  });
1504
1506
 
1507
+ // ═══════════════════════════════════════════════════════════════════════════
1508
+ // AI SUPERVISOR INITIALIZATION (same as single-symbol)
1509
+ // ═══════════════════════════════════════════════════════════════════════════
1510
+ let aiAgentCount = 0;
1511
+ if (enableAI) {
1512
+ const aiAgents = aiService.getAgents();
1513
+ aiAgentCount = aiAgents.length;
1514
+ stats.agentCount = aiAgentCount;
1515
+ if (aiAgents.length > 0) {
1516
+ // Use first symbol's strategy for AI supervisor
1517
+ const firstContract = contracts[0];
1518
+ const firstSymbolName = firstContract.name || firstContract.symbol;
1519
+ // Strategy will be created below, so we init supervisor after strategies
1520
+ }
1521
+ }
1522
+
1505
1523
  // ═══════════════════════════════════════════════════════════════════════════
1506
1524
  // POSITION MANAGERS & STRATEGIES - One per symbol
1507
1525
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1675,6 +1693,22 @@ const launchMultiSymbolRithmic = async (service, account, contracts, config) =>
1675
1693
  });
1676
1694
  });
1677
1695
 
1696
+ // ═══════════════════════════════════════════════════════════════════════════
1697
+ // AI SUPERVISOR - Initialize after strategies are created
1698
+ // ═══════════════════════════════════════════════════════════════════════════
1699
+ if (enableAI && aiAgentCount > 0) {
1700
+ const aiAgents = aiService.getAgents();
1701
+ const firstSymbol = Object.keys(strategies)[0];
1702
+ const firstStrategy = strategies[firstSymbol];
1703
+ const supervisorResult = StrategySupervisor.initialize(firstStrategy, aiAgents, service, rithmicAccountId);
1704
+ stats.aiSupervision = supervisorResult.success;
1705
+ stats.aiMode = supervisorResult.mode;
1706
+
1707
+ if (stats.aiSupervision) {
1708
+ algoLogger.info(ui, 'AI SUPERVISION', `${aiAgentCount} agent(s) - ${stats.aiMode} mode - LEARNING ACTIVE`);
1709
+ }
1710
+ }
1711
+
1678
1712
  // ═══════════════════════════════════════════════════════════════════════════
1679
1713
  // MARKET DATA FEED - Single connection, multiple subscriptions
1680
1714
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1842,29 +1876,45 @@ const launchMultiSymbolRithmic = async (service, account, contracts, config) =>
1842
1876
  // ═══════════════════════════════════════════════════════════════════════════
1843
1877
  // TARGET/RISK CHECK - Stop algo when limits reached
1844
1878
  // Uses SESSION P&L (trades from this HQX session only) + Open P&L
1845
- // NOT account-wide closedPnl which includes all trades from today
1879
+ // Risk triggers if: closedPnl hits risk OR openPnl hits risk OR total hits risk
1846
1880
  // ═══════════════════════════════════════════════════════════════════════════
1847
1881
  const checkTargetRisk = () => {
1848
1882
  if (!running) return;
1849
1883
 
1850
- // Session P&L = closed trades from THIS session + current open P&L
1851
- const sessionTotalPnl = (stats.sessionPnl || 0) + (stats.openPnl || 0);
1884
+ const closedPnl = stats.closedPnl || 0; // Session closed P&L
1885
+ const openPnl = stats.openPnl || 0; // Current open P&L
1886
+ const totalPnl = closedPnl + openPnl; // Total session P&L
1852
1887
 
1853
1888
  // Daily target reached - STOP with profit
1854
- if (sessionTotalPnl >= dailyTarget) {
1889
+ if (totalPnl >= dailyTarget) {
1855
1890
  stopReason = 'target';
1856
1891
  running = false;
1857
- algoLogger.info(ui, 'TARGET REACHED', `+$${sessionTotalPnl.toFixed(2)} >= $${dailyTarget}`);
1858
- ui.addLog('success', `████ DAILY TARGET REACHED: +$${sessionTotalPnl.toFixed(2)} ████`);
1859
- emergencyStopAll(); // Close all positions
1892
+ algoLogger.info(ui, 'TARGET REACHED', `+$${totalPnl.toFixed(2)} >= $${dailyTarget}`);
1893
+ ui.addLog('success', `████ DAILY TARGET REACHED: +$${totalPnl.toFixed(2)} ████`);
1894
+ emergencyStopAll();
1895
+ return;
1860
1896
  }
1897
+
1861
1898
  // Max risk reached - STOP to protect capital
1862
- else if (sessionTotalPnl <= -maxRisk) {
1899
+ // Trigger if: closed P&L hits risk OR open P&L hits risk OR total hits risk
1900
+ if (closedPnl <= -maxRisk) {
1901
+ stopReason = 'risk';
1902
+ running = false;
1903
+ algoLogger.info(ui, 'CLOSED P&L RISK', `Closed: -$${Math.abs(closedPnl).toFixed(2)} <= -$${maxRisk}`);
1904
+ ui.addLog('error', `████ MAX RISK (CLOSED): -$${Math.abs(closedPnl).toFixed(2)} ████`);
1905
+ emergencyStopAll();
1906
+ } else if (openPnl <= -maxRisk) {
1907
+ stopReason = 'risk';
1908
+ running = false;
1909
+ algoLogger.info(ui, 'OPEN P&L RISK', `Open: -$${Math.abs(openPnl).toFixed(2)} <= -$${maxRisk}`);
1910
+ ui.addLog('error', `████ MAX RISK (OPEN): -$${Math.abs(openPnl).toFixed(2)} ████`);
1911
+ emergencyStopAll();
1912
+ } else if (totalPnl <= -maxRisk) {
1863
1913
  stopReason = 'risk';
1864
1914
  running = false;
1865
- algoLogger.info(ui, 'MAX RISK HIT', `-$${Math.abs(sessionTotalPnl).toFixed(2)} <= -$${maxRisk}`);
1866
- ui.addLog('error', `████ MAX RISK REACHED: -$${Math.abs(sessionTotalPnl).toFixed(2)} ████`);
1867
- emergencyStopAll(); // Close all positions
1915
+ algoLogger.info(ui, 'TOTAL P&L RISK', `Total: -$${Math.abs(totalPnl).toFixed(2)} <= -$${maxRisk}`);
1916
+ ui.addLog('error', `████ MAX RISK (TOTAL): -$${Math.abs(totalPnl).toFixed(2)} ████`);
1917
+ emergencyStopAll();
1868
1918
  }
1869
1919
  };
1870
1920