hedgequantx 1.2.77 → 1.2.79
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/pages/algo.js +58 -35
package/package.json
CHANGED
package/src/pages/algo.js
CHANGED
|
@@ -455,8 +455,8 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
455
455
|
const latLabel = 'WS';
|
|
456
456
|
const latVal = latencyStr;
|
|
457
457
|
|
|
458
|
-
// Row 1 cells: widths = 36 +
|
|
459
|
-
const c1w = 36, c2w =
|
|
458
|
+
// Row 1 cells: widths = 36 + 17 + 9 + 13 + 13 = 88 + 4 separators + 4 spaces = 96
|
|
459
|
+
const c1w = 36, c2w = 17, c3w = 9, c4w = 13, c5w = 17;
|
|
460
460
|
|
|
461
461
|
// Safe padding function
|
|
462
462
|
const safePad = (len) => ' '.repeat(Math.max(0, len));
|
|
@@ -478,11 +478,14 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
478
478
|
cell4 + safePad(c4w - cell4plain.length) + chalk.cyan(VS) +
|
|
479
479
|
cell5 + safePad(c5w - cell5plain.length);
|
|
480
480
|
|
|
481
|
+
// Top separator for grid (after HQX Ultra-Scalping)
|
|
482
|
+
const GRID_TOP = '\u2560' + '\u2550'.repeat(c1w) + '\u2564' + '\u2550'.repeat(c2w) + '\u2564' + '\u2550'.repeat(c3w) + '\u2564' + '\u2550'.repeat(c4w) + '\u2564' + '\u2550'.repeat(c5w) + '\u2563';
|
|
483
|
+
console.log(chalk.cyan(GRID_TOP));
|
|
484
|
+
|
|
481
485
|
console.log(chalk.cyan(V) + row1 + chalk.cyan(V));
|
|
482
486
|
|
|
483
|
-
//
|
|
484
|
-
const
|
|
485
|
-
console.log(chalk.cyan(SEP));
|
|
487
|
+
// Middle separator with intersections (between row1 and row2)
|
|
488
|
+
const GRID_MID = '\u2560' + '\u2550'.repeat(c1w) + '\u256A' + '\u2550'.repeat(c2w) + '\u256A' + '\u2550'.repeat(c3w) + '\u256A' + '\u2550'.repeat(c4w) + '\u256A' + '\u2550'.repeat(c5w) + '\u2563';
|
|
486
489
|
|
|
487
490
|
// Row 2: Target | Risk | P&L | Trades | W/L
|
|
488
491
|
const tgtLabel = 'Target';
|
|
@@ -513,8 +516,12 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
513
516
|
cell9 + safePad(c4w - cell9plain.length) + chalk.cyan(VS) +
|
|
514
517
|
cell10 + safePad(c5w - cell10plain.length);
|
|
515
518
|
|
|
519
|
+
console.log(chalk.cyan(GRID_MID));
|
|
516
520
|
console.log(chalk.cyan(V) + row2 + chalk.cyan(V));
|
|
517
|
-
|
|
521
|
+
|
|
522
|
+
// Bottom of grid (before Activity Log)
|
|
523
|
+
const GRID_BOT = '\u2560' + '\u2550'.repeat(c1w) + '\u2567' + '\u2550'.repeat(c2w) + '\u2567' + '\u2550'.repeat(c3w) + '\u2567' + '\u2550'.repeat(c4w) + '\u2567' + '\u2550'.repeat(c5w) + '\u2563';
|
|
524
|
+
console.log(chalk.cyan(GRID_BOT));
|
|
518
525
|
|
|
519
526
|
// Activity log header with spinner and centered date
|
|
520
527
|
spinnerFrame = (spinnerFrame + 1) % spinnerChars.length;
|
|
@@ -653,11 +660,21 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
653
660
|
|
|
654
661
|
hqxServer.on('error', (data) => {
|
|
655
662
|
printLog('error', data.message || 'Unknown error');
|
|
663
|
+
// Stop algo on connection error
|
|
664
|
+
if (!stopReason) {
|
|
665
|
+
stopReason = 'connection_error';
|
|
666
|
+
algoRunning = false;
|
|
667
|
+
}
|
|
656
668
|
});
|
|
657
669
|
|
|
658
670
|
hqxServer.on('disconnected', () => {
|
|
659
671
|
hqxConnected = false;
|
|
660
|
-
printLog('
|
|
672
|
+
printLog('error', 'Connection lost - Stopping algo');
|
|
673
|
+
// Stop algo on disconnect
|
|
674
|
+
if (!stopReason) {
|
|
675
|
+
stopReason = 'disconnected';
|
|
676
|
+
algoRunning = false;
|
|
677
|
+
}
|
|
661
678
|
});
|
|
662
679
|
|
|
663
680
|
// Display header once
|
|
@@ -790,15 +807,18 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
790
807
|
console.log(chalk.green.bold(' [OK] Daily target reached! Algo stopped.'));
|
|
791
808
|
} else if (stopReason === 'risk') {
|
|
792
809
|
console.log(chalk.red.bold(' [X] Max risk reached! Algo stopped.'));
|
|
810
|
+
} else if (stopReason === 'disconnected' || stopReason === 'connection_error') {
|
|
811
|
+
console.log(chalk.red.bold(' [X] Connection lost! Algo stopped.'));
|
|
793
812
|
} else {
|
|
794
813
|
console.log(chalk.yellow(' [OK] Algo stopped by user'));
|
|
795
814
|
}
|
|
796
815
|
console.log();
|
|
797
816
|
|
|
798
|
-
// Final stats in a grid box
|
|
799
|
-
const
|
|
800
|
-
const
|
|
801
|
-
const
|
|
817
|
+
// Final stats in a grid box - must match main UI width of 96
|
|
818
|
+
const summaryV = '\u2551';
|
|
819
|
+
const summaryVS = '\u2502';
|
|
820
|
+
const summaryH = '\u2550';
|
|
821
|
+
const summaryW = 96; // Same as main UI
|
|
802
822
|
|
|
803
823
|
// Calculate session duration
|
|
804
824
|
const sessionDuration = Date.now() - sessionStartTime;
|
|
@@ -811,50 +831,53 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
811
831
|
? `${durationMin}m ${durationSec % 60}s`
|
|
812
832
|
: `${durationSec}s`;
|
|
813
833
|
|
|
814
|
-
//
|
|
815
|
-
|
|
816
|
-
|
|
834
|
+
// 4 cells + 3 separators = 96 inner chars
|
|
835
|
+
// 96 - 3 separators = 93, divided by 4 = 23.25, so use 24+23+24+23 = 94... need 96
|
|
836
|
+
// Let's use: 24 + 24 + 24 + 21 = 93 + 3 sep = 96
|
|
837
|
+
const sc1 = 24, sc2 = 24, sc3 = 24, sc4 = 21;
|
|
817
838
|
|
|
818
|
-
const
|
|
819
|
-
const MID = '\u2560' + H.repeat(cw) + '\u256A' + H.repeat(cw) + '\u256A' + H.repeat(cw) + '\u256A' + H.repeat(cw) + '\u2563';
|
|
820
|
-
const BOT = '\u255A' + H.repeat(cw) + '\u2567' + H.repeat(cw) + '\u2567' + H.repeat(cw) + '\u2567' + H.repeat(cw) + '\u255D';
|
|
821
|
-
|
|
822
|
-
const cell = (label, value, width) => {
|
|
839
|
+
const summaryCell = (label, value, width) => {
|
|
823
840
|
const text = ` ${label}: ${value}`;
|
|
824
841
|
const stripped = text.replace(/\x1b\[[0-9;]*m/g, '');
|
|
825
842
|
const padding = Math.max(0, width - stripped.length);
|
|
826
843
|
return text + ' '.repeat(padding);
|
|
827
844
|
};
|
|
828
845
|
|
|
829
|
-
const
|
|
846
|
+
const centerSummaryTitle = (text, width) => {
|
|
830
847
|
const pad = Math.floor((width - text.length) / 2);
|
|
831
848
|
return ' '.repeat(pad) + text + ' '.repeat(width - pad - text.length);
|
|
832
849
|
};
|
|
833
850
|
|
|
834
851
|
const pnlValue = stats.pnl >= 0 ? chalk.green('+$' + stats.pnl.toFixed(2)) : chalk.red('-$' + Math.abs(stats.pnl).toFixed(2));
|
|
835
852
|
|
|
853
|
+
// Build separator lines
|
|
854
|
+
const SUMMARY_TOP = '\u2554' + summaryH.repeat(summaryW) + '\u2557';
|
|
855
|
+
const SUMMARY_GRID_TOP = '\u2560' + summaryH.repeat(sc1) + '\u2564' + summaryH.repeat(sc2) + '\u2564' + summaryH.repeat(sc3) + '\u2564' + summaryH.repeat(sc4) + '\u2563';
|
|
856
|
+
const SUMMARY_GRID_MID = '\u2560' + summaryH.repeat(sc1) + '\u256A' + summaryH.repeat(sc2) + '\u256A' + summaryH.repeat(sc3) + '\u256A' + summaryH.repeat(sc4) + '\u2563';
|
|
857
|
+
const SUMMARY_BOT = '\u255A' + summaryH.repeat(sc1) + '\u2567' + summaryH.repeat(sc2) + '\u2567' + summaryH.repeat(sc3) + '\u2567' + summaryH.repeat(sc4) + '\u255D';
|
|
858
|
+
|
|
836
859
|
console.log();
|
|
837
|
-
console.log(chalk.cyan(
|
|
838
|
-
console.log(chalk.cyan(
|
|
839
|
-
console.log(chalk.cyan(
|
|
860
|
+
console.log(chalk.cyan(SUMMARY_TOP));
|
|
861
|
+
console.log(chalk.cyan(summaryV) + chalk.white.bold(centerSummaryTitle('Session Summary', summaryW)) + chalk.cyan(summaryV));
|
|
862
|
+
console.log(chalk.cyan(SUMMARY_GRID_TOP));
|
|
840
863
|
|
|
841
864
|
// Row 1: Target | Risk | P&L | Win Rate
|
|
842
|
-
const r1c1 =
|
|
843
|
-
const r1c2 =
|
|
844
|
-
const r1c3 =
|
|
845
|
-
const r1c4 =
|
|
846
|
-
console.log(chalk.cyan(
|
|
865
|
+
const r1c1 = summaryCell('Target', chalk.green('$' + dailyTarget.toFixed(2)), sc1);
|
|
866
|
+
const r1c2 = summaryCell('Risk', chalk.red('$' + maxRisk.toFixed(2)), sc2);
|
|
867
|
+
const r1c3 = summaryCell('P&L', pnlValue, sc3);
|
|
868
|
+
const r1c4 = summaryCell('Win Rate', chalk.yellow(stats.winRate + '%'), sc4);
|
|
869
|
+
console.log(chalk.cyan(summaryV) + r1c1 + chalk.cyan(summaryVS) + r1c2 + chalk.cyan(summaryVS) + r1c3 + chalk.cyan(summaryVS) + r1c4 + chalk.cyan(summaryV));
|
|
847
870
|
|
|
848
|
-
console.log(chalk.cyan(
|
|
871
|
+
console.log(chalk.cyan(SUMMARY_GRID_MID));
|
|
849
872
|
|
|
850
873
|
// Row 2: Trades | Wins | Losses | Duration
|
|
851
|
-
const r2c1 =
|
|
852
|
-
const r2c2 =
|
|
853
|
-
const r2c3 =
|
|
854
|
-
const r2c4 =
|
|
855
|
-
console.log(chalk.cyan(
|
|
874
|
+
const r2c1 = summaryCell('Trades', chalk.cyan(stats.trades.toString()), sc1);
|
|
875
|
+
const r2c2 = summaryCell('Wins', chalk.green(stats.wins.toString()), sc2);
|
|
876
|
+
const r2c3 = summaryCell('Losses', chalk.red(stats.losses.toString()), sc3);
|
|
877
|
+
const r2c4 = summaryCell('Duration', chalk.white(durationStr), sc4);
|
|
878
|
+
console.log(chalk.cyan(summaryV) + r2c1 + chalk.cyan(summaryVS) + r2c2 + chalk.cyan(summaryVS) + r2c3 + chalk.cyan(summaryVS) + r2c4 + chalk.cyan(summaryV));
|
|
856
879
|
|
|
857
|
-
console.log(chalk.cyan(
|
|
880
|
+
console.log(chalk.cyan(SUMMARY_BOT));
|
|
858
881
|
console.log();
|
|
859
882
|
|
|
860
883
|
await inquirer.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|