hedgequantx 2.9.180 → 2.9.182
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
|
@@ -251,9 +251,23 @@ const fetchAllFrontMonths = (service) => {
|
|
|
251
251
|
|
|
252
252
|
let sentCount = 0;
|
|
253
253
|
let sendErrors = [];
|
|
254
|
-
|
|
254
|
+
|
|
255
|
+
// Prioritize CME products (ES, NQ, MNQ, MES, etc.) - most used by traders
|
|
255
256
|
const productsArray = Array.from(productsToCheck.values());
|
|
256
|
-
const
|
|
257
|
+
const prioritySymbols = ['ES', 'NQ', 'MNQ', 'MES', 'RTY', 'M2K', 'YM', 'MYM', 'CL', 'MCL', 'GC', 'MGC', 'SI', 'HG', 'NG', 'ZB', 'ZN', 'ZF', 'ZT', '6E', '6J', '6B', '6A', '6C', '6S', 'ZC', 'ZS', 'ZW', 'ZM', 'ZL', 'HE', 'LE', 'GF'];
|
|
258
|
+
|
|
259
|
+
// Sort: priority symbols first (CME), then others
|
|
260
|
+
productsArray.sort((a, b) => {
|
|
261
|
+
const aPriority = prioritySymbols.includes(a.productCode) ? 0 : 1;
|
|
262
|
+
const bPriority = prioritySymbols.includes(b.productCode) ? 0 : 1;
|
|
263
|
+
if (aPriority !== bPriority) return aPriority - bPriority;
|
|
264
|
+
// Within same priority, prefer CME/CBOT
|
|
265
|
+
const aExchange = (a.exchange === 'CME' || a.exchange === 'CBOT') ? 0 : 1;
|
|
266
|
+
const bExchange = (b.exchange === 'CME' || b.exchange === 'CBOT') ? 0 : 1;
|
|
267
|
+
return aExchange - bExchange;
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const testProducts = productsArray.slice(0, 60); // Limit to 60
|
|
257
271
|
|
|
258
272
|
for (const product of testProducts) {
|
|
259
273
|
try {
|
package/src/services/session.js
CHANGED
|
@@ -85,13 +85,19 @@ const storage = {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
// Lazy load services to avoid circular dependencies
|
|
88
|
-
let RithmicBrokerClient, brokerManager;
|
|
88
|
+
let RithmicBrokerClient, brokerManager, RithmicService;
|
|
89
89
|
const loadServices = () => {
|
|
90
90
|
if (!RithmicBrokerClient) {
|
|
91
91
|
({ RithmicBrokerClient, manager: brokerManager } = require('./rithmic-broker'));
|
|
92
92
|
}
|
|
93
|
+
if (!RithmicService) {
|
|
94
|
+
({ RithmicService } = require('./rithmic'));
|
|
95
|
+
}
|
|
93
96
|
};
|
|
94
97
|
|
|
98
|
+
// Direct mode flag - bypass daemon completely
|
|
99
|
+
const DIRECT_MODE = process.env.HQX_DIRECT === '1' || true; // Default to direct for now
|
|
100
|
+
|
|
95
101
|
/**
|
|
96
102
|
* Multi-connection manager (Rithmic only)
|
|
97
103
|
*/
|
|
@@ -152,6 +158,28 @@ const connections = {
|
|
|
152
158
|
async restoreFromStorage() {
|
|
153
159
|
loadServices();
|
|
154
160
|
|
|
161
|
+
// DIRECT MODE: Bypass daemon, connect directly to Rithmic
|
|
162
|
+
if (DIRECT_MODE) {
|
|
163
|
+
log.info('Direct mode enabled - bypassing daemon');
|
|
164
|
+
|
|
165
|
+
const sessions = storage.load();
|
|
166
|
+
const rithmicSessions = sessions.filter(s => s.type === 'rithmic');
|
|
167
|
+
|
|
168
|
+
if (!rithmicSessions.length) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const session of rithmicSessions) {
|
|
173
|
+
try {
|
|
174
|
+
await this._restoreSessionDirect(session);
|
|
175
|
+
} catch (err) {
|
|
176
|
+
log.warn('Failed to restore session direct', { error: err.message });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return this.services.length > 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
155
183
|
// Check if daemon is already running with active connections
|
|
156
184
|
const daemonStatus = await brokerManager.getStatus();
|
|
157
185
|
|
|
@@ -211,6 +239,41 @@ const connections = {
|
|
|
211
239
|
|
|
212
240
|
return this.services.length > 0;
|
|
213
241
|
},
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Restore session using direct RithmicService (no daemon)
|
|
245
|
+
*/
|
|
246
|
+
async _restoreSessionDirect(session) {
|
|
247
|
+
const { type, propfirm, propfirmKey } = session;
|
|
248
|
+
|
|
249
|
+
if (type === 'rithmic' && session.credentials) {
|
|
250
|
+
const service = new RithmicService(propfirmKey || 'apex_rithmic');
|
|
251
|
+
|
|
252
|
+
// Validate cached accounts
|
|
253
|
+
let validAccounts = null;
|
|
254
|
+
if (session.accounts && Array.isArray(session.accounts)) {
|
|
255
|
+
validAccounts = session.accounts
|
|
256
|
+
.map(a => this._sanitizeAccount(a))
|
|
257
|
+
.filter(Boolean);
|
|
258
|
+
if (validAccounts.length === 0) validAccounts = null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Login with cached accounts to avoid API limit
|
|
262
|
+
const loginOptions = validAccounts ? { skipFetchAccounts: true, cachedAccounts: validAccounts } : {};
|
|
263
|
+
const result = await service.login(session.credentials.username, session.credentials.password, loginOptions);
|
|
264
|
+
|
|
265
|
+
if (result.success) {
|
|
266
|
+
this.services.push({
|
|
267
|
+
type,
|
|
268
|
+
service,
|
|
269
|
+
propfirm,
|
|
270
|
+
propfirmKey,
|
|
271
|
+
connectedAt: new Date(),
|
|
272
|
+
});
|
|
273
|
+
log.info('Direct session restored', { propfirm, accounts: service.accounts?.length || 0 });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
214
277
|
|
|
215
278
|
async _restoreSession(session) {
|
|
216
279
|
const { type, propfirm, propfirmKey } = session;
|