hedgequantx 2.9.165 → 2.9.167
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
|
@@ -342,16 +342,23 @@ class RithmicBrokerDaemon {
|
|
|
342
342
|
// Log service state for debugging
|
|
343
343
|
const hasCredentials = !!conn.service.credentials;
|
|
344
344
|
const hasTickerConn = !!conn.service.tickerConn;
|
|
345
|
-
|
|
345
|
+
const tickerState = conn.service.tickerConn?.connectionState;
|
|
346
|
+
log('DEBUG', 'getContracts request', { propfirm: payload.propfirmKey, hasCredentials, hasTickerConn, tickerState });
|
|
346
347
|
|
|
347
348
|
try {
|
|
348
349
|
const result = await conn.service.getContracts();
|
|
350
|
+
|
|
351
|
+
// Log detailed result
|
|
352
|
+
const tickerStateAfter = conn.service.tickerConn?.connectionState;
|
|
349
353
|
log('DEBUG', 'getContracts result', {
|
|
350
354
|
propfirm: payload.propfirmKey,
|
|
351
355
|
success: result.success,
|
|
352
356
|
count: result.contracts?.length || 0,
|
|
357
|
+
source: result.source,
|
|
358
|
+
tickerStateAfter,
|
|
353
359
|
error: result.error
|
|
354
360
|
});
|
|
361
|
+
|
|
355
362
|
return { type: 'contracts', payload: result, requestId };
|
|
356
363
|
} catch (err) {
|
|
357
364
|
log('ERROR', 'getContracts exception', { propfirm: payload.propfirmKey, error: err.message, stack: err.stack?.split('\n')[1] });
|
package/src/services/session.js
CHANGED
|
@@ -111,19 +111,38 @@ const connections = {
|
|
|
111
111
|
log.info('Connection added', { type, propfirm: propfirm || type });
|
|
112
112
|
},
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Sanitize account data to prevent corrupted data from being saved
|
|
116
|
+
*/
|
|
117
|
+
_sanitizeAccount(acc) {
|
|
118
|
+
if (!acc || typeof acc !== 'object' || !acc.accountId) return null;
|
|
119
|
+
return {
|
|
120
|
+
accountId: String(acc.accountId),
|
|
121
|
+
fcmId: acc.fcmId ? String(acc.fcmId) : undefined,
|
|
122
|
+
ibId: acc.ibId ? String(acc.ibId) : undefined,
|
|
123
|
+
accountName: acc.accountName ? String(acc.accountName) : undefined,
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
|
|
114
127
|
saveToStorage() {
|
|
115
128
|
// Load existing sessions to preserve AI agents
|
|
116
129
|
const existingSessions = storage.load();
|
|
117
130
|
const aiSessions = existingSessions.filter(s => s.type === 'ai');
|
|
118
131
|
|
|
119
132
|
// Build Rithmic sessions - INCLUDE accounts to avoid Rithmic API limit on restore
|
|
120
|
-
const rithmicSessions = this.services.map(conn =>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
const rithmicSessions = this.services.map(conn => {
|
|
134
|
+
// Sanitize accounts to prevent corrupted data
|
|
135
|
+
const rawAccounts = conn.service.accounts || [];
|
|
136
|
+
const accounts = rawAccounts.map(a => this._sanitizeAccount(a)).filter(Boolean);
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
type: conn.type,
|
|
140
|
+
propfirm: conn.propfirm,
|
|
141
|
+
propfirmKey: conn.service.propfirmKey || conn.propfirmKey,
|
|
142
|
+
credentials: conn.service.credentials,
|
|
143
|
+
accounts, // CRITICAL: Cache sanitized accounts to avoid 2000 GetAccounts limit
|
|
144
|
+
};
|
|
145
|
+
});
|
|
127
146
|
|
|
128
147
|
// Merge: AI sessions + Rithmic sessions
|
|
129
148
|
storage.save([...aiSessions, ...rithmicSessions]);
|
|
@@ -200,8 +219,17 @@ const connections = {
|
|
|
200
219
|
if (type === 'rithmic' && session.credentials) {
|
|
201
220
|
const client = new RithmicBrokerClient(propfirmKey || 'apex_rithmic');
|
|
202
221
|
|
|
203
|
-
//
|
|
204
|
-
|
|
222
|
+
// Validate cached accounts before using
|
|
223
|
+
let validAccounts = null;
|
|
224
|
+
if (session.accounts && Array.isArray(session.accounts)) {
|
|
225
|
+
validAccounts = session.accounts
|
|
226
|
+
.map(a => this._sanitizeAccount(a))
|
|
227
|
+
.filter(Boolean);
|
|
228
|
+
if (validAccounts.length === 0) validAccounts = null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// CRITICAL: Pass validated cached accounts to avoid Rithmic's 2000 GetAccounts limit
|
|
232
|
+
const loginOptions = validAccounts ? { cachedAccounts: validAccounts } : {};
|
|
205
233
|
const result = await client.login(session.credentials.username, session.credentials.password, loginOptions);
|
|
206
234
|
|
|
207
235
|
if (result.success) {
|
|
@@ -212,7 +240,7 @@ const connections = {
|
|
|
212
240
|
propfirmKey,
|
|
213
241
|
connectedAt: new Date(),
|
|
214
242
|
});
|
|
215
|
-
log.debug('Rithmic session restored via broker', { hasCachedAccounts: !!
|
|
243
|
+
log.debug('Rithmic session restored via broker', { hasCachedAccounts: !!validAccounts, accountCount: validAccounts?.length || 0 });
|
|
216
244
|
}
|
|
217
245
|
}
|
|
218
246
|
},
|