hedgequantx 2.9.74 → 2.9.76

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.74",
3
+ "version": "2.9.76",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -41,21 +41,21 @@ function getVariedMessage(category, pool, defaultMsg) {
41
41
  // =============================================================================
42
42
 
43
43
  const LONG_BIAS_MESSAGES = [
44
- 'Buyers taking control',
45
- 'Bid side absorbing',
46
- 'Bullish order flow detected',
47
- 'Buy programs active',
48
- 'Strong buyer presence',
49
- 'Accumulation pattern',
50
- 'Demand exceeding supply',
51
- 'Buyers stepping up',
52
- 'Long-side momentum building',
53
- 'Bid accumulation detected',
54
- 'Bullish delta divergence',
55
- 'Buy-side imbalance',
56
- 'Institutional buying detected',
57
- 'Aggressive bid lifting',
58
- 'Bullish tape reading',
44
+ 'Buyers taking control of the tape',
45
+ 'Bid side absorbing sell pressure',
46
+ 'Bullish order flow detected on sweep',
47
+ 'Buy programs actively lifting offers',
48
+ 'Strong buyer presence at current levels',
49
+ 'Accumulation pattern forming on volume',
50
+ 'Demand exceeding supply at bid',
51
+ 'Buyers stepping up with size',
52
+ 'Long-side momentum building steadily',
53
+ 'Bid accumulation detected at support',
54
+ 'Bullish delta divergence confirmed',
55
+ 'Buy-side imbalance driving price higher',
56
+ 'Institutional buying detected on tape',
57
+ 'Aggressive bid lifting through offers',
58
+ 'Bullish tape reading with strong delta',
59
59
  ];
60
60
 
61
61
  // =============================================================================
@@ -63,21 +63,21 @@ const LONG_BIAS_MESSAGES = [
63
63
  // =============================================================================
64
64
 
65
65
  const SHORT_BIAS_MESSAGES = [
66
- 'Sellers taking control',
67
- 'Offer side absorbing',
68
- 'Bearish order flow detected',
69
- 'Sell programs active',
70
- 'Strong seller presence',
71
- 'Distribution pattern',
72
- 'Supply exceeding demand',
73
- 'Sellers stepping in',
74
- 'Short-side momentum building',
75
- 'Offer distribution detected',
76
- 'Bearish delta divergence',
77
- 'Sell-side imbalance',
78
- 'Institutional selling detected',
79
- 'Aggressive offer hitting',
80
- 'Bearish tape reading',
66
+ 'Sellers taking control of the tape',
67
+ 'Offer side absorbing buy pressure',
68
+ 'Bearish order flow detected on sweep',
69
+ 'Sell programs actively hitting bids',
70
+ 'Strong seller presence at current levels',
71
+ 'Distribution pattern forming on volume',
72
+ 'Supply exceeding demand at offer',
73
+ 'Sellers stepping in with size',
74
+ 'Short-side momentum building steadily',
75
+ 'Offer distribution detected at resistance',
76
+ 'Bearish delta divergence confirmed',
77
+ 'Sell-side imbalance driving price lower',
78
+ 'Institutional selling detected on tape',
79
+ 'Aggressive offer hitting through bids',
80
+ 'Bearish tape reading with weak delta',
81
81
  ];
82
82
 
83
83
  // =============================================================================
@@ -219,10 +219,14 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
219
219
  let sellVolume = 0;
220
220
  let barCount = 0;
221
221
 
222
+ // Track tick arrival times for latency estimation
223
+ let lastTickTime = 0;
224
+ let tickLatencies = [];
225
+
222
226
  marketFeed.on('tick', (tick) => {
223
227
  tickCount++;
224
- const latencyStart = Date.now();
225
- const currentSecond = Math.floor(Date.now() / 1000);
228
+ const now = Date.now();
229
+ const currentSecond = Math.floor(now / 1000);
226
230
 
227
231
  // Count ticks per second
228
232
  if (currentSecond === lastTickSecond) {
@@ -266,16 +270,17 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
266
270
  if (buyPressure > 55) bias = 'LONG';
267
271
  else if (buyPressure < 45) bias = 'SHORT';
268
272
 
269
- // Log bias only when it changes or every 10 seconds
270
- if (bias !== lastBias || currentSecond % 10 === 0) {
273
+ // Log bias when it changes, or every 5 seconds if strong signal
274
+ const strongSignal = Math.abs(delta) > 20 || buyPressure > 65 || buyPressure < 35;
275
+ if (bias !== lastBias || (strongSignal && currentSecond % 5 === 0) || (!strongSignal && currentSecond % 15 === 0)) {
271
276
  const biasLog = smartLogs.getMarketBiasLog(bias, delta, buyPressure);
272
277
  const biasType = bias === 'LONG' ? 'bullish' : bias === 'SHORT' ? 'bearish' : 'analysis';
273
278
  ui.addLog(biasType, `${biasLog.message} ${biasLog.details || ''}`);
274
279
  lastBias = bias;
275
280
  }
276
281
 
277
- // Strategy state log every 10 seconds
278
- if (currentSecond % 10 === 0) {
282
+ // Strategy state log every 30 seconds (reduced frequency)
283
+ if (currentSecond % 30 === 0) {
279
284
  const state = strategy.getAnalysisState?.(contractId, price);
280
285
  if (state) {
281
286
  if (!state.ready) {
@@ -283,42 +288,43 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
283
288
  } else {
284
289
  const resStr = state.nearestResistance ? state.nearestResistance.toFixed(2) : '--';
285
290
  const supStr = state.nearestSupport ? state.nearestSupport.toFixed(2) : '--';
286
- ui.addLog('analysis', `Bars: ${state.barsProcessed} | Zones: ${state.activeZones} | Swings: ${state.swingsDetected}`);
287
- ui.addLog('analysis', `Resistance: ${resStr} | Support: ${supStr}`);
288
291
 
289
- // Explain why no trade
292
+ // Combined single line for zones info
293
+ ui.addLog('analysis', `Zones: ${state.activeZones} | R: ${resStr} | S: ${supStr} | Swings: ${state.swingsDetected}`);
294
+
295
+ // Strategy status - what we're waiting for
290
296
  if (state.activeZones === 0) {
291
- ui.addLog('risk', 'No zones detected - waiting for swing points');
297
+ ui.addLog('risk', 'Scanning for swing points to build liquidity zones...');
292
298
  } else if (!state.nearestSupport && !state.nearestResistance) {
293
- ui.addLog('risk', 'Zones too far from price - waiting');
299
+ ui.addLog('risk', 'Zones detected but too far from current price level');
294
300
  } else if (!state.nearestSupport) {
295
- ui.addLog('risk', 'No support zone - only SHORT sweeps possible');
301
+ ui.addLog('analysis', 'Watching resistance for HIGH SWEEP entry (SHORT)');
296
302
  } else if (!state.nearestResistance) {
297
- ui.addLog('risk', 'No resistance zone - only LONG sweeps possible');
303
+ ui.addLog('analysis', 'Watching support for LOW SWEEP entry (LONG)');
298
304
  } else {
299
- ui.addLog('ready', 'Zones active - waiting for sweep signal');
305
+ ui.addLog('ready', 'Both zones active - monitoring for liquidity sweep');
300
306
  }
301
307
  }
302
308
  }
303
309
  }
304
310
 
305
- // Scanning log every 7 seconds (when no position)
306
- if (currentSecond % 7 === 0 && currentPosition === 0) {
311
+ // Scanning log every 20 seconds (when no position)
312
+ if (currentSecond % 20 === 0 && currentPosition === 0) {
307
313
  const scanLog = smartLogs.getScanningLog(true);
308
314
  ui.addLog('system', scanLog.message);
309
315
  }
310
316
 
311
- // Tick flow log every 15 seconds
312
- if (currentSecond % 15 === 0) {
317
+ // Tick flow log every 45 seconds (less frequent)
318
+ if (currentSecond % 45 === 0) {
313
319
  const tickLog = smartLogs.getTickFlowLog(tickCount, ticksPerSecond);
314
320
  ui.addLog('debug', `${tickLog.message} ${tickLog.details}`);
315
321
  }
316
322
 
317
- // AI Agents status log every 20 seconds
318
- if (currentSecond % 20 === 0 && supervisionEnabled && supervisionEngine) {
323
+ // AI Agents status log every 60 seconds
324
+ if (currentSecond % 60 === 0 && supervisionEnabled && supervisionEngine) {
319
325
  const status = supervisionEngine.getStatus();
320
326
  const agentNames = status.agents.map(a => a.name.split(' ')[0]).join(', ');
321
- ui.addLog('analysis', `AI Agents (${status.availableAgents}): ${agentNames} - watching...`);
327
+ ui.addLog('analysis', `AI Supervision active: ${agentNames} (${status.availableAgents} agents monitoring)`);
322
328
  }
323
329
 
324
330
  // Reset volume counters
@@ -338,16 +344,30 @@ const executeAlgo = async ({ service, account, contract, config, strategy: strat
338
344
  timestamp: tick.timestamp || Date.now()
339
345
  });
340
346
 
341
- // Calculate network latency from tick timestamp (if available)
347
+ // Calculate latency based on tick timestamp or inter-tick timing
342
348
  if (tick.timestamp) {
343
349
  const tickTime = typeof tick.timestamp === 'number' ? tick.timestamp : Date.parse(tick.timestamp);
344
- if (!isNaN(tickTime)) {
345
- stats.latency = Math.max(0, Date.now() - tickTime);
350
+ if (!isNaN(tickTime) && tickTime > 1000000000000) { // Valid millisecond timestamp
351
+ stats.latency = Math.max(0, now - tickTime);
346
352
  }
353
+ } else if (tick.ssboe && tick.usecs) {
354
+ // Rithmic sends ssboe (seconds since epoch) and usecs (microseconds)
355
+ const tickTimeMs = tick.ssboe * 1000 + Math.floor(tick.usecs / 1000);
356
+ stats.latency = Math.max(0, now - tickTimeMs);
347
357
  } else {
348
- // Fallback: processing latency
349
- stats.latency = Date.now() - latencyStart;
358
+ // Estimate latency from tick frequency - if we're getting real-time data, latency should be low
359
+ if (lastTickTime > 0) {
360
+ const timeSinceLastTick = now - lastTickTime;
361
+ // If ticks are coming frequently, latency is low
362
+ if (timeSinceLastTick < 100) {
363
+ tickLatencies.push(timeSinceLastTick);
364
+ if (tickLatencies.length > 20) tickLatencies.shift();
365
+ // Average of recent inter-tick times as proxy for latency
366
+ stats.latency = Math.round(tickLatencies.reduce((a, b) => a + b, 0) / tickLatencies.length);
367
+ }
368
+ }
350
369
  }
370
+ lastTickTime = now;
351
371
  });
352
372
 
353
373
  marketFeed.on('connected', () => {