hedgequantx 1.2.98 → 1.2.100
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 +1 -1
- package/src/app.js +27 -17
- package/src/pages/algo.js +18 -6
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -580,47 +580,57 @@ const mainMenu = async () => {
|
|
|
580
580
|
const dashboardMenu = async (service) => {
|
|
581
581
|
const user = service.user;
|
|
582
582
|
const boxWidth = getLogoWidth();
|
|
583
|
-
const
|
|
583
|
+
const W = boxWidth - 2; // Same width as logo (inner width)
|
|
584
|
+
|
|
585
|
+
// Helper to center text
|
|
586
|
+
const centerLine = (text, width) => {
|
|
587
|
+
const pad = Math.floor((width - text.length) / 2);
|
|
588
|
+
return ' '.repeat(Math.max(0, pad)) + text + ' '.repeat(Math.max(0, width - pad - text.length));
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
// Helper to pad text left
|
|
592
|
+
const padLine = (text, width) => {
|
|
593
|
+
return ' ' + text + ' '.repeat(Math.max(0, width - text.length - 1));
|
|
594
|
+
};
|
|
584
595
|
|
|
585
596
|
// Dashboard box header
|
|
586
597
|
console.log();
|
|
587
|
-
console.log(chalk.cyan('╔' + '═'.repeat(
|
|
588
|
-
console.log(chalk.cyan('║') + chalk.white.bold(
|
|
589
|
-
console.log(chalk.cyan('╠' + '═'.repeat(
|
|
598
|
+
console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
|
|
599
|
+
console.log(chalk.cyan('║') + chalk.white.bold(centerLine('DASHBOARD', W)) + chalk.cyan('║'));
|
|
600
|
+
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
590
601
|
|
|
591
602
|
// Connection info - show all active connections
|
|
592
603
|
const allConns = connections.getAll();
|
|
593
604
|
if (allConns.length > 0) {
|
|
594
605
|
const connNames = allConns.map(c => c.propfirm || c.type).join(', ');
|
|
595
606
|
const connText = `Connected to ${connNames}`;
|
|
596
|
-
|
|
597
|
-
console.log(chalk.cyan('║') + ' ' + connInfo + ' '.repeat(Math.max(0, innerWidth - connText.length - 2)) + chalk.cyan('║'));
|
|
607
|
+
console.log(chalk.cyan('║') + chalk.green(padLine(connText, W)) + chalk.cyan('║'));
|
|
598
608
|
}
|
|
599
609
|
|
|
600
610
|
if (user) {
|
|
601
|
-
const
|
|
602
|
-
console.log(chalk.cyan('║') +
|
|
611
|
+
const userText = 'Welcome, ' + user.userName.toUpperCase() + '!';
|
|
612
|
+
console.log(chalk.cyan('║') + chalk.white(padLine(userText, W)) + chalk.cyan('║'));
|
|
603
613
|
}
|
|
604
614
|
|
|
605
|
-
console.log(chalk.cyan('╠' + '═'.repeat(
|
|
615
|
+
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
606
616
|
|
|
607
617
|
// Menu options in 2 columns
|
|
608
|
-
const col1Width = Math.floor(
|
|
609
|
-
const col2Width =
|
|
618
|
+
const col1Width = Math.floor(W / 2);
|
|
619
|
+
const col2Width = W - col1Width;
|
|
610
620
|
|
|
611
621
|
const menuRow = (left, right) => {
|
|
612
|
-
const
|
|
613
|
-
const
|
|
614
|
-
const leftPad = col1Width -
|
|
615
|
-
const rightPad = col2Width -
|
|
616
|
-
console.log(chalk.cyan('║') +
|
|
622
|
+
const leftPlain = left.replace(/\x1b\[[0-9;]*m/g, '');
|
|
623
|
+
const rightPlain = right ? right.replace(/\x1b\[[0-9;]*m/g, '') : '';
|
|
624
|
+
const leftPad = ' '.repeat(Math.max(0, col1Width - leftPlain.length - 2));
|
|
625
|
+
const rightPad = ' '.repeat(Math.max(0, col2Width - rightPlain.length - 2));
|
|
626
|
+
console.log(chalk.cyan('║') + ' ' + left + leftPad + ' ' + (right || '') + rightPad + chalk.cyan('║'));
|
|
617
627
|
};
|
|
618
628
|
|
|
619
629
|
menuRow(chalk.cyan('[1] View Accounts'), chalk.cyan('[2] View Stats'));
|
|
620
630
|
menuRow(chalk.cyan('[+] Add Prop-Account'), chalk.cyan('[A] Algo-Trading'));
|
|
621
631
|
menuRow(chalk.yellow('[U] Update HQX'), chalk.red('[X] Disconnect'));
|
|
622
632
|
|
|
623
|
-
console.log(chalk.cyan('╚' + '═'.repeat(
|
|
633
|
+
console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
|
|
624
634
|
console.log();
|
|
625
635
|
|
|
626
636
|
const { action } = await inquirer.prompt([
|
package/src/pages/algo.js
CHANGED
|
@@ -241,8 +241,11 @@ const selectSymbolMenu = async (service, account) => {
|
|
|
241
241
|
'ZW': 'Wheat'
|
|
242
242
|
};
|
|
243
243
|
|
|
244
|
-
// Format symbols for display
|
|
245
|
-
const
|
|
244
|
+
// Format symbols for display - deduplicate by base symbol + month
|
|
245
|
+
const seenSymbols = new Set();
|
|
246
|
+
const symbolChoices = [];
|
|
247
|
+
|
|
248
|
+
for (const symbol of availableSymbols) {
|
|
246
249
|
const symbolCode = symbol.symbol || symbol.id || '';
|
|
247
250
|
|
|
248
251
|
// Extract base symbol (e.g., NQ from NQH6) and month code
|
|
@@ -258,15 +261,20 @@ const selectSymbolMenu = async (service, account) => {
|
|
|
258
261
|
monthYear = (monthCodes[monthCode] || monthCode) + year;
|
|
259
262
|
}
|
|
260
263
|
|
|
264
|
+
// Create unique key to deduplicate
|
|
265
|
+
const uniqueKey = `${baseSymbol}-${monthYear}`;
|
|
266
|
+
if (seenSymbols.has(uniqueKey)) continue;
|
|
267
|
+
seenSymbols.add(uniqueKey);
|
|
268
|
+
|
|
261
269
|
// Get descriptive name from mapping
|
|
262
270
|
const description = symbolDescriptions[baseSymbol] || symbol.name || baseSymbol;
|
|
263
271
|
|
|
264
272
|
// Format: "NQ Mar26 E-mini NASDAQ-100"
|
|
265
|
-
|
|
273
|
+
symbolChoices.push({
|
|
266
274
|
name: chalk.yellow(baseSymbol.padEnd(5)) + chalk.cyan(monthYear.padEnd(7)) + chalk.white(description),
|
|
267
275
|
value: symbol
|
|
268
|
-
};
|
|
269
|
-
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
270
278
|
|
|
271
279
|
symbolChoices.push(new inquirer.Separator());
|
|
272
280
|
symbolChoices.push({ name: chalk.yellow('< Back'), value: 'back' });
|
|
@@ -506,9 +514,10 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
506
514
|
// Use ANSI escape codes to avoid flickering
|
|
507
515
|
let firstDraw = true;
|
|
508
516
|
const displayUI = () => {
|
|
509
|
-
// First time: clear screen, after: just move cursor to top
|
|
517
|
+
// First time: clear screen and hide cursor, after: just move cursor to top
|
|
510
518
|
if (firstDraw) {
|
|
511
519
|
console.clear();
|
|
520
|
+
process.stdout.write('\x1B[?25l'); // Hide cursor
|
|
512
521
|
firstDraw = false;
|
|
513
522
|
} else {
|
|
514
523
|
// Move cursor to top-left without clearing (avoids flicker)
|
|
@@ -871,6 +880,9 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
871
880
|
// Clear spinner interval
|
|
872
881
|
clearInterval(spinnerInterval);
|
|
873
882
|
|
|
883
|
+
// Show cursor again
|
|
884
|
+
process.stdout.write('\x1B[?25h');
|
|
885
|
+
|
|
874
886
|
// Stop algo
|
|
875
887
|
console.log();
|
|
876
888
|
if (!stopReason) {
|