hedgequantx 2.9.147 → 2.9.148

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.9.147",
3
+ "version": "2.9.148",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -302,6 +302,9 @@ const oneAccountMenu = async (service) => {
302
302
  const selectMultipleSymbols = async (service, account) => {
303
303
  const spinner = ora({ text: 'Loading symbols...', color: 'yellow' }).start();
304
304
 
305
+ // Debug: log service type
306
+ const serviceType = service.constructor?.name || 'Unknown';
307
+
305
308
  // Ensure we have a logged-in service
306
309
  if (!service.loginInfo && service.credentials) {
307
310
  spinner.text = 'Reconnecting to broker...';
@@ -312,19 +315,24 @@ const selectMultipleSymbols = async (service, account) => {
312
315
  }
313
316
  }
314
317
 
315
- const contractsResult = await service.getContracts();
318
+ let contractsResult;
319
+ try {
320
+ contractsResult = await service.getContracts();
321
+ } catch (err) {
322
+ spinner.fail(`getContracts exception: ${err.message}`);
323
+ console.log(chalk.gray(` Service: ${serviceType} | Tip: Try "hqx login"`));
324
+ return null;
325
+ }
316
326
  if (!contractsResult.success || !contractsResult.contracts?.length) {
317
327
  spinner.fail(`Failed to load contracts: ${contractsResult.error || 'No contracts'}`);
328
+ console.log(chalk.gray(` Service: ${serviceType} | Tip: Try "hqx login"`));
318
329
  return null;
319
330
  }
320
331
 
321
332
  const contracts = sortContracts(contractsResult.contracts);
322
333
  spinner.succeed(`Found ${contracts.length} contracts`);
323
-
324
- console.log();
325
- console.log(chalk.cyan(' Select up to 5 symbols (one at a time)'));
326
- console.log(chalk.gray(' Select "Done" when finished'));
327
- console.log();
334
+ console.log(chalk.cyan('\n Select up to 5 symbols (one at a time)'));
335
+ console.log(chalk.gray(' Select "Done" when finished\n'));
328
336
 
329
337
  const selectedContracts = [];
330
338
  const maxSymbols = 5;
@@ -356,30 +364,17 @@ const selectMultipleSymbols = async (service, account) => {
356
364
  : `Select Symbol ${selectedContracts.length + 1}/${maxSymbols} (${remaining} remaining):`;
357
365
 
358
366
  const selection = await prompts.selectOption(chalk.yellow(promptText), options);
359
-
360
- if (selection === 'back' || selection === null) {
361
- return null;
362
- }
363
- if (selection === 'done') {
364
- break;
365
- }
366
-
367
+ if (selection === 'back' || selection === null) return null;
368
+ if (selection === 'done') break;
367
369
  selectedContracts.push(selection);
368
370
  console.log(chalk.green(` ✓ Added: ${selection.symbol}`));
369
371
  }
370
-
371
- if (selectedContracts.length === 0) {
372
- return null;
373
- }
372
+ if (selectedContracts.length === 0) return null;
374
373
 
375
374
  // Display summary
375
+ console.log(chalk.cyan(`\n Selected ${selectedContracts.length} symbol(s):`));
376
+ for (const c of selectedContracts) console.log(chalk.white(` - ${c.symbol} (${c.baseSymbol || c.name})`));
376
377
  console.log();
377
- console.log(chalk.cyan(` Selected ${selectedContracts.length} symbol(s):`));
378
- for (const c of selectedContracts) {
379
- console.log(chalk.white(` - ${c.symbol} (${c.baseSymbol || c.name})`));
380
- }
381
- console.log();
382
-
383
378
  return selectedContracts;
384
379
  };
385
380
 
@@ -389,6 +384,9 @@ const selectMultipleSymbols = async (service, account) => {
389
384
  const selectSymbol = async (service, account) => {
390
385
  const spinner = ora({ text: 'Loading symbols...', color: 'yellow' }).start();
391
386
 
387
+ // Debug: log service type
388
+ const serviceType = service.constructor?.name || 'Unknown';
389
+
392
390
  // Ensure we have a logged-in service (for direct RithmicService, not BrokerClient)
393
391
  if (!service.loginInfo && service.credentials && typeof service.login === 'function') {
394
392
  spinner.text = 'Reconnecting to broker...';
@@ -399,12 +397,17 @@ const selectSymbol = async (service, account) => {
399
397
  }
400
398
  }
401
399
 
402
- const contractsResult = await service.getContracts();
403
-
400
+ let contractsResult;
401
+ try {
402
+ contractsResult = await service.getContracts();
403
+ } catch (err) {
404
+ spinner.fail(`getContracts exception: ${err.message}`);
405
+ console.log(chalk.gray(` Service: ${serviceType} | Tip: Try "hqx login"`));
406
+ return null;
407
+ }
404
408
  if (!contractsResult.success || !contractsResult.contracts?.length) {
405
- const errorMsg = contractsResult.error || 'No contracts available';
406
- spinner.fail(`Failed to load contracts: ${errorMsg}`);
407
- console.log(chalk.gray(' Tip: Try reconnecting with "hqx login"'));
409
+ spinner.fail(`Failed to load contracts: ${contractsResult.error || 'No contracts available'}`);
410
+ console.log(chalk.gray(` Service: ${serviceType} | Tip: Try "hqx login"`));
408
411
  return null;
409
412
  }
410
413
 
@@ -211,7 +211,13 @@ class RithmicBrokerClient extends EventEmitter {
211
211
  */
212
212
  async getContracts() {
213
213
  const result = await this._request('getContracts', { propfirmKey: this.propfirmKey });
214
- if (result.error) return { success: false, contracts: [], error: result.error };
214
+ if (result.error) {
215
+ // Debug: show exactly what error came from daemon
216
+ if (process.env.HQX_DEBUG === '1') {
217
+ console.log('[BrokerClient] getContracts error:', result.error, 'propfirmKey:', this.propfirmKey);
218
+ }
219
+ return { success: false, contracts: [], error: result.error };
220
+ }
215
221
  return result.payload || { success: true, contracts: [] };
216
222
  }
217
223
 
@@ -299,13 +299,27 @@ class RithmicBrokerDaemon {
299
299
 
300
300
  async _handleGetContracts(payload, requestId) {
301
301
  const conn = this.connections.get(payload.propfirmKey);
302
- if (!conn?.service) return { error: 'Not connected to broker', requestId };
302
+ if (!conn?.service) {
303
+ log('WARN', 'getContracts: Not connected', { propfirm: payload.propfirmKey, hasConn: !!conn });
304
+ return { error: 'Not connected to broker', requestId };
305
+ }
306
+
307
+ // Log service state for debugging
308
+ const hasCredentials = !!conn.service.credentials;
309
+ const hasTickerConn = !!conn.service.tickerConn;
310
+ log('DEBUG', 'getContracts request', { propfirm: payload.propfirmKey, hasCredentials, hasTickerConn });
303
311
 
304
312
  try {
305
313
  const result = await conn.service.getContracts();
314
+ log('DEBUG', 'getContracts result', {
315
+ propfirm: payload.propfirmKey,
316
+ success: result.success,
317
+ count: result.contracts?.length || 0,
318
+ error: result.error
319
+ });
306
320
  return { type: 'contracts', payload: result, requestId };
307
321
  } catch (err) {
308
- log('ERROR', 'getContracts failed', { propfirm: payload.propfirmKey, error: err.message });
322
+ log('ERROR', 'getContracts exception', { propfirm: payload.propfirmKey, error: err.message, stack: err.stack?.split('\n')[1] });
309
323
  return { type: 'contracts', payload: { success: false, error: err.message, contracts: [] }, requestId };
310
324
  }
311
325
  }