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.
- package/package.json +1 -1
- package/src/pages/algo.js +75 -24
package/package.json
CHANGED
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 ?
|
|
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
|
-
//
|
|
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(
|
|
399
|
-
console.log(chalk.cyan(
|
|
400
|
-
console.log(chalk.cyan(
|
|
401
|
-
console.log(chalk.cyan(
|
|
402
|
-
console.log(chalk.cyan(
|
|
403
|
-
console.log(chalk.cyan('
|
|
404
|
-
console.log(chalk.cyan(
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
console.log(chalk.cyan(
|
|
409
|
-
console.log(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
|
-
//
|
|
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.
|
|
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
|
-
|
|
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
|