hedgequantx 2.5.42 → 2.5.43

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.42",
3
+ "version": "2.5.43",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -6,6 +6,7 @@
6
6
  const { getProviders, getProvider } = require('./providers');
7
7
  const { storage } = require('../session');
8
8
  const AISupervisor = require('./supervisor');
9
+ const StrategySupervisor = require('./strategy-supervisor');
9
10
 
10
11
  // In-memory cache of connections
11
12
  let connectionsCache = null;
@@ -228,10 +229,17 @@ const addAgent = async (providerId, optionId, credentials, model = null, customN
228
229
 
229
230
  saveAISettings(aiSettings);
230
231
 
231
- // Agent is ready - supervision will start when algo trading begins
232
- // Supervision requires a real service connection and account
232
+ // Get the full agent object
233
233
  const agent = getAgent(agentId);
234
234
 
235
+ // Notify StrategySupervisor if algo is running
236
+ // This ensures new agents are immediately connected to live trading
237
+ try {
238
+ StrategySupervisor.addAgent(agent);
239
+ } catch (e) {
240
+ // Supervisor might not be active - that's OK
241
+ }
242
+
235
243
  return agent;
236
244
  };
237
245
 
@@ -253,6 +261,13 @@ const removeAgent = (agentId) => {
253
261
  // Stop AI supervision for this agent
254
262
  AISupervisor.stop(agentId);
255
263
 
264
+ // Notify StrategySupervisor to remove agent from live trading
265
+ try {
266
+ StrategySupervisor.removeAgent(agentId);
267
+ } catch (e) {
268
+ // Supervisor might not be active - that's OK
269
+ }
270
+
256
271
  // If removed agent was active, set new active
257
272
  if (aiSettings.activeAgentId === agentId) {
258
273
  aiSettings.activeAgentId = agents.length > 0 ? agents[0].id : null;
@@ -289,6 +304,13 @@ const disconnectAll = () => {
289
304
  // Stop all AI supervision sessions
290
305
  AISupervisor.stopAll();
291
306
 
307
+ // Refresh StrategySupervisor to clear agents
308
+ try {
309
+ StrategySupervisor.refreshAgents();
310
+ } catch (e) {
311
+ // Supervisor might not be active
312
+ }
313
+
292
314
  saveAISettings({ agents: [] });
293
315
  };
294
316
 
@@ -609,6 +609,11 @@ const initialize = (strategy, agents, service, accountId) => {
609
609
  }
610
610
  }, 10000);
611
611
 
612
+ // Start agent sync interval - ensures new agents are picked up dynamically
613
+ if (!supervisorState.agentSyncInterval) {
614
+ supervisorState.agentSyncInterval = setInterval(syncAgents, 5000);
615
+ }
616
+
612
617
  return {
613
618
  success: true,
614
619
  agents: agents.length,
@@ -616,6 +621,108 @@ const initialize = (strategy, agents, service, accountId) => {
616
621
  };
617
622
  };
618
623
 
