Riy777 commited on
Commit
e6070bd
·
verified ·
1 Parent(s): c6cfba4

Update learning_hub/adaptive_hub.py

Browse files
Files changed (1) hide show
  1. learning_hub/adaptive_hub.py +68 -18
learning_hub/adaptive_hub.py CHANGED
@@ -1,6 +1,6 @@
1
  # ==============================================================================
2
  # 🧠 learning_hub/adaptive_hub.py
3
- # (V54.1 - GEM-Architect: Fix Missing Method)
4
  # ==============================================================================
5
 
6
  import json
@@ -11,12 +11,22 @@ from typing import Dict, Any, List
11
  from ml_engine.processor import SystemLimits
12
 
13
  class StrategyDNA:
14
- def __init__(self, name, model_weights, ob_settings, filters, guard_settings=None):
15
  self.name = name
16
  self.model_weights = model_weights
17
  self.ob_settings = ob_settings
18
  self.filters = filters
19
  self.guard_settings = guard_settings if guard_settings else {}
 
 
 
 
 
 
 
 
 
 
20
  self.stats = {"wins": 0, "losses": 0, "win_rate": 0.0}
21
 
22
  def to_dict(self):
@@ -26,6 +36,7 @@ class StrategyDNA:
26
  "ob_settings": self.ob_settings,
27
  "filters": self.filters,
28
  "guard_settings": self.guard_settings,
 
29
  "stats": self.stats
30
  }
31
 
@@ -35,7 +46,7 @@ class AdaptiveHub:
35
  self.dna_file_key = "learning/strategic_dna_v5_struct.json"
36
  self.current_market_regime = "RANGE"
37
  self.strategies: Dict[str, StrategyDNA] = {}
38
- print("🧠 [AdaptiveHub V54.1] Core Initialized (Method Restored).")
39
 
40
  async def initialize(self):
41
  try:
@@ -54,7 +65,7 @@ class AdaptiveHub:
54
 
55
  def _create_default_dna(self):
56
  default_guards = {"hydra_crash": 0.85, "hydra_giveback": 0.70, "legacy_v2": 0.95, "legacy_v3": 0.95}
57
-
58
  self.strategies["BULL"] = StrategyDNA("BULL", {"titan": 0.50, "structure": 0.30, "sniper": 0.20}, {"wall_ratio_limit": 0.60, "imbalance_thresh": 0.5}, {"l1_min_score": 0.55, "l3_conf_thresh": 0.60}, default_guards)
59
  self.strategies["BEAR"] = StrategyDNA("BEAR", {"titan": 0.30, "structure": 0.40, "sniper": 0.30}, {"wall_ratio_limit": 0.30, "imbalance_thresh": 0.7}, {"l1_min_score": 0.75, "l3_conf_thresh": 0.75}, default_guards)
60
  self.strategies["RANGE"] = StrategyDNA("RANGE", {"titan": 0.40, "structure": 0.40, "sniper": 0.20}, {"wall_ratio_limit": 0.40, "imbalance_thresh": 0.6}, {"l1_min_score": 0.65, "l3_conf_thresh": 0.65}, default_guards)
@@ -62,36 +73,75 @@ class AdaptiveHub:
62
 
63
  def _load_from_dict(self, data):
64
  for key, val in data.get("strategies", {}).items():
65
- self.strategies[key] = StrategyDNA(val["name"], val["model_weights"], val["ob_settings"], val["filters"], val.get("guard_settings", {}))
 
 
 
 
 
 
 
66
  self.current_market_regime = data.get("current_regime", "RANGE")
67
 
68
- # الدالة المفقودة تمت استعادتها هنا
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  async def register_trade_outcome(self, trade_data: Dict[str, Any]):
70
  try:
71
- # نتأكد من وجود البيانات، أحياناً قد تأتي كائن Trade وأحياناً Dict
72
- # إذا كانت كائن، نحولها لـ dict أو نصل للخاصية مباشرة
73
  pnl = 0.0
74
  if isinstance(trade_data, dict):
