hedgequantx 2.6.50 → 2.6.52

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.50",
3
+ "version": "2.6.52",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -739,12 +739,14 @@ const launchAlgo = async (service, account, contract, config) => {
739
739
  const smartLogs = require('./smart-logs');
740
740
  const stateLog = smartLogs.getMarketStateLog(ofi, zscore, mom, delta);
741
741
 
742
- if (currentPosition !== 0) {
742
+ // Use stats.position from Rithmic API (real-time WebSocket)
743
+ const positionQty = stats.position || 0;
744
+ if (positionQty !== 0) {
743
745
  // In position - show position status with varied messages
744
- const side = currentPosition > 0 ? 'LONG' : 'SHORT';
746
+ const side = positionQty > 0 ? 'LONG' : 'SHORT';
745
747
  const unrealizedPnl = stats.openPnl || 0;
746
748
  const holdTime = Math.floor((now - (stats.entryTime || now)) / 1000);
747
- const posLog = smartLogs.getPositionUpdateLog(side, Math.abs(currentPosition), unrealizedPnl, stats.entryPrice, tickData.price, holdTime);
749
+ const posLog = smartLogs.getPositionUpdateLog(side, Math.abs(positionQty), unrealizedPnl, stats.entryPrice, tickData.price, holdTime);
748
750
  ui.addLog('trade', `${posLog.message} - ${posLog.details}`);
749
751
  } else {
750
752
  // Not in position - show market state with varied messages
@@ -102,11 +102,7 @@ class AlgoUI {
102
102
  this.config = config;
103
103
  this.W = 96; // Fixed width
104
104
  this.logs = [];
105
- // Calculate maxLogs based on terminal height
106
- // Header (logo + titles): ~12 lines, Stats: ~12 lines, Log header: 2 lines, Bottom: 1 line = 27 fixed
107
- const terminalHeight = process.stdout.rows || 50;
108
- const fixedLines = 27;
109
- this.maxLogs = Math.max(10, terminalHeight - fixedLines); // Min 10 logs
105
+ this.maxLogs = 40; // Fixed at 40 logs for one-account and copy-trading
110
106
  this.spinnerFrame = 0;
111
107
  this.firstDraw = true;
112
108
  this.isDrawing = false;
@@ -186,18 +182,7 @@ class AlgoUI {
186
182
 
187
183
  this._line(chalk.cyan(GM));
188
184
 
189
- // Row 2: Position | P&L (like R Trader)
190
- const posQty = stats.position || 0;
191
- const posStr = posQty === 0 ? 'FLAT' : (posQty > 0 ? `+${posQty} LONG` : `${posQty} SHORT`);
192
- const posColor = posQty === 0 ? chalk.gray : (posQty > 0 ? chalk.green : chalk.red);
193
- const r2c1 = buildCell('POSITION', posStr, posColor, colL);
194
- const r2c2 = buildCell('P&L', pnlStr, pnlColor, colR);
195
- row(r2c1.padded, r2c2.padded);
196
-
197
- this._line(chalk.cyan(GM));
198
-
199
- // Row 3: Open P&L | Closed P&L (R Trader style breakdown)
200
- // Data from Rithmic PNL_PLANT WebSocket - show '--' if null (no data from API)
185
+ // Row 2: Open P&L | Closed P&L (essential trading metrics)
201
186
  const openPnl = stats.openPnl;
202
187
  const closedPnl = stats.closedPnl;
203
188
  const openPnlStr = openPnl === null || openPnl === undefined
@@ -208,61 +193,26 @@ class AlgoUI {
208
193
  : (closedPnl >= 0 ? `+$${closedPnl.toFixed(2)}` : `-$${Math.abs(closedPnl).toFixed(2)}`);
209
194
  const openPnlColor = (openPnl || 0) >= 0 ? chalk.green : chalk.red;
210
195
  const closedPnlColor = (closedPnl || 0) >= 0 ? chalk.green : chalk.red;
211
- const r3c1 = buildCell('OPEN P&L', openPnlStr, openPnlColor, colL);
212
- const r3c2 = buildCell('CLOSED P&L', closedPnlStr, closedPnlColor, colR);
213
- row(r3c1.padded, r3c2.padded);
214
-
215
- this._line(chalk.cyan(GM));
216
-
217
- // Row 4: Balance | Net Liquidation (R Trader style)
218
- const balanceStr = stats.balance !== null && stats.balance !== undefined
219
- ? '$' + stats.balance.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
220
- : '--';
221
- const netLiqStr = stats.netLiquidation !== null && stats.netLiquidation !== undefined
222
- ? '$' + stats.netLiquidation.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
223
- : '--';
224
- const r4c1 = buildCell('BALANCE', balanceStr, chalk.white, colL);
225
- const r4c2 = buildCell('NET LIQ', netLiqStr, chalk.cyan, colR);
226
- row(r4c1.padded, r4c2.padded);
227
-
228
- this._line(chalk.cyan(GM));
229
-
230
- // Row 5: Buying Power | Margin (R Trader style)
231
- const bpStr = stats.buyingPower !== null && stats.buyingPower !== undefined
232
- ? '$' + stats.buyingPower.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
233
- : '--';
234
- const marginStr = stats.margin !== null && stats.margin !== undefined
235
- ? '$' + stats.margin.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
236
- : '--';
237
- const r5c1 = buildCell('BUYING PWR', bpStr, chalk.green, colL);
238
- const r5c2 = buildCell('MARGIN', marginStr, chalk.yellow, colR);
239
- row(r5c1.padded, r5c2.padded);
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);
240
199
 
241
200
  this._line(chalk.cyan(GM));
242
201
 
243
- // Row 6: Target | Risk
202
+ // Row 3: Target | Risk
244
203
  const targetStr = stats.target !== null && stats.target !== undefined ? '$' + stats.target.toFixed(2) : '--';
245
204
  const riskStr = stats.risk !== null && stats.risk !== undefined ? '$' + stats.risk.toFixed(2) : '--';
246
- const r6c1 = buildCell('TARGET', targetStr, chalk.green, colL);
247
- const r6c2 = buildCell('RISK', riskStr, chalk.red, colR);
248
- row(r6c1.padded, r6c2.padded);
249
-
250
- this._line(chalk.cyan(GM));
251
-
252
- // Row 7: Trades W/L | Entry Price (if in position)
253
- const r7c1t = ` ${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)}`;
254
- const r7c1p = ` TRADES: ${stats.trades || 0} W/L: ${stats.wins || 0}/${stats.losses || 0}`;
255
- const entryStr = stats.entryPrice > 0 ? stats.entryPrice.toFixed(2) : '--';
256
- const r7c2 = buildCell('ENTRY', entryStr, chalk.yellow, colR);
257
- row(r7c1t + pad(colL - r7c1p.length), r7c2.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);
258
208
 
259
209
  this._line(chalk.cyan(GM));
260
210
 
261
- // Row 8: Connection | Propfirm
262
- const connection = stats.platform || 'ProjectX';
263
- const r8c1 = buildCell('CONNECTION', connection, chalk.cyan, colL);
264
- const r8c2 = buildCell('PROPFIRM', stats.propfirm || 'N/A', chalk.cyan, colR);
265
- row(r8c1.padded, r8c2.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);
266
216
 
267
217
  this._line(chalk.cyan(GB));
268
218
  }