624
+ /**
625
+ * Sync agents with AI service
626
+ * Called periodically to pick up newly added/removed agents
627
+ * Ensures all agents are always connected to the supervisor
628
+ */
629
+ const syncAgents = () => {
630
+ if (!supervisorState.active) return;
631
+
632
+ try {
633
+ // Dynamic import to avoid circular dependency
634
+ const aiService = require('./index');
635
+ const currentAgents = aiService.getAgents();
636
+
637
+ if (!currentAgents) return;
638
+
639
+ const currentIds = new Set(currentAgents.map(a => a.id));
640
+ const supervisorIds = new Set(supervisorState.agents.map(a => a.id));
641
+
642
+ // Check for new agents
643
+ const newAgents = currentAgents.filter(a => !supervisorIds.has(a.id));
644
+
645
+ // Check for removed agents
646
+ const removedIds = [...supervisorIds].filter(id => !currentIds.has(id));
647
+
648
+ // Add new agents
649
+ if (newAgents.length > 0) {
650
+ supervisorState.agents = [...supervisorState.agents, ...newAgents];
651
+ // Log would go here if we had UI access
652
+ }
653
+
654
+ // Remove agents that were disconnected
655
+ if (removedIds.length > 0) {
656
+ supervisorState.agents = supervisorState.agents.filter(a => !removedIds.includes(a.id));
657
+ }
658
+
659
+ // Update mode based on current agent count
660
+ supervisorState.mode = supervisorState.agents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL';
661
+
662
+ } catch (e) {
663
+ // Silent fail - aiService might not be ready
664
+ }
665
+ };
666
+
667
+ /**
668
+ * Force refresh agents from AI service
669
+ * Call this when you know agents have changed
670
+ */
671
+ const refreshAgents = () => {
672
+ syncAgents();
673
+ return {
674
+ agents: supervisorState.agents.length,
675
+ mode: supervisorState.agents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL'
676
+ };
677
+ };
678
+
679
+ /**
680
+ * Add a single agent to the supervisor (called when agent is added)
681
+ */
682
+ const addAgent = (agent) => {
683
+ if (!supervisorState.active) return false;
684
+
685
+ // Check if already exists
686
+ if (supervisorState.agents.some(a => a.id === agent.id)) {
687
+ return false;
688
+ }
689
+
690
+ supervisorState.agents.push(agent);
691
+ supervisorState.mode = supervisorState.agents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL';
692
+
693
+ return true;
694
+ };
695
+
696
+ /**
697
+ * Remove an agent from the supervisor (called when agent is removed)
698
+ */
699
+ const removeAgent = (agentId) => {
700
+ if (!supervisorState.active) return false;
701
+
702
+ const index = supervisorState.agents.findIndex(a => a.id === agentId);
703
+ if (index === -1) return false;
704
+
705
+ supervisorState.agents.splice(index, 1);
706
+ supervisorState.mode = supervisorState.agents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL';
707
+
708
+ return true;
709
+ };
710
+
711
+ /**
712
+ * Get current agent count and mode
713
+ */
714
+ const getAgentInfo = () => {
715
+ return {
716
+ count: supervisorState.agents.length,
717
+ mode: supervisorState.agents.length >= 2 ? 'CONSENSUS' : 'INDIVIDUAL',
718
+ agents: supervisorState.agents.map(a => ({
719
+ id: a.id,
720
+ name: a.name,
721
+ provider: a.providerId
722
+ }))
723
+ };
724
+ };
725
+
619
726
  /**
620
727
  * Stop supervisor and save learned data
621
728
  */
@@ -625,6 +732,12 @@ const stop = () => {
625
732
  analysisInterval = null;
626
733
  }
627
734
 
735
+ // Stop agent sync
736
+ if (supervisorState.agentSyncInterval) {
737
+ clearInterval(supervisorState.agentSyncInterval);
738
+ supervisorState.agentSyncInterval = null;
739
+ }
740
+
628
741
  // Save all learned data before stopping
629
742
  const saved = saveLearningData();
630
743
 
@@ -1921,18 +2034,34 @@ const clearLearningData = () => {
1921
2034
  };
1922
2035
 
1923
2036
  module.exports = {
2037
+ // Core lifecycle
1924
2038
  initialize,
1925
2039
  stop,
2040
+
2041
+ // Data feeds (from algo)
1926
2042
  feedTick,
1927
2043
  feedSignal,
1928
2044
  feedTradeResult,
2045
+
2046
+ // Trading decisions
1929
2047
  getCurrentAdvice,
1930
2048
  shouldTrade,
2049
+
2050
+ // Agent management (dynamic sync)
2051
+ syncAgents,
2052
+ refreshAgents,
2053
+ addAgent,
2054
+ removeAgent,
2055
+ getAgentInfo,
2056
+
2057
+ // Status & stats
1931
2058
  getStatus,
1932
2059
  analyzeAndOptimize,
1933
2060
  getBehaviorHistory,
1934
2061
  getLearningStats,
1935
2062
  getLifetimeStats,
2063
+
2064
+ // Data management
1936
2065
  clearLearningData,
1937
2066
  loadLearningData
1938
2067
  };