75
  pnl = trade_data.get('profit_pct', 0.0)
76
- # دعم للتسميات المختلفة
77
  if 'pnl_percent' in trade_data: pnl = trade_data['pnl_percent']
78
  else:
79
- # في حال كان كائناً (Object)
80
  pnl = getattr(trade_data, 'profit_pct', 0.0)
81
 
82
  is_win = pnl > 0
83
-
84
  if self.current_market_regime in self.strategies:
85
  active_dna = self.strategies[self.current_market_regime]
86
  if is_win: active_dna.stats["wins"] += 1
87
  else: active_dna.stats["losses"] += 1
88
-
89
- # طباعة خفيفة للتأكد
90
- # print(f"🧠 [AdaptiveHub] Learned: {self.current_market_regime} | Win? {is_win}")
91
-
92
- except Exception as e:
93
- print(f"❌ [AdaptiveHub] Trade Analysis Error: {e}")
94
- traceback.print_exc()
95
 
96
  def _inject_current_parameters(self):
97
  if self.current_market_regime not in self.strategies: return
 
1
  # ==============================================================================
2
  # 🧠 learning_hub/adaptive_hub.py
3
+ # (V55.0 - GEM-Architect: The Judge Logic)
4
  # ==============================================================================
5
 
6
  import json
 
11
  from ml_engine.processor import SystemLimits
12
 
13
  class StrategyDNA:
14
+ def __init__(self, name, model_weights, ob_settings, filters, guard_settings=None, backtest_performance=None):
15
  self.name = name
16
  self.model_weights = model_weights
17
  self.ob_settings = ob_settings
18
  self.filters = filters
19
  self.guard_settings = guard_settings if guard_settings else {}
20
+
21
+ # ✅ الإضافة الجديدة: سجل أداء الباكتست الذي أنتج هذه الإعدادات
22
+ # هذا هو "السجل الرياضي" للبطل الحالي
23
+ self.backtest_performance = backtest_performance if backtest_performance else {
24
+ "net_profit": -9999.0, # قيمة منخفضة جداً للبداية
25
+ "win_rate": 0.0,
26
+ "total_trades": 0,
27
+ "date_recorded": "N/A"
28
+ }
29
+
30
  self.stats = {"wins": 0, "losses": 0, "win_rate": 0.0}
31
 
32
  def to_dict(self):
 
36
  "ob_settings": self.ob_settings,
37
  "filters": self.filters,
38
  "guard_settings": self.guard_settings,
39
+ "backtest_performance": self.backtest_performance, # ✅ حفظ السجل
40
  "stats": self.stats
41
  }
42
 
 
46
  self.dna_file_key = "learning/strategic_dna_v5_struct.json"
47
  self.current_market_regime = "RANGE"
48
  self.strategies: Dict[str, StrategyDNA] = {}
49
+ print("🧠 [AdaptiveHub V55.0] The Judge Core Initialized.")
50
 
51
  async def initialize(self):
52
  try:
 
65
 
66
  def _create_default_dna(self):
67
  default_guards = {"hydra_crash": 0.85, "hydra_giveback": 0.70, "legacy_v2": 0.95, "legacy_v3": 0.95}
68
+ # القيم الافتراضية ليس لها سجل باكتست، لذا ستكون سهلة الهزيمة
69
  self.strategies["BULL"] = StrategyDNA("BULL", {"titan": 0.50, "structure": 0.30, "sniper": 0.20}, {"wall_ratio_limit": 0.60, "imbalance_thresh": 0.5}, {"l1_min_score": 0.55, "l3_conf_thresh": 0.60}, default_guards)
70
  self.strategies["BEAR"] = StrategyDNA("BEAR", {"titan": 0.30, "structure": 0.40, "sniper": 0.30}, {"wall_ratio_limit": 0.30, "imbalance_thresh": 0.7}, {"l1_min_score": 0.75, "l3_conf_thresh": 0.75}, default_guards)
