hedgequantx 2.7.87 → 2.7.89

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.7.87",
3
+ "version": "2.7.89",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -0,0 +1,379 @@
1
+ /**
2
+ * Custom Strategy - AI-powered strategy builder
3
+ * Same config flow as One Account, then AI chat to create strategy
4
+ */
5
+
6
+ const chalk = require('chalk');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const os = require('os');
10
+ const ora = require('ora');
11
+ const readline = require('readline');
12
+
13
+ const { getLogoWidth, centerText, displayBanner } = require('../../ui');
14
+ const { prompts } = require('../../utils');
15
+ const { connections } = require('../../services');
16
+ const { getActiveProvider } = require('../ai-agents');
17
+ const cliproxy = require('../../services/cliproxy');
18
+ const { checkMarketHours } = require('../../services/rithmic/market');
19
+
20
+ // Strategies directory
21
+ const STRATEGIES_DIR = path.join(os.homedir(), '.hqx', 'strategies');
22
+
23
+ /** Ensure strategies directory exists */
24
+ const ensureStrategiesDir = () => {
25
+ if (!fs.existsSync(STRATEGIES_DIR)) fs.mkdirSync(STRATEGIES_DIR, { recursive: true });
26
+ };
27
+
28
+ /** Custom Strategy Menu */
29
+ const customStrategyMenu = async (service) => {
30
+ // Check AI provider first
31
+ const aiProvider = getActiveProvider();
32
+ if (!aiProvider) {
33
+ console.log(chalk.red('\n No AI Agent connected. Go to AI Agents menu first.'));
34
+ await prompts.waitForEnter();
35
+ return;
36
+ }
37
+
38
+ // Check market hours
39
+ const market = checkMarketHours();
40
+ if (!market.isOpen && !market.message.includes('early')) {
41
+ console.log();
42
+ console.log(chalk.red(` ${market.message}`));
43
+ console.log(chalk.gray(' Custom strategy requires market to be open'));
44
+ console.log();
45
+ await prompts.waitForEnter();
46
+ return;
47
+ }
48
+
49
+ // Step 1: Fetch accounts
50
+ const spinner = ora({ text: 'Fetching active accounts...', color: 'yellow' }).start();
51
+ const allAccounts = await connections.getAllAccounts();
52
+
53
+ if (!allAccounts?.length) {
54
+ spinner.fail('No accounts found');
55
+ await prompts.waitForEnter();
56
+ return;
57
+ }
58
+
59
+ const activeAccounts = allAccounts.filter(acc => acc.status === 0);
60
+ if (!activeAccounts.length) {
61
+ spinner.fail('No active accounts');
62
+ await prompts.waitForEnter();
63
+ return;
64
+ }
65
+
66
+ spinner.succeed(`Found ${activeAccounts.length} active account(s)`);
67
+
68
+ // Step 2: Select account
69
+ console.log();
70
+ console.log(chalk.cyan.bold(' STEP 1: SELECT ACCOUNT'));
71
+ const accountOptions = activeAccounts.map(acc => {
72
+ const name = acc.accountName || acc.rithmicAccountId || acc.accountId;
73
+ const balance = acc.balance !== null && acc.balance !== undefined
74
+ ? ` - $${acc.balance.toLocaleString()}` : '';
75
+ return {
76
+ label: `${name} (${acc.propfirm || acc.platform || 'Unknown'})${balance}`,
77
+ value: acc
78
+ };
79
+ });
80
+ accountOptions.push({ label: '< Back', value: 'back' });
81
+
82
+ const selectedAccount = await prompts.selectOption('Select Account:', accountOptions);
83
+ if (!selectedAccount || selectedAccount === 'back') return;
84
+
85
+ const accountService = selectedAccount.service || connections.getServiceForAccount(selectedAccount.accountId) || service;
86
+
87
+ // Step 3: Select symbol
88
+ console.log();
89
+ console.log(chalk.cyan.bold(' STEP 2: SELECT SYMBOL'));
90
+ const contract = await selectSymbol(accountService);
91
+ if (!contract) return;
92
+
93
+ // Step 4: Configure parameters
94
+ console.log();
95
+ console.log(chalk.cyan.bold(' STEP 3: CONFIGURE PARAMETERS'));
96
+ console.log();
97
+
98
+ const contracts = await prompts.numberInput('Number of contracts:', 1, 1, 10);
99
+ if (contracts === null) return;
100
+
101
+ const dailyTarget = await prompts.numberInput('Daily target ($):', 200, 1, 10000);
102
+ if (dailyTarget === null) return;
103
+
104
+ const maxRisk = await prompts.numberInput('Max risk ($):', 100, 1, 5000);
105
+ if (maxRisk === null) return;
106
+
107
+ const showName = await prompts.confirmPrompt('Show account name?', false);
108
+ if (showName === null) return;
109
+
110
+ // Step 5: AI Supervision
111
+ console.log();
112
+ console.log(chalk.cyan.bold(' STEP 4: AI SUPERVISION'));
113
+ const aiSupervision = await prompts.confirmPrompt('Enable AI supervision during execution?', true);
114
+ if (aiSupervision === null) return;
115
+
116
+ const config = {
117
+ account: selectedAccount,
118
+ contract,
119
+ contracts,
120
+ dailyTarget,
121
+ maxRisk,
122
+ showName,
123
+ aiSupervision,
124
+ aiProvider
125
+ };
126
+
127
+ // Step 6: AI Chat to create/configure strategy
128
+ console.log();
129
+ console.log(chalk.cyan.bold(' STEP 5: CREATE YOUR STRATEGY WITH AI'));
130
+ console.log(chalk.gray(' Describe your trading strategy in plain English.'));
131
+ console.log(chalk.gray(' The AI will help you build and validate it.'));
132
+ console.log();
133
+
134
+ await strategyChat(config, accountService);
135
+ };
136
+
137
+ /** Select symbol - same as one-account */
138
+ const selectSymbol = async (service) => {
139
+ const spinner = ora({ text: 'Loading symbols...', color: 'yellow' }).start();
140
+
141
+ const contractsResult = await service.getContracts();
142
+ if (!contractsResult.success || !contractsResult.contracts?.length) {
143
+ spinner.fail('Failed to load contracts');
144
+ return null;
145
+ }
146
+
147
+ let contracts = contractsResult.contracts;
148
+
149
+ // Sort popular indices first
150
+ const popular = ['ES', 'NQ', 'MES', 'MNQ', 'M2K', 'RTY', 'YM', 'MYM', 'NKD', 'GC', 'SI', 'CL'];
151
+ contracts.sort((a, b) => {
152
+ const baseA = a.baseSymbol || a.symbol || '';
153
+ const baseB = b.baseSymbol || b.symbol || '';
154
+ const idxA = popular.findIndex(p => baseA === p || baseA.startsWith(p));
155
+ const idxB = popular.findIndex(p => baseB === p || baseB.startsWith(p));
156
+ if (idxA !== -1 && idxB !== -1) return idxA - idxB;
157
+ if (idxA !== -1) return -1;
158
+ if (idxB !== -1) return 1;
159
+ return baseA.localeCompare(baseB);
160
+ });
161
+
162
+ spinner.succeed(`Found ${contracts.length} contracts`);
163
+
164
+ const options = contracts.map(c => ({
165
+ label: `${c.symbol} - ${c.name} (${c.exchange})`,
166
+ value: c
167
+ }));
168
+ options.push({ label: chalk.gray('< Back'), value: 'back' });
169
+
170
+ const selected = await prompts.selectOption(chalk.yellow('Select Symbol:'), options);
171
+ return selected === 'back' || selected === null ? null : selected;
172
+ };
173
+
174
+ /** AI Chat for strategy creation */
175
+ const strategyChat = async (config, service) => {
176
+ const { account, contract, contracts, dailyTarget, maxRisk, showName, aiSupervision, aiProvider } = config;
177
+
178
+ const accountName = showName
179
+ ? (account.accountName || account.rithmicAccountId || account.accountId)
180
+ : 'HQX *****';
181
+
182
+ console.clear();
183
+ displayBanner();
184
+
185
+ const boxWidth = getLogoWidth();
186
+ const W = boxWidth - 2;
187
+
188
+ console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
189
+ console.log(chalk.cyan('║') + chalk.green.bold(centerText('CUSTOM STRATEGY - AI CHAT', W)) + chalk.cyan('║'));
190
+ console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
191
+ console.log(chalk.cyan('║') + centerText(`Account: ${accountName} | Symbol: ${contract.name} | Qty: ${contracts}`, W) + chalk.cyan('║'));
192
+ console.log(chalk.cyan('║') + centerText(`Target: $${dailyTarget} | Risk: $${maxRisk} | AI Supervision: ${aiSupervision ? 'ON' : 'OFF'}`, W) + chalk.cyan('║'));
193
+ console.log(chalk.cyan('║') + chalk.gray(centerText(`AI: ${aiProvider.name} (${aiProvider.modelName || 'default'})`, W)) + chalk.cyan('║'));
194
+ console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
195
+ console.log(chalk.cyan('║') + chalk.gray(centerText('Type your strategy. "run" to execute, "save" to save, "cancel" to abort', W)) + chalk.cyan('║'));
196
+ console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
197
+ console.log();
198
+
199
+ const systemPrompt = `You are an expert algorithmic trading assistant for futures trading.
200
+
201
+ Current setup:
202
+ - Account: ${accountName}
203
+ - Symbol: ${contract.name} (${contract.symbol})
204
+ - Contracts: ${contracts}
205
+ - Daily Target: $${dailyTarget}
206
+ - Max Risk: $${maxRisk}
207
+ - AI Supervision: ${aiSupervision ? 'Enabled' : 'Disabled'}
208
+
209
+ Help the user create a trading strategy. When they describe what they want:
210
+ 1. Understand their entry/exit logic
211
+ 2. Validate the strategy makes sense
212
+ 3. Suggest improvements if needed
213
+ 4. When ready, confirm the strategy is valid
214
+
215
+ Keep responses concise (2-3 sentences max unless explaining strategy details).
216
+ When the user says "run", output: [STRATEGY_READY]
217
+ Include the strategy parameters in JSON format when ready.`;
218
+
219
+ const messages = [{ role: 'system', content: systemPrompt }];
220
+ let strategyReady = false;
221
+ let strategyConfig = null;
222
+
223
+ console.log(chalk.green(' AI: ') + `Hello! I'll help you create a custom strategy for ${contract.name}.`);
224
+ console.log(chalk.green(' ') + 'What kind of trading strategy do you want to build?');
225
+ console.log();
226
+
227
+ while (true) {
228
+ const userInput = await prompts.textInput(chalk.yellow(' You: '));
229
+
230
+ if (!userInput) continue;
231
+
232
+ const cmd = userInput.toLowerCase().trim();
233
+
234
+ if (cmd === 'cancel' || cmd === 'exit' || cmd === 'quit') {
235
+ console.log(chalk.gray('\n Strategy creation cancelled.'));
236
+ await prompts.waitForEnter();
237
+ return;
238
+ }
239
+
240
+ if (cmd === 'save') {
241
+ if (strategyConfig) {
242
+ await saveStrategy(strategyConfig, config);
243
+ } else {
244
+ console.log(chalk.yellow('\n No strategy to save yet. Keep describing your strategy.'));
245
+ }
246
+ continue;
247
+ }
248
+
249
+ if (cmd === 'run') {
250
+ if (strategyReady && strategyConfig) {
251
+ console.log(chalk.green('\n Launching strategy...'));
252
+ await launchCustomStrategy(config, strategyConfig, service);
253
+ return;
254
+ } else {
255
+ console.log(chalk.yellow('\n Strategy not ready yet. Describe your entry/exit conditions first.'));
256
+ continue;
257
+ }
258
+ }
259
+
260
+ messages.push({ role: 'user', content: userInput });
261
+
262
+ const spinner = ora({ text: 'AI thinking...', color: 'yellow' }).start();
263
+
264
+ try {
265
+ const modelId = aiProvider.modelId || getDefaultModel(aiProvider.id);
266
+ const result = await cliproxy.chatCompletion(modelId, messages);
267
+
268
+ if (!result.success) {
269
+ spinner.fail(`AI Error: ${result.error}`);
270
+ messages.pop();
271
+ continue;
272
+ }
273
+
274
+ const response = result.response?.choices?.[0]?.message?.content || '';
275
+ messages.push({ role: 'assistant', content: response });
276
+
277
+ spinner.stop();
278
+ console.log();
279
+ console.log(chalk.green(' AI: ') + formatResponse(response));
280
+ console.log();
281
+
282
+ // Check if strategy is ready
283
+ if (response.includes('[STRATEGY_READY]') || response.toLowerCase().includes('strategy is ready')) {
284
+ strategyReady = true;
285
+ // Try to extract JSON config
286
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
287
+ if (jsonMatch) {
288
+ try { strategyConfig = JSON.parse(jsonMatch[0]); } catch (e) {}
289
+ }
290
+ if (!strategyConfig) {
291
+ strategyConfig = { description: userInput, messages: messages.slice(1) };
292
+ }
293
+ console.log(chalk.cyan(' [Strategy ready! Type "run" to execute or "save" to save for later]'));
294
+ console.log();
295
+ }
296
+
297
+ } catch (e) {
298
+ spinner.fail(`Error: ${e.message}`);
299
+ messages.pop();
300
+ }
301
+ }
302
+ };
303
+
304
+ /** Get default model for provider */
305
+ const getDefaultModel = (providerId) => {
306
+ const defaults = { anthropic: 'claude-sonnet-4-20250514', google: 'gemini-2.5-pro', openai: 'gpt-4o' };
307
+ return defaults[providerId] || 'claude-sonnet-4-20250514';
308
+ };
309
+
310
+ /** Format AI response */
311
+ const formatResponse = (text) => {
312
+ const clean = text.replace(/\[STRATEGY_READY\]/g, '').trim();
313
+ const lines = clean.split('\n');
314
+ return lines.map((l, i) => i === 0 ? l : ' ' + l).join('\n');
315
+ };
316
+
317
+ /** Save strategy to disk */
318
+ const saveStrategy = async (strategyConfig, config) => {
319
+ ensureStrategiesDir();
320
+
321
+ const name = await prompts.textInput(chalk.cyan(' Strategy name: '));
322
+ if (!name || !name.trim()) {
323
+ console.log(chalk.gray(' Save cancelled.'));
324
+ return;
325
+ }
326
+
327
+ const folderName = name.trim().toLowerCase().replace(/[^a-z0-9]/g, '-');
328
+ const strategyPath = path.join(STRATEGIES_DIR, folderName);
329
+
330
+ if (!fs.existsSync(strategyPath)) fs.mkdirSync(strategyPath, { recursive: true });
331
+
332
+ const configFile = {
333
+ name: name.trim(),
334
+ symbol: config.contract.name,
335
+ contracts: config.contracts,
336
+ dailyTarget: config.dailyTarget,
337
+ maxRisk: config.maxRisk,
338
+ aiSupervision: config.aiSupervision,
339
+ strategy: strategyConfig,
340
+ createdAt: new Date().toISOString()
341
+ };
342
+
343
+ fs.writeFileSync(path.join(strategyPath, 'config.json'), JSON.stringify(configFile, null, 2));
344
+ console.log(chalk.green(`\n ✓ Strategy saved: ${strategyPath}`));
345
+ };
346
+
347
+ /** Launch custom strategy execution */
348
+ const launchCustomStrategy = async (config, strategyConfig, service) => {
349
+ const { account, contract, contracts, dailyTarget, maxRisk, showName, aiSupervision, aiProvider } = config;
350
+
351
+ console.log(chalk.yellow('\n Custom strategy execution coming soon...'));
352
+ console.log(chalk.gray(' Your strategy will use the HQX engine with AI supervision.'));
353
+ console.log();
354
+ console.log(chalk.white(' Strategy Summary:'));
355
+ console.log(chalk.gray(` - Symbol: ${contract.name}`));
356
+ console.log(chalk.gray(` - Contracts: ${contracts}`));
357
+ console.log(chalk.gray(` - Target: $${dailyTarget}`));
358
+ console.log(chalk.gray(` - Risk: $${maxRisk}`));
359
+ console.log(chalk.gray(` - AI Supervision: ${aiSupervision ? 'Enabled' : 'Disabled'}`));
360
+
361
+ await prompts.waitForEnter();
362
+ };
363
+
364
+ /** Load saved strategies */
365
+ const loadStrategies = () => {
366
+ ensureStrategiesDir();
367
+ try {
368
+ const items = fs.readdirSync(STRATEGIES_DIR, { withFileTypes: true });
369
+ return items.filter(i => i.isDirectory()).map(dir => {
370
+ const configPath = path.join(STRATEGIES_DIR, dir.name, 'config.json');
371
+ if (fs.existsSync(configPath)) {
372
+ return { folder: dir.name, ...JSON.parse(fs.readFileSync(configPath, 'utf8')) };
373
+ }
374
+ return { folder: dir.name, name: dir.name };
375
+ });
376
+ } catch (e) { return []; }
377
+ };
378
+
379
+ module.exports = { customStrategyMenu, loadStrategies };
@@ -5,11 +5,13 @@
5
5
  const chalk = require('chalk');
