hedgequantx 1.2.69 → 1.2.71

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/pages/algo.js +75 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "1.2.69",
3
+ "version": "1.2.71",
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/pages/algo.js CHANGED
@@ -379,50 +379,101 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
379
379
  // Display full UI with logs (newest first)
380
380
  const displayUI = () => {
381
381
  console.clear();
382
- const marketStatus = checkMarketStatus();
383
382
 
384
383
  // Stats
385
384
  const pnlColor = stats.pnl >= 0 ? chalk.green : chalk.red;
386
385
  const pnlStr = (stats.pnl >= 0 ? '+$' : '-$') + Math.abs(stats.pnl).toFixed(2);
387
386
  const latencyStr = hqxConnected ? (latency > 0 ? `${latency}ms` : '---') : '---';
388
387
  const latencyColor = latency < 100 ? chalk.green : (latency < 300 ? chalk.yellow : chalk.red);
389
- const serverStatus = hqxConnected ? chalk.green('ON') : chalk.red('OFF');
388
+ const serverStatus = hqxConnected ? 'ON' : 'OFF';
389
+ const serverColor = hqxConnected ? chalk.green : chalk.red;
390
390
 
391
391
  // Current date
392
392
  const now = new Date();
393
393
  const dateStr = now.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' });
394
394
 
395
- // Full header with logo inside box
395
+ // Get package version
396
+ const version = require('../../package.json').version;
397
+
398
+ // Fixed width = 96 inner chars
399
+ const W = 96;
400
+ const TOP = '\u2554' + '\u2550'.repeat(W) + '\u2557';
401
+ const MID = '\u2560' + '\u2550'.repeat(W) + '\u2563';
402
+ const BOT = '\u255A' + '\u2550'.repeat(W) + '\u255D';
403
+ const V = '\u2551';
404
+
405
+ // Center text helper
406
+ const center = (text, width) => {
407
+ const pad = Math.floor((width - text.length) / 2);
408
+ return ' '.repeat(pad) + text + ' '.repeat(width - pad - text.length);
409
+ };
410
+
411
+ // Pad text to exact width
412
+ const padRight = (text, width) => {
413
+ if (text.length >= width) return text.substring(0, width);
414
+ return text + ' '.repeat(width - text.length);
415
+ };
416
+
396
417
  console.log();
397
- console.log(chalk.cyan('+=================================================================================================================+'));
398
- console.log(chalk.cyan('|') + chalk.cyan(' ## ## ###### ##### #### ###### #### ## ## #### ## ## ###### ## ## ') + chalk.cyan('|'));
399
- console.log(chalk.cyan('|') + chalk.cyan(' ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## #### ') + chalk.cyan('|'));
400
- console.log(chalk.cyan('|') + chalk.cyan(' ###### #### ## ## ## ### #### ## ## ## ## ###### ## ### ## ## ') + chalk.cyan('|'));
401
- console.log(chalk.cyan('|') + chalk.cyan(' ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## #### ') + chalk.cyan('|'));
402
- console.log(chalk.cyan('|') + chalk.cyan(' ## ## ###### ##### #### ###### #### ## #### ## ## ## ## ## ## ## ') + chalk.cyan('|'));
403
- console.log(chalk.cyan('+=================================================================================================================+'));
404
- console.log(chalk.cyan('|') + chalk.white(' HQX Ultra-Scalping Algorithm ') + chalk.cyan('|'));
405
- console.log(chalk.cyan('+=================================================================================================================+'));
406
- console.log(chalk.cyan('|') + chalk.white(` Account: ${chalk.cyan(accountName.padEnd(28))} Symbol: ${chalk.yellow(symbolName.padEnd(12))} Qty: ${chalk.cyan(numContracts.toString().padEnd(4))} Server: ${serverStatus} ${latencyColor(latencyStr.padEnd(8))}`) + chalk.cyan('|'));
407
- console.log(chalk.cyan('|') + chalk.white(` Target: ${chalk.green(('$' + dailyTarget.toFixed(2)).padEnd(12))} Risk: ${chalk.red(('$' + maxRisk.toFixed(2)).padEnd(12))} P&L: ${pnlColor(pnlStr.padEnd(12))} Trades: ${chalk.cyan(stats.trades.toString())} W:${chalk.green(stats.wins.toString())} L:${chalk.red(stats.losses.toString())} `) + chalk.cyan('|'));
408
- console.log(chalk.cyan('+=================================================================================================================+'));
409
- console.log(chalk.cyan('|') + chalk.white(` Activity Log - ${chalk.gray(dateStr)} `) + chalk.yellow('Press X to stop') + chalk.cyan(' |'));
410
- console.log(chalk.cyan('+=================================================================================================================+'));
418
+ console.log(chalk.cyan(TOP));
419
+ console.log(chalk.cyan(V) + chalk.cyan(' \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 ') + chalk.cyan(V));
420
+ console.log(chalk.cyan(V) + chalk.cyan(' \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D ') + chalk.cyan(V));
421
+ console.log(chalk.cyan(V) + chalk.cyan(' \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2554\u255D ') + chalk.cyan(V));
422
+ console.log(chalk.cyan(V) + chalk.cyan(' \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u2584\u2584 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 ') + chalk.cyan(V));
423
+ console.log(chalk.cyan(V) + chalk.cyan(' \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2557 ') + chalk.cyan(V));
424
+ console.log(chalk.cyan(V) + chalk.cyan(' \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ') + chalk.cyan(V));
425
+ console.log(chalk.cyan(MID));
426
+
427
+ // Centered title
428
+ const title1 = `Prop Futures Algo Trading v${version}`;
429
+ console.log(chalk.cyan(V) + chalk.white(center(title1, W)) + chalk.cyan(V));
430
+ console.log(chalk.cyan(MID));
411
431
 
412
- // Logs (without date, just time)
432
+ // Centered subtitle
433
+ const title2 = 'HQX Ultra-Scalping Algorithm';
434
+ console.log(chalk.cyan(V) + chalk.white(center(title2, W)) + chalk.cyan(V));
435
+ console.log(chalk.cyan(MID));
436
+
437
+ // Account line - build plain string first, then color
438
+ const acc = accountName.length > 24 ? accountName.substring(0, 24) : accountName.padEnd(24);
439
+ const sym = symbolName.length > 8 ? symbolName.substring(0, 8) : symbolName.padEnd(8);
440
+ const qty = numContracts.toString().padEnd(2);
441
+ const srv = serverStatus.padEnd(3);
442
+ const lat = latencyStr.padEnd(6);
443
+ const line1 = ` Account: ${acc} Symbol: ${sym} Qty: ${qty} Server: ${srv} ${lat}`;
444
+ const line1Colored = ` Account: ${chalk.cyan(acc)} Symbol: ${chalk.yellow(sym)} Qty: ${chalk.cyan(qty)} Server: ${serverColor(srv)} ${latencyColor(lat)}`;
445
+ console.log(chalk.cyan(V) + line1Colored + ' '.repeat(W - line1.length) + chalk.cyan(V));
446
+
447
+ // Target line
448
+ const tgt = ('$' + dailyTarget.toFixed(2)).padEnd(10);
449
+ const rsk = ('$' + maxRisk.toFixed(2)).padEnd(10);
450
+ const pnl = pnlStr.padEnd(10);
451
+ const trd = stats.trades.toString().padEnd(2);
452
+ const win = stats.wins.toString();
453
+ const los = stats.losses.toString();
454
+ const line2 = ` Target: ${tgt} Risk: ${rsk} P&L: ${pnl} Trades: ${trd} W:${win} L:${los}`;
455
+ const line2Colored = ` Target: ${chalk.green(tgt)} Risk: ${chalk.red(rsk)} P&L: ${pnlColor(pnl)} Trades: ${chalk.cyan(trd)} W:${chalk.green(win)} L:${chalk.red(los)}`;
456
+ console.log(chalk.cyan(V) + line2Colored + ' '.repeat(W - line2.length) + chalk.cyan(V));
457
+ console.log(chalk.cyan(MID));
458
+
459
+ // Activity log header
460
+ const actLeft = ` Activity Log - ${dateStr}`;
461
+ const actRight = 'Press X to stop ';
462
+ const actMid = W - actLeft.length - actRight.length;
463
+ console.log(chalk.cyan(V) + chalk.white(actLeft) + ' '.repeat(actMid) + chalk.yellow(actRight) + chalk.cyan(V));
464
+ console.log(chalk.cyan(BOT));
465
+
466
+ // Logs (without borders)
467
+ console.log();
413
468
  if (logs.length === 0) {
414
- console.log(chalk.cyan('|') + chalk.gray(' Waiting for activity...'.padEnd(111)) + chalk.cyan('|'));
469
+ console.log(chalk.gray(' Waiting for activity...'));
415
470
  } else {
416
471
  logs.forEach(log => {
417
472
  const color = typeColors[log.type] || chalk.white;
418
473
  const icon = getIcon(log.type);
419
- const logLine = `[${log.timestamp}] ${icon} ${log.message}`;
420
- const truncated = logLine.length > 109 ? logLine.substring(0, 106) + '...' : logLine;
421
- console.log(chalk.cyan('|') + ' ' + color(truncated.padEnd(110)) + chalk.cyan('|'));
474
+ console.log(color(` [${log.timestamp}] ${icon} ${log.message}`));
422
475
  });
423
476
  }
424
-
425
- console.log(chalk.cyan('+=================================================================================================================+'));
426
477
  };
427
478
 
428
479
  // Connect to HQX Server