71
  self.strategies["RANGE"] = StrategyDNA("RANGE", {"titan": 0.40, "structure": 0.40, "sniper": 0.20}, {"wall_ratio_limit": 0.40, "imbalance_thresh": 0.6}, {"l1_min_score": 0.65, "l3_conf_thresh": 0.65}, default_guards)
 
73
 
74
  def _load_from_dict(self, data):
75
  for key, val in data.get("strategies", {}).items():
76
+ self.strategies[key] = StrategyDNA(
77
+ val["name"],
78
+ val["model_weights"],
79
+ val["ob_settings"],
80
+ val["filters"],
81
+ val.get("guard_settings", {}),
82
+ val.get("backtest_performance", None) # ✅ تحميل السجل
83
+ )
84
  self.current_market_regime = data.get("current_regime", "RANGE")
85
 
86
+ # 🔥🔥🔥 الدالة الجديدة: الحكم (The Judge) 🔥🔥🔥
87
+ def submit_challenger(self, regime: str, new_config: dict, new_stats: dict) -> bool:
88
+ """
89
+ تقارن بين المتحدي الجديد والبطل الحالي.
90
+ تعيد True إذا فاز الجديد وتم التحديث، و False إذا تم رفضه.
91
+ """
92
+ if regime not in self.strategies: return False
93
+
94
+ champion = self.strategies[regime]
95
+ old_stats = champion.backtest_performance
96
+
97
+ # معايير التحكيم:
98
+ # 1. الربح الصافي هو الملك.
99
+ # 2. إذا تساوى الربح، نختار نسبة الفوز الأعلى.
100
+
101
+ new_profit = new_stats.get('net_profit', -100)
102
+ old_profit = old_stats.get('net_profit', -9999)
103
+
104
+ print(f"⚖️ [JUDGE] Comparing {regime} DNA:")
105
+ print(f" 👑 Champion: Profit ${old_profit:.2f} | WinRate {old_stats.get('win_rate', 0):.1f}%")
106
+ print(f" 🥊 Challenger: Profit ${new_profit:.2f} | WinRate {new_stats.get('win_rate', 0):.1f}%")
107
+
108
+ is_winner = False
109
+
110
+ # القاعدة 1: الربح الصافي يجب أن يكون أعلى بوضوح (أو النظام جديد كلياً)
111
+ if new_profit > old_profit:
112
+ is_winner = True
113
+ # القاعدة 2: إذا الربح متقارب جداً، نفضل نسبة الفوز الأعلى
114
+ elif abs(new_profit - old_profit) < 0.5 and new_stats.get('win_rate', 0) > old_stats.get('win_rate', 0):
115
+ is_winner = True
116
+
117
+ if is_winner:
118
+ print(f" ✅ [JUDGE] Challenger WINS! Updating DNA.")
119
+ # تحديث الجينات
120
+ champion.model_weights['titan'] = new_config['w_titan']
121
+ champion.model_weights['structure'] = new_config['w_struct']
122
+ champion.filters['l1_min_score'] = new_config['thresh']
123
+ # تحديث سجل البطل
124
+ champion.backtest_performance = new_stats
125
+ return True
126
+ else:
127
+ print(f" 🛡️ [JUDGE] Champion retains title. Challenger rejected.")
128
+ return False
129
+
130
  async def register_trade_outcome(self, trade_data: Dict[str, Any]):
131
  try:
 
 
132
  pnl = 0.0
133
  if isinstance(trade_data, dict):
134
  pnl = trade_data.get('profit_pct', 0.0)
 
135
  if 'pnl_percent' in trade_data: pnl = trade_data['pnl_percent']
136
  else:
 
137
  pnl = getattr(trade_data, 'profit_pct', 0.0)
138
 
139
  is_win = pnl > 0
 
140
  if self.current_market_regime in self.strategies:
141
  active_dna = self.strategies[self.current_market_regime]
142
  if is_win: active_dna.stats["wins"] += 1
143
  else: active_dna.stats["losses"] += 1
144
+ except Exception: traceback.print_exc()
 
 
 
 
 
 
145
 
146
  def _inject_current_parameters(self):
147
  if self.current_market_regime not in self.strategies: return