hedgequantx 2.6.51 → 2.6.53

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.51",
3
+ "version": "2.6.53",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -724,7 +724,7 @@ const launchAlgo = async (service, account, contract, config) => {
724
724
 
725
725
  stats.latency = Date.now() - latencyStart;
726
726
 
727
- // Smart logs every 1 second - non-repetitive, varied messages
727
+ // Smart logs - only on STATE CHANGES (not every second when in position)
728
728
  const now = Date.now();
729
729
  if (now - lastHeartbeat > 1000) {
730
730
  const modelValues = strategy.getModelValues?.() || strategy.getModelValues?.(contractId) || null;
@@ -735,30 +735,28 @@ const launchAlgo = async (service, account, contract, config) => {
735
735
  const zscore = modelValues.zscore || 0;
736
736
  const mom = modelValues.momentum || 0;
737
737
 
738
- // Get smart varied log based on market state
739
- const smartLogs = require('./smart-logs');
740
- const stateLog = smartLogs.getMarketStateLog(ofi, zscore, mom, delta);
738
+ // Use stats.position from Rithmic API (real-time WebSocket)
739
+ const positionQty = stats.position || 0;
741
740
 
742
- if (currentPosition !== 0) {
743
- // In position - show position status with varied messages
744
- const side = currentPosition > 0 ? 'LONG' : 'SHORT';
745
- const unrealizedPnl = stats.openPnl || 0;
746
- const holdTime = Math.floor((now - (stats.entryTime || now)) / 1000);
747
- const posLog = smartLogs.getPositionUpdateLog(side, Math.abs(currentPosition), unrealizedPnl, stats.entryPrice, tickData.price, holdTime);
748
- ui.addLog('trade', `${posLog.message} - ${posLog.details}`);
749
- } else {
750
- // Not in position - show market state with varied messages
741
+ if (positionQty === 0) {
742
+ // Not in position - show market analysis (varied messages)
743
+ const smartLogs = require('./smart-logs');
744
+ const stateLog = smartLogs.getMarketStateLog(ofi, zscore, mom, delta);
751
745
  if (stateLog.details) {
752
746
  ui.addLog('analysis', `${stateLog.message} - ${stateLog.details}`);
753
747
  } else {
754
748
  ui.addLog('info', stateLog.message);
755
749
  }
756
750
  }
751
+ // When IN POSITION: Don't spam logs every second
752
+ // Position updates come from order fills and exit events
757
753
  } else {
758
- // Waiting for data
759
- const smartLogs = require('./smart-logs');
760
- const scanLog = smartLogs.getScanningLog(true);
761
- ui.addLog('info', `${scanLog.message} ${tps} ticks/s`);
754
+ // Waiting for data - log every 5 seconds only
755
+ if (now - lastHeartbeat > 5000) {
756
+ const smartLogs = require('./smart-logs');
757
+ const scanLog = smartLogs.getScanningLog(true);
758
+ ui.addLog('info', `${scanLog.message} ${tps} ticks/s`);
759
+ }
762
760
  }
763
761
  lastHeartbeat = now;
764
762
  tps = 0;
@@ -182,21 +182,37 @@ class AlgoUI {
182
182
 
183
183
  this._line(chalk.cyan(GM));
184
184
 
185
- // Row 2: Target | Risk
185
+ // Row 2: Open P&L | Closed P&L (essential trading metrics)
186
+ const openPnl = stats.openPnl;
187
+ const closedPnl = stats.closedPnl;
188
+ const openPnlStr = openPnl === null || openPnl === undefined
189
+ ? '--'
190
+ : (openPnl >= 0 ? `+$${openPnl.toFixed(2)}` : `-$${Math.abs(openPnl).toFixed(2)}`);
191
+ const closedPnlStr = closedPnl === null || closedPnl === undefined
192
+ ? '--'
193
+ : (closedPnl >= 0 ? `+$${closedPnl.toFixed(2)}` : `-$${Math.abs(closedPnl).toFixed(2)}`);
194
+ const openPnlColor = (openPnl || 0) >= 0 ? chalk.green : chalk.red;
195
+ const closedPnlColor = (closedPnl || 0) >= 0 ? chalk.green : chalk.red;
196
+ const r2c1 = buildCell('OPEN P&L', openPnlStr, openPnlColor, colL);
197
+ const r2c2 = buildCell('CLOSED P&L', closedPnlStr, closedPnlColor, colR);
198
+ row(r2c1.padded, r2c2.padded);
199
+
200
+ this._line(chalk.cyan(GM));
201
+
202
+ // Row 3: Target | Risk
186
203
  const targetStr = stats.target !== null && stats.target !== undefined ? '$' + stats.target.toFixed(2) : '--';
187
204
  const riskStr = stats.risk !== null && stats.risk !== undefined ? '$' + stats.risk.toFixed(2) : '--';
188
- const r2c1 = buildCell('TARGET', targetStr, chalk.green, colL);
189
- const r2c2 = buildCell('RISK', riskStr, chalk.red, colR);
190
- row(r2c1.padded, r2c2.padded);
205
+ const r3c1 = buildCell('TARGET', targetStr, chalk.green, colL);
206
+ const r3c2 = buildCell('RISK', riskStr, chalk.red, colR);
207
+ row(r3c1.padded, r3c2.padded);
191
208
 
192
209
  this._line(chalk.cyan(GM));
193
210
 
194
- // Row 3: Trades W/L | Connection
195
- const r3c1t = ` ${chalk.bold('TRADES')}: ${chalk.cyan.bold(stats.trades || 0)} ${chalk.bold('W/L')}: ${chalk.green.bold(stats.wins || 0)}/${chalk.red.bold(stats.losses || 0)}`;
196
- const r3c1p = ` TRADES: ${stats.trades || 0} W/L: ${stats.wins || 0}/${stats.losses || 0}`;
197
- const connection = stats.platform || 'ProjectX';
198
- const r3c2 = buildCell('CONNECTION', connection, chalk.cyan, colR);
199
- row(r3c1t + pad(colL - r3c1p.length), r3c2.padded);
211
+ // Row 4: Trades W/L | Propfirm
212
+ const r4c1t = ` ${chalk.bold('TRADES')}: ${chalk.cyan.bold(stats.trades || 0)} ${chalk.bold('W/L')}: ${chalk.green.bold(stats.wins || 0)}/${chalk.red.bold(stats.losses || 0)}`;
213
+ const r4c1p = ` TRADES: ${stats.trades || 0} W/L: ${stats.wins || 0}/${stats.losses || 0}`;
214
+ const r4c2 = buildCell('PROPFIRM', stats.propfirm || 'N/A', chalk.cyan, colR);
215
+ row(r4c1t + pad(colL - r4c1p.length), r4c2.padded);
200
216
 
201
217
  this._line(chalk.cyan(GB));
202
218
  }