hedgequantx 2.9.149 → 2.9.150

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.149",
3
+ "version": "2.9.150",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -328,7 +328,13 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
328
328
  try {
329
329
  // Try sync (RithmicService) then async (BrokerClient)
330
330
  let rithmicCredentials = service.getRithmicCredentials?.();
331
- if (!rithmicCredentials && service.getRithmicCredentialsAsync) rithmicCredentials = await service.getRithmicCredentialsAsync();
331
+ if (!rithmicCredentials && service.getRithmicCredentialsAsync) {
332
+ try {
333
+ rithmicCredentials = await service.getRithmicCredentialsAsync();
334
+ } catch (credErr) {
335
+ throw new Error(`Broker error: ${credErr.message} - try "hqx login"`);
336
+ }
337
+ }
332
338
  if (!rithmicCredentials) throw new Error('Rithmic credentials not available - try "hqx login"');
333
339
  if (service.disconnectTicker) await service.disconnectTicker(); // Avoid TICKER conflict
334
340
  await marketFeed.connect(rithmicCredentials);
@@ -191,7 +191,11 @@ const launchCopyTrading = async (config) => {
191
191
  // Try sync first (RithmicService), then async (RithmicBrokerClient)
192
192
  let rithmicCredentials = leadService.getRithmicCredentials?.();
193
193
  if (!rithmicCredentials && leadService.getRithmicCredentialsAsync) {
194
- rithmicCredentials = await leadService.getRithmicCredentialsAsync();
194
+ try {
195
+ rithmicCredentials = await leadService.getRithmicCredentialsAsync();
196
+ } catch (credErr) {
197
+ throw new Error(`Broker error: ${credErr.message} - try "hqx login"`);
198
+ }
195
199
  }
196
200
  if (!rithmicCredentials) {
197
201
  throw new Error('Rithmic credentials not available - try "hqx login"');
@@ -270,7 +270,11 @@ const executeMultiSymbol = async ({ service, account, contracts, config, strateg
270
270
  // Try sync first (RithmicService), then async (RithmicBrokerClient)
271
271
  let rithmicCredentials = service.getRithmicCredentials?.();
272
272
  if (!rithmicCredentials && service.getRithmicCredentialsAsync) {
273
- rithmicCredentials = await service.getRithmicCredentialsAsync();
273
+ try {
274
+ rithmicCredentials = await service.getRithmicCredentialsAsync();
275
+ } catch (credErr) {
276
+ throw new Error(`Broker error: ${credErr.message} - try "hqx login"`);
277
+ }
274
278
  }
275
279
  if (!rithmicCredentials) throw new Error('Rithmic credentials not available - try "hqx login"');
276
280
 
@@ -249,9 +249,14 @@ class RithmicBrokerClient extends EventEmitter {
249
249
 
250
250
  /**
251
251
  * Get async Rithmic credentials from daemon
252
+ * @returns {Object|null} Credentials object or null
253
+ * @throws {Error} If daemon returns error
252
254
  */
253
255
  async getRithmicCredentialsAsync() {
254
256
  const result = await this._request('getRithmicCredentials', { propfirmKey: this.propfirmKey });
257
+ if (result.error) {
258
+ throw new Error(result.error);
259
+ }
255
260
  return result.payload || null;
256
261
  }
257
262
 
@@ -332,8 +332,20 @@ class RithmicBrokerDaemon {
332
332
 
333
333
  _handleGetCredentials(payload, requestId) {
334
334
  const conn = this.connections.get(payload.propfirmKey);
335
- if (!conn?.service) return { error: 'Not connected', requestId };
336
- return { type: 'credentials', payload: conn.service.getRithmicCredentials?.() || null, requestId };
335
+ if (!conn) {
336
+ log('WARN', 'getCredentials: propfirm not found', { propfirm: payload.propfirmKey });
337
+ return { error: `Propfirm "${payload.propfirmKey}" not connected - run "hqx login"`, requestId };
338
+ }
339
+ if (!conn.service) {
340
+ log('WARN', 'getCredentials: service is null', { propfirm: payload.propfirmKey, status: conn.status });
341
+ return { error: `Connection lost for "${payload.propfirmKey}" - run "hqx login"`, requestId };
342
+ }
343
+ const creds = conn.service.getRithmicCredentials?.();
344
+ if (!creds) {
345
+ log('WARN', 'getCredentials: credentials null', { propfirm: payload.propfirmKey });
346
+ return { error: `Credentials not available for "${payload.propfirmKey}"`, requestId };
347
+ }
348
+ return { type: 'credentials', payload: creds, requestId };
337
349
  }
338
350
 
339
351
  /**
@@ -146,6 +146,17 @@ const connections = {
146
146
  const accountsResult = await client.getTradingAccounts();
147
147
  client.accounts = accountsResult.accounts || [];
148
148
 
149
+ // Cache credentials locally for sync access (fetch from daemon)
150
+ try {
151
+ const creds = await client.getRithmicCredentialsAsync();
152
+ if (creds && creds.userId && creds.password) {
153
+ client.credentials = { username: creds.userId, password: creds.password };
154
+ client.propfirm = { name: conn.propfirmKey, systemName: creds.systemName, gateway: creds.gateway };
155
+ }
156
+ } catch (e) {
157
+ log.warn('Failed to cache credentials', { propfirm: conn.propfirmKey, error: e.message });
158
+ }
159
+
149
160
  this.services.push({
150
161
  type: 'rithmic',
151
162
  service: client,
@@ -153,7 +164,7 @@ const connections = {
153
164
  propfirmKey: conn.propfirmKey,
154
165
  connectedAt: new Date(conn.connectedAt),
155
166
  });
156
- log.debug('Restored from broker', { propfirm: conn.propfirmKey });
167
+ log.debug('Restored from broker', { propfirm: conn.propfirmKey, hasCreds: !!client.credentials });
157
168
  }
158
169
 
159
170
  return this.services.length > 0;