hedgequantx 2.6.3 → 2.6.5
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/algo/copy-trading.js +34 -7
- package/src/pages/algo/index.js +14 -221
- package/src/pages/algo/one-account.js +35 -6
package/package.json
CHANGED
|
@@ -652,6 +652,30 @@ const copyTradingMenu = async () => {
|
|
|
652
652
|
]);
|
|
653
653
|
if (showNames === null) return;
|
|
654
654
|
|
|
655
|
+
// Step 7: AI Agents option
|
|
656
|
+
const aiAgents = aiService.getAgents();
|
|
657
|
+
let enableAI = false;
|
|
658
|
+
|
|
659
|
+
if (aiAgents.length > 0) {
|
|
660
|
+
console.log();
|
|
661
|
+
console.log(chalk.magenta(` ${aiAgents.length} AI AGENT(S) AVAILABLE:`));
|
|
662
|
+
aiAgents.forEach((agent, i) => {
|
|
663
|
+
const modelInfo = agent.model ? chalk.gray(` (${agent.model})`) : '';
|
|
664
|
+
console.log(chalk.white(` ${i + 1}. ${agent.name}${modelInfo}`));
|
|
665
|
+
});
|
|
666
|
+
console.log();
|
|
667
|
+
|
|
668
|
+
enableAI = await prompts.confirmPrompt('ACTIVATE AI MODELS?', true);
|
|
669
|
+
if (enableAI === null) return;
|
|
670
|
+
|
|
671
|
+
if (enableAI) {
|
|
672
|
+
const mode = aiAgents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL';
|
|
673
|
+
console.log(chalk.green(` AI MODE: ${mode} (${aiAgents.length} agent${aiAgents.length > 1 ? 's' : ''})`));
|
|
674
|
+
} else {
|
|
675
|
+
console.log(chalk.gray(' AI AGENTS DISABLED FOR THIS SESSION'));
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
655
679
|
// Summary
|
|
656
680
|
console.log();
|
|
657
681
|
console.log(chalk.white.bold(' ═══════════════════════════════════════'));
|
|
@@ -677,6 +701,7 @@ const copyTradingMenu = async () => {
|
|
|
677
701
|
dailyTarget,
|
|
678
702
|
maxRisk,
|
|
679
703
|
showNames,
|
|
704
|
+
enableAI,
|
|
680
705
|
});
|
|
681
706
|
};
|
|
682
707
|
|
|
@@ -810,7 +835,7 @@ const getContractsFromAPI = async () => {
|
|
|
810
835
|
* Launch Copy Trading session
|
|
811
836
|
*/
|
|
812
837
|
const launchCopyTrading = async (config) => {
|
|
813
|
-
const { lead, followers, dailyTarget, maxRisk, showNames } = config;
|
|
838
|
+
const { lead, followers, dailyTarget, maxRisk, showNames, enableAI } = config;
|
|
814
839
|
|
|
815
840
|
const leadName = showNames
|
|
816
841
|
? (lead.account.accountName || lead.account.accountId)
|
|
@@ -837,12 +862,14 @@ const launchCopyTrading = async (config) => {
|
|
|
837
862
|
aiMode: null
|
|
838
863
|
};
|
|
839
864
|
|
|
840
|
-
// Initialize AI Supervisor
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
865
|
+
// Initialize AI Supervisor - only if user enabled it
|
|
866
|
+
if (enableAI) {
|
|
867
|
+
const aiAgents = aiService.getAgents();
|
|
868
|
+
if (aiAgents.length > 0) {
|
|
869
|
+
const supervisorResult = StrategySupervisor.initialize(null, aiAgents, lead.service, lead.account.accountId);
|
|
870
|
+
stats.aiSupervision = supervisorResult.success;
|
|
871
|
+
stats.aiMode = supervisorResult.mode;
|
|
872
|
+
}
|
|
846
873
|
}
|
|
847
874
|
|
|
848
875
|
// Startup logs
|
package/src/pages/algo/index.js
CHANGED
|
@@ -1,254 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Algo Trading -
|
|
2
|
+
* Algo Trading - Simple Menu
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const chalk = require('chalk');
|
|
6
|
-
const ora = require('ora');
|
|
7
6
|
const { getLogoWidth, drawBoxHeaderContinue, drawBoxFooter, displayBanner } = require('../../ui');
|
|
8
|
-
const {
|
|
9
|
-
const aiService = require('../../services/ai');
|
|
10
|
-
const AISupervisor = require('../../services/ai/supervisor');
|
|
11
|
-
|
|
12
|
-
const log = logger.scope('AlgoMenu');
|
|
7
|
+
const { prompts } = require('../../utils');
|
|
13
8
|
|
|
14
9
|
const { oneAccountMenu } = require('./one-account');
|
|
15
10
|
const { copyTradingMenu } = require('./copy-trading');
|
|
16
11
|
|
|
17
12
|
/**
|
|
18
|
-
* Algo Trading Menu
|
|
13
|
+
* Algo Trading Menu - Simplified
|
|
19
14
|
*/
|
|
20
15
|
const algoTradingMenu = async (service) => {
|
|
21
16
|
const boxWidth = getLogoWidth();
|
|
22
17
|
const W = boxWidth - 2;
|
|
23
18
|
|
|
24
|
-
const makeLine = (content
|
|
19
|
+
const makeLine = (content) => {
|
|
25
20
|
const plainLen = content.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
26
21
|
const padding = W - plainLen;
|
|
27
|
-
if (align === 'center') {
|
|
28
|
-
const leftPad = Math.floor(padding / 2);
|
|
29
|
-
return chalk.cyan('║') + ' '.repeat(leftPad) + content + ' '.repeat(padding - leftPad) + chalk.cyan('║');
|
|
30
|
-
}
|
|
31
22
|
return chalk.cyan('║') + ' ' + content + ' '.repeat(Math.max(0, padding - 1)) + chalk.cyan('║');
|
|
32
23
|
};
|
|
33
24
|
|
|
34
|
-
log.info('Algo Trading menu opened');
|
|
35
|
-
|
|
36
25
|
console.clear();
|
|
37
26
|
displayBanner();
|
|
38
27
|
drawBoxHeaderContinue('ALGO TRADING', boxWidth);
|
|
39
28
|
|
|
40
|
-
|
|
41
|
-
const aiAgents = aiService.getAgents();
|
|
42
|
-
const aiConnected = aiAgents.length > 0;
|
|
43
|
-
const activeAgent = aiService.getActiveAgent();
|
|
44
|
-
const supervisionStatus = AISupervisor.getAllStatus();
|
|
45
|
-
|
|
46
|
-
// Show AI supervision status
|
|
47
|
-
if (aiConnected && activeAgent) {
|
|
48
|
-
console.log(makeLine(chalk.green(`AI SUPERVISION: ACTIVE`), 'center'));
|
|
49
|
-
console.log(makeLine(chalk.magenta(`AGENT: ${activeAgent.name}`), 'center'));
|
|
50
|
-
|
|
51
|
-
if (supervisionStatus.length > 0) {
|
|
52
|
-
const supervisor = supervisionStatus[0];
|
|
53
|
-
const duration = Math.floor(supervisor.duration / 1000);
|
|
54
|
-
console.log(makeLine(chalk.gray(`SESSION: ${duration}s | DECISIONS: ${supervisor.metrics.totalDecisions}`), 'center'));
|
|
55
|
-
|
|
56
|
-
if (supervisor.lastDecision) {
|
|
57
|
-
console.log(makeLine(chalk.yellow(`LAST: ${supervisor.lastDecision.reason.substring(0, 50)}...`), 'center'));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
} else {
|
|
61
|
-
console.log(makeLine(chalk.gray('AI SUPERVISION: INACTIVE'), 'center'));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
65
|
-
|
|
66
|
-
// Menu options
|
|
67
|
-
const options = [];
|
|
68
|
-
|
|
69
|
-
if (aiConnected && activeAgent) {
|
|
70
|
-
options.push({ label: chalk.cyan('[1] HQX ULTRA SCALPING (AI SUPERVISED)'), value: 'ai_supervised' });
|
|
71
|
-
options.push({ label: chalk.white('[2] HQX ULTRA SCALPING (MANUAL MODE)'), value: 'one_account' });
|
|
72
|
-
options.push({ label: chalk.magenta('[3] AI SUPERVISION DASHBOARD'), value: 'ai_dashboard' });
|
|
73
|
-
} else {
|
|
74
|
-
options.push({ label: chalk.cyan('[1] HQX ULTRA SCALPING (MANUAL MODE)'), value: 'one_account' });
|
|
75
|
-
options.push({ label: chalk.gray('[2] HQX ULTRA SCALPING (AI SUPERVISED) - NO AI AGENT'), value: 'no_agent' });
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
options.push({ label: chalk.white('[C] COPY TRADING'), value: 'copy_trading' });
|
|
79
|
-
options.push({ label: chalk.gray('[<] BACK'), value: 'back' });
|
|
80
|
-
|
|
81
|
-
for (const opt of options) {
|
|
82
|
-
console.log(makeLine(opt.label));
|
|
83
|
-
}
|
|
29
|
+
console.log(makeLine(chalk.white('[1] ONE ACCOUNT [2] COPY TRADING')));
|
|
84
30
|
|
|
85
31
|
drawBoxFooter(boxWidth);
|
|
86
32
|
|
|
87
33
|
const choice = await prompts.textInput(chalk.cyan('SELECT:'));
|
|
88
34
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
break;
|
|
97
|
-
|
|
98
|
-
case '2':
|
|
99
|
-
if (aiConnected && activeAgent) {
|
|
100
|
-
await oneAccountMenu(service);
|
|
101
|
-
} else {
|
|
102
|
-
console.log(chalk.yellow('\n NO AI AGENT CONNECTED'));
|
|
103
|
-
console.log(chalk.gray(' Connect an AI agent first from [I] AI AGENTS menu'));
|
|
104
|
-
await prompts.waitForEnter();
|
|
105
|
-
}
|
|
106
|
-
break;
|
|
107
|
-
|
|
108
|
-
case '3':
|
|
109
|
-
if (aiConnected && activeAgent) {
|
|
110
|
-
await showAIDashboard(activeAgent);
|
|
111
|
-
}
|
|
112
|
-
break;
|
|
113
|
-
|
|
114
|
-
case 'c':
|
|
115
|
-
await copyTradingMenu();
|
|
116
|
-
break;
|
|
117
|
-
|
|
118
|
-
case '<':
|
|
119
|
-
case 'b':
|
|
120
|
-
return 'back';
|
|
121
|
-
|
|
122
|
-
default:
|
|
123
|
-
// Handle direct number input
|
|
124
|
-
const num = parseInt(choice);
|
|
125
|
-
if (num === 1) {
|
|
126
|
-
if (aiConnected && activeAgent) {
|
|
127
|
-
return await startAISupervised(service, activeAgent);
|
|
128
|
-
} else {
|
|
129
|
-
await oneAccountMenu(service);
|
|
130
|
-
}
|
|
131
|
-
} else if (num === 2) {
|
|
132
|
-
if (aiConnected && activeAgent) {
|
|
133
|
-
await oneAccountMenu(service);
|
|
134
|
-
} else {
|
|
135
|
-
console.log(chalk.yellow('\n NO AI AGENT CONNECTED'));
|
|
136
|
-
await prompts.waitForEnter();
|
|
137
|
-
}
|
|
138
|
-
} else if (num === 3 && aiConnected && activeAgent) {
|
|
139
|
-
await showAIDashboard(activeAgent);
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return algoTradingMenu(service);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Start AI supervised trading
|
|
149
|
-
*/
|
|
150
|
-
const startAISupervised = async (service, agent) => {
|
|
151
|
-
const boxWidth = getLogoWidth();
|
|
152
|
-
const W = boxWidth - 2;
|
|
153
|
-
|
|
154
|
-
const makeLine = (content) => {
|
|
155
|
-
const plainLen = content.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
156
|
-
const padding = W - plainLen;
|
|
157
|
-
return chalk.cyan('║') + ' ' + content + ' '.repeat(Math.max(0, padding - 1)) + chalk.cyan('║');
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
console.clear();
|
|
161
|
-
displayBanner();
|
|
162
|
-
drawBoxHeaderContinue('AI SUPERVISED TRADING', boxWidth);
|
|
163
|
-
|
|
164
|
-
console.log(makeLine(chalk.magenta(`AGENT: ${agent.name}`)));
|
|
165
|
-
console.log(makeLine(chalk.green('STATUS: STARTING SUPERVISION...')));
|
|
166
|
-
|
|
167
|
-
drawBoxFooter(boxWidth);
|
|
168
|
-
|
|
169
|
-
// Start AI supervision
|
|
170
|
-
const success = AISupervisor.start(agent.id, { /* algo target */ });
|
|
171
|
-
|
|
172
|
-
if (success) {
|
|
173
|
-
const spinner = ora({ text: 'INITIALIZING AI SUPERVISION...', color: 'cyan' }).start();
|
|
174
|
-
|
|
175
|
-
// Simulate initialization
|
|
176
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
177
|
-
|
|
178
|
-
spinner.succeed('AI SUPERVISION ACTIVE');
|
|
179
|
-
console.log(chalk.green('\n ✓ Agent is now monitoring HQX Ultra Scalping'));
|
|
180
|
-
console.log(chalk.gray(' ✓ AI will optimize parameters and manage risk'));
|
|
181
|
-
console.log(chalk.gray(' ✓ Supervision continues until agent is disconnected'));
|
|
182
|
-
|
|
183
|
-
await prompts.waitForEnter();
|
|
184
|
-
|
|
185
|
-
// Launch algo trading with AI supervision active
|
|
186
|
-
return await oneAccountMenu(service);
|
|
187
|
-
|
|
188
|
-
} else {
|
|
189
|
-
console.log(chalk.red('\n ✗ Failed to start AI supervision'));
|
|
190
|
-
await prompts.waitForEnter();
|
|
35
|
+
if (choice === '1') {
|
|
36
|
+
await oneAccountMenu(service);
|
|
37
|
+
return algoTradingMenu(service);
|
|
38
|
+
} else if (choice === '2') {
|
|
39
|
+
await copyTradingMenu();
|
|
40
|
+
return algoTradingMenu(service);
|
|
191
41
|
}
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Show AI Dashboard
|
|
196
|
-
*/
|
|
197
|
-
const showAIDashboard = async (agent) => {
|
|
198
|
-
const boxWidth = getLogoWidth();
|
|
199
|
-
const W = boxWidth - 2;
|
|
200
|
-
|
|
201
|
-
const makeLine = (content) => {
|
|
202
|
-
const plainLen = content.replace(/\x1b\[[0-9;]*m/g, '').length;
|
|
203
|
-
const padding = W - plainLen;
|
|
204
|
-
return chalk.cyan('║') + ' ' + content + ' '.repeat(Math.max(0, padding - 1)) + chalk.cyan('║');
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const supervisionStatus = AISupervisor.getStatus(agent.id);
|
|
208
42
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
displayBanner();
|
|
212
|
-
drawBoxHeaderContinue('AI SUPERVISION DASHBOARD', boxWidth);
|
|
213
|
-
|
|
214
|
-
console.log(makeLine(chalk.magenta(`AGENT: ${agent.name}`)));
|
|
215
|
-
console.log(makeLine(chalk.green(`STATUS: ${supervisionStatus.active ? 'ACTIVE' : 'INACTIVE'}`)));
|
|
216
|
-
|
|
217
|
-
if (supervisionStatus.active) {
|
|
218
|
-
const duration = Math.floor(supervisionStatus.duration / 1000);
|
|
219
|
-
console.log(makeLine(chalk.gray(`SESSION: ${duration}s`)));
|
|
220
|
-
console.log(makeLine(chalk.gray(`DECISIONS: ${supervisionStatus.decisions}`)));
|
|
221
|
-
console.log(makeLine(chalk.yellow(`INTERVENTIONS: ${supervisionStatus.interventions}`)));
|
|
222
|
-
console.log(makeLine(chalk.cyan(`OPTIMIZATIONS: ${supervisionStatus.optimizations}`)));
|
|
223
|
-
|
|
224
|
-
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
225
|
-
|
|
226
|
-
if (supervisionStatus.lastDecision) {
|
|
227
|
-
const decision = supervisionStatus.lastDecision;
|
|
228
|
-
console.log(makeLine(chalk.white('LAST DECISION:')));
|
|
229
|
-
console.log(makeLine(chalk.gray(` Type: ${decision.type}`)));
|
|
230
|
-
console.log(makeLine(chalk.gray(` Reason: ${decision.reason}`)));
|
|
231
|
-
console.log(makeLine(chalk.gray(` Confidence: ${decision.confidence}%`)));
|
|
232
|
-
} else {
|
|
233
|
-
console.log(makeLine(chalk.gray('No decisions yet...')));
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
238
|
-
console.log(makeLine(chalk.gray('[<] BACK')));
|
|
239
|
-
|
|
240
|
-
drawBoxFooter(boxWidth);
|
|
241
|
-
|
|
242
|
-
const choice = await prompts.textInput(chalk.cyan('PRESS < TO GO BACK:'));
|
|
243
|
-
|
|
244
|
-
if (choice === '<' || choice?.toLowerCase() === 'b') {
|
|
245
|
-
break;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Refresh data
|
|
249
|
-
const freshStatus = AISupervisor.getStatus(agent.id);
|
|
250
|
-
Object.assign(supervisionStatus, freshStatus);
|
|
251
|
-
}
|
|
43
|
+
// Empty or other = back
|
|
44
|
+
return 'back';
|
|
252
45
|
};
|
|
253
46
|
|
|
254
|
-
module.exports = { algoTradingMenu };
|
|
47
|
+
module.exports = { algoTradingMenu };
|
|
@@ -162,6 +162,32 @@ const configureAlgo = async (account, contract) => {
|
|
|
162
162
|
const showName = await prompts.confirmPrompt('SHOW ACCOUNT NAME?', false);
|
|
163
163
|
if (showName === null) return null;
|
|
164
164
|
|
|
165
|
+
// Check if AI agents are available
|
|
166
|
+
const aiAgents = aiService.getAgents();
|
|
167
|
+
let enableAI = false;
|
|
168
|
+
|
|
169
|
+
if (aiAgents.length > 0) {
|
|
170
|
+
// Show available agents
|
|
171
|
+
console.log();
|
|
172
|
+
console.log(chalk.magenta(` ${aiAgents.length} AI AGENT(S) AVAILABLE:`));
|
|
173
|
+
aiAgents.forEach((agent, i) => {
|
|
174
|
+
const modelInfo = agent.model ? chalk.gray(` (${agent.model})`) : '';
|
|
175
|
+
console.log(chalk.white(` ${i + 1}. ${agent.name}${modelInfo}`));
|
|
176
|
+
});
|
|
177
|
+
console.log();
|
|
178
|
+
|
|
179
|
+
enableAI = await prompts.confirmPrompt('ACTIVATE AI MODELS?', true);
|
|
180
|
+
if (enableAI === null) return null;
|
|
181
|
+
|
|
182
|
+
if (enableAI) {
|
|
183
|
+
const mode = aiAgents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL';
|
|
184
|
+
console.log(chalk.green(` AI MODE: ${mode} (${aiAgents.length} agent${aiAgents.length > 1 ? 's' : ''})`));
|
|
185
|
+
} else {
|
|
186
|
+
console.log(chalk.gray(' AI AGENTS DISABLED FOR THIS SESSION'));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log();
|
|
165
191
|
const confirm = await prompts.confirmPrompt('START ALGO TRADING?', true);
|
|
166
192
|
if (!confirm) return null;
|
|
167
193
|
|
|
@@ -170,7 +196,7 @@ const configureAlgo = async (account, contract) => {
|
|
|
170
196
|
await new Promise(r => setTimeout(r, 500));
|
|
171
197
|
initSpinner.succeed('LAUNCHING ALGO...');
|
|
172
198
|
|
|
173
|
-
return { contracts, dailyTarget, maxRisk, showName };
|
|
199
|
+
return { contracts, dailyTarget, maxRisk, showName, enableAI };
|
|
174
200
|
};
|
|
175
201
|
|
|
176
202
|
/**
|
|
@@ -317,11 +343,14 @@ const launchAlgo = async (service, account, contract, config) => {
|
|
|
317
343
|
}
|
|
318
344
|
|
|
319
345
|
// Initialize AI Strategy Supervisor - agents observe, learn & optimize
|
|
320
|
-
|
|
321
|
-
if (
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
346
|
+
// Only if user enabled AI in config
|
|
347
|
+
if (config.enableAI) {
|
|
348
|
+
const aiAgents = aiService.getAgents();
|
|
349
|
+
if (aiAgents.length > 0) {
|
|
350
|
+
const supervisorResult = StrategySupervisor.initialize(strategy, aiAgents, service, account.accountId);
|
|
351
|
+
stats.aiSupervision = supervisorResult.success;
|
|
352
|
+
stats.aiMode = supervisorResult.mode;
|
|
353
|
+
}
|
|
325
354
|
}
|
|
326
355
|
|
|
327
356
|
// Initialize Market Data Feed
|