hedgequantx 2.7.59 → 2.7.61
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/ai-agents-ui.js +53 -42
- package/src/pages/algo/index.js +38 -18
- package/src/pages/user.js +5 -1
package/package.json
CHANGED
|
@@ -85,29 +85,68 @@ const draw2ColRowCentered = (leftText, rightText, W) => {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* Draw providers table
|
|
88
|
+
* Draw providers table with vertically aligned columns
|
|
89
89
|
* @param {Array} providers - List of AI providers
|
|
90
90
|
* @param {Object} config - Current config
|
|
91
91
|
* @param {number} boxWidth - Box width
|
|
92
92
|
*/
|
|
93
93
|
const drawProvidersTable = (providers, config, boxWidth) => {
|
|
94
94
|
const W = boxWidth - 2;
|
|
95
|
+
const colWidth = Math.floor(W / 2);
|
|
95
96
|
|
|
96
97
|
// New rectangle (banner is always closed)
|
|
97
98
|
console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
|
|
98
99
|
console.log(chalk.cyan('║') + chalk.yellow.bold(centerText('AI AGENTS CONFIGURATION', W)) + chalk.cyan('║'));
|
|
99
100
|
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
100
101
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
const rows = Math.ceil(providers.length / 2);
|
|
103
|
+
|
|
104
|
+
// Find max name length across ALL providers for consistent alignment
|
|
105
|
+
const maxNameLen = Math.max(...providers.map(p => p.name.length));
|
|
106
|
+
|
|
107
|
+
// Fixed format: "[N] NAME" where N is always same width, NAME padded to maxNameLen
|
|
108
|
+
// Total content width = 3 ([N]) + 1 (space) + maxNameLen + 2 (possible " ●")
|
|
109
|
+
const contentWidth = 3 + 1 + maxNameLen + 2;
|
|
110
|
+
const leftPad = Math.floor((colWidth - contentWidth) / 2);
|
|
111
|
+
const rightPad = Math.floor(((W - colWidth) - contentWidth) / 2);
|
|
105
112
|
|
|
106
|
-
const rows = Math.ceil(items.length / 2);
|
|
107
113
|
for (let row = 0; row < rows; row++) {
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
|
|
114
|
+
const leftP = providers[row];
|
|
115
|
+
const rightP = providers[row + rows];
|
|
116
|
+
|
|
117
|
+
// Left column
|
|
118
|
+
let leftCol = '';
|
|
119
|
+
if (leftP) {
|
|
120
|
+
const num = row + 1;
|
|
121
|
+
const status = config.providers[leftP.id]?.active ? chalk.green(' ●') : ' ';
|
|
122
|
+
const statusRaw = config.providers[leftP.id]?.active ? ' ●' : ' ';
|
|
123
|
+
const name = leftP.provider ? leftP.provider.name : leftP.name;
|
|
124
|
+
const namePadded = name.toUpperCase().padEnd(maxNameLen);
|
|
125
|
+
const content = chalk.cyan(`[${num}]`) + ' ' + chalk[leftP.color](namePadded) + status;
|
|
126
|
+
const contentLen = 3 + 1 + maxNameLen + 2;
|
|
127
|
+
const padR = colWidth - leftPad - contentLen;
|
|
128
|
+
leftCol = ' '.repeat(leftPad) + content + ' '.repeat(Math.max(0, padR));
|
|
129
|
+
} else {
|
|
130
|
+
leftCol = ' '.repeat(colWidth);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Right column
|
|
134
|
+
let rightCol = '';
|
|
135
|
+
const rightColWidth = W - colWidth;
|
|
136
|
+
if (rightP) {
|
|
137
|
+
const num = row + rows + 1;
|
|
138
|
+
const status = config.providers[rightP.id]?.active ? chalk.green(' ●') : ' ';
|
|
139
|
+
const name = rightP.provider ? rightP.provider.name : rightP.name;
|
|
140
|
+
const namePadded = name.toUpperCase().padEnd(maxNameLen);
|
|
141
|
+
const content = chalk.cyan(`[${num}]`) + ' ' + chalk[rightP.color](namePadded) + status;
|
|
142
|
+
const contentLen = 3 + 1 + maxNameLen + 2;
|
|
143
|
+
const padR2 = rightColWidth - rightPad - contentLen;
|
|
144
|
+
rightCol = ' '.repeat(rightPad) + content + ' '.repeat(Math.max(0, padR2));
|
|
145
|
+
} else {
|
|
146
|
+
rightCol = ' '.repeat(rightColWidth);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(chalk.cyan('║') + leftCol + rightCol + chalk.cyan('║'));
|
|
111
150
|
}
|
|
112
151
|
|
|
113
152
|
console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
|
|
@@ -144,18 +183,12 @@ const drawProviderWindow = (provider, config, boxWidth) => {
|
|
|
144
183
|
console.log(chalk.cyan('║') + chalk[provider.color].bold(centerText(provider.name.toUpperCase(), W)) + chalk.cyan('║'));
|
|
145
184
|
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
146
185
|
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// Options in 2 columns
|
|
151
|
-
const opt1Title = '[1] CONNECT VIA PAID PLAN';
|
|
152
|
-
const opt1Desc = 'USES CLIPROXY - NO API KEY NEEDED';
|
|
153
|
-
const opt2Title = '[2] CONNECT VIA API KEY';
|
|
154
|
-
const opt2Desc = 'ENTER YOUR OWN API KEY';
|
|
186
|
+
// Options in 2 columns (centered)
|
|
187
|
+
const opt1 = '[1] CONNECT VIA PAID PLAN';
|
|
188
|
+
const opt2 = '[2] CONNECT VIA API KEY';
|
|
155
189
|
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
const right1 = chalk.yellow(opt2Title);
|
|
190
|
+
const left1 = chalk.green(opt1);
|
|
191
|
+
const right1 = chalk.yellow(opt2);
|
|
159
192
|
const left1Len = visibleLength(left1);
|
|
160
193
|
const right1Len = visibleLength(right1);
|
|
161
194
|
const left1PadTotal = col1Width - left1Len;
|
|
@@ -172,28 +205,6 @@ const drawProviderWindow = (provider, config, boxWidth) => {
|
|
|
172
205
|
chalk.cyan('║')
|
|
173
206
|
);
|
|
174
207
|
|
|
175
|
-
// Row 2: Descriptions
|
|
176
|
-
const left2 = chalk.gray(opt1Desc);
|
|
177
|
-
const right2 = chalk.gray(opt2Desc);
|
|
178
|
-
const left2Len = visibleLength(left2);
|
|
179
|
-
const right2Len = visibleLength(right2);
|
|
180
|
-
const left2PadTotal = col1Width - left2Len;
|
|
181
|
-
const left2PadL = Math.floor(left2PadTotal / 2);
|
|
182
|
-
const left2PadR = left2PadTotal - left2PadL;
|
|
183
|
-
const right2PadTotal = col2Width - right2Len;
|
|
184
|
-
const right2PadL = Math.floor(right2PadTotal / 2);
|
|
185
|
-
const right2PadR = right2PadTotal - right2PadL;
|
|
186
|
-
|
|
187
|
-
console.log(
|
|
188
|
-
chalk.cyan('║') +
|
|
189
|
-
' '.repeat(left2PadL) + left2 + ' '.repeat(left2PadR) +
|
|
190
|
-
' '.repeat(right2PadL) + right2 + ' '.repeat(right2PadR) +
|
|
191
|
-
chalk.cyan('║')
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
// Empty line
|
|
195
|
-
console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
|
|
196
|
-
|
|
197
208
|
// Status bar
|
|
198
209
|
console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
|
|
199
210
|
|
package/src/pages/algo/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const chalk = require('chalk');
|
|
6
|
-
const {
|
|
6
|
+
const { getLogoWidth, centerText, displayBanner } = require('../../ui');
|
|
7
7
|
const { logger, prompts } = require('../../utils');
|
|
8
8
|
|
|
9
9
|
const log = logger.scope('AlgoMenu');
|
|
@@ -18,39 +18,59 @@ const algoTradingMenu = async (service) => {
|
|
|
18
18
|
log.info('Algo Trading menu opened');
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
|
-
|
|
22
|
-
console.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
// Clear screen and show banner
|
|
22
|
+
console.clear();
|
|
23
|
+
displayBanner();
|
|
24
|
+
|
|
25
|
+
const boxWidth = getLogoWidth();
|
|
26
|
+
const W = boxWidth - 2;
|
|
27
|
+
|
|
28
|
+
// Draw menu rectangle
|
|
29
|
+
console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
|
|
30
|
+
console.log(chalk.cyan('║') + chalk.magenta.bold(centerText('ALGO-TRADING', W)) + chalk.cyan('║'));
|
|
31
|
+
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
32
|
+
|
|
33
|
+
// Options centered in 2 columns
|
|
34
|
+
const col1 = '[1] ONE ACCOUNT';
|
|
35
|
+
const col2 = '[2] COPY TRADING';
|
|
36
|
+
const colWidth = Math.floor(W / 2);
|
|
37
|
+
const pad1 = Math.floor((colWidth - col1.length) / 2);
|
|
38
|
+
const pad2 = Math.floor((colWidth - col2.length) / 2);
|
|
39
|
+
const line = ' '.repeat(pad1) + chalk.cyan(col1) + ' '.repeat(colWidth - col1.length - pad1) +
|
|
40
|
+
' '.repeat(pad2) + chalk.cyan(col2) + ' '.repeat(colWidth - col2.length - pad2);
|
|
41
|
+
console.log(chalk.cyan('║') + line + chalk.cyan('║'));
|
|
42
|
+
|
|
43
|
+
console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
|
|
44
|
+
console.log(chalk.cyan('║') + chalk.red(centerText('[B] BACK', W)) + chalk.cyan('║'));
|
|
45
|
+
console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
|
|
26
46
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
{ value: 'copy_trading', label: 'Copy Trading' },
|
|
30
|
-
{ value: 'back', label: '< Back' }
|
|
31
|
-
]);
|
|
47
|
+
const input = await prompts.textInput(chalk.cyan('SELECT (1/2/B): '));
|
|
48
|
+
const choice = (input || '').toLowerCase().trim();
|
|
32
49
|
|
|
33
|
-
log.debug('Algo mode selected', {
|
|
50
|
+
log.debug('Algo mode selected', { choice });
|
|
34
51
|
|
|
35
|
-
if (
|
|
52
|
+
if (choice === 'b' || choice === '') {
|
|
36
53
|
return 'back';
|
|
37
54
|
}
|
|
38
55
|
|
|
39
|
-
switch (
|
|
40
|
-
case '
|
|
56
|
+
switch (choice) {
|
|
57
|
+
case '1':
|
|
41
58
|
log.info('Starting One Account mode');
|
|
42
59
|
await oneAccountMenu(service);
|
|
43
60
|
break;
|
|
44
|
-
case '
|
|
61
|
+
case '2':
|
|
45
62
|
log.info('Starting Copy Trading mode');
|
|
46
63
|
await copyTradingMenu();
|
|
47
64
|
break;
|
|
65
|
+
default:
|
|
66
|
+
console.log(chalk.red(' INVALID OPTION'));
|
|
67
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
48
68
|
}
|
|
49
69
|
|
|
50
|
-
return
|
|
70
|
+
return choice;
|
|
51
71
|
} catch (err) {
|
|
52
72
|
log.error('Algo menu error:', err.message);
|
|
53
|
-
console.log(chalk.red(`
|
|
73
|
+
console.log(chalk.red(` ERROR: ${err.message.toUpperCase()}`));
|
|
54
74
|
await prompts.waitForEnter();
|
|
55
75
|
return 'back';
|
|
56
76
|
}
|
package/src/pages/user.js
CHANGED
|
@@ -6,13 +6,17 @@ const chalk = require('chalk');
|
|
|
6
6
|
const ora = require('ora');
|
|
7
7
|
|
|
8
8
|
const { connections } = require('../services');
|
|
9
|
-
const { getLogoWidth, getColWidths, drawBoxHeader, drawBoxFooter, draw2ColHeader, visibleLength, padText } = require('../ui');
|
|
9
|
+
const { getLogoWidth, getColWidths, drawBoxHeader, drawBoxFooter, draw2ColHeader, visibleLength, padText, displayBanner } = require('../ui');
|
|
10
10
|
const { prompts } = require('../utils');
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Show user info
|
|
14
14
|
*/
|
|
15
15
|
const showUserInfo = async (service) => {
|
|
16
|
+
// Clear screen and show banner
|
|
17
|
+
console.clear();
|
|
18
|
+
displayBanner();
|
|
19
|
+
|
|
16
20
|
const boxWidth = getLogoWidth();
|
|
17
21
|
const { col1, col2 } = getColWidths(boxWidth);
|
|
18
22
|
let spinner;
|