hedgequantx 1.2.70 → 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 +72 -27
package/package.json
CHANGED
package/src/pages/algo.js
CHANGED
|
@@ -379,14 +379,14 @@ 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();
|
|
@@ -395,40 +395,85 @@ const launchAlgo = async (service, account, contract, numContracts, dailyTarget,
|
|
|
395
395
|
// Get package version
|
|
396
396
|
const version = require('../../package.json').version;
|
|
397
397
|
|
|
398
|
-
//
|
|
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
|
+
|
|
399
417
|
console.log();
|
|
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
|
-
console.log(chalk.cyan(
|
|
406
|
-
console.log(chalk.cyan(
|
|
407
|
-
console.log(chalk.cyan(
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
console.log(chalk.cyan(
|
|
412
|
-
console.log(chalk.cyan(
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
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));
|
|
431
|
+
|
|
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));
|
|
417
436
|
|
|
418
|
-
//
|
|
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();
|
|
419
468
|
if (logs.length === 0) {
|
|
420
|
-
console.log(chalk.
|
|
469
|
+
console.log(chalk.gray(' Waiting for activity...'));
|
|
421
470
|
} else {
|
|
422
471
|
logs.forEach(log => {
|
|
423
472
|
const color = typeColors[log.type] || chalk.white;
|
|
424
473
|
const icon = getIcon(log.type);
|
|
425
|
-
|
|
426
|
-
const truncated = logLine.length > 93 ? logLine.substring(0, 90) + '...' : logLine;
|
|
427
|
-
console.log(chalk.cyan('\u2551') + ' ' + color(truncated.padEnd(94)) + chalk.cyan('\u2551'));
|
|
474
|
+
console.log(color(` [${log.timestamp}] ${icon} ${log.message}`));
|
|
428
475
|
});
|
|
429
476
|
}
|
|
430
|
-
|
|
431
|
-
console.log(chalk.cyan('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D'));
|
|
432
477
|
};
|
|
433
478
|
|
|
434
479
|
// Connect to HQX Server
|