hedgequantx 2.6.156 → 2.6.158

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.156",
3
+ "version": "2.6.158",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -28,7 +28,7 @@ const { RithmicMarketDataFeed } = require('../../services/rithmic/market-data');
28
28
  const { algoLogger } = require('./logger');
29
29
  const { recoveryMath } = require('../../services/strategy/recovery-math');
30
30
  const aiService = require('../../services/ai');
31
- const { launchMultiSymbolRithmic } = require('./one-account');
31
+ const { launchMultiSymbolRithmic, selectSymbol, configureAlgo } = require('./one-account');
32
32
  const aiClient = require('../../services/ai/client');
33
33
 
34
34
  // Strategy template that the AI will fill
@@ -391,109 +391,69 @@ const customStrategyMenu = async (service) => {
391
391
 
392
392
  /**
393
393
  * Execute trading with custom strategy
394
- * Same as one-account but uses the custom strategy class
394
+ * Uses same flow as one-account.js
395
395
  */
396
396
  async function executeWithCustomStrategy(service, StrategyClass, strategyName) {
397
- const boxWidth = Math.max(getLogoWidth(), 98);
398
- const innerWidth = boxWidth - 2;
397
+ const { connections } = require('../../services');
399
398
 
400
- // Get accounts
401
- const accountsResult = await service.getTradingAccounts();
402
- if (!accountsResult.success || !accountsResult.accounts?.length) {
399
+ // Get all accounts (same as one-account.js)
400
+ const allAccounts = await connections.getAllAccounts();
401
+ if (!allAccounts || allAccounts.length === 0) {
403
402
  console.log(chalk.red('\n No trading accounts available.\n'));
404
403
  await prompts.waitForEnter();
405
404
  return;
406
405
  }
407
-
408
- // Account selection
409
- console.log(chalk.cyan('\n SELECT ACCOUNT:\n'));
410
- accountsResult.accounts.forEach((acc, i) => {
411
- const balance = acc.balance !== null ? `$${acc.balance.toLocaleString()}` : 'N/A';
412
- console.log(chalk.cyan(` [${i + 1}]`) + chalk.white(` ${acc.name || acc.accountId}`) + chalk.gray(` - ${balance}`));
413
- });
414
-
415
- const accChoice = await prompts.numberInput('\n ACCOUNT #:', 1, 1, accountsResult.accounts.length);
416
- if (accChoice === null) return;
417
- const account = accountsResult.accounts[accChoice - 1];
418
-
419
- // Symbol selection
420
- const symbolInput = await prompts.textInput(chalk.cyan(' SYMBOL (e.g., MES, MNQ): '));
421
- if (!symbolInput) return;
422
- const symbols = symbolInput.toUpperCase().split(',').map(s => s.trim()).filter(Boolean);
423
-
424
- // Target and Risk
425
- const dailyTarget = await prompts.numberInput(' TARGET ($):', 1000, 100, 50000);
426
- if (dailyTarget === null) return;
427
-
428
- const maxRisk = await prompts.numberInput(' MAX RISK ($):', 500, 50, 10000);
429
- if (maxRisk === null) return;
430
-
431
- // Confirm
432
- console.log(chalk.cyan('\n ╔════════════════════════════════════════════════════════════╗'));
433
- console.log(chalk.cyan(' ║') + chalk.yellow.bold(' CONFIRM SETTINGS ') + chalk.cyan('║'));
434
- console.log(chalk.cyan(' ╠════════════════════════════════════════════════════════════╣'));
435
- console.log(chalk.cyan(' ║') + chalk.white(` Strategy: ${strategyName.substring(0, 47).padEnd(47)}`) + chalk.cyan('║'));
436
- console.log(chalk.cyan(' ║') + chalk.white(` Account: ${(account.name || account.accountId).substring(0, 47).padEnd(47)}`) + chalk.cyan('║'));
437
- console.log(chalk.cyan(' ║') + chalk.white(` Symbols: ${symbols.join(', ').substring(0, 47).padEnd(47)}`) + chalk.cyan('║'));
438
- console.log(chalk.cyan(' ║') + chalk.green(` Target: $${dailyTarget.toLocaleString().padEnd(46)}`) + chalk.cyan('║'));
439
- console.log(chalk.cyan(' ║') + chalk.red(` Risk: $${maxRisk.toLocaleString().padEnd(46)}`) + chalk.cyan('║'));
440
- console.log(chalk.cyan(' ╚════════════════════════════════════════════════════════════╝\n'));
441
-
442
- const startConfirm = await prompts.textInput(chalk.cyan(' START TRADING? (Y/n): '));
443
- if (startConfirm.toLowerCase() === 'n') {
444
- console.log(chalk.yellow('\n Cancelled.\n'));
445
- await prompts.waitForEnter();
446
- return;
447
- }
448
-
449
- // Launch with custom strategy
450
- console.log(chalk.green('\n Starting custom strategy trading...\n'));
451
406
 
452
- // Get front month contracts for each symbol
453
- const contracts = [];
454
- for (const symbol of symbols) {
455
- // Get front month contract from Rithmic API
456
- const frontMonth = await service.getFrontMonthContract(symbol);
457
- if (frontMonth && frontMonth.success) {
458
- contracts.push({
459
- name: frontMonth.symbol || symbol,
460
- symbol: frontMonth.symbol || symbol,
461
- exchange: frontMonth.exchange || 'CME',
462
- id: frontMonth.contractId || symbol,
463
- tickSize: frontMonth.tickSize,
464
- tickValue: frontMonth.tickValue,
465
- qty: 1, // Default 1 contract per symbol
466
- });
467
- } else {
468
- // Fallback - use symbol directly
469
- contracts.push({
470
- name: symbol,
471
- symbol: symbol,
472
- exchange: 'CME',
473
- id: symbol,
474
- tickSize: null,
475
- tickValue: null,
476
- qty: 1,
477
- });
478
- }
479
- }
480
-
481
- if (contracts.length === 0) {
482
- console.log(chalk.red('\n No valid contracts found.\n'));
407
+ // Filter active accounts
408
+ const activeAccounts = allAccounts.filter(acc => acc.status === 'active' || !acc.status);
409
+ if (activeAccounts.length === 0) {
410
+ console.log(chalk.red('\n No active trading accounts.\n'));
483
411
  await prompts.waitForEnter();
484
412
  return;
485
413
  }
486
414
 
487
- // Config for launchMultiSymbolRithmic
488
- const config = {
489
- dailyTarget,
490
- maxRisk,
491
- showName: true,
492
- enableAI: false, // Custom strategy doesn't need AI supervisor (it IS the AI strategy)
493
- };
494
-
415
+ // Account selection - same format as one-account.js
416
+ const options = activeAccounts.map(acc => {
417
+ const name = acc.accountName || acc.rithmicAccountId || acc.accountId;
418
+ const balance = acc.balance !== null && acc.balance !== undefined
419
+ ? ` - $${acc.balance.toLocaleString()}`
420
+ : '';
421
+ return {
422
+ label: `${name} (${acc.propfirm || acc.platform || 'Unknown'})${balance}`,
423
+ value: acc
424
+ };
425
+ });
426
+ options.push({ label: '< BACK', value: 'back' });
427
+
428
+ const selectedAccount = await prompts.selectOption('SELECT ACCOUNT:', options);
429
+ if (!selectedAccount || selectedAccount === 'back') return;
430
+
431
+ // Get the service for this account
432
+ const accountService = selectedAccount.service || connections.getServiceForAccount(selectedAccount.accountId) || service;
433
+
434
+ // Select symbol(s) - same as one-account.js
435
+ console.log();
436
+ const useMultiSymbol = await prompts.confirmPrompt(chalk.cyan('MULTI-SYMBOL MODE? (up to 5 symbols)'), false);
437
+ if (useMultiSymbol === null) return;
438
+
439
+ const contracts = await selectSymbol(accountService, selectedAccount, useMultiSymbol);
440
+ if (!contracts) return;
441
+
442
+ // Normalize to array
443
+ const contractList = Array.isArray(contracts) ? contracts : [contracts];
444
+
445
+ // Configure algo - same as one-account.js
446
+ const config = await configureAlgo(selectedAccount, contractList);
447
+ if (!config) return;
448
+
449
+ // Override: Custom strategy doesn't need AI supervisor (it IS the AI strategy)
450
+ config.enableAI = false;
451
+
452
+ // Show custom strategy info
453
+ console.log(chalk.magenta(`\n CUSTOM STRATEGY: ${strategyName}\n`));
454
+
495
455
  // Launch with custom strategy class
496
- await launchMultiSymbolRithmic(service, account, contracts, config, StrategyClass);
456
+ await launchMultiSymbolRithmic(accountService, selectedAccount, contractList, config, StrategyClass);
497
457
  }
498
458
 
499
459
  module.exports = { customStrategyMenu, generateStrategyCode, validateStrategyCode };
@@ -2194,4 +2194,4 @@ const launchMultiSymbolRithmic = async (service, account, contracts, config, Cus
2194
2194
  await prompts.waitForEnter();
2195
2195
  };
2196
2196
 
2197
- module.exports = { oneAccountMenu, launchMultiSymbolRithmic };
2197
+ module.exports = { oneAccountMenu, launchMultiSymbolRithmic, selectSymbol, configureAlgo };