hedgequantx 2.5.35 → 2.5.37

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.5.35",
3
+ "version": "2.5.37",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -16,6 +16,10 @@ const { M1 } = require('../../../dist/lib/m/s1');
16
16
  const { MarketDataFeed } = require('../../../dist/lib/data');
17
17
  const { algoLogger } = require('./logger');
18
18
 
19
+ // AI Strategy Supervisor - observes, learns, and optimizes the strategy
20
+ const aiService = require('../../services/ai');
21
+ const StrategySupervisor = require('../../services/ai/strategy-supervisor');
22
+
19
23
 
20
24
 
21
25
  /**
@@ -167,6 +171,7 @@ const configureAlgo = async (account, contract) => {
167
171
  /**
168
172
  * Launch algo trading - HQX Ultra Scalping Strategy
169
173
  * Real-time market data + Strategy signals + Auto order execution
174
+ * AI Supervision: All connected agents monitor and supervise trading
170
175
  */
171
176
  const launchAlgo = async (service, account, contract, config) => {
172
177
  const { contracts, dailyTarget, maxRisk, showName } = config;
@@ -197,7 +202,9 @@ const launchAlgo = async (service, account, contract, config) => {
197
202
  losses: 0,
198
203
  latency: 0,
199
204
  connected: false,
200
- startTime: Date.now()
205
+ startTime: Date.now(),
206
+ aiSupervision: false,
207
+ aiMode: null
201
208
  };
202
209
 
203
210
  let running = true;
@@ -213,6 +220,14 @@ const launchAlgo = async (service, account, contract, config) => {
213
220
  const strategy = M1;
214
221
  strategy.initialize(contractId, tickSize, tickValue);
215
222
 
223
+ // Initialize AI Strategy Supervisor - agents observe, learn & optimize
224
+ const aiAgents = aiService.getAgents();
225
+ if (aiAgents.length > 0) {
226
+ const supervisorResult = StrategySupervisor.initialize(strategy, aiAgents, service, account.accountId);
227
+ stats.aiSupervision = supervisorResult.success;
228
+ stats.aiMode = supervisorResult.mode;
229
+ }
230
+
216
231
  // Initialize Market Data Feed
217
232
  const marketFeed = new MarketDataFeed({ propfirm: account.propfirm });
218
233
 
@@ -225,17 +240,44 @@ const launchAlgo = async (service, account, contract, config) => {
225
240
  algoLogger.engineStarting(ui, connectionType, dailyTarget, maxRisk);
226
241
  algoLogger.marketOpen(ui, sessionName.toUpperCase(), etTime);
227
242
 
243
+ // Log AI supervision status
244
+ if (stats.aiSupervision) {
245
+ algoLogger.info(ui, 'AI SUPERVISION', `${aiAgents.length} agent(s) - ${stats.aiMode} mode - LEARNING ACTIVE`);
246
+ }
247
+
228
248
  // Handle strategy signals
229
249
  strategy.on('signal', async (signal) => {
230
250
  if (!running || pendingOrder || currentPosition !== 0) return;
231
251
 
232
252
  const { side, direction, entry, stopLoss, takeProfit, confidence } = signal;
233
253
 
254
+ // Feed signal to AI supervisor (agents observe the signal)
255
+ if (stats.aiSupervision) {
256
+ StrategySupervisor.feedSignal({ direction, entry, stopLoss, takeProfit, confidence });
257
+
258
+ // Check AI advice - agents may recommend caution based on learned patterns
259
+ const advice = StrategySupervisor.shouldTrade();
260
+ if (!advice.proceed) {
261
+ algoLogger.info(ui, 'AI HOLD', advice.reason);
262
+ return; // Skip - agents learned this pattern leads to losses
263
+ }
264
+ }
265
+
234
266
  // Calculate position size with kelly
235
- const kelly = Math.min(0.25, confidence);
236
- const riskAmount = Math.round(maxRisk * kelly);
237
- const riskPct = Math.round((riskAmount / maxRisk) * 100);
267
+ let kelly = Math.min(0.25, confidence);
268
+ let riskAmount = Math.round(maxRisk * kelly);
238
269
 
270
+ // AI may adjust size based on learning
271
+ if (stats.aiSupervision) {
272
+ const advice = StrategySupervisor.getCurrentAdvice();
273
+ if (advice.sizeMultiplier && advice.sizeMultiplier !== 1.0) {
274
+ kelly = kelly * advice.sizeMultiplier;
275
+ riskAmount = Math.round(riskAmount * advice.sizeMultiplier);
276
+ algoLogger.info(ui, 'AI ADJUST', `Size x${advice.sizeMultiplier.toFixed(2)} - ${advice.reason}`);
277
+ }
278
+ }
279
+
280
+ const riskPct = Math.round((riskAmount / maxRisk) * 100);
239
281
  algoLogger.positionSized(ui, contracts, kelly, riskAmount, riskPct);
240
282
 
241
283
  // Place order via API
@@ -319,6 +361,11 @@ const launchAlgo = async (service, account, contract, config) => {
319
361
  timestamp: tick.timestamp || Date.now()
320
362
  };
321
363
 
364
+ // Feed tick to AI supervisor (agents observe same data as strategy)
365
+ if (stats.aiSupervision) {
366
+ StrategySupervisor.feedTick(tickData);
367
+ }
368
+
322
369
  strategy.processTick(tickData);
323
370
 
324
371
  stats.latency = Date.now() - latencyStart;
@@ -443,6 +490,25 @@ const launchAlgo = async (service, account, contract, config) => {
443
490
 
444
491
  // Record in strategy for adaptation
445
492
  strategy.recordTradeResult(pnl);
493
+
494
+ // Feed trade result to AI supervisor - THIS IS WHERE AGENTS LEARN
495
+ if (stats.aiSupervision) {
496
+ StrategySupervisor.feedTradeResult({
497
+ side,
498
+ qty: contracts,
499
+ price: exitPrice,
500
+ pnl,
501
+ symbol: symbolName,
502
+ direction: side
503
+ });
504
+
505
+ // Log if AI learned something
506
+ const status = StrategySupervisor.getStatus();
507
+ if (status.patternsLearned.winning + status.patternsLearned.losing > 0) {
508
+ algoLogger.info(ui, 'AI LEARNING',
509
+ `${status.patternsLearned.winning}W/${status.patternsLearned.losing}L patterns`);
510
+ }
511
+ }
446
512
  }
447
513
  }
448
514
  } catch (e) {
@@ -510,6 +576,15 @@ const launchAlgo = async (service, account, contract, config) => {
510
576
  clearInterval(refreshInterval);
511
577
  clearInterval(pnlInterval);
512
578
 
579
+ // Stop AI Supervisor and get learning summary
580
+ if (stats.aiSupervision) {
581
+ const aiSummary = StrategySupervisor.stop();
582
+ stats.aiLearning = {
583
+ optimizations: aiSummary.optimizationsApplied || 0,
584
+ patternsLearned: (aiSummary.winningPatterns || 0) + (aiSummary.losingPatterns || 0)
585
+ };
586
+ }
587
+
513
588
  // Disconnect market feed with timeout
514
589
  try {
515
590
  await Promise.race([
@@ -449,11 +449,15 @@ const showStats = async (service) => {
449
449
 
450
450
  // Add consensus info if in consensus mode
451
451
  if (isConsensusMode && consensusData) {
452
- const agreement = consensusData.agreement !== null
453
- ? Math.round(consensusData.agreement * 100) + '%'
454
- : 'N/A';
452
+ const isUnanimous = consensusData.isUnanimous;
455
453
  const consensusAction = consensusData.action || 'PENDING';
456
- agentsData.push({ label: 'CONSENSUS:', value: chalk.magenta(consensusAction + ' (' + agreement + ')') });
454
+ // Show action with unanimity status
455
+ const consensusDisplay = isUnanimous
456
+ ? chalk.green(consensusAction + ' (UNANIMOUS)')
457
+ : chalk.yellow(consensusAction + ' (DISAGREEMENT)');
458
+ agentsData.push({ label: 'DECISION:', value: consensusDisplay });
459
+ } else if (isConsensusMode) {
460
+ agentsData.push({ label: 'DECISION:', value: chalk.white('WAITING...') });
457
461
  }
458
462
 
459
463
  // Add each agent as a separate line with ● indicator
@@ -308,6 +308,145 @@ Analyze and provide recommendation.`;
308
308
  }
309
309
  };
310
310
 
311
+ /**
312
+ * Analyze strategy performance and suggest optimizations
313
+ * Called periodically to help the strategy improve
314
+ *
315
+ * @param {Object} agent - AI agent
316
+ * @param {Object} performanceData - Strategy performance data
317
+ * @returns {Promise<Object|null>} Optimization suggestions
318
+ */
319
+ const analyzePerformance = async (agent, performanceData) => {
320
+ if (!agent || !performanceData) return null;
321
+
322
+ const systemPrompt = `You are an AI supervisor for HQX Ultra Scalping, a professional prop firm futures trading strategy.
323
+
324
+ The strategy uses advanced mathematical models:
325
+ - Order flow analysis (delta, cumulative delta, absorption)
326
+ - Market microstructure (bid/ask imbalance, volume profile)
327
+ - Statistical edge detection (z-score, standard deviation bands)
328
+ - Dynamic risk management (Kelly criterion, volatility-adjusted sizing)
329
+
330
+ Your job is to analyze performance data and suggest parameter optimizations.
331
+ Be precise and actionable. Focus on improving win rate, reducing drawdown, and optimizing risk/reward.
332
+
333
+ Respond ONLY in valid JSON format:
334
+ {
335
+ "assessment": "brief performance assessment",
336
+ "winRateAnalysis": "analysis of win/loss patterns",
337
+ "riskAnalysis": "analysis of risk management",
338
+ "optimizations": [
339
+ { "param": "parameter_name", "current": "current_value", "suggested": "new_value", "reason": "why" }
340
+ ],
341
+ "marketCondition": "trending|ranging|volatile|calm",
342
+ "confidence": 0-100
343
+ }`;
344
+
345
+ const prompt = `STRATEGY PERFORMANCE DATA - ANALYZE AND OPTIMIZE
346
+
347
+ Session Stats:
348
+ - Trades: ${performanceData.trades || 0}
349
+ - Wins: ${performanceData.wins || 0}
350
+ - Losses: ${performanceData.losses || 0}
351
+ - Win Rate: ${performanceData.winRate ? (performanceData.winRate * 100).toFixed(1) + '%' : 'N/A'}
352
+ - Total P&L: $${performanceData.pnl?.toFixed(2) || '0.00'}
353
+ - Avg Win: $${performanceData.avgWin?.toFixed(2) || 'N/A'}
354
+ - Avg Loss: $${performanceData.avgLoss?.toFixed(2) || 'N/A'}
355
+ - Largest Win: $${performanceData.largestWin?.toFixed(2) || 'N/A'}
356
+ - Largest Loss: $${performanceData.largestLoss?.toFixed(2) || 'N/A'}
357
+ - Max Drawdown: $${performanceData.maxDrawdown?.toFixed(2) || 'N/A'}
358
+ - Profit Factor: ${performanceData.profitFactor?.toFixed(2) || 'N/A'}
359
+
360
+ Current Parameters:
361
+ - Position Size: ${performanceData.positionSize || 'N/A'} contracts
362
+ - Daily Target: $${performanceData.dailyTarget || 'N/A'}
363
+ - Max Risk: $${performanceData.maxRisk || 'N/A'}
364
+ - Symbol: ${performanceData.symbol || 'N/A'}
365
+
366
+ Recent Trades:
367
+ ${performanceData.recentTrades?.map(t =>
368
+ `- ${t.side} ${t.qty}x @ ${t.price} → P&L: $${t.pnl?.toFixed(2) || 'N/A'}`
369
+ ).join('\n') || 'No recent trades'}
370
+
371
+ Market Context:
372
+ - Volatility: ${performanceData.volatility || 'N/A'}
373
+ - Trend: ${performanceData.trend || 'N/A'}
374
+ - Session: ${performanceData.session || 'N/A'}
375
+
376
+ Analyze and suggest optimizations to improve performance.`;
377
+
378
+ try {
379
+ const response = await callAI(agent, prompt, systemPrompt);
380
+ if (!response) return null;
381
+
382
+ // Parse JSON from response
383
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
384
+ if (jsonMatch) {
385
+ return JSON.parse(jsonMatch[0]);
386
+ }
387
+
388
+ return null;
389
+ } catch (error) {
390
+ return null;
391
+ }
392
+ };
393
+
394
+ /**
395
+ * Get real-time trading advice based on current market conditions
396
+ *
397
+ * @param {Object} agent - AI agent
398
+ * @param {Object} marketData - Current market data
399
+ * @returns {Promise<Object|null>} Trading advice
400
+ */
401
+ const getMarketAdvice = async (agent, marketData) => {
402
+ if (!agent || !marketData) return null;
403
+
404
+ const systemPrompt = `You are an AI supervisor for HQX Ultra Scalping futures strategy.
405
+ Analyze real-time market data and provide actionable advice.
406
+ Be concise and precise. The strategy will use your recommendations.
407
+
408
+ Respond ONLY in valid JSON:
409
+ {
410
+ "action": "AGGRESSIVE|NORMAL|CAUTIOUS|PAUSE",
411
+ "sizeMultiplier": 0.5-1.5,
412
+ "reason": "brief reason",
413
+ "confidence": 0-100
414
+ }`;
415
+
416
+ const prompt = `REAL-TIME MARKET ANALYSIS
417
+
418
+ Current Price: ${marketData.price || 'N/A'}
419
+ Bid: ${marketData.bid || 'N/A'} | Ask: ${marketData.ask || 'N/A'}
420
+ Spread: ${marketData.spread || 'N/A'}
421
+ Volume: ${marketData.volume || 'N/A'}
422
+ Delta: ${marketData.delta || 'N/A'}
423
+ Volatility: ${marketData.volatility || 'N/A'}
424
+
425
+ Recent Price Action:
426
+ - High: ${marketData.high || 'N/A'}
427
+ - Low: ${marketData.low || 'N/A'}
428
+ - Range: ${marketData.range || 'N/A'}
429
+
430
+ Current Position: ${marketData.position || 'FLAT'}
431
+ Session P&L: $${marketData.pnl?.toFixed(2) || '0.00'}
432
+
433
+ What should the strategy do?`;
434
+
435
+ try {
436
+ const response = await callAI(agent, prompt, systemPrompt);
437
+ if (!response) return null;
438
+
439
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
440
+ if (jsonMatch) {
441
+ return JSON.parse(jsonMatch[0]);
442
+ }
443
+
444
+ return null;
445
+ } catch (error) {
446
+ return null;
447
+ }
448
+ };
449
+
311
450
  /**
312
451
  * Fetch available models from Anthropic API (API Key auth)
313
452
  * @param {string} apiKey - API key
@@ -429,6 +568,8 @@ const fetchOpenAIModels = async (endpoint, apiKey) => {
429
568
  module.exports = {
430
569
  callAI,
431
570
  analyzeTrading,
571
+ analyzePerformance,
572
+ getMarketAdvice,
432
573
  callOpenAICompatible,
433
574
  callAnthropic,
434
575
  callGemini,