hedgequantx 1.2.40 → 1.2.41

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/app.js +73 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "1.2.40",
3
+ "version": "1.2.41",
4
4
  "description": "Prop Futures Algo Trading CLI - Connect to Topstep, Alpha Futures, and other prop firms",
5
5
  "main": "src/app.js",
6
6
  "bin": {
package/src/app.js CHANGED
@@ -110,18 +110,21 @@ const banner = async () => {
110
110
 
111
111
  const connStr = `Connections: ${statsInfo.connections}`;
112
112
  const accStr = `Accounts: ${statsInfo.accounts}`;
113
- const balVal = `$${statsInfo.balance.toLocaleString()}`;
114
- const pnlVal = `$${statsInfo.pnl.toLocaleString()} (${pnlSign}${statsInfo.pnlPercent}%)`;
113
+ const balStr = `Balance: $${statsInfo.balance.toLocaleString()}`;
114
+ const pnlStr = `P&L: $${statsInfo.pnl.toLocaleString()} (${pnlSign}${statsInfo.pnlPercent}%)`;
115
115
 
116
- const statsLen = connStr.length + 4 + accStr.length + 4 + 8 + balVal.length + 4 + 5 + pnlVal.length;
116
+ // Build full stats text and calculate padding
117
+ const statsText = `${connStr} ${accStr} ${balStr} ${pnlStr}`;
118
+ const statsLen = statsText.length;
117
119
  const statsLeftPad = Math.floor((innerWidth - statsLen) / 2);
118
120
  const statsRightPad = innerWidth - statsLen - statsLeftPad;
119
121
 
120
122
  console.log(chalk.cyan('║') + ' '.repeat(statsLeftPad) +
121
123
  chalk.white(connStr) + ' ' +
122
124
  chalk.white(accStr) + ' ' +
123
- chalk.white('Balance: ') + chalk.green(balVal) + ' ' +
124
- chalk.white('P&L: ') + pnlColor(pnlVal) + ' '.repeat(statsRightPad) + chalk.cyan('║')
125
+ chalk.white('Balance: ') + chalk.green(`$${statsInfo.balance.toLocaleString()}`) + ' ' +
126
+ chalk.white('P&L: ') + pnlColor(`$${statsInfo.pnl.toLocaleString()} (${pnlSign}${statsInfo.pnlPercent}%)`) +
127
+ ' '.repeat(statsRightPad) + chalk.cyan('║')
125
128
  );
126
129
  }
127
130
 
@@ -455,6 +458,60 @@ const tradovateMenu = async () => {
455
458
  }
456
459
  };
457
460
 
461
+ /**
462
+ * Add Prop Account menu (select platform)
463
+ */
464
+ const addPropAccountMenu = async () => {
465
+ const boxWidth = getLogoWidth();
466
+ const innerWidth = boxWidth - 2;
467
+ const col1Width = Math.floor(innerWidth / 2);
468
+ const col2Width = innerWidth - col1Width;
469
+
470
+ console.log();
471
+ console.log(chalk.cyan('╔' + '═'.repeat(innerWidth) + '╗'));
472
+ console.log(chalk.cyan('║') + chalk.white.bold(centerText('ADD PROP ACCOUNT', innerWidth)) + chalk.cyan('║'));
473
+ console.log(chalk.cyan('╠' + '═'.repeat(innerWidth) + '╣'));
474
+
475
+ const menuRow = (left, right) => {
476
+ const leftText = ' ' + left;
477
+ const rightText = right ? ' ' + right : '';
478
+ const leftLen = leftText.replace(/\x1b\[[0-9;]*m/g, '').length;
479
+ const rightLen = rightText.replace(/\x1b\[[0-9;]*m/g, '').length;
480
+ const leftPad = col1Width - leftLen;
481
+ const rightPad = col2Width - rightLen;
482
+ console.log(chalk.cyan('║') + leftText + ' '.repeat(Math.max(0, leftPad)) + rightText + ' '.repeat(Math.max(0, rightPad)) + chalk.cyan('║'));
483
+ };
484
+
485
+ menuRow(chalk.cyan('[1] ProjectX'), chalk.cyan('[2] Rithmic'));
486
+ menuRow(chalk.cyan('[3] Tradovate'), chalk.red('[X] Back'));
487
+
488
+ console.log(chalk.cyan('╚' + '═'.repeat(innerWidth) + '╝'));
489
+ console.log();
490
+
491
+ const { action } = await inquirer.prompt([
492
+ {
493
+ type: 'input',
494
+ name: 'action',
495
+ message: chalk.cyan('Enter choice (1/2/3/X):'),
496
+ validate: (input) => {
497
+ const valid = ['1', '2', '3', 'x', 'X'];
498
+ if (valid.includes(input)) return true;
499
+ return 'Please enter 1, 2, 3 or X';
500
+ }
501
+ }
502
+ ]);
503
+
504
+ const actionMap = {
505
+ '1': 'projectx',
506
+ '2': 'rithmic',
507
+ '3': 'tradovate',
508
+ 'x': null,
509
+ 'X': null
510
+ };
511
+
512
+ return actionMap[action];
513
+ };
514
+
458
515
  /**
459
516
  * Main connection menu
460
517
  */
@@ -722,9 +779,17 @@ const run = async () => {
722
779
  await showStats(currentService);
723
780
  break;
724
781
  case 'add_prop_account':
725
- const newService = await projectXMenu();
726
- if (newService) {
727
- currentService = newService;
782
+ // Show platform selection menu
783
+ const platformChoice = await addPropAccountMenu();
784
+ if (platformChoice === 'projectx') {
785
+ const newService = await projectXMenu();
786
+ if (newService) currentService = newService;
787
+ } else if (platformChoice === 'rithmic') {
788
+ const newService = await rithmicMenu();
789
+ if (newService) currentService = newService;
790
+ } else if (platformChoice === 'tradovate') {
791
+ const newService = await tradovateMenu();
792
+ if (newService) currentService = newService;
728
793
  }
729
794
  break;
730
795
  case 'algotrading':