hedgequantx 1.3.7 → 1.3.9
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/menus/dashboard.js +4 -0
- package/src/pages/algo/one-account.js +14 -8
- package/src/services/session.js +24 -0
- package/src/ui/index.js +22 -1
package/package.json
CHANGED
package/src/menus/dashboard.js
CHANGED
|
@@ -113,6 +113,10 @@ const dashboardMenu = async (service) => {
|
|
|
113
113
|
console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
|
|
114
114
|
console.log();
|
|
115
115
|
|
|
116
|
+
// Small delay to ensure stdin is ready
|
|
117
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
118
|
+
prepareStdin();
|
|
119
|
+
|
|
116
120
|
const { action } = await inquirer.prompt([
|
|
117
121
|
{
|
|
118
122
|
type: 'input',
|
|
@@ -19,15 +19,16 @@ const { AlgoUI, checkMarketStatus } = require('./ui');
|
|
|
19
19
|
const oneAccountMenu = async (service) => {
|
|
20
20
|
const spinner = ora('Fetching active accounts...').start();
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// Get ALL accounts from ALL connections
|
|
23
|
+
const allAccounts = await connections.getAllAccounts();
|
|
23
24
|
|
|
24
|
-
if (!
|
|
25
|
+
if (!allAccounts?.length) {
|
|
25
26
|
spinner.fail('No accounts found');
|
|
26
27
|
await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter...' }]);
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
const activeAccounts =
|
|
31
|
+
const activeAccounts = allAccounts.filter(acc => acc.status === 0);
|
|
31
32
|
|
|
32
33
|
if (!activeAccounts.length) {
|
|
33
34
|
spinner.fail('No active accounts');
|
|
@@ -37,14 +38,16 @@ const oneAccountMenu = async (service) => {
|
|
|
37
38
|
|
|
38
39
|
spinner.succeed(`Found ${activeAccounts.length} active account(s)`);
|
|
39
40
|
|
|
40
|
-
// Select account
|
|
41
|
+
// Select account - show propfirm for clarity
|
|
41
42
|
const { selectedAccount } = await inquirer.prompt([{
|
|
42
43
|
type: 'list',
|
|
43
44
|
name: 'selectedAccount',
|
|
44
45
|
message: 'Select Account:',
|
|
45
46
|
choices: [
|
|
46
47
|
...activeAccounts.map(acc => ({
|
|
47
|
-
name: chalk.cyan(`${acc.accountName || acc.accountId}
|
|
48
|
+
name: chalk.cyan(`${acc.accountName || acc.accountId}`) +
|
|
49
|
+
chalk.gray(` (${acc.propfirm || 'Unknown'})`) +
|
|
50
|
+
chalk.white(` - $${(acc.balance || 0).toLocaleString()}`),
|
|
48
51
|
value: acc
|
|
49
52
|
})),
|
|
50
53
|
new inquirer.Separator(),
|
|
@@ -54,16 +57,19 @@ const oneAccountMenu = async (service) => {
|
|
|
54
57
|
|
|
55
58
|
if (selectedAccount === 'back') return;
|
|
56
59
|
|
|
60
|
+
// Find the service for this account
|
|
61
|
+
const accountService = connections.getServiceForAccount(selectedAccount.accountId) || service;
|
|
62
|
+
|
|
57
63
|
// Select symbol
|
|
58
|
-
const contract = await selectSymbol(
|
|
64
|
+
const contract = await selectSymbol(accountService, selectedAccount);
|
|
59
65
|
if (!contract) return;
|
|
60
66
|
|
|
61
67
|
// Configure algo
|
|
62
68
|
const config = await configureAlgo(selectedAccount, contract);
|
|
63
69
|
if (!config) return;
|
|
64
70
|
|
|
65
|
-
// Launch
|
|
66
|
-
await launchAlgo(
|
|
71
|
+
// Launch with the correct service for this account
|
|
72
|
+
await launchAlgo(accountService, selectedAccount, contract, config);
|
|
67
73
|
};
|
|
68
74
|
|
|
69
75
|
/**
|
package/src/services/session.js
CHANGED
|
@@ -261,6 +261,30 @@ const connections = {
|
|
|
261
261
|
return allAccounts;
|
|
262
262
|
},
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Gets the service for a specific account
|
|
266
|
+
* @param {string|number} accountId - Account ID to find
|
|
267
|
+
* @returns {Object|null} Service instance or null
|
|
268
|
+
*/
|
|
269
|
+
getServiceForAccount(accountId) {
|
|
270
|
+
for (const conn of this.services) {
|
|
271
|
+
try {
|
|
272
|
+
// Check if this service has this account
|
|
273
|
+
if (conn.service && conn.service.accounts) {
|
|
274
|
+
const found = conn.service.accounts.find(acc =>
|
|
275
|
+
acc.accountId == accountId ||
|
|
276
|
+
acc.rithmicAccountId == accountId ||
|
|
277
|
+
acc.accountName == accountId
|
|
278
|
+
);
|
|
279
|
+
if (found) return conn.service;
|
|
280
|
+
}
|
|
281
|
+
} catch (e) {
|
|
282
|
+
// Skip
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return null;
|
|
286
|
+
},
|
|
287
|
+
|
|
264
288
|
/**
|
|
265
289
|
* Checks if any connection is active
|
|
266
290
|
* @returns {boolean} True if connected
|
package/src/ui/index.js
CHANGED
|
@@ -29,11 +29,32 @@ const { createBoxMenu } = require('./menu');
|
|
|
29
29
|
* This fixes input leaking to bash after session restore or algo trading
|
|
30
30
|
*/
|
|
31
31
|
const prepareStdin = () => {
|
|
32
|
-
// Minimal intervention - just ensure stdin is flowing
|
|
33
32
|
try {
|
|
33
|
+
// Ensure stdin is flowing
|
|
34
34
|
if (process.stdin.isPaused()) {
|
|
35
35
|
process.stdin.resume();
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
// Reset stdin to proper state for inquirer
|
|
39
|
+
if (process.stdin.isTTY) {
|
|
40
|
+
// Disable raw mode if it was left on
|
|
41
|
+
if (process.stdin.isRaw) {
|
|
42
|
+
process.stdin.setRawMode(false);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Clear any buffered input by removing old listeners temporarily
|
|
47
|
+
const oldListeners = process.stdin.listeners('data');
|
|
48
|
+
process.stdin.removeAllListeners('data');
|
|
49
|
+
|
|
50
|
+
// Restore listeners after a tick
|
|
51
|
+
setImmediate(() => {
|
|
52
|
+
oldListeners.forEach(listener => {
|
|
53
|
+
if (!process.stdin.listeners('data').includes(listener)) {
|
|
54
|
+
process.stdin.on('data', listener);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
37
58
|
} catch (e) {
|
|
38
59
|
// Ignore errors
|
|
39
60
|
}
|