6
6
  const { getLogoWidth, centerText, displayBanner } = require('../../ui');
7
7
  const { logger, prompts } = require('../../utils');
8
+ const { getActiveProvider } = require('../ai-agents');
8
9
 
9
10
  const log = logger.scope('AlgoMenu');
10
11
 
11
12
  const { oneAccountMenu } = require('./one-account');
12
13
  const { copyTradingMenu } = require('./copy-trading');
14
+ const { customStrategyMenu } = require('./custom-strategy');
13
15
 
14
16
  /**
15
17
  * Algo Trading Menu
@@ -25,33 +27,52 @@ const algoTradingMenu = async (service) => {
25
27
  const boxWidth = getLogoWidth();
26
28
  const W = boxWidth - 2;
27
29
 
30
+ // Check if AI agent is connected
31
+ const aiProvider = getActiveProvider();
32
+ const hasAI = !!aiProvider;
33
+
28
34
  // Draw menu rectangle
29
35
  console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
30
36
  console.log(chalk.cyan('║') + chalk.magenta.bold(centerText('ALGO-TRADING', W)) + chalk.cyan('║'));
31
37
  console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
32
38
 
33
- // 3 columns layout
39
+ // 2 or 3 columns layout based on AI availability
34
40
  const col1 = '[1] ONE ACCOUNT';
35
41
  const col2 = '[2] COPY TRADING';
36
- const col3 = '[3] CUSTOM STRATEGY';
37
- const colWidth = Math.floor(W / 3);
38
- const lastColWidth = W - 2 * colWidth;
39
-
40
- const pad1 = Math.floor((colWidth - col1.length) / 2);
41
- const pad2 = Math.floor((colWidth - col2.length) / 2);
42
- const pad3 = Math.floor((lastColWidth - col3.length) / 2);
43
-
44
- const col1Str = ' '.repeat(pad1) + chalk.cyan(col1) + ' '.repeat(colWidth - col1.length - pad1);
45
- const col2Str = ' '.repeat(pad2) + chalk.yellow(col2) + ' '.repeat(colWidth - col2.length - pad2);
46
- const col3Str = ' '.repeat(pad3) + chalk.green(col3) + ' '.repeat(lastColWidth - col3.length - pad3);
42
+ const col3 = hasAI ? '[3] CUSTOM STRATEGY' : '';
47
43
 
48
- console.log(chalk.cyan('║') + col1Str + col2Str + col3Str + chalk.cyan('║'));
44
+ if (hasAI) {
45
+ // 3 columns
46
+ const colWidth = Math.floor(W / 3);
47
+ const lastColWidth = W - 2 * colWidth;
48
+
49
+ const pad1 = Math.floor((colWidth - col1.length) / 2);
50
+ const pad2 = Math.floor((colWidth - col2.length) / 2);
51
+ const pad3 = Math.floor((lastColWidth - col3.length) / 2);
52
+
53
+ const col1Str = ' '.repeat(pad1) + chalk.cyan(col1) + ' '.repeat(colWidth - col1.length - pad1);
54
+ const col2Str = ' '.repeat(pad2) + chalk.yellow(col2) + ' '.repeat(colWidth - col2.length - pad2);
55
+ const col3Str = ' '.repeat(pad3) + chalk.green(col3) + ' '.repeat(lastColWidth - col3.length - pad3);
56
+
57
+ console.log(chalk.cyan('║') + col1Str + col2Str + col3Str + chalk.cyan('║'));
58
+ } else {
59
+ // 2 columns only (no AI connected)
60
+ const colWidth = Math.floor(W / 2);
61
+ const pad1 = Math.floor((colWidth - col1.length) / 2);
62
+ const pad2 = Math.floor((W - colWidth - col2.length) / 2);
63
+
64
+ const col1Str = ' '.repeat(pad1) + chalk.cyan(col1) + ' '.repeat(colWidth - col1.length - pad1);
65
+ const col2Str = ' '.repeat(pad2) + chalk.yellow(col2) + ' '.repeat(W - colWidth - col2.length - pad2);
66
+
67
+ console.log(chalk.cyan('║') + col1Str + col2Str + chalk.cyan('║'));
68
+ }
49
69
 
50
70
  console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
51
71
  console.log(chalk.cyan('║') + chalk.red(centerText('[B] BACK', W)) + chalk.cyan('║'));
52
72
  console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
53
73
 
54
- const input = await prompts.textInput(chalk.cyan('SELECT (1/2/3/B): '));
74
+ const promptText = hasAI ? 'SELECT (1/2/3/B): ' : 'SELECT (1/2/B): ';
75
+ const input = await prompts.textInput(chalk.cyan(promptText));
55
76
  const choice = (input || '').toLowerCase().trim();
56
77
 
57
78
  log.debug('Algo mode selected', { choice });
@@ -70,8 +91,13 @@ const algoTradingMenu = async (service) => {
70
91
  await copyTradingMenu();
71
92
  break;
72
93
  case '3':
73
- log.info('Starting Custom Strategy mode');
74
- await customStrategyMenu(service);
94
+ if (hasAI) {
95
+ log.info('Starting Custom Strategy mode');
96
+ await customStrategyMenu(service);
97
+ } else {
98
+ console.log(chalk.red(' INVALID OPTION'));
99
+ await new Promise(r => setTimeout(r, 1000));
100
+ }
75
101
  break;
76
102
  default:
77
103
  console.log(chalk.red(' INVALID OPTION'));
@@ -87,27 +113,4 @@ const algoTradingMenu = async (service) => {
87
113
  }
88
114
  };
89
115
 
90
- /**
91
- * Custom Strategy Menu - AI-powered strategy creation
92
- */
93
- const customStrategyMenu = async (service) => {
94
- console.clear();
95
- displayBanner();
96
-
97
- const boxWidth = getLogoWidth();
98
- const W = boxWidth - 2;
99
-
100
- console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
101
- console.log(chalk.cyan('║') + chalk.green.bold(centerText('CUSTOM STRATEGY', W)) + chalk.cyan('║'));
102
- console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
103
- console.log(chalk.cyan('║') + centerText('Create your own trading strategy with AI assistance', W) + chalk.cyan('║'));
104
- console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
105
- console.log(chalk.cyan('║') + chalk.gray(centerText('Coming soon...', W)) + chalk.cyan('║'));
106
- console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
107
- console.log(chalk.cyan('║') + chalk.red(centerText('[B] BACK', W)) + chalk.cyan('║'));
108
- console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
109
-
110
- await prompts.waitForEnter();
111
- };
112
-
113
116
  module.exports = { algoTradingMenu };
package/src/ui/index.js CHANGED
@@ -70,7 +70,7 @@ const displayBanner = () => {
70
70
 
71
71
  console.log(chalk.cyan('╠' + '═'.repeat(innerWidth) + '╣'));
72
72
  const tagline = isMobile ? `HQX V${version}` : `PROP FUTURES ALGO TRADING V${version}`;
73
- console.log(chalk.cyan('║') + chalk.white(centerText(tagline, innerWidth)) + chalk.cyan('║'));
73
+ console.log(chalk.cyan('║') + chalk.yellow(centerText(tagline, innerWidth)) + chalk.cyan('║'));
74
74
 
75
75
  // ALWAYS close the banner
76
76
  console.log(chalk.cyan('╚' + '═'.repeat(innerWidth) + '╝'));