hedgequantx 2.4.37 → 2.4.38

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.4.37",
3
+ "version": "2.4.38",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -62,14 +62,14 @@ const dashboardMenu = async (service) => {
62
62
 
63
63
  // Yellow icons: ✔ for each stat
64
64
  const icon = chalk.yellow('✔ ');
65
- const statsPlain = `✔ Connections: ${statsInfo.connections} ✔ Accounts: ${statsInfo.accounts} ✔ Balance: ${balStr} ✔ P&L: ${pnlDisplay}`;
65
+ const statsPlain = `✔ CONNECTIONS: ${statsInfo.connections} ✔ ACCOUNTS: ${statsInfo.accounts} ✔ BALANCE: ${balStr} ✔ P&L: ${pnlDisplay}`;
66
66
  const statsLeftPad = Math.max(0, Math.floor((W - statsPlain.length) / 2));
67
67
  const statsRightPad = Math.max(0, W - statsPlain.length - statsLeftPad);
68
68
 
69
69
  console.log(chalk.cyan('║') + ' '.repeat(statsLeftPad) +
70
- icon + chalk.white(`Connections: ${statsInfo.connections}`) + ' ' +
71
- icon + chalk.white(`Accounts: ${statsInfo.accounts}`) + ' ' +
72
- icon + chalk.white('Balance: ') + balColor(balStr) + ' ' +
70
+ icon + chalk.white(`CONNECTIONS: ${statsInfo.connections}`) + ' ' +
71
+ icon + chalk.white(`ACCOUNTS: ${statsInfo.accounts}`) + ' ' +
72
+ icon + chalk.white('BALANCE: ') + balColor(balStr) + ' ' +
73
73
  icon + chalk.white('P&L: ') + pnlColor(pnlDisplay) +
74
74
  ' '.repeat(Math.max(0, statsRightPad)) + chalk.cyan('║'));
75
75
  }
@@ -105,7 +105,7 @@ const showAccounts = async (service) => {
105
105
  const balStr2 = bal2 !== null && bal2 !== undefined ? '$' + Number(bal2).toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) : '--';
106
106
  const balColor1 = bal1 === null || bal1 === undefined ? chalk.gray : (bal1 >= 0 ? chalk.green : chalk.red);
107
107
  const balColor2 = bal2 === null || bal2 === undefined ? chalk.gray : (bal2 >= 0 ? chalk.green : chalk.red);
