hedgequantx 2.9.122 → 2.9.124
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
|
@@ -277,11 +277,18 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
277
277
|
else if (price < lastPrice) sellVolume += volume;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
// Log first tick
|
|
280
|
+
// Log first tick and periodic tick count
|
|
281
281
|
if (tickCount === 1) {
|
|
282
282
|
ui.addLog('connected', `First tick @ ${price?.toFixed(2) || 'N/A'}`);
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
// Log tick count every 10 seconds to confirm data flow
|
|
286
|
+
if (tickCount % 1000 === 0 || (currentSecond % 10 === 0 && currentSecond !== lastLogSecond)) {
|
|
287
|
+
const state = strategy.getAnalysisState?.(contractId, price);
|
|
288
|
+
const bars = state?.barsProcessed || 0;
|
|
289
|
+
ui.addLog('debug', `Ticks: ${tickCount} | Bars: ${bars} | Price: ${price?.toFixed(2)}`);
|
|
290
|
+
}
|
|
291
|
+
|
|
285
292
|
// === SMART LOGS - REDUCED FREQUENCY ===
|
|
286
293
|
if (currentSecond !== lastLogSecond && tickCount > 1) {
|
|
287
294
|
lastLogSecond = currentSecond;
|
|
@@ -291,12 +298,15 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
291
298
|
const delta = buyVolume - sellVolume;
|
|
292
299
|
|
|
293
300
|
let bias = buyPressure > 55 ? 'LONG' : buyPressure < 45 ? 'SHORT' : 'FLAT';
|
|
294
|
-
|
|
295
|
-
if (bias !== lastBias ||
|
|
301
|
+
// Log bias every 5 seconds or when it changes
|
|
302
|
+
if (bias !== lastBias || currentSecond % 5 === 0) {
|
|
296
303
|
const biasLog = smartLogs.getMarketBiasLog(bias, delta, buyPressure);
|
|
297
304
|
const biasType = bias === 'LONG' ? 'bullish' : bias === 'SHORT' ? 'bearish' : 'analysis';
|
|
298
305
|
ui.addLog(biasType, `${biasLog.message} ${biasLog.details || ''}`);
|
|
299
306
|
lastBias = bias;
|
|
307
|
+
// Reset volume after logging
|
|
308
|
+
buyVolume = 0;
|
|
309
|
+
sellVolume = 0;
|
|
300
310
|
}
|
|
301
311
|
|
|
302
312
|
// Strategy state log every 30 seconds (reduced frequency)
|
|
@@ -329,28 +339,8 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
|
|
|
329
339
|
}
|
|
330
340
|
}
|
|
331
341
|
|
|
332
|
-
//
|
|
333
|
-
if (currentSecond %
|
|
334
|
-
// Tick flow log every 45 seconds
|
|
335
|
-
if (currentSecond % 45 === 0) { const t = smartLogs.getTickFlowLog(tickCount, ticksPerSecond); ui.addLog('debug', `${t.message} ${t.details}`); }
|
|
336
|
-
// AI Agents status every 60 seconds
|
|
337
|
-
if (currentSecond % 60 === 0 && supervisionEnabled && supervisionEngine) {
|
|
338
|
-
const status = supervisionEngine.getStatus();
|
|
339
|
-
const agentNames = status.agents.map(a => a.name.split(' ')[0]).join(', ');
|
|
340
|
-
ui.addLog('analysis', `AI Supervision active: ${agentNames} (${status.availableAgents} agents monitoring)`);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Strategy health status every 2 minutes (confirms strategy is working)
|
|
344
|
-
if (currentSecond % 120 === 0 && strategy.getHealthStatus) {
|
|
345
|
-
const health = strategy.getHealthStatus(contractId);
|
|
346
|
-
const uptime = Math.floor(health.uptime / 60000);
|
|
347
|
-
const status = health.healthy ? 'OK' : 'WARMING';
|
|
348
|
-
ui.addLog('ready', `HEALTH: ${status} | Bars: ${health.barsTotal} | Zones: ${health.zonesTotal} (R:${health.zonesResistance}/S:${health.zonesSupport}) | Swings: ${health.swingsTotal} | Uptime: ${uptime}m`);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Reset volume counters
|
|
352
|
-
buyVolume = 0;
|
|
353
|
-
sellVolume = 0;
|
|
342
|
+
// AI status every 60s
|
|
343
|
+
if (currentSecond % 60 === 0 && supervisionEnabled && supervisionEngine) ui.addLog('analysis', `AI: ${supervisionEngine.getStatus().agents.map(a => a.name.split(' ')[0]).join(', ')}`);
|
|
354
344
|
}
|
|
355
345
|
|
|
356
346
|
lastPrice = price;
|
|
@@ -98,6 +98,18 @@ class RithmicService extends EventEmitter {
|
|
|
98
98
|
|
|
99
99
|
await this.orderConn.connect(config);
|
|
100
100
|
this.orderConn.on('message', createOrderHandler(this));
|
|
101
|
+
|
|
102
|
+
// Auto-reconnect on disconnect
|
|
103
|
+
this.orderConn.on('disconnected', async ({ code, reason }) => {
|
|
104
|
+
log.warn('ORDER_PLANT disconnected', { code, reason });
|
|
105
|
+
this.emit('disconnected', { plant: 'ORDER', code, reason });
|
|
106
|
+
|
|
107
|
+
// Auto-reconnect if we have credentials (not manual disconnect)
|
|
108
|
+
if (this.credentials && code !== 1000) {
|
|
109
|
+
log.info('Attempting auto-reconnect in 3s...');
|
|
110
|
+
setTimeout(() => this._autoReconnect(), 3000);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
101
113
|
|
|
102
114
|
return new Promise((resolve) => {
|
|
103
115
|
const timeout = setTimeout(() => {
|
|
@@ -163,6 +175,13 @@ class RithmicService extends EventEmitter {
|
|
|
163
175
|
|
|
164
176
|
await this.pnlConn.connect(config);
|
|
165
177
|
this.pnlConn.on('message', createPnLHandler(this));
|
|
178
|
+
|
|
179
|
+
// Auto-reconnect PnL on disconnect
|
|
180
|
+
this.pnlConn.on('disconnected', ({ code }) => {
|
|
181
|
+
if (this.credentials && code !== 1000) {
|
|
182
|
+
setTimeout(() => this.connectPnL(this.credentials.username, this.credentials.password), 3000);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
166
185
|
|
|
167
186
|
return new Promise((resolve) => {
|
|
168
187
|
const timeout = setTimeout(() => resolve(false), TIMEOUTS.RITHMIC_PNL);
|
|
@@ -200,6 +219,13 @@ class RithmicService extends EventEmitter {
|
|
|
200
219
|
};
|
|
201
220
|
|
|
202
221
|
await this.tickerConn.connect(config);
|
|
222
|
+
|
|
223
|
+
// Auto-reconnect Ticker on disconnect
|
|
224
|
+
this.tickerConn.on('disconnected', ({ code }) => {
|
|
225
|
+
if (this.credentials && code !== 1000) {
|
|
226
|
+
setTimeout(() => this.connectTicker(this.credentials.username, this.credentials.password), 3000);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
203
229
|
|
|
204
230
|
return new Promise((resolve) => {
|
|
205
231
|
const timeout = setTimeout(() => {
|
|
@@ -383,9 +409,42 @@ class RithmicService extends EventEmitter {
|
|
|
383
409
|
return { isOpen: true, message: 'Market is open' };
|
|
384
410
|
}
|
|
385
411
|
|
|
412
|
+
// ==================== AUTO-RECONNECT ====================
|
|
413
|
+
|
|
414
|
+
async _autoReconnect() {
|
|
415
|
+
if (!this.credentials) {
|
|
416
|
+
log.warn('Cannot auto-reconnect: no credentials');
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const { username, password } = this.credentials;
|
|
421
|
+
log.info('Auto-reconnecting...');
|
|
422
|
+
this.emit('reconnecting');
|
|
423
|
+
|
|
424
|
+
try {
|
|
425
|
+
const result = await this.login(username, password);
|
|
426
|
+
if (result.success) {
|
|
427
|
+
log.info('Auto-reconnect successful');
|
|
428
|
+
this.emit('reconnected', { accounts: result.accounts });
|
|
429
|
+
} else {
|
|
430
|
+
log.warn('Auto-reconnect failed', { error: result.error });
|
|
431
|
+
this.emit('reconnectFailed', { error: result.error });
|
|
432
|
+
// Retry in 10s
|
|
433
|
+
setTimeout(() => this._autoReconnect(), 10000);
|
|
434
|
+
}
|
|
435
|
+
} catch (err) {
|
|
436
|
+
log.error('Auto-reconnect error', { error: err.message });
|
|
437
|
+
this.emit('reconnectFailed', { error: err.message });
|
|
438
|
+
// Retry in 10s
|
|
439
|
+
setTimeout(() => this._autoReconnect(), 10000);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
386
443
|
// ==================== CLEANUP ====================
|
|
387
444
|
|
|
388
445
|
async disconnect() {
|
|
446
|
+
// Clear credentials to prevent auto-reconnect on manual disconnect
|
|
447
|
+
this.credentials = null;
|
|
389
448
|
const connections = [this.orderConn, this.pnlConn, this.tickerConn];
|
|
390
449
|
|
|
391
450
|
for (const conn of connections) {
|