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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.6.3",
3
+ "version": "2.6.5",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -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
- const aiAgents = aiService.getAgents();
842
- if (aiAgents.length > 0) {
843
- const supervisorResult = StrategySupervisor.initialize(null, aiAgents, lead.service, lead.account.accountId);
844
- stats.aiSupervision = supervisorResult.success;
845
- stats.aiMode = supervisorResult.mode;
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
@@ -1,254 +1,47 @@
1
1
  /**
2
- * Algo Trading - Main Menu with AI Supervision
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 { logger, prompts } = require('../../utils');
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 with AI status
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, align = 'left') => {
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
- // Get AI status
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
- switch (choice?.toLowerCase()) {
90
- case '1':
91
- if (aiConnected && activeAgent) {
92
- return await startAISupervised(service, activeAgent);
93
- } else {
94
- await oneAccountMenu(service);
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
- while (true) {
210
- console.clear();
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
- const aiAgents = aiService.getAgents();
321
- if (aiAgents.length > 0) {
322
- const supervisorResult = StrategySupervisor.initialize(strategy, aiAgents, service, account.accountId);
323
- stats.aiSupervision = supervisorResult.success;
324
- stats.aiMode = supervisorResult.mode;
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