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.
@@ -1,30 +1,27 @@
1
1
  /**
2
- * One Account Mode - Single account algo trading
3
- * Lightweight - UI + HQX Server connection only
2
+ * One Account Mode
4
3
  */
5
4
 
6
5
  const chalk = require('chalk');
7
6
  const ora = require('ora');
8
- const inquirer = require('inquirer');
9
7
  const readline = require('readline');
10
8
 
11
9
  const { connections } = require('../../services');
12
10
  const { HQXServerService } = require('../../services/hqx-server');
13
- const { FUTURES_SYMBOLS } = require('../../config');
14
- const { AlgoUI, checkMarketStatus } = require('./ui');
11
+ const { AlgoUI } = require('./ui');
12
+ const { prompts } = require('../../utils');
15
13
 
16
14
  /**
17
- * One Account Menu - Select account and launch
15
+ * One Account Menu
18
16
  */
19
17
  const oneAccountMenu = async (service) => {
20
18
  const spinner = ora({ text: 'Fetching active accounts...', color: 'yellow' }).start();
21
19
 
22
- // Get ALL accounts from ALL connections
23
20
  const allAccounts = await connections.getAllAccounts();
24
21
 
25
22
  if (!allAccounts?.length) {
26
23
  spinner.fail('No accounts found');
27
- await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter...' }]);
24
+ await prompts.waitForEnter();
28
25
  return;
29
26
  }
30
27
 
@@ -32,32 +29,22 @@ const oneAccountMenu = async (service) => {
32
29
 
33
30
  if (!activeAccounts.length) {
34
31
  spinner.fail('No active accounts');
35
- await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter...' }]);
32
+ await prompts.waitForEnter();
36
33
  return;
37
34
  }
38
35
 
39
36
  spinner.succeed(`Found ${activeAccounts.length} active account(s)`);
40
37
 
41
- // Select account - show propfirm for clarity
42
- const { selectedAccount } = await inquirer.prompt([{
43
- type: 'list',
44
- name: 'selectedAccount',
45
- message: 'Select Account:',
46
- choices: [
47
- ...activeAccounts.map(acc => ({
48
- name: chalk.cyan(`${acc.accountName || acc.accountId}`) +
49
- chalk.gray(` (${acc.propfirm || 'Unknown'})`) +
50
- chalk.white(` - $${(acc.balance || 0).toLocaleString()}`),
51
- value: acc
52
- })),
53
- new inquirer.Separator(),
54
- { name: chalk.yellow('< Back'), value: 'back' }
55
- ]
56
- }]);
57
-
58
- if (selectedAccount === 'back') return;
59
-
60
- // Find the service for this account
38
+ // Select account
39
+ const options = activeAccounts.map(acc => ({
40
+ label: `${acc.accountName || acc.accountId} (${acc.propfirm || 'Unknown'}) - $${(acc.balance || 0).toLocaleString()}`,
41
+ value: acc
42
+ }));
43
+ options.push({ label: '< Back', value: 'back' });
44
+
45
+ const selectedAccount = await prompts.selectOption('Select Account:', options);
46
+ if (!selectedAccount || selectedAccount === 'back') return;
47
+
61
48
  const accountService = connections.getServiceForAccount(selectedAccount.accountId) || service;
62
49
 
63
50
  // Select symbol
@@ -68,7 +55,6 @@ const oneAccountMenu = async (service) => {
68
55
  const config = await configureAlgo(selectedAccount, contract);
69
56
  if (!config) return;
70
57
 
71
- // Launch with the correct service for this account
72
58
  await launchAlgo(accountService, selectedAccount, contract, config);
73
59
  };
74
60
 
@@ -94,74 +80,40 @@ const selectSymbol = async (service, account) => {
94
80
  categories[cat].push(c);
95
81
  }
96
82
 
97
- // Build choices
98
- const choices = [];
83
+ // Flatten with categories as hints
84
+ const options = [];
99
85
  for (const [cat, contracts] of Object.entries(categories)) {
100
- choices.push(new inquirer.Separator(chalk.gray(`--- ${cat} ---`)));
101
86
  for (const c of contracts.slice(0, 10)) {
102
- choices.push({ name: chalk.white(c.name || c.symbol), value: c });
87
+ options.push({ label: `[${cat}] ${c.name || c.symbol}`, value: c });
103
88
  }
104
89
  }
105
- choices.push(new inquirer.Separator());
106
- choices.push({ name: chalk.yellow('< Back'), value: 'back' });
107
-
108
- const { contract } = await inquirer.prompt([{
109
- type: 'list',
110
- name: 'contract',
111
- message: 'Select Symbol:',
112
- choices,
113
- pageSize: 20
114
- }]);
90
+ options.push({ label: '< Back', value: 'back' });
115
91
 
92
+ const contract = await prompts.selectOption('Select Symbol:', options);
116
93
  return contract === 'back' ? null : contract;
117
94
  };
118
95
 
119
96
  /**
120
- * Configure algo parameters
97
+ * Configure algo
121
98
  */
122
99
  const configureAlgo = async (account, contract) => {
123
100
  console.log();
124
101
  console.log(chalk.cyan(' Configure Algo Parameters'));
125
102
  console.log();
126
103
 
127
- const { contracts } = await inquirer.prompt([{
128
- type: 'number',
129
- name: 'contracts',
130
- message: 'Number of contracts:',
131
- default: 1,
132
- validate: v => v > 0 && v <= 10 ? true : 'Enter 1-10'
133
- }]);
134
-
135
- const { dailyTarget } = await inquirer.prompt([{
136
- type: 'number',
137
- name: 'dailyTarget',
138
- message: 'Daily target ($):',
139
- default: 200,
140
- validate: v => v > 0 ? true : 'Must be positive'
141
- }]);
142
-
143
- const { maxRisk } = await inquirer.prompt([{
144
- type: 'number',
145
- name: 'maxRisk',
146
- message: 'Max risk ($):',
147
- default: 100,
148
- validate: v => v > 0 ? true : 'Must be positive'
149
- }]);
150
-
151
- const { showName } = await inquirer.prompt([{
152
- type: 'confirm',
153
- name: 'showName',
154
- message: 'Show account name?',
155
- default: true
156
- }]);
157
-
158
- const { confirm } = await inquirer.prompt([{
159
- type: 'confirm',
160
- name: 'confirm',
161
- message: chalk.yellow('Start algo trading?'),
162
- default: true
163
- }]);
104
+ const contracts = await prompts.numberInput('Number of contracts:', 1, 1, 10);
105
+ if (contracts === null) return null;
106
+
107
+ const dailyTarget = await prompts.numberInput('Daily target ($):', 200, 1, 10000);
108
+ if (dailyTarget === null) return null;
164
109
 
110
+ const maxRisk = await prompts.numberInput('Max risk ($):', 100, 1, 5000);
111
+ if (maxRisk === null) return null;
112
+
113
+ const showName = await prompts.confirmPrompt('Show account name?', true);
114
+ if (showName === null) return null;
115
+
116
+ const confirm = await prompts.confirmPrompt('Start algo trading?', true);
165
117
  if (!confirm) return null;
166
118
 
167
119
  return { contracts, dailyTarget, maxRisk, showName };
@@ -175,30 +127,19 @@ const launchAlgo = async (service, account, contract, config) => {
175
127
  const accountName = showName ? (account.accountName || account.accountId) : 'HQX *****';
176
128
  const symbolName = contract.name || contract.symbol;
177
129
 
178
- // Initialize UI
179
130
  const ui = new AlgoUI({ subtitle: 'HQX Ultra-Scalping' });
180
131
 
181
- // Stats state
182
132
  const stats = {
183
- accountName,
184
- symbol: symbolName,
185
- contracts,
186
- target: dailyTarget,
187
- risk: maxRisk,
188
- pnl: 0,
189
- trades: 0,
190
- wins: 0,
191
- losses: 0,
192
- latency: 0,
193
- connected: false
133
+ accountName, symbol: symbolName, contracts,
134
+ target: dailyTarget, risk: maxRisk,
135
+ pnl: 0, trades: 0, wins: 0, losses: 0,
136
+ latency: 0, connected: false
194
137
  };
195
138
 
196
139
  let running = true;
197
140
  let stopReason = null;
198
141
 
199
- // Connect to HQX Server
200
142
  const hqx = new HQXServerService();
201
-
202
143
  const spinner = ora({ text: 'Connecting to HQX Server...', color: 'yellow' }).start();
203
144
 
204
145
  try {
@@ -211,106 +152,72 @@ const launchAlgo = async (service, account, contract, config) => {
211
152
 
212
153
  spinner.succeed('Connected to HQX Server');
213
154
  stats.connected = true;
214
-
215
155
  } catch (err) {
216
156
  spinner.warn('HQX Server unavailable - offline mode');
217
- stats.connected = false;
218
157
  }
219
158
 
220
159
  // Event handlers
221
- hqx.on('latency', (data) => { stats.latency = data.latency || 0; });
222
-
223
- hqx.on('log', (data) => {
224
- let msg = data.message;
225
- if (!showName && account.accountName) {
226
- msg = msg.replace(new RegExp(account.accountName, 'gi'), 'HQX *****');
227
- }
228
- ui.addLog(data.type || 'info', msg);
160
+ hqx.on('latency', (d) => { stats.latency = d.latency || 0; });
161
+ hqx.on('log', (d) => {
162
+ let msg = d.message;
163
+ if (!showName && account.accountName) msg = msg.replace(new RegExp(account.accountName, 'gi'), 'HQX *****');
164
+ ui.addLog(d.type || 'info', msg);
229
165
  });
230
-
231
- hqx.on('signal', (data) => {
166
+ hqx.on('signal', (d) => {
232
167
  stats.signals = (stats.signals || 0) + 1;
233
- const side = data.side === 'long' ? 'BUY' : 'SELL';
234
- ui.addLog('signal', `${side} @ ${data.entry?.toFixed(2) || 'MKT'}`);
168
+ ui.addLog('signal', `${d.side === 'long' ? 'BUY' : 'SELL'} @ ${d.entry?.toFixed(2) || 'MKT'}`);
235
169
  });
236
-
237
- hqx.on('trade', (data) => {
170
+ hqx.on('trade', (d) => {
238
171
  stats.trades++;
239
- stats.pnl += data.pnl || 0;
240
- if (data.pnl >= 0) {
241
- stats.wins++;
242
- ui.addLog('trade', `+$${data.pnl.toFixed(2)}`);
243
- } else {
244
- stats.losses++;
245
- ui.addLog('loss', `-$${Math.abs(data.pnl).toFixed(2)}`);
246
- }
172
+ stats.pnl += d.pnl || 0;
173
+ if (d.pnl >= 0) { stats.wins++; ui.addLog('trade', `+$${d.pnl.toFixed(2)}`); }
174
+ else { stats.losses++; ui.addLog('loss', `-$${Math.abs(d.pnl).toFixed(2)}`); }
247
175
 
248
- // Check targets
249
176
  if (stats.pnl >= dailyTarget) {
250
- stopReason = 'target';
251
- running = false;
252
- ui.addLog('success', `TARGET REACHED! +$${stats.pnl.toFixed(2)}`);
177
+ stopReason = 'target'; running = false;
178
+ ui.addLog('success', `TARGET! +$${stats.pnl.toFixed(2)}`);
253
179
  hqx.stopAlgo();
254
180
  } else if (stats.pnl <= -maxRisk) {
255
- stopReason = 'risk';
256
- running = false;
181
+ stopReason = 'risk'; running = false;
257
182
  ui.addLog('error', `MAX RISK! -$${Math.abs(stats.pnl).toFixed(2)}`);
258
183
  hqx.stopAlgo();
259
184
  }
260
185
  });
186
+ hqx.on('error', (d) => { ui.addLog('error', d.message || 'Error'); });
187
+ hqx.on('disconnected', () => { stats.connected = false; ui.addLog('warning', 'Disconnected'); });
261
188
 
262
- hqx.on('error', (data) => {
263
- ui.addLog('error', data.message || 'Error');
264
- });
265
-
266
- hqx.on('disconnected', () => {
267
- stats.connected = false;
268
- ui.addLog('warning', 'Server disconnected');
269
- });
270
-
271
- // Start algo on server
189
+ // Start on server
272
190
  if (stats.connected) {
273
191
  ui.addLog('info', 'Starting algo...');
274
192
 
275
- // Get credentials if Rithmic
276
193
  let rithmicCreds = null;
277
- if (service.getRithmicCredentials) {
278
- rithmicCreds = service.getRithmicCredentials();
279
- }
194
+ if (service.getRithmicCredentials) rithmicCreds = service.getRithmicCredentials();
280
195
 
281
196
  hqx.startAlgo({
282
197
  accountId: account.accountId,
283
198
  contractId: contract.id || contract.contractId,
284
199
  symbol: contract.symbol || contract.name,
285
- contracts,
286
- dailyTarget,
287
- maxRisk,
200
+ contracts, dailyTarget, maxRisk,
288
201
  propfirm: account.propfirm || 'topstep',
289
- propfirmToken: service.getToken ? service.getToken() : null,
202
+ propfirmToken: service.getToken?.() || null,
290
203
  rithmicCredentials: rithmicCreds
291
204
  });
292
205
  }
293
206
 
294
- // UI refresh interval
295
- const refreshInterval = setInterval(() => {
296
- if (running) ui.render(stats);
297
- }, 250);
207
+ const refreshInterval = setInterval(() => { if (running) ui.render(stats); }, 250);
298
208
 
299
- // Keyboard handler
209
+ // Keyboard
300
210
  const setupKeyHandler = () => {
301
211
  if (!process.stdin.isTTY) return;
302
-
303
212
  readline.emitKeypressEvents(process.stdin);
304
213
  process.stdin.setRawMode(true);
305
214
  process.stdin.resume();
306
215
 
307
216
  const onKey = (str, key) => {
308
217
  if (key && (key.name === 'x' || key.name === 'X' || (key.ctrl && key.name === 'c'))) {
309
- running = false;
310
- stopReason = 'manual';
218
+ running = false; stopReason = 'manual';
311
219
  }
312
220
  };
313
-
314
221
  process.stdin.on('keypress', onKey);
315
222
  return () => {
316
223
  process.stdin.removeListener('keypress', onKey);
@@ -320,39 +227,26 @@ const launchAlgo = async (service, account, contract, config) => {
320
227
 
321
228
  const cleanupKeys = setupKeyHandler();
322
229
 
323
- // Wait for stop
324
230
  await new Promise(resolve => {
325
- const check = setInterval(() => {
326
- if (!running) {
327
- clearInterval(check);
328
- resolve();
329
- }
330
- }, 100);
231
+ const check = setInterval(() => { if (!running) { clearInterval(check); resolve(); } }, 100);
331
232
  });
332
233
 
333
- // Cleanup
334
234
  clearInterval(refreshInterval);
335
235
  if (cleanupKeys) cleanupKeys();
336
-
337
- if (stats.connected) {
338
- hqx.stopAlgo();
339
- hqx.disconnect();
340
- }
341
-
236
+ if (stats.connected) { hqx.stopAlgo(); hqx.disconnect(); }
342
237
  ui.cleanup();
343
238
 
344
- // Final summary
239
+ // Summary
345
240
  console.clear();
346
241
  console.log();
347
242
  console.log(chalk.cyan(' === Session Summary ==='));
348
243
  console.log();
349
244
  console.log(chalk.white(` Stop Reason: ${stopReason || 'unknown'}`));
350
245
  console.log(chalk.white(` Trades: ${stats.trades} (W: ${stats.wins} / L: ${stats.losses})`));
351
- const pnlColor = stats.pnl >= 0 ? chalk.green : chalk.red;
352
- console.log(pnlColor(` P&L: ${stats.pnl >= 0 ? '+' : ''}$${stats.pnl.toFixed(2)}`));
246
+ console.log((stats.pnl >= 0 ? chalk.green : chalk.red)(` P&L: ${stats.pnl >= 0 ? '+' : ''}$${stats.pnl.toFixed(2)}`));
353
247
  console.log();
354
248
 
355
- await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter to continue...' }]);
249
+ await prompts.waitForEnter();
356
250
  };
357
251
 
358
252
  module.exports = { oneAccountMenu };
@@ -1,25 +1,22 @@
1
1
  /**
2
- * @fileoverview Orders page
3
- * @module pages/orders
2
+ * Orders 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 { ORDER_STATUS, ORDER_TYPE, ORDER_SIDE } = require('../config');
12
- const { getLogoWidth, drawBoxHeader, drawBoxFooter, drawBoxRow, drawBoxSeparator, visibleLength, padText } = require('../ui');
10
+ const { getLogoWidth, drawBoxHeader, drawBoxFooter, drawBoxRow, drawBoxSeparator } = require('../ui');
11
+ const { prompts } = require('../utils');
13
12
 
14
13
  /**
15
- * Shows all orders from all connections
16
- * @param {Object} service - Current service
14
+ * Show all orders
17
15
  */
18
16
  const showOrders = async (service) => {
19
17
  const spinner = ora({ text: 'Fetching orders...', color: 'yellow' }).start();
20
18
  const boxWidth = getLogoWidth();
21
19
 
22
- // Get all accounts first
23
20
  let allAccounts = [];
24
21
 
25
22
  if (connections.count() > 0) {
@@ -28,14 +25,10 @@ const showOrders = async (service) => {
28
25
  const result = await conn.service.getTradingAccounts();
29
26
  if (result.success && result.accounts) {
30
27
  result.accounts.forEach(account => {
31
- allAccounts.push({
32
- ...account,
33
- propfirm: conn.propfirm || conn.type,
34
- service: conn.service
35
- });
28
+ allAccounts.push({ ...account, propfirm: conn.propfirm || conn.type, service: conn.service });
36
29
  });
37
30
  }
38
- } catch (e) { /* ignore */ }
31
+ } catch (e) {}
39
32
  }
40
33
  } else if (service) {
41
34
  const result = await service.getTradingAccounts();
@@ -44,22 +37,17 @@ const showOrders = async (service) => {
44
37
  }
45
38
  }
46
39
 
47
- // Get orders for each account
48
40
  let allOrders = [];
49
41
 
50
42
  for (const account of allAccounts) {
51
43
  try {
52
44
  const result = await account.service.getOrders(account.accountId);
53
- if (result.success && result.orders && result.orders.length > 0) {
45
+ if (result.success && result.orders?.length > 0) {
54
46
  result.orders.forEach(order => {
55
- allOrders.push({
56
- ...order,
57
- accountName: account.accountName || account.name,
58
- propfirm: account.propfirm
59
- });
47
+ allOrders.push({ ...order, accountName: account.accountName || account.name, propfirm: account.propfirm });
60
48
  });
61
49
  }
62
- } catch (e) { /* ignore */ }
50
+ } catch (e) {}
63
51
  }
64
52
 
65
53
  spinner.succeed(`Found ${allOrders.length} order(s)`);
@@ -70,19 +58,10 @@ const showOrders = async (service) => {
70
58
  if (allOrders.length === 0) {
71
59
  drawBoxRow(chalk.gray(' No orders found'), boxWidth);
72
60
  } else {
73
- // Header row
74
- const header = ' ' +
75
- 'Symbol'.padEnd(12) +
76
- 'Side'.padEnd(6) +
77
- 'Type'.padEnd(8) +
78
- 'Qty'.padEnd(6) +
79
- 'Price'.padEnd(10) +
80
- 'Status'.padEnd(12) +
81
- 'Account';
61
+ const header = ' ' + 'Symbol'.padEnd(12) + 'Side'.padEnd(6) + 'Type'.padEnd(8) + 'Qty'.padEnd(6) + 'Price'.padEnd(10) + 'Status'.padEnd(12) + 'Account';
82
62
  drawBoxRow(chalk.white.bold(header), boxWidth);
83
63
  drawBoxSeparator(boxWidth);
84
64
 
85
- // Order rows
86
65
  for (const order of allOrders) {
87
66
  const symbol = (order.contractId || order.symbol || 'Unknown').substring(0, 11);
88
67
  const sideInfo = ORDER_SIDE[order.side] || { text: '?', color: 'white' };
@@ -108,7 +87,7 @@ const showOrders = async (service) => {
108
87
  drawBoxFooter(boxWidth);
109
88
  console.log();
110
89
 
111
- await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter to continue...' }]);
90
+ await prompts.waitForEnter();
112
91
  };
113
92
 
114
93
  module.exports = { showOrders };
@@ -1,26 +1,22 @@
1
1
  /**
2
- * @fileoverview Positions page
3
- * @module pages/positions
2
+ * Positions 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 { ORDER_SIDE } = require('../config');
12
- const { getLogoWidth, drawBoxHeader, drawBoxFooter, drawBoxRow, drawBoxSeparator, visibleLength, padText } = require('../ui');
10
+ const { getLogoWidth, drawBoxHeader, drawBoxFooter, drawBoxRow, drawBoxSeparator } = require('../ui');
11
+ const { prompts } = require('../utils');
13
12
 
14
13
  /**
15
- * Shows all open positions from all connections
16
- * @param {Object} service - Current service
14
+ * Show all open positions
17
15
  */
18
16
  const showPositions = async (service) => {
19
17
  const spinner = ora({ text: 'Fetching positions...', color: 'yellow' }).start();
20
18
  const boxWidth = getLogoWidth();
21
- const innerWidth = boxWidth - 2;
22
19
 
23
- // Get all accounts first
24
20
  let allAccounts = [];
25
21
 
26
22
  if (connections.count() > 0) {
@@ -29,14 +25,10 @@ const showPositions = async (service) => {
29
25
  const result = await conn.service.getTradingAccounts();
30
26
  if (result.success && result.accounts) {
31
27
  result.accounts.forEach(account => {
32
- allAccounts.push({
33
- ...account,
34
- propfirm: conn.propfirm || conn.type,
35
- service: conn.service
36
- });
28
+ allAccounts.push({ ...account, propfirm: conn.propfirm || conn.type, service: conn.service });
37
29
  });
38
30
  }
39
- } catch (e) { /* ignore */ }
31
+ } catch (e) {}
40
32
  }
41
33
  } else if (service) {
42
34
  const result = await service.getTradingAccounts();
@@ -45,22 +37,17 @@ const showPositions = async (service) => {
45
37
  }
46
38
  }
47
39
 
48
- // Get positions for each account
49
40
  let allPositions = [];
50
41
 
51
42
  for (const account of allAccounts) {
52
43
  try {
53
44
  const result = await account.service.getPositions(account.accountId);
54
- if (result.success && result.positions && result.positions.length > 0) {
45
+ if (result.success && result.positions?.length > 0) {
55
46
  result.positions.forEach(pos => {
56
- allPositions.push({
57
- ...pos,
58
- accountName: account.accountName || account.name,
59
- propfirm: account.propfirm
60
- });
47
+ allPositions.push({ ...pos, accountName: account.accountName || account.name, propfirm: account.propfirm });
61
48
  });
62
49
  }
63
- } catch (e) { /* ignore */ }
50
+ } catch (e) {}
64
51
  }
65
52
 
66
53
  spinner.succeed(`Found ${allPositions.length} position(s)`);
@@ -71,18 +58,10 @@ const showPositions = async (service) => {
71
58
  if (allPositions.length === 0) {
72
59
  drawBoxRow(chalk.gray(' No open positions'), boxWidth);
73
60
  } else {
74
- // Header row
75
- const header = ' ' +
76
- 'Symbol'.padEnd(15) +
77
- 'Side'.padEnd(8) +
78
- 'Size'.padEnd(8) +
79
- 'Entry'.padEnd(12) +
80
- 'P&L'.padEnd(12) +
81
- 'Account';
61
+ const header = ' ' + 'Symbol'.padEnd(15) + 'Side'.padEnd(8) + 'Size'.padEnd(8) + 'Entry'.padEnd(12) + 'P&L'.padEnd(12) + 'Account';
82
62
  drawBoxRow(chalk.white.bold(header), boxWidth);
83
63
  drawBoxSeparator(boxWidth);
84
64
 
85
- // Position rows
86
65
  for (const pos of allPositions) {
87
66
  const symbol = (pos.contractId || pos.symbol || 'Unknown').substring(0, 14);
88
67
  const sideInfo = ORDER_SIDE[pos.side] || { text: 'Unknown', color: 'white' };
@@ -109,7 +88,7 @@ const showPositions = async (service) => {
109
88
  drawBoxFooter(boxWidth);
110
89
  console.log();
111
90
 
112
- await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter to continue...' }]);
91
+ await prompts.waitForEnter();
113
92
  };
114
93
 
115
94
  module.exports = { showPositions };
@@ -4,21 +4,12 @@
4
4
 
5
5
  const chalk = require('chalk');
6
6
  const ora = require('ora');
7
- const inquirer = require('inquirer');
8
7
  const asciichart = require('asciichart');
9
8
 
10
9
  const { connections } = require('../services');
11
10
  const { ACCOUNT_STATUS, ACCOUNT_TYPE } = require('../config');
12
- const {
13
- getLogoWidth,
14
- visibleLength,
15
- drawBoxHeader,
16
- drawBoxFooter,
17
- getColWidths,
18
- draw2ColHeader,
19
- draw2ColSeparator,
20
- fmtRow
21
- } = require('../ui');
11
+ const { getLogoWidth, visibleLength, drawBoxHeader, drawBoxFooter, getColWidths, draw2ColHeader, draw2ColSeparator, fmtRow } = require('../ui');
12
+ const { prompts } = require('../utils');
22
13
 
23
14
  /**
24
15
  * Show Stats Page
@@ -53,7 +44,7 @@ const showStats = async (service) => {
53
44
 
54
45
  if (allAccountsData.length === 0) {
55
46
  spinner.fail('No accounts found');
56
- await inquirer.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
47
+ await prompts.waitForEnter();
57
48
  return;
58
49
  }
59
50
 
@@ -70,7 +61,7 @@ const showStats = async (service) => {
70
61
 
71
62
  if (activeAccounts.length === 0) {
72
63
  spinner.fail('No active accounts found');
73
- await inquirer.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
64
+ await prompts.waitForEnter();
74
65
  return;
75
66
  }
76
67
 
@@ -498,7 +489,7 @@ const showStats = async (service) => {
498
489
  drawBoxFooter(boxWidth);
499
490
  console.log();
500
491
 
501
- await inquirer.prompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
492
+ await prompts.waitForEnter();
502
493
  };
503
494
 
504
495
  module.exports = { showStats };