hedgequantx 1.2.74 → 1.2.75

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 +60 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "1.2.74",
3
+ "version": "1.2.75",
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
@@ -309,6 +309,7 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
309
309
  let latency = 0;
310
310
  let spinnerFrame = 0;
311
311
  const spinnerChars = ['\u280B', '\u2819', '\u2839', '\u2838', '\u283C', '\u2834', '\u2826', '\u2827', '\u2807', '\u280F'];
312
+ const sessionStartTime = Date.now();
312
313
 
313
314
  // Stats
314
315
  let stats = {
@@ -789,19 +790,65 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
789
790
  }
790
791
  console.log();
791
792
 
792
- // Final stats
793
- console.log(chalk.gray(getSeparator()));
794
- console.log(chalk.white.bold(' Session Summary'));
795
- console.log(chalk.gray(getSeparator()));
796
- console.log(chalk.white(` Daily Target: ${chalk.green('$' + dailyTarget.toFixed(2))}`));
797
- console.log(chalk.white(` Max Risk: ${chalk.red('$' + maxRisk.toFixed(2))}`));
798
- console.log(chalk.white(` Final P&L: ${stats.pnl >= 0 ? chalk.green('+$' + stats.pnl.toFixed(2)) : chalk.red('-$' + Math.abs(stats.pnl).toFixed(2))}`));
799
- console.log(chalk.gray(getSeparator()));
800
- console.log(chalk.white(` Total Trades: ${chalk.cyan(stats.trades)}`));
801
- console.log(chalk.white(` Wins: ${chalk.green(stats.wins)}`));
802
- console.log(chalk.white(` Losses: ${chalk.red(stats.losses)}`));
803
- console.log(chalk.white(` Win Rate: ${chalk.yellow(stats.winRate + '%')}`));
804
- console.log(chalk.gray(getSeparator()));
793
+ // Final stats in a grid box
794
+ const V = '\u2551';
795
+ const VS = '\u2502';
796
+ const H = '\u2550';
797
+
798
+ // Calculate session duration
799
+ const sessionDuration = Date.now() - sessionStartTime;
800
+ const durationSec = Math.floor(sessionDuration / 1000);
801
+ const durationMin = Math.floor(durationSec / 60);
802
+ const durationHr = Math.floor(durationMin / 60);
803
+ const durationStr = durationHr > 0
804
+ ? `${durationHr}h ${durationMin % 60}m ${durationSec % 60}s`
805
+ : durationMin > 0
806
+ ? `${durationMin}m ${durationSec % 60}s`
807
+ : `${durationSec}s`;
808
+
809
+ // Cell widths: 4 cells of 24 each = 96
810
+ const cw = 24;
811
+ const W = cw * 4;
812
+
813
+ const TOP = '\u2554' + H.repeat(cw) + '\u2564' + H.repeat(cw) + '\u2564' + H.repeat(cw) + '\u2564' + H.repeat(cw) + '\u2557';
814
+ const MID = '\u2560' + H.repeat(cw) + '\u256A' + H.repeat(cw) + '\u256A' + H.repeat(cw) + '\u256A' + H.repeat(cw) + '\u2563';
815
+ const BOT = '\u255A' + H.repeat(cw) + '\u2567' + H.repeat(cw) + '\u2567' + H.repeat(cw) + '\u2567' + H.repeat(cw) + '\u255D';
816
+
817
+ const cell = (label, value, width) => {
818
+ const text = ` ${label}: ${value}`;
819
+ const stripped = text.replace(/\x1b\[[0-9;]*m/g, '');
820
+ return text + ' '.repeat(width - stripped.length);
821
+ };
822
+
823
+ const centerTitle = (text, width) => {
824
+ const pad = Math.floor((width - text.length) / 2);
825
+ return ' '.repeat(pad) + text + ' '.repeat(width - pad - text.length);
826
+ };
827
+
828
+ const pnlValue = stats.pnl >= 0 ? chalk.green('+$' + stats.pnl.toFixed(2)) : chalk.red('-$' + Math.abs(stats.pnl).toFixed(2));
829
+
830
+ console.log();
831
+ console.log(chalk.cyan('\u2554' + H.repeat(W) + '\u2557'));
832
+ console.log(chalk.cyan(V) + chalk.white.bold(centerTitle('Session Summary', W)) + chalk.cyan(V));
833
+ console.log(chalk.cyan(TOP.replace('\u2554', '\u2560').replace('\u2557', '\u2563')));
834
+
835
+ // Row 1: Target | Risk | P&L | Win Rate
836
+ const r1c1 = cell('Target', chalk.green('$' + dailyTarget.toFixed(2)), cw);
837
+ const r1c2 = cell('Risk', chalk.red('$' + maxRisk.toFixed(2)), cw);
838
+ const r1c3 = cell('P&L', pnlValue, cw);
839
+ const r1c4 = cell('Win Rate', chalk.yellow(stats.winRate + '%'), cw);
840
+ console.log(chalk.cyan(V) + r1c1 + chalk.cyan(VS) + r1c2 + chalk.cyan(VS) + r1c3 + chalk.cyan(VS) + r1c4 + chalk.cyan(V));
841
+
842
+ console.log(chalk.cyan(MID));
843
+
844
+ // Row 2: Trades | Wins | Losses | Duration
845
+ const r2c1 = cell('Trades', chalk.cyan(stats.trades.toString()), cw);
846
+ const r2c2 = cell('Wins', chalk.green(stats.wins.toString()), cw);
847
+ const r2c3 = cell('Losses', chalk.red(stats.losses.toString()), cw);
848
+ const r2c4 = cell('Duration', chalk.white(durationStr), cw);
849
+ console.log(chalk.cyan(V) + r2c1 + chalk.cyan(VS) + r2c2 + chalk.cyan(VS) + r2c3 + chalk.cyan(VS) + r2c4 + chalk.cyan(V));
850
+
851
+ console.log(chalk.cyan(BOT));
805
852
  console.log();
806
853
 
807
854
  await inquirer.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);