108
- console.log(chalk.cyan('║') + fmtRow('Balance:', balColor1(balStr1), col1) + chalk.cyan('│') + (acc2 ? fmtRow('Balance:', balColor2(balStr2), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
108
+ console.log(chalk.cyan('║') + fmtRow('BALANCE:', balColor1(balStr1), col1) + chalk.cyan('│') + (acc2 ? fmtRow('BALANCE:', balColor2(balStr2), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
109
109
 
110
110
  // P&L
111
111
  const pnl1 = acc1.profitAndLoss;
@@ -119,7 +119,7 @@ const showAccounts = async (service) => {
119
119
  // Status
120
120
  const status1 = ACCOUNT_STATUS[acc1.status] || { text: 'Unknown', color: 'gray' };
121
121
  const status2 = acc2 ? (ACCOUNT_STATUS[acc2.status] || { text: 'Unknown', color: 'gray' }) : null;
122
- console.log(chalk.cyan('║') + fmtRow('Status:', chalk[status1.color](status1.text), col1) + chalk.cyan('│') + (acc2 ? fmtRow('Status:', chalk[status2.color](status2.text), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
122
+ console.log(chalk.cyan('║') + fmtRow('STATUS:', chalk[status1.color](status1.text), col1) + chalk.cyan('│') + (acc2 ? fmtRow('STATUS:', chalk[status2.color](status2.text), col2) : ' '.repeat(col2)) + chalk.cyan('║'));
123
123
 
124
124
  // Type
125
125
  const type1 = ACCOUNT_TYPE[acc1.type] || { text: 'Unknown', color: 'white' };
@@ -183,7 +183,7 @@ class AlgoUI {
183
183
  this._line(chalk.cyan(GM));
184
184
 
185
185
  // Row 2: Qty | P&L
186
- const r2c1 = buildCell('Qty', (stats.qty || '1').toString(), chalk.cyan, colL);
186
+ const r2c1 = buildCell('QTY', (stats.qty || '1').toString(), chalk.cyan, colL);
187
187
  const r2c2 = buildCell('P&L', pnlStr, pnlColor, colR);
188
188
  row(r2c1.padded, r2c2.padded);
189
189
 
@@ -192,8 +192,8 @@ class AlgoUI {
192
192
  // Row 3: Target | Risk
193
193
  const targetStr = stats.target !== null && stats.target !== undefined ? '$' + stats.target.toFixed(2) : '--';
194
194
  const riskStr = stats.risk !== null && stats.risk !== undefined ? '$' + stats.risk.toFixed(2) : '--';
195
- const r3c1 = buildCell('Target', targetStr, chalk.green, colL);
196
- const r3c2 = buildCell('Risk', riskStr, chalk.red, colR);
195
+ const r3c1 = buildCell('TARGET', targetStr, chalk.green, colL);
196
+ const r3c2 = buildCell('RISK', riskStr, chalk.red, colR);
197
197
  row(r3c1.padded, r3c2.padded);
198
198
 
199
199
  this._line(chalk.cyan(GM));
@@ -201,15 +201,15 @@ class AlgoUI {
201
201
  // Row 4: Trades | Latency (API response time) - UPPERCASE BOLD
202
202
  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)}`;
203
203
  const r4c1p = ` TRADES: ${stats.trades || 0} W/L: ${stats.wins || 0}/${stats.losses || 0}`;
204
- const r4c2 = buildCell('Latency', `${stats.latency || 0}MS`, latencyColor, colR);
204
+ const r4c2 = buildCell('LATENCY', `${stats.latency || 0}MS`, latencyColor, colR);
205
205
  row(r4c1t + pad(colL - r4c1p.length), r4c2.padded);
206
206
 
207
207
  this._line(chalk.cyan(GM));
208
208
 
209
209
  // Row 5: Connection | Propfirm
210
210
  const connection = stats.platform || 'ProjectX';
211
- const r5c1 = buildCell('Connection', connection, chalk.cyan, colL);
212
- const r5c2 = buildCell('Propfirm', stats.propfirm || 'N/A', chalk.cyan, colR);
211
+ const r5c1 = buildCell('CONNECTION', connection, chalk.cyan, colL);
212
+ const r5c2 = buildCell('PROPFIRM', stats.propfirm || 'N/A', chalk.cyan, colR);
213
213
  row(r5c1.padded, r5c2.padded);
214
214
 
215
215
  this._line(chalk.cyan(GB));
@@ -244,22 +244,22 @@ class AlgoUI {
244
244
 
245
245
  // Row 2: Symbol (centered, single row)
246
246
  const symbol = (stats.symbol || stats.leadSymbol || 'N/A').substring(0, 60);
247
- const symbolText = `Symbol: ${symbol}`;
247
+ const symbolText = `SYMBOL: ${symbol}`;
248
248
  const symbolPadded = center(symbolText, W);
249
249
  this._line(chalk.cyan(BOX.V) + chalk.yellow(symbolPadded) + chalk.cyan(BOX.V));
250
250
 
251
251
  this._line(chalk.cyan(GT));
252
252
 
253
253
  // Row 3: Lead Qty | Follower Qty
254
- const r3c1 = buildCell('Qty', (stats.leadQty || '1').toString(), chalk.cyan, colL);
255
- const r3c2 = buildCell('Qty', (stats.followerQty || '1').toString(), chalk.cyan, colR);
254
+ const r3c1 = buildCell('QTY', (stats.leadQty || '1').toString(), chalk.cyan, colL);
255
+ const r3c2 = buildCell('QTY', (stats.followerQty || '1').toString(), chalk.cyan, colR);
256
256
  row(r3c1.padded, r3c2.padded);
257
257
 
258
258
  this._line(chalk.cyan(GM));
259
259
 
260
260
  // Row 4: Target | Risk
261
- const r4c1 = buildCell('Target', '$' + (stats.target || 0).toFixed(2), chalk.green, colL);
262
- const r4c2 = buildCell('Risk', '$' + (stats.risk || 0).toFixed(2), chalk.red, colR);
261
+ const r4c1 = buildCell('TARGET', '$' + (stats.target || 0).toFixed(2), chalk.green, colL);
262
+ const r4c2 = buildCell('RISK', '$' + (stats.risk || 0).toFixed(2), chalk.red, colR);
263
263
  row(r4c1.padded, r4c2.padded);
264
264
 
265
265
  this._line(chalk.cyan(GM));
@@ -443,7 +443,7 @@ const renderSessionSummary = (stats, stopReason) => {
443
443
  const pnlStr = `${pnl >= 0 ? '+' : ''}$${Math.abs(pnl).toFixed(2)}`;
444
444
  const pnlColor = pnl >= 0 ? chalk.green : chalk.red;
445
445
  const targetStr = `$${(stats.target || 0).toFixed(2)}`;
446
- row('P&L', pnlStr, pnlColor, 'Target', targetStr, chalk.cyan);
446
+ row('P&L', pnlStr, pnlColor, 'TARGET', targetStr, chalk.cyan);
447
447
 
448
448
  // Bottom border
449
449
  console.log(chalk.cyan(BOX.BOT + BOX.H.repeat(W) + BOX.BR));
@@ -337,13 +337,13 @@ const showStats = async (service) => {
337
337
  : 'N/A';
338
338
  const startBalStr = totalStartingBalance > 0 ? '$' + totalStartingBalance.toLocaleString(undefined, {minimumFractionDigits: 2}) : 'N/A';
339
339
 
340
- console.log(chalk.cyan('\u2551') + fmtRow('Connections:', chalk.cyan(connTypeStr.join(', ') || String(connections.count() || 1)), col1) + chalk.cyan('\u2502') + fmtRow('Total Trades:', hasTradeData || stats.totalTrades > 0 ? chalk.white(String(stats.totalTrades)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
341
- console.log(chalk.cyan('\u2551') + fmtRow('Total Accounts:', chalk.cyan(String(activeAccounts.length)), col1) + chalk.cyan('\u2502') + fmtRow('Winning Trades:', hasTradeData || stats.winningTrades > 0 ? chalk.green(String(stats.winningTrades)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
342
- console.log(chalk.cyan('\u2551') + fmtRow('Total Balance:', totalBalanceColor(balanceStr), col1) + chalk.cyan('\u2502') + fmtRow('Losing Trades:', hasTradeData || stats.losingTrades > 0 ? chalk.red(String(stats.losingTrades)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
343
- console.log(chalk.cyan('\u2551') + fmtRow('Starting Balance:', chalk.white(startBalStr), col1) + chalk.cyan('\u2502') + fmtRow('Win Rate:', winRate !== 'N/A' ? (parseFloat(winRate) >= 50 ? chalk.green(winRate + '%') : chalk.yellow(winRate + '%')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
344
- console.log(chalk.cyan('\u2551') + fmtRow('Total P&L:', pnlColor(pnlStr), col1) + chalk.cyan('\u2502') + fmtRow('Long Trades:', hasTradeData ? chalk.white(stats.longTrades + (longWinRate !== 'N/A' ? ' (' + longWinRate + '%)' : '')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
345
- console.log(chalk.cyan('\u2551') + fmtRow('Open Positions:', chalk.white(String(totalOpenPositions)), col1) + chalk.cyan('\u2502') + fmtRow('Short Trades:', hasTradeData ? chalk.white(stats.shortTrades + (shortWinRate !== 'N/A' ? ' (' + shortWinRate + '%)' : '')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
346
- console.log(chalk.cyan('\u2551') + fmtRow('Open Orders:', chalk.white(String(totalOpenOrders)), col1) + chalk.cyan('\u2502') + fmtRow('Volume:', hasTradeData ? chalk.white(stats.totalVolume + ' contracts') : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
340
+ console.log(chalk.cyan('\u2551') + fmtRow('CONNECTIONS:', chalk.cyan(connTypeStr.join(', ') || String(connections.count() || 1)), col1) + chalk.cyan('\u2502') + fmtRow('TOTAL TRADES:', hasTradeData || stats.totalTrades > 0 ? chalk.white(String(stats.totalTrades)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
341
+ console.log(chalk.cyan('\u2551') + fmtRow('TOTAL ACCOUNTS:', chalk.cyan(String(activeAccounts.length)), col1) + chalk.cyan('\u2502') + fmtRow('WINNING TRADES:', hasTradeData || stats.winningTrades > 0 ? chalk.green(String(stats.winningTrades)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
342
+ console.log(chalk.cyan('\u2551') + fmtRow('TOTAL BALANCE:', totalBalanceColor(balanceStr), col1) + chalk.cyan('\u2502') + fmtRow('LOSING TRADES:', hasTradeData || stats.losingTrades > 0 ? chalk.red(String(stats.losingTrades)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
343
+ console.log(chalk.cyan('\u2551') + fmtRow('STARTING BALANCE:', chalk.white(startBalStr), col1) + chalk.cyan('\u2502') + fmtRow('WIN RATE:', winRate !== 'N/A' ? (parseFloat(winRate) >= 50 ? chalk.green(winRate + '%') : chalk.yellow(winRate + '%')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
344
+ console.log(chalk.cyan('\u2551') + fmtRow('TOTAL P&L:', pnlColor(pnlStr), col1) + chalk.cyan('\u2502') + fmtRow('LONG TRADES:', hasTradeData ? chalk.white(stats.longTrades + (longWinRate !== 'N/A' ? ' (' + longWinRate + '%)' : '')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
345
+ console.log(chalk.cyan('\u2551') + fmtRow('OPEN POSITIONS:', chalk.white(String(totalOpenPositions)), col1) + chalk.cyan('\u2502') + fmtRow('SHORT TRADES:', hasTradeData ? chalk.white(stats.shortTrades + (shortWinRate !== 'N/A' ? ' (' + shortWinRate + '%)' : '')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
346
+ console.log(chalk.cyan('\u2551') + fmtRow('OPEN ORDERS:', chalk.white(String(totalOpenOrders)), col1) + chalk.cyan('\u2502') + fmtRow('VOLUME:', hasTradeData ? chalk.white(stats.totalVolume + ' contracts') : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
347
347
 
348
348
  // ========== P&L METRICS ==========
349
349
  draw2ColSeparator(boxWidth);
@@ -361,11 +361,11 @@ const showStats = async (service) => {
361
361
 
362
362
  const netPnLStr = hasTradeData ? (netPnL >= 0 ? chalk.green('$' + netPnL.toFixed(2)) : chalk.red('-$' + Math.abs(netPnL).toFixed(2))) : chalk.gray('N/A');
363
363
 
364
- console.log(chalk.cyan('\u2551') + fmtRow('Net P&L:', netPnLStr, col1) + chalk.cyan('\u2502') + fmtRow('Profit Factor:', pfColor, col2) + chalk.cyan('\u2551'));
365
- console.log(chalk.cyan('\u2551') + fmtRow('Gross Profit:', hasTradeData ? chalk.green('$' + stats.totalWinAmount.toFixed(2)) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('Max Consec. Wins:', hasTradeData ? chalk.green(String(stats.maxConsecutiveWins)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
366
- console.log(chalk.cyan('\u2551') + fmtRow('Gross Loss:', hasTradeData ? chalk.red('-$' + stats.totalLossAmount.toFixed(2)) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('Max Consec. Loss:', hasTradeData ? (stats.maxConsecutiveLosses > 0 ? chalk.red(String(stats.maxConsecutiveLosses)) : chalk.green('0')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
367
- console.log(chalk.cyan('\u2551') + fmtRow('Avg Win:', hasTradeData ? chalk.green('$' + avgWin) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('Best Trade:', hasTradeData ? chalk.green('$' + stats.bestTrade.toFixed(2)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
368
- console.log(chalk.cyan('\u2551') + fmtRow('Avg Loss:', hasTradeData ? (stats.losingTrades > 0 ? chalk.red('-$' + avgLoss) : chalk.green('$0.00')) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('Worst Trade:', hasTradeData ? (stats.worstTrade < 0 ? chalk.red(worstTradeStr) : chalk.green(worstTradeStr)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
364
+ console.log(chalk.cyan('\u2551') + fmtRow('NET P&L:', netPnLStr, col1) + chalk.cyan('\u2502') + fmtRow('PROFIT FACTOR:', pfColor, col2) + chalk.cyan('\u2551'));
365
+ console.log(chalk.cyan('\u2551') + fmtRow('GROSS PROFIT:', hasTradeData ? chalk.green('$' + stats.totalWinAmount.toFixed(2)) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('MAX CONSEC. WINS:', hasTradeData ? chalk.green(String(stats.maxConsecutiveWins)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
366
+ console.log(chalk.cyan('\u2551') + fmtRow('GROSS LOSS:', hasTradeData ? chalk.red('-$' + stats.totalLossAmount.toFixed(2)) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('MAX CONSEC. LOSS:', hasTradeData ? (stats.maxConsecutiveLosses > 0 ? chalk.red(String(stats.maxConsecutiveLosses)) : chalk.green('0')) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
367
+ console.log(chalk.cyan('\u2551') + fmtRow('AVG WIN:', hasTradeData ? chalk.green('$' + avgWin) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('BEST TRADE:', hasTradeData ? chalk.green('$' + stats.bestTrade.toFixed(2)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
368
+ console.log(chalk.cyan('\u2551') + fmtRow('AVG LOSS:', hasTradeData ? (stats.losingTrades > 0 ? chalk.red('-$' + avgLoss) : chalk.green('$0.00')) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('WORST TRADE:', hasTradeData ? (stats.worstTrade < 0 ? chalk.red(worstTradeStr) : chalk.green(worstTradeStr)) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
369
369
 
370
370
  // ========== QUANTITATIVE METRICS ==========
371
371
  draw2ColSeparator(boxWidth);
@@ -376,10 +376,10 @@ const showStats = async (service) => {
376
376
  const ddColor = maxDrawdown === 0 ? chalk.gray : maxDrawdown <= 5 ? chalk.green : maxDrawdown <= 15 ? chalk.yellow : chalk.red;
377
377
  const rrColor = riskRewardRatio === 'N/A' ? chalk.gray : parseFloat(riskRewardRatio) >= 2 ? chalk.green : parseFloat(riskRewardRatio) >= 1 ? chalk.yellow : chalk.red;
378
378
 
379
- console.log(chalk.cyan('\u2551') + fmtRow('Sharpe Ratio:', sharpeColor(sharpeRatio), col1) + chalk.cyan('\u2502') + fmtRow('Risk/Reward:', rrColor(riskRewardRatio), col2) + chalk.cyan('\u2551'));
380
- console.log(chalk.cyan('\u2551') + fmtRow('Sortino Ratio:', sortinoColor(sortinoRatio), col1) + chalk.cyan('\u2502') + fmtRow('Calmar Ratio:', calmarRatio === 'N/A' ? chalk.gray(calmarRatio) : chalk.white(calmarRatio), col2) + chalk.cyan('\u2551'));
381
- console.log(chalk.cyan('\u2551') + fmtRow('Max Drawdown:', hasTradeData && maxDrawdown > 0 ? ddColor(maxDrawdown.toFixed(2) + '%') : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('Expectancy:', hasTradeData ? (expectancy >= 0 ? chalk.green('$' + expectancy.toFixed(2)) : chalk.red('$' + expectancy.toFixed(2))) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
382
- console.log(chalk.cyan('\u2551') + fmtRow('Std Deviation:', hasTradeData ? chalk.white('$' + stdDev.toFixed(2)) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('Avg Trade:', hasTradeData ? (avgReturn >= 0 ? chalk.green('$' + avgReturn.toFixed(2)) : chalk.red('$' + avgReturn.toFixed(2))) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
379
+ console.log(chalk.cyan('\u2551') + fmtRow('SHARPE RATIO:', sharpeColor(sharpeRatio), col1) + chalk.cyan('\u2502') + fmtRow('RISK/REWARD:', rrColor(riskRewardRatio), col2) + chalk.cyan('\u2551'));
380
+ console.log(chalk.cyan('\u2551') + fmtRow('SORTINO RATIO:', sortinoColor(sortinoRatio), col1) + chalk.cyan('\u2502') + fmtRow('CALMAR RATIO:', calmarRatio === 'N/A' ? chalk.gray(calmarRatio) : chalk.white(calmarRatio), col2) + chalk.cyan('\u2551'));
381
+ console.log(chalk.cyan('\u2551') + fmtRow('MAX DRAWDOWN:', hasTradeData && maxDrawdown > 0 ? ddColor(maxDrawdown.toFixed(2) + '%') : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('EXPECTANCY:', hasTradeData ? (expectancy >= 0 ? chalk.green('$' + expectancy.toFixed(2)) : chalk.red('$' + expectancy.toFixed(2))) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
382
+ console.log(chalk.cyan('\u2551') + fmtRow('STD DEVIATION:', hasTradeData ? chalk.white('$' + stdDev.toFixed(2)) : chalk.gray('N/A'), col1) + chalk.cyan('\u2502') + fmtRow('AVG TRADE:', hasTradeData ? (avgReturn >= 0 ? chalk.green('$' + avgReturn.toFixed(2)) : chalk.red('$' + avgReturn.toFixed(2))) : chalk.gray('N/A'), col2) + chalk.cyan('\u2551'));
383
383
 
384
384
  drawBoxFooter(boxWidth);
385
385
 
package/src/pages/user.js CHANGED
@@ -71,10 +71,10 @@ const showUserInfo = async (service) => {
71
71
 
72
72
  const username = userInfo.userName || userInfo.username || 'Unknown';
73
73
  const connCount = connections.count() || 1;
74
- console.log(chalk.cyan('║') + fmtRow('Username:', chalk.cyan(username.toUpperCase()), col1) + chalk.cyan('│') + fmtRow('Connections:', chalk.cyan(String(connCount)), col2) + chalk.cyan('║'));
74
+ console.log(chalk.cyan('║') + fmtRow('USERNAME:', chalk.cyan(username.toUpperCase()), col1) + chalk.cyan('│') + fmtRow('CONNECTIONS:', chalk.cyan(String(connCount)), col2) + chalk.cyan('║'));
75
75
 
76
76
  const email = userInfo.email || 'N/A';
77
- console.log(chalk.cyan('║') + fmtRow('Email:', chalk.white(email), col1) + chalk.cyan('│') + fmtRow('Accounts:', chalk.cyan(String(accountCount)), col2) + chalk.cyan('║'));
77
+ console.log(chalk.cyan('║') + fmtRow('EMAIL:', chalk.white(email), col1) + chalk.cyan('│') + fmtRow('ACCOUNTS:', chalk.cyan(String(accountCount)), col2) + chalk.cyan('║'));
78
78
 
79
79
  const userId = userInfo.userId || userInfo.id || 'N/A';
80
80
  const platform = service?.propfirm?.name || 'ProjectX';