hedgequantx 1.8.47 → 1.8.48
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/accounts.js +10 -26
- package/src/pages/stats.js +8 -27
- package/src/utils/prompts.js +15 -10
package/package.json
CHANGED
package/src/pages/accounts.js
CHANGED
|
@@ -28,8 +28,8 @@ const showAccounts = async (service) => {
|
|
|
28
28
|
let spinner;
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
//
|
|
32
|
-
spinner = ora({ text: 'Loading
|
|
31
|
+
// Single spinner for loading
|
|
32
|
+
spinner = ora({ text: 'Loading accounts...', color: 'yellow' }).start();
|
|
33
33
|
|
|
34
34
|
const allConns = connections.count() > 0 ? connections.getAll() : (service ? [{ service, propfirm: service.propfirm?.name || 'Unknown', type: 'single' }] : []);
|
|
35
35
|
|
|
@@ -38,16 +38,11 @@ const showAccounts = async (service) => {
|
|
|
38
38
|
await prompts.waitForEnter();
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
spinner.succeed(`Found ${allConns.length} connection(s)`);
|
|
43
41
|
|
|
44
|
-
//
|
|
45
|
-
for (
|
|
46
|
-
const conn = allConns[i];
|
|
42
|
+
// Fetch accounts from each connection
|
|
43
|
+
for (const conn of allConns) {
|
|
47
44
|
const propfirmName = conn.propfirm || conn.type || 'Unknown';
|
|
48
45
|
|
|
49
|
-
spinner = ora({ text: `Fetching accounts from ${propfirmName}...`, color: 'yellow' }).start();
|
|
50
|
-
|
|
51
46
|
try {
|
|
52
47
|
const result = await conn.service.getTradingAccounts();
|
|
53
48
|
if (result.success && result.accounts && result.accounts.length > 0) {
|
|
@@ -58,29 +53,21 @@ const showAccounts = async (service) => {
|
|
|
58
53
|
service: conn.service
|
|
59
54
|
});
|
|
60
55
|
});
|
|
61
|
-
spinner.succeed(`${propfirmName}: ${result.accounts.length} account(s)`);
|
|
62
|
-
} else {
|
|
63
|
-
spinner.warn(`${propfirmName}: No accounts found`);
|
|
64
56
|
}
|
|
65
57
|
} catch (e) {
|
|
66
|
-
|
|
58
|
+
// Silent fail
|
|
67
59
|
}
|
|
68
60
|
}
|
|
69
61
|
|
|
70
|
-
// Step 3: Check if we have accounts
|
|
71
62
|
if (allAccounts.length === 0) {
|
|
72
|
-
|
|
63
|
+
spinner.fail('No accounts found');
|
|
73
64
|
await prompts.waitForEnter();
|
|
74
65
|
return;
|
|
75
66
|
}
|
|
76
67
|
|
|
77
|
-
//
|
|
78
|
-
spinner = ora({ text: 'Loading account details...', color: 'yellow' }).start();
|
|
79
|
-
|
|
80
|
-
let detailsLoaded = 0;
|
|
68
|
+
// Fetch additional data for each account
|
|
81
69
|
for (const account of allAccounts) {
|
|
82
70
|
try {
|
|
83
|
-
// Try to get fresh balance/P&L if available
|
|
84
71
|
if (account.service && typeof account.service.getAccountBalance === 'function') {
|
|
85
72
|
const balanceResult = await account.service.getAccountBalance(account.accountId);
|
|
86
73
|
if (balanceResult.success) {
|
|
@@ -88,14 +75,11 @@ const showAccounts = async (service) => {
|
|
|
88
75
|
account.profitAndLoss = balanceResult.profitAndLoss;
|
|
89
76
|
}
|
|
90
77
|
}
|
|
91
|
-
|
|
92
|
-
spinner.text = `Loading account details... (${detailsLoaded}/${allAccounts.length})`;
|
|
93
|
-
} catch (e) {
|
|
94
|
-
// Continue with existing data
|
|
95
|
-
}
|
|
78
|
+
} catch (e) {}
|
|
96
79
|
}
|
|
97
80
|
|
|
98
|
-
spinner.
|
|
81
|
+
spinner.stop();
|
|
82
|
+
console.clear();
|
|
99
83
|
console.log();
|
|
100
84
|
|
|
101
85
|
// Display accounts
|
package/src/pages/stats.js
CHANGED
|
@@ -17,8 +17,8 @@ const showStats = async (service) => {
|
|
|
17
17
|
let spinner;
|
|
18
18
|
|
|
19
19
|
try {
|
|
20
|
-
//
|
|
21
|
-
spinner = ora({ text: 'Loading
|
|
20
|
+
// Single spinner for loading
|
|
21
|
+
spinner = ora({ text: 'Loading stats...', color: 'yellow' }).start();
|
|
22
22
|
|
|
23
23
|
const allConns = connections.count() > 0
|
|
24
24
|
? connections.getAll()
|
|
@@ -29,14 +29,12 @@ const showStats = async (service) => {
|
|
|
29
29
|
await prompts.waitForEnter();
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
spinner.succeed(`Found ${allConns.length} connection(s)`);
|
|
33
32
|
|
|
34
|
-
//
|
|
33
|
+
// Fetch accounts from each connection
|
|
35
34
|
let allAccountsData = [];
|
|
36
35
|
|
|
37
36
|
for (const conn of allConns) {
|
|
38
37
|
const propfirmName = conn.propfirm || conn.type || 'Unknown';
|
|
39
|
-
spinner = ora({ text: `Fetching accounts from ${propfirmName}...`, color: 'yellow' }).start();
|
|
40
38
|
|
|
41
39
|
try {
|
|
42
40
|
const result = await conn.service.getTradingAccounts();
|
|
@@ -48,17 +46,12 @@ const showStats = async (service) => {
|
|
|
48
46
|
service: conn.service
|
|
49
47
|
});
|
|
50
48
|
});
|
|
51
|
-
spinner.succeed(`${propfirmName}: ${result.accounts.length} account(s)`);
|
|
52
|
-
} else {
|
|
53
|
-
spinner.warn(`${propfirmName}: No accounts`);
|
|
54
49
|
}
|
|
55
|
-
} catch (e) {
|
|
56
|
-
spinner.fail(`${propfirmName}: Failed`);
|
|
57
|
-
}
|
|
50
|
+
} catch (e) {}
|
|
58
51
|
}
|
|
59
52
|
|
|
60
53
|
if (allAccountsData.length === 0) {
|
|
61
|
-
|
|
54
|
+
spinner.fail('No accounts found');
|
|
62
55
|
await prompts.waitForEnter();
|
|
63
56
|
return;
|
|
64
57
|
}
|
|
@@ -76,12 +69,12 @@ const showStats = async (service) => {
|
|
|
76
69
|
const activeAccounts = allAccountsData.filter(acc => acc.status === 0);
|
|
77
70
|
|
|
78
71
|
if (activeAccounts.length === 0) {
|
|
79
|
-
|
|
72
|
+
spinner.fail('No active accounts found');
|
|
80
73
|
await prompts.waitForEnter();
|
|
81
74
|
return;
|
|
82
75
|
}
|
|
83
76
|
|
|
84
|
-
//
|
|
77
|
+
// Collect stats for each account
|
|
85
78
|
let totalBalance = 0;
|
|
86
79
|
let totalPnL = 0;
|
|
87
80
|
let totalStartingBalance = 0;
|
|
@@ -94,9 +87,6 @@ const showStats = async (service) => {
|
|
|
94
87
|
for (let i = 0; i < activeAccounts.length; i++) {
|
|
95
88
|
const account = activeAccounts[i];
|
|
96
89
|
const svc = account.service;
|
|
97
|
-
const accName = String(account.accountId || account.accountName || `Account ${i+1}`).substring(0, 20);
|
|
98
|
-
|
|
99
|
-
spinner = ora({ text: `Loading stats for ${accName}...`, color: 'yellow' }).start();
|
|
100
90
|
|
|
101
91
|
try {
|
|
102
92
|
// Balance
|
|
@@ -118,7 +108,6 @@ const showStats = async (service) => {
|
|
|
118
108
|
}
|
|
119
109
|
|
|
120
110
|
// Positions
|
|
121
|
-
spinner.text = `Loading positions for ${accName}...`;
|
|
122
111
|
try {
|
|
123
112
|
const posResult = await svc.getPositions(account.accountId);
|
|
124
113
|
if (posResult.success && posResult.positions) {
|
|
@@ -127,7 +116,6 @@ const showStats = async (service) => {
|
|
|
127
116
|
} catch (e) {}
|
|
128
117
|
|
|
129
118
|
// Orders
|
|
130
|
-
spinner.text = `Loading orders for ${accName}...`;
|
|
131
119
|
try {
|
|
132
120
|
const ordResult = await svc.getOrders(account.accountId);
|
|
133
121
|
if (ordResult.success && ordResult.orders) {
|
|
@@ -136,7 +124,6 @@ const showStats = async (service) => {
|
|
|
136
124
|
} catch (e) {}
|
|
137
125
|
|
|
138
126
|
// Lifetime stats
|
|
139
|
-
spinner.text = `Loading lifetime stats for ${accName}...`;
|
|
140
127
|
if (typeof svc.getLifetimeStats === 'function') {
|
|
141
128
|
try {
|
|
142
129
|
const lifetimeResult = await svc.getLifetimeStats(account.accountId);
|
|
@@ -147,7 +134,6 @@ const showStats = async (service) => {
|
|
|
147
134
|
}
|
|
148
135
|
|
|
149
136
|
// Trade history
|
|
150
|
-
spinner.text = `Loading trade history for ${accName}...`;
|
|
151
137
|
if (typeof svc.getTradeHistory === 'function') {
|
|
152
138
|
try {
|
|
153
139
|
const tradesResult = await svc.getTradeHistory(account.accountId, 30);
|
|
@@ -160,15 +146,10 @@ const showStats = async (service) => {
|
|
|
160
146
|
}
|
|
161
147
|
} catch (e) {}
|
|
162
148
|
}
|
|
163
|
-
|
|
164
|
-
spinner.succeed(`${accName}: Stats loaded`);
|
|
165
|
-
} catch (e) {
|
|
166
|
-
spinner.fail(`${accName}: Failed to load stats`);
|
|
167
|
-
}
|
|
149
|
+
} catch (e) {}
|
|
168
150
|
}
|
|
169
151
|
|
|
170
152
|
// Aggregate stats
|
|
171
|
-
spinner = ora({ text: 'Calculating metrics...', color: 'yellow' }).start();
|
|
172
153
|
|
|
173
154
|
let stats = {
|
|
174
155
|
totalTrades: 0, winningTrades: 0, losingTrades: 0,
|
package/src/utils/prompts.js
CHANGED
|
@@ -46,13 +46,13 @@ const prepareStdin = () => {
|
|
|
46
46
|
* Native readline prompt
|
|
47
47
|
*/
|
|
48
48
|
const nativePrompt = (message) => {
|
|
49
|
-
return new Promise((resolve
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
50
|
try {
|
|
51
51
|
prepareStdin();
|
|
52
52
|
|
|
53
53
|
// Always create a fresh readline for each prompt to avoid state issues
|
|
54
54
|
if (rl && !rl.closed) {
|
|
55
|
-
rl.close();
|
|
55
|
+
try { rl.close(); } catch (e) {}
|
|
56
56
|
rl = null;
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -62,18 +62,23 @@ const nativePrompt = (message) => {
|
|
|
62
62
|
terminal: true
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
rl.on('close', () => {
|
|
67
|
-
resolve('');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
rl.on('error', (err) => {
|
|
71
|
-
resolve('');
|
|
72
|
-
});
|
|
65
|
+
let answered = false;
|
|
73
66
|
|
|
74
67
|
rl.question(message + ' ', (answer) => {
|
|
68
|
+
answered = true;
|
|
69
|
+
try { rl.close(); } catch (e) {}
|
|
70
|
+
rl = null;
|
|
75
71
|
resolve(answer || '');
|
|
76
72
|
});
|
|
73
|
+
|
|
74
|
+
// Handle readline close (e.g., Ctrl+C)
|
|
75
|
+
rl.on('close', () => {
|
|
76
|
+
if (!answered) {
|
|
77
|
+
rl = null;
|
|
78
|
+
resolve('');
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
77
82
|
} catch (e) {
|
|
78
83
|
resolve('');
|
|
79
84
|
}
|