hedgequantx 1.7.5 → 1.7.7
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 +2 -2
- package/src/app.js +38 -159
- package/src/menus/connect.js +54 -166
- package/src/menus/dashboard.js +39 -122
- package/src/pages/accounts.js +11 -22
- package/src/pages/algo/copy-trading.js +63 -210
- package/src/pages/algo/index.js +10 -20
- package/src/pages/algo/one-account.js +66 -172
- package/src/pages/orders.js +11 -32
- package/src/pages/positions.js +11 -32
- package/src/pages/stats.js +5 -14
- package/src/pages/user.js +8 -22
- package/src/utils/index.js +2 -1
- package/src/utils/prompts.js +87 -0
package/src/pages/user.js
CHANGED
|
@@ -1,55 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @module pages/user
|
|
2
|
+
* User info page
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
const chalk = require('chalk');
|
|
7
6
|
const ora = require('ora');
|
|
8
|
-
const inquirer = require('inquirer');
|
|
9
7
|
|
|
10
8
|
const { connections } = require('../services');
|
|
11
9
|
const { getLogoWidth, getColWidths, drawBoxHeader, drawBoxFooter, draw2ColHeader, visibleLength, padText } = require('../ui');
|
|
10
|
+
const { prompts } = require('../utils');
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {Object} service - Current service
|
|
13
|
+
* Show user info
|
|
16
14
|
*/
|
|
17
15
|
const showUserInfo = async (service) => {
|
|
18
16
|
const spinner = ora({ text: 'Fetching user info...', color: 'yellow' }).start();
|
|
19
17
|
const boxWidth = getLogoWidth();
|
|
20
18
|
const { col1, col2 } = getColWidths(boxWidth);
|
|
21
19
|
|
|
22
|
-
// Helper for row formatting
|
|
23
20
|
const fmtRow = (label, value, colW) => {
|
|
24
21
|
const labelStr = ' ' + label.padEnd(14);
|
|
25
22
|
const valueVisible = visibleLength(value || '');
|
|
26
|
-
const
|
|
27
|
-
const padding = Math.max(0, colW - totalVisible);
|
|
23
|
+
const padding = Math.max(0, colW - labelStr.length - valueVisible);
|
|
28
24
|
return chalk.white(labelStr) + value + ' '.repeat(padding);
|
|
29
25
|
};
|
|
30
26
|
|
|
31
|
-
// Get user info
|
|
32
27
|
let userInfo = null;
|
|
33
28
|
let accountCount = 0;
|
|
34
29
|
|
|
35
|
-
if (service
|
|
30
|
+
if (service?.user) {
|
|
36
31
|
userInfo = service.user;
|
|
37
32
|
} else if (service) {
|
|
38
33
|
const result = await service.getUser();
|
|
39
|
-
if (result.success)
|
|
40
|
-
userInfo = result.user;
|
|
41
|
-
}
|
|
34
|
+
if (result.success) userInfo = result.user;
|
|
42
35
|
}
|
|
43
36
|
|
|
44
|
-
// Get account count
|
|
45
37
|
if (connections.count() > 0) {
|
|
46
38
|
const accounts = await connections.getAllAccounts();
|
|
47
39
|
accountCount = accounts.length;
|
|
48
40
|
} else if (service) {
|
|
49
41
|
const result = await service.getTradingAccounts();
|
|
50
|
-
if (result.success)
|
|
51
|
-
accountCount = result.accounts.length;
|
|
52
|
-
}
|
|
42
|
+
if (result.success) accountCount = result.accounts.length;
|
|
53
43
|
}
|
|
54
44
|
|
|
55
45
|
spinner.succeed('User info loaded');
|
|
@@ -62,21 +52,17 @@ const showUserInfo = async (service) => {
|
|
|
62
52
|
} else {
|
|
63
53
|
draw2ColHeader('PROFILE', 'CONNECTIONS', boxWidth);
|
|
64
54
|
|
|
65
|
-
// Username
|
|
66
55
|
const username = userInfo.userName || userInfo.username || 'Unknown';
|
|
67
56
|
const connCount = connections.count() || 1;
|
|
68
57
|
console.log(chalk.cyan('║') + fmtRow('Username:', chalk.cyan(username.toUpperCase()), col1) + chalk.cyan('│') + fmtRow('Connections:', chalk.cyan(connCount.toString()), col2) + chalk.cyan('║'));
|
|
69
58
|
|
|
70
|
-
// Email
|
|
71
59
|
const email = userInfo.email || 'N/A';
|
|
72
60
|
console.log(chalk.cyan('║') + fmtRow('Email:', chalk.white(email), col1) + chalk.cyan('│') + fmtRow('Accounts:', chalk.cyan(accountCount.toString()), col2) + chalk.cyan('║'));
|
|
73
61
|
|
|
74
|
-
// User ID
|
|
75
62
|
const userId = userInfo.userId || userInfo.id || 'N/A';
|
|
76
63
|
const platform = service.propfirm?.name || 'ProjectX';
|
|
77
64
|
console.log(chalk.cyan('║') + fmtRow('User ID:', chalk.gray(userId.toString()), col1) + chalk.cyan('│') + fmtRow('Platform:', chalk.magenta(platform), col2) + chalk.cyan('║'));
|
|
78
65
|
|
|
79
|
-
// First/Last Name
|
|
80
66
|
const firstName = userInfo.firstName || '';
|
|
81
67
|
const lastName = userInfo.lastName || '';
|
|
82
68
|
const fullName = (firstName + ' ' + lastName).trim() || 'N/A';
|
|
@@ -86,7 +72,7 @@ const showUserInfo = async (service) => {
|
|
|
86
72
|
drawBoxFooter(boxWidth);
|
|
87
73
|
console.log();
|
|
88
74
|
|
|
89
|
-
await
|
|
75
|
+
await prompts.waitForEnter();
|
|
90
76
|
};
|
|
91
77
|
|
|
92
78
|
module.exports = { showUserInfo };
|
package/src/utils/index.js
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized prompts utility using @clack/prompts
|
|
3
|
+
* Replaces inquirer throughout the app
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { select, text, password, confirm, isCancel } = require('@clack/prompts');
|
|
7
|
+
const readline = require('readline');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Wait for Enter key
|
|
11
|
+
*/
|
|
12
|
+
const waitForEnter = (message = 'Press Enter to continue...') => new Promise(resolve => {
|
|
13
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
14
|
+
rl.question(message, () => { rl.close(); resolve(); });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Select from list
|
|
19
|
+
*/
|
|
20
|
+
const selectOption = async (message, options) => {
|
|
21
|
+
const result = await select({ message, options });
|
|
22
|
+
if (isCancel(result)) return null;
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Text input
|
|
28
|
+
*/
|
|
29
|
+
const textInput = async (message, initialValue = '', validate = null) => {
|
|
30
|
+
const opts = { message };
|
|
31
|
+
if (initialValue) opts.initialValue = initialValue;
|
|
32
|
+
if (validate) opts.validate = validate;
|
|
33
|
+
|
|
34
|
+
const result = await text(opts);
|
|
35
|
+
if (isCancel(result)) return null;
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Password input
|
|
41
|
+
*/
|
|
42
|
+
const passwordInput = async (message, validate = null) => {
|
|
43
|
+
const opts = { message };
|
|
44
|
+
if (validate) opts.validate = validate;
|
|
45
|
+
|
|
46
|
+
const result = await password(opts);
|
|
47
|
+
if (isCancel(result)) return null;
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Confirm yes/no
|
|
53
|
+
*/
|
|
54
|
+
const confirmPrompt = async (message, initial = true) => {
|
|
55
|
+
const result = await confirm({ message, initialValue: initial });
|
|
56
|
+
if (isCancel(result)) return null;
|
|
57
|
+
return result;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Number input with validation
|
|
62
|
+
*/
|
|
63
|
+
const numberInput = async (message, defaultVal = 1, min = 1, max = 1000) => {
|
|
64
|
+
const result = await text({
|
|
65
|
+
message,
|
|
66
|
+
initialValue: String(defaultVal),
|
|
67
|
+
validate: v => {
|
|
68
|
+
const n = parseInt(v);
|
|
69
|
+
if (isNaN(n)) return 'Enter a number';
|
|
70
|
+
if (n < min) return `Minimum is ${min}`;
|
|
71
|
+
if (n > max) return `Maximum is ${max}`;
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (isCancel(result)) return null;
|
|
76
|
+
return parseInt(result);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
waitForEnter,
|
|
81
|
+
selectOption,
|
|
82
|
+
textInput,
|
|
83
|
+
passwordInput,
|
|
84
|
+
confirmPrompt,
|
|
85
|
+
numberInput,
|
|
86
|
+
isCancel
|
|
87
|
+
};
|