hedgequantx 2.6.157 → 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.157",
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,111 +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
- const propfirm = acc.propfirm || 'Unknown';
413
- const accId = acc.rithmicAccountId || acc.accountId;
414
- console.log(chalk.cyan(` [${i + 1}]`) + chalk.yellow(` ${propfirm}`) + chalk.gray(` (${accId})`) + chalk.green(` ${balance}`));
415
- });
416
-
417
- const accChoice = await prompts.numberInput('\n ACCOUNT #:', 1, 1, accountsResult.accounts.length);
418
- if (accChoice === null) return;
419
- const account = accountsResult.accounts[accChoice - 1];
420
-
421
- // Symbol selection
422
- const symbolInput = await prompts.textInput(chalk.cyan(' SYMBOL (e.g., MES, MNQ): '));
423
- if (!symbolInput) return;
424
- const symbols = symbolInput.toUpperCase().split(',').map(s => s.trim()).filter(Boolean);
425
-
426
- // Target and Risk
427
- const dailyTarget = await prompts.numberInput(' TARGET ($):', 1000, 100, 50000);
428
- if (dailyTarget === null) return;
429
-
430
- const maxRisk = await prompts.numberInput(' MAX RISK ($):', 500, 50, 10000);
431
- if (maxRisk === null) return;
432
-
433
- // Confirm
434
- console.log(chalk.cyan('\n ╔════════════════════════════════════════════════════════════╗'));
435
- console.log(chalk.cyan(' ║') + chalk.yellow.bold(' CONFIRM SETTINGS ') + chalk.cyan('║'));
436
- console.log(chalk.cyan(' ╠════════════════════════════════════════════════════════════╣'));
437
- console.log(chalk.cyan(' ║') + chalk.white(` Strategy: ${strategyName.substring(0, 47).padEnd(47)}`) + chalk.cyan('║'));
438
- console.log(chalk.cyan(' ║') + chalk.white(` Account: ${(account.name || account.accountId).substring(0, 47).padEnd(47)}`) + chalk.cyan('║'));
439
- console.log(chalk.cyan(' ║') + chalk.white(` Symbols: ${symbols.join(', ').substring(0, 47).padEnd(47)}`) + chalk.cyan('║'));
440
- console.log(chalk.cyan(' ║') + chalk.green(` Target: $${dailyTarget.toLocaleString().padEnd(46)}`) + chalk.cyan('║'));
441
- console.log(chalk.cyan(' ║') + chalk.red(` Risk: $${maxRisk.toLocaleString().padEnd(46)}`) + chalk.cyan('║'));
442
- console.log(chalk.cyan(' ╚════════════════════════════════════════════════════════════╝\n'));
443
-
444
- const startConfirm = await prompts.textInput(chalk.cyan(' START TRADING? (Y/n): '));
445
- if (startConfirm.toLowerCase() === 'n') {
446
- console.log(chalk.yellow('\n Cancelled.\n'));
447
- await prompts.waitForEnter();
448
- return;
449
- }
450
-
451
- // Launch with custom strategy
452
- console.log(chalk.green('\n Starting custom strategy trading...\n'));
453
406
 
454
- // Get front month contracts for each symbol
455
- const contracts = [];
456
- for (const symbol of symbols) {
457
- // Get front month contract from Rithmic API
458
- const frontMonth = await service.getFrontMonthContract(symbol);
459
- if (frontMonth && frontMonth.success) {
460
- contracts.push({
461
- name: frontMonth.symbol || symbol,
462
- symbol: frontMonth.symbol || symbol,
463
- exchange: frontMonth.exchange || 'CME',
464
- id: frontMonth.contractId || symbol,
465
- tickSize: frontMonth.tickSize,
466
- tickValue: frontMonth.tickValue,
467
- qty: 1, // Default 1 contract per symbol
468
- });
469
- } else {
470
- // Fallback - use symbol directly
471
- contracts.push({
472
- name: symbol,
473
- symbol: symbol,
474
- exchange: 'CME',
475
- id: symbol,
476
- tickSize: null,
477
- tickValue: null,
478
- qty: 1,
479
- });
480
- }
481
- }
482
-
483
- if (contracts.length === 0) {
484
- 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'));
485
411
  await prompts.waitForEnter();
486
412
  return;
487
413
  }
488
414
 
489
- // Config for launchMultiSymbolRithmic
490
- const config = {
491
- dailyTarget,
492
- maxRisk,
493
- showName: true,
494
- enableAI: false, // Custom strategy doesn't need AI supervisor (it IS the AI strategy)
495
- };
496
-
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
+
497
455
  // Launch with custom strategy class
498
- await launchMultiSymbolRithmic(service, account, contracts, config, StrategyClass);
456
+ await launchMultiSymbolRithmic(accountService, selectedAccount, contractList, config, StrategyClass);
499
457
  }
500
458
 
501
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 };