hedgequantx 2.9.148 → 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 +1 -1
- package/src/pages/algo/algo-executor.js +10 -7
- package/src/pages/algo/copy-executor.js +10 -2
- package/src/pages/algo/multi-symbol-executor.js +10 -2
- package/src/services/rithmic-broker/client.js +5 -0
- package/src/services/rithmic-broker/daemon.js +14 -2
- package/src/services/session.js +12 -1
package/package.json
CHANGED
|
@@ -326,14 +326,17 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
326
326
|
marketFeed.on('disconnected', () => { stats.connected = false; ui.addLog('error', 'Market disconnected'); });
|
|
327
327
|
|
|
328
328
|
try {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
329
|
+
// Try sync (RithmicService) then async (BrokerClient)
|
|
330
|
+
let rithmicCredentials = service.getRithmicCredentials?.();
|
|
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
|
+
}
|
|
336
337
|
}
|
|
338
|
+
if (!rithmicCredentials) throw new Error('Rithmic credentials not available - try "hqx login"');
|
|
339
|
+
if (service.disconnectTicker) await service.disconnectTicker(); // Avoid TICKER conflict
|
|
337
340
|
await marketFeed.connect(rithmicCredentials);
|
|
338
341
|
await marketFeed.subscribe(symbolCode, contract.exchange || 'CME');
|
|
339
342
|
|
|
@@ -188,9 +188,17 @@ const launchCopyTrading = async (config) => {
|
|
|
188
188
|
|
|
189
189
|
// Connect to market data (Rithmic TICKER_PLANT)
|
|
190
190
|
try {
|
|
191
|
-
|
|
191
|
+
// Try sync first (RithmicService), then async (RithmicBrokerClient)
|
|
192
|
+
let rithmicCredentials = leadService.getRithmicCredentials?.();
|
|
193
|
+
if (!rithmicCredentials && leadService.getRithmicCredentialsAsync) {
|
|
194
|
+
try {
|
|
195
|
+
rithmicCredentials = await leadService.getRithmicCredentialsAsync();
|
|
196
|
+
} catch (credErr) {
|
|
197
|
+
throw new Error(`Broker error: ${credErr.message} - try "hqx login"`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
192
200
|
if (!rithmicCredentials) {
|
|
193
|
-
throw new Error('Rithmic credentials not available');
|
|
201
|
+
throw new Error('Rithmic credentials not available - try "hqx login"');
|
|
194
202
|
}
|
|
195
203
|
await marketFeed.connect(rithmicCredentials);
|
|
196
204
|
await marketFeed.subscribe(symbolName, contract.exchange || 'CME');
|
|
@@ -267,8 +267,16 @@ const executeMultiSymbol = async ({ service, account, contracts, config, strateg
|
|
|
267
267
|
|
|
268
268
|
// Connect and subscribe to all symbols
|
|
269
269
|
try {
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
// Try sync first (RithmicService), then async (RithmicBrokerClient)
|
|
271
|
+
let rithmicCredentials = service.getRithmicCredentials?.();
|
|
272
|
+
if (!rithmicCredentials && service.getRithmicCredentialsAsync) {
|
|
273
|
+
try {
|
|
274
|
+
rithmicCredentials = await service.getRithmicCredentialsAsync();
|
|
275
|
+
} catch (credErr) {
|
|
276
|
+
throw new Error(`Broker error: ${credErr.message} - try "hqx login"`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!rithmicCredentials) throw new Error('Rithmic credentials not available - try "hqx login"');
|
|
272
280
|
|
|
273
281
|
if (service.disconnectTicker) await service.disconnectTicker();
|
|
274
282
|
await marketFeed.connect(rithmicCredentials);
|
|
@@ -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
|
|
336
|
-
|
|
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
|
/**
|
package/src/services/session.js
CHANGED
|
@@ -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;
|