hedgequantx 1.3.12 → 1.3.13
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/app.js +52 -22
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -22,6 +22,9 @@ const { projectXMenu, rithmicMenu, tradovateMenu, addPropAccountMenu, dashboardM
|
|
|
22
22
|
let currentService = null;
|
|
23
23
|
let currentPlatform = null; // 'projectx' or 'rithmic'
|
|
24
24
|
|
|
25
|
+
// Cached stats for banner (avoid refetching on every screen)
|
|
26
|
+
let cachedStats = null;
|
|
27
|
+
|
|
25
28
|
/**
|
|
26
29
|
* Global terminal restoration - ensures terminal is always restored on exit
|
|
27
30
|
*/
|
|
@@ -58,20 +61,9 @@ process.on('unhandledRejection', (reason) => {
|
|
|
58
61
|
});
|
|
59
62
|
|
|
60
63
|
/**
|
|
61
|
-
*
|
|
64
|
+
* Refresh cached stats (call after connection/disconnection/add account)
|
|
62
65
|
*/
|
|
63
|
-
const
|
|
64
|
-
console.clear();
|
|
65
|
-
const termWidth = process.stdout.columns || 100;
|
|
66
|
-
const isMobile = termWidth < 60;
|
|
67
|
-
// Logo HEDGEQUANTX + X = 94 chars, need 98 for box (94 + 2 borders + 2 padding)
|
|
68
|
-
const boxWidth = isMobile ? Math.max(termWidth - 2, 40) : Math.max(getLogoWidth(), 98);
|
|
69
|
-
const innerWidth = boxWidth - 2;
|
|
70
|
-
const version = require('../package.json').version;
|
|
71
|
-
|
|
72
|
-
// Get stats if connected (only active accounts: status === 0)
|
|
73
|
-
// STRICT: Only display values from API, no estimation
|
|
74
|
-
let statsInfo = null;
|
|
66
|
+
const refreshStats = async () => {
|
|
75
67
|
if (connections.count() > 0) {
|
|
76
68
|
try {
|
|
77
69
|
const allAccounts = await connections.getAllAccounts();
|
|
@@ -97,18 +89,35 @@ const banner = async () => {
|
|
|
97
89
|
}
|
|
98
90
|
});
|
|
99
91
|
|
|
100
|
-
|
|
92
|
+
cachedStats = {
|
|
101
93
|
connections: connections.count(),
|
|
102
94
|
accounts: activeAccounts.length,
|
|
103
95
|
balance: hasBalanceData ? totalBalance : null,
|
|
104
96
|
pnl: hasPnlData ? totalPnl : null,
|
|
105
|
-
// No percentage calculation if no verified data
|
|
106
97
|
pnlPercent: null
|
|
107
98
|
};
|
|
108
99
|
} catch (e) {
|
|
109
100
|
// Ignore errors
|
|
110
101
|
}
|
|
102
|
+
} else {
|
|
103
|
+
cachedStats = null;
|
|
111
104
|
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Displays the application banner with stats if connected
|
|
109
|
+
*/
|
|
110
|
+
const banner = async () => {
|
|
111
|
+
console.clear();
|
|
112
|
+
const termWidth = process.stdout.columns || 100;
|
|
113
|
+
const isMobile = termWidth < 60;
|
|
114
|
+
// Logo HEDGEQUANTX + X = 94 chars, need 98 for box (94 + 2 borders + 2 padding)
|
|
115
|
+
const boxWidth = isMobile ? Math.max(termWidth - 2, 40) : Math.max(getLogoWidth(), 98);
|
|
116
|
+
const innerWidth = boxWidth - 2;
|
|
117
|
+
const version = require('../package.json').version;
|
|
118
|
+
|
|
119
|
+
// Use cached stats (no refetch on every banner display)
|
|
120
|
+
const statsInfo = cachedStats;
|
|
112
121
|
|
|
113
122
|
// Draw logo - compact for mobile, full for desktop
|
|
114
123
|
|
|
@@ -292,6 +301,8 @@ const run = async () => {
|
|
|
292
301
|
if (restored) {
|
|
293
302
|
spinner.succeed('Session restored');
|
|
294
303
|
currentService = connections.getAll()[0].service;
|
|
304
|
+
// Refresh stats after session restore
|
|
305
|
+
await refreshStats();
|
|
295
306
|
} else {
|
|
296
307
|
spinner.info('No active session');
|
|
297
308
|
}
|
|
@@ -302,7 +313,7 @@ const run = async () => {
|
|
|
302
313
|
// Ensure stdin is ready for prompts (fixes input leaking to bash)
|
|
303
314
|
prepareStdin();
|
|
304
315
|
|
|
305
|
-
//
|
|
316
|
+
// Display banner (uses cached stats, no refetch)
|
|
306
317
|
await banner();
|
|
307
318
|
|
|
308
319
|
if (!connections.isConnected()) {
|
|
@@ -315,17 +326,26 @@ const run = async () => {
|
|
|
315
326
|
|
|
316
327
|
if (choice === 'projectx') {
|
|
317
328
|
const service = await projectXMenu();
|
|
318
|
-
if (service)
|
|
329
|
+
if (service) {
|
|
330
|
+
currentService = service;
|
|
331
|
+
await refreshStats(); // Refresh after new connection
|
|
332
|
+
}
|
|
319
333
|
}
|
|
320
334
|
|
|
321
335
|
if (choice === 'rithmic') {
|
|
322
336
|
const service = await rithmicMenu();
|
|
323
|
-
if (service)
|
|
337
|
+
if (service) {
|
|
338
|
+
currentService = service;
|
|
339
|
+
await refreshStats(); // Refresh after new connection
|
|
340
|
+
}
|
|
324
341
|
}
|
|
325
342
|
|
|
326
343
|
if (choice === 'tradovate') {
|
|
327
344
|
const service = await tradovateMenu();
|
|
328
|
-
if (service)
|
|
345
|
+
if (service) {
|
|
346
|
+
currentService = service;
|
|
347
|
+
await refreshStats(); // Refresh after new connection
|
|
348
|
+
}
|
|
329
349
|
}
|
|
330
350
|
} else {
|
|
331
351
|
const action = await dashboardMenu(currentService);
|
|
@@ -343,13 +363,22 @@ const run = async () => {
|
|
|
343
363
|
const platformChoice = await addPropAccountMenu();
|
|
344
364
|
if (platformChoice === 'projectx') {
|
|
345
365
|
const newService = await projectXMenu();
|
|
346
|
-
if (newService)
|
|
366
|
+
if (newService) {
|
|
367
|
+
currentService = newService;
|
|
368
|
+
await refreshStats(); // Refresh after adding account
|
|
369
|
+
}
|
|
347
370
|
} else if (platformChoice === 'rithmic') {
|
|
348
371
|
const newService = await rithmicMenu();
|
|
349
|
-
if (newService)
|
|
372
|
+
if (newService) {
|
|
373
|
+
currentService = newService;
|
|
374
|
+
await refreshStats(); // Refresh after adding account
|
|
375
|
+
}
|
|
350
376
|
} else if (platformChoice === 'tradovate') {
|
|
351
377
|
const newService = await tradovateMenu();
|
|
352
|
-
if (newService)
|
|
378
|
+
if (newService) {
|
|
379
|
+
currentService = newService;
|
|
380
|
+
await refreshStats(); // Refresh after adding account
|
|
381
|
+
}
|
|
353
382
|
}
|
|
354
383
|
break;
|
|
355
384
|
case 'algotrading':
|
|
@@ -363,6 +392,7 @@ const run = async () => {
|
|
|
363
392
|
const connCount = connections.count();
|
|
364
393
|
connections.disconnectAll();
|
|
365
394
|
currentService = null;
|
|
395
|
+
cachedStats = null; // Clear cached stats
|
|
366
396
|
console.log(chalk.yellow(`Disconnected ${connCount} connection${connCount > 1 ? 's' : ''}`));
|
|
367
397
|
break;
|
|
368
398
|
case 'exit':
|