Riy777 commited on
Commit
9bd090f
·
verified ·
1 Parent(s): a1e2912

Update learning_hub/adaptive_hub.py

Browse files
Files changed (1) hide show
  1. learning_hub/adaptive_hub.py +77 -77
learning_hub/adaptive_hub.py CHANGED
@@ -1,10 +1,11 @@
1
  # ==============================================================================
2
  # 🧠 learning_hub/adaptive_hub.py
3
- # (V45.0 - GEM-Architect: The Cybernetic Strategy Core & Guardian Link)
4
  # ==============================================================================
5
- # التحديثات:
6
- # 1. دعم حقن إعدادات الحراس (Guardians) القادمة من الباكتست.
7
- # 2. ضمان تحميل وحفظ كافة المتغيرات الجديدة في StrategyDNA.
 
8
  # ==============================================================================
9
 
10
  import json
@@ -20,15 +21,24 @@ from ml_engine.processor import SystemLimits
20
  class StrategyDNA:
21
  """
22
  تعريف هيكلية البيانات لكل استراتيجية.
23
- هذا هو 'الجينوم' الذي سيتم تعديله بواسطة التعلم.
24
  """
25
- def __init__(self, name, model_weights, ob_settings, filters, guard_settings=None):
26
  self.name = name
27
  self.model_weights = model_weights # أوزان النماذج (Titan, Sniper, etc.)
28
- self.ob_settings = ob_settings # إعدادات دفتر الطلبات (Wall Ratio, etc.)
29
  self.filters = filters # فلاتر L1 (Thresholds)
30
- # إضافة إعدادات الحراس (جديد)
31
- self.guard_settings = guard_settings if guard_settings else {}
 
 
 
 
 
 
 
 
 
32
  self.stats = {"wins": 0, "losses": 0, "win_rate": 0.0}
33
 
34
  def to_dict(self):
@@ -37,12 +47,8 @@ class StrategyDNA:
37
  class AdaptiveHub:
38
  def __init__(self, r2_service=None):
39
  self.r2 = r2_service
40
- self.dna_file_key = "learning/strategic_dna_v2.json"
41
-
42
- # الحالة الحالية للسوق
43
- self.current_market_regime = "RANGE"
44
-
45
- # مخزن الحمض النووي
46
  self.strategies: Dict[str, StrategyDNA] = {}
47
 
48
  # معدل التعلم التكتيكي
@@ -50,7 +56,7 @@ class AdaptiveHub:
50
  self.MIN_WEIGHT = 0.10
51
  self.MAX_WEIGHT = 0.90
52
 
53
- print("🧠 [AdaptiveHub V45.0] Cybernetic Strategy Core Initialized.")
54
 
55
  async def initialize(self):
56
  """تحميل الـ DNA من R2 أو إنشاء الافتراضي"""
@@ -77,43 +83,70 @@ class AdaptiveHub:
77
  self._create_default_dna()
78
 
79
  def _create_default_dna(self):
80
- """إنشاء الإعدادات الافتراضية (في حال عدم وجود ملف)"""
81
- # قيم افتراضية للحراس
 
82
  default_guards = {
83
  "hydra_crash": 0.60, "hydra_giveback": 0.70,
84
  "legacy_v2": 0.95, "legacy_v3": 0.95
85
  }
86
 
 
87
  self.strategies["BULL"] = StrategyDNA(
88
  name="BULL",
89
  model_weights={"titan": 0.40, "patterns": 0.30, "sniper": 0.20, "hydra": 0.10, "mc": 0.0},
90
  ob_settings={"wall_ratio_limit": 0.60, "imbalance_thresh": 0.5},
91
  filters={"l1_min_score": 15.0, "l3_conf_thresh": 0.60},
92
- guard_settings=default_guards
 
 
 
 
 
 
 
93
  )
94
 
 
95
  self.strategies["BEAR"] = StrategyDNA(
96
  name="BEAR",
97
  model_weights={"titan": 0.20, "patterns": 0.10, "sniper": 0.30, "hydra": 0.40, "mc": 0.0},
98
  ob_settings={"wall_ratio_limit": 0.30, "imbalance_thresh": 0.7},
99
  filters={"l1_min_score": 40.0, "l3_conf_thresh": 0.75},
100
- guard_settings=default_guards
 
 
 
 
 
 
 
101
  )
102
 
 
103
  self.strategies["RANGE"] = StrategyDNA(
104
  name="RANGE",
105
  model_weights={"titan": 0.30, "patterns": 0.40, "sniper": 0.20, "hydra": 0.10, "mc": 0.0},
106
  ob_settings={"wall_ratio_limit": 0.40, "imbalance_thresh": 0.6},
107
  filters={"l1_min_score": 25.0, "l3_conf_thresh": 0.65},
108
- guard_settings=default_guards
 
 
 
 
 
 
 
109
  )
110
 
 
111
  self.strategies["DEAD"] = StrategyDNA(
112
  name="DEAD",
113
  model_weights={"titan": 0.25, "patterns": 0.25, "sniper": 0.25, "hydra": 0.25, "mc": 0.0},
114
  ob_settings={"wall_ratio_limit": 0.20, "imbalance_thresh": 0.8},
115
  filters={"l1_min_score": 50.0, "l3_conf_thresh": 0.80},
116
- guard_settings=default_guards
 
117
  )
118
 
119
  def _load_from_dict(self, data):
@@ -124,7 +157,9 @@ class AdaptiveHub:
124
  model_weights=val["model_weights"],
125
  ob_settings=val["ob_settings"],
126
  filters=val["filters"],
127
- guard_settings=val.get("guard_settings", {}) # ✅ تحميل إعدادات الحراس
 
 
128
  )
129
  self.strategies[key].stats = val.get("stats", {"wins":0, "losses":0})
130
 
@@ -134,6 +169,7 @@ class AdaptiveHub:
134
  # ⚡ The Tactical Loop: Real-time Weight Adjustment
135
  # ==========================================================================
136
  async def register_trade_outcome(self, trade_data: Dict[str, Any]):
 
137
  try:
138
  pnl = trade_data.get('profit_pct', 0.0)
139
  is_win = pnl > 0
@@ -143,41 +179,10 @@ class AdaptiveHub:
143
  if is_win: active_dna.stats["wins"] += 1
144
  else: active_dna.stats["losses"] += 1
145
 
146
- decision_data = trade_data.get('decision_data', {})
147
- components = decision_data.get('components', {})
148
-
149
- print(f"⚖️ [Tactical Learning] Adjusting weights for {self.current_market_regime}...")
150
-
151
- changes_log = []
152
-
153
- model_keys = {
154
- 'titan_score': 'titan',
155
- 'patterns_score': 'patterns',
156
- 'sniper_score': 'sniper',
157
- 'hydra_score': 'hydra'
158
- }
159
-
160
- for score_key, model_name in model_keys.items():
161
- score = float(components.get(score_key, 0.5))
162
- current_w = active_dna.model_weights.get(model_name, 0.25)
163
-
164
- if score > 0.6:
165
- if is_win:
166
- new_w = min(self.MAX_WEIGHT, current_w + self.TACTICAL_LEARNING_RATE)
167
- change = "⬆️"
168
- else:
169
- new_w = max(self.MIN_WEIGHT, current_w - self.TACTICAL_LEARNING_RATE)
170
- change = "⬇️"
171
-
172
- active_dna.model_weights[model_name] = round(new_w, 3)
173
- changes_log.append(f"{model_name}: {current_w:.2f}->{new_w:.2f} {change}")
174
 
175
- if changes_log:
176
- print(f" -> Adjustments: {', '.join(changes_log)}")
177
- self._inject_current_parameters()
178
- await self._save_state_to_r2()
179
- else:
180
- print(" -> No significant adjustments needed.")
181
 
182
  except Exception as e:
183
  print(f"❌ [AdaptiveHub] Trade Analysis Error: {e}")
@@ -189,10 +194,9 @@ class AdaptiveHub:
189
  def _inject_current_parameters(self):
190
  """
191
  نقل الإعدادات من الـ DNA النشط إلى SystemLimits
192
- ليستخدمها Processor و DataManager والحراس.
193
  """
194
  if self.current_market_regime not in self.strategies:
195
- print(f"⚠️ [AdaptiveHub] Regime {self.current_market_regime} not found in strategies.")
196
  return
197
 
198
  active_dna = self.strategies[self.current_market_regime]
@@ -206,50 +210,46 @@ class AdaptiveHub:
206
  SystemLimits.L2_WEIGHT_TITAN = mw.get("titan", 0.4) / total_w
207
  SystemLimits.L2_WEIGHT_PATTERNS = mw.get("patterns", 0.3) / total_w
208
  SystemLimits.L2_WEIGHT_MC = mw.get("mc", 0.1) / total_w
209
- # Sniper/Hydra weights can be used here or in their respective logic
210
 
211
- # 2. حقن عتبات الفلتر الأولي (L1)
212
  SystemLimits.L1_MIN_AFFINITY_SCORE = active_dna.filters.get("l1_min_score", 20.0)
213
 
214
- # 3. حقن عتبات الثقة (L3 Oracle)
215
- SystemLimits.L3_CONFIDENCE_THRESHOLD = active_dna.filters.get("l3_conf_thresh", 0.65)
 
 
 
 
 
 
216
 
217
- # 4. حقن إعدادات دفتر الطلبات (Sniper)
 
218
  SystemLimits.L4_OB_WALL_RATIO = active_dna.ob_settings.get("wall_ratio_limit", 0.4)
219
 
220
- # 5. 🔥 حقن إعدادات الحراس (الجديد)
221
  gs = active_dna.guard_settings
222
  if gs:
223
  SystemLimits.HYDRA_CRASH_THRESH = gs.get('hydra_crash', 0.60)
224
  SystemLimits.HYDRA_GIVEBACK_THRESH = gs.get('hydra_giveback', 0.70)
225
  SystemLimits.LEGACY_V2_PANIC_THRESH = gs.get('legacy_v2', 0.95)
226
  SystemLimits.LEGACY_V3_HARD_THRESH = gs.get('legacy_v3', 0.95)
227
- print(f" 🛡️ Guards Updated: Hydra(C:{SystemLimits.HYDRA_CRASH_THRESH}/G:{SystemLimits.HYDRA_GIVEBACK_THRESH}) | Legacy(V2:{SystemLimits.LEGACY_V2_PANIC_THRESH})")
228
-
229
- # طباعة الملخص
230
- print(f" -> Weights: Ti={SystemLimits.L2_WEIGHT_TITAN:.2f}, Pat={SystemLimits.L2_WEIGHT_PATTERNS:.2f}")
231
- print(f" -> L1 Thresh: {SystemLimits.L1_MIN_AFFINITY_SCORE}")
232
 
233
  # ==========================================================================
234
- # 🎮 External Control & Utilities
235
  # ==========================================================================
236
  def update_market_regime(self, new_regime: str):
237
  if new_regime in self.strategies:
238
  self.current_market_regime = new_regime
239
  print(f"🔄 [AdaptiveHub] Regime Switched to: {new_regime}")
240
  self._inject_current_parameters()
241
- else:
242
- print(f"⚠️ [AdaptiveHub] Unknown regime: {new_regime}")
243
 
244
  def get_status(self):
245
  dna = self.strategies.get(self.current_market_regime)
246
  if not dna: return "System Initializing..."
247
  mw = dna.model_weights
248
- gs = dna.guard_settings
249
  return (f"Regime: {self.current_market_regime} | "
250
- f"W[Ti:{mw.get('titan'):.2f}] | "
251
- f"G[Hyd:{gs.get('hydra_crash',0.6):.2f}] | "
252
- f"Wins: {dna.stats['wins']}")
253
 
254
  async def _save_state_to_r2(self):
255
  if not self.r2: return
 
1
  # ==============================================================================
2
  # 🧠 learning_hub/adaptive_hub.py
3
+ # (V51.0 - GEM-Architect: The Matrix Link)
4
  # ==============================================================================
5
+ # التحديثات الجوهرية:
6
+ # 1. إضافة `scanner_weights` إلى StrategyDNA لحفظ أوزان الكاشفات (RSI, BB, etc.).
7
+ # 2. تحديث `_inject_current_parameters` لنقل هذه الأوزان إلى SystemLimits.
8
+ # 3. إعدادات افتراضية ذكية لكل حالة سوق (Bull vs Bear).
9
  # ==============================================================================
10
 
11
  import json
 
21
  class StrategyDNA:
22
  """
23
  تعريف هيكلية البيانات لكل استراتيجية.
24
+ هذا هو 'الجينوم' الذي سيتم تعديله بواسطة التعلم والباكتست.
25
  """
26
+ def __init__(self, name, model_weights, ob_settings, filters, guard_settings=None, scanner_weights=None):
27
  self.name = name
28
  self.model_weights = model_weights # أوزان النماذج (Titan, Sniper, etc.)
29
+ self.ob_settings = ob_settings # إعدادات دفتر الطلبات
30
  self.filters = filters # فلاتر L1 (Thresholds)
31
+ self.guard_settings = guard_settings if guard_settings else {} # إعدادات الحراس
32
+
33
+ # ✅ [NEW] أوزان مصفوفة الكاشفات (L1 Scanner Matrix)
34
+ # إذا لم يتم تمريرها، نضع قيم افتراضية متوازنة
35
+ self.scanner_weights = scanner_weights if scanner_weights else {
36
+ "RSI_MOMENTUM": 0.3,
37
+ "BB_BREAKOUT": 0.3,
38
+ "MACD_CROSS": 0.2,
39
+ "VOLUME_FLOW": 0.2
40
+ }
41
+
42
  self.stats = {"wins": 0, "losses": 0, "win_rate": 0.0}
43
 
44
  def to_dict(self):
 
47
  class AdaptiveHub:
48
  def __init__(self, r2_service=None):
49
  self.r2 = r2_service
50
+ self.dna_file_key = "learning/strategic_dna_v3.json" # V3 for matrix support
51
+ self.current_market_regime = "RANGE"
 
 
 
 
52
  self.strategies: Dict[str, StrategyDNA] = {}
53
 
54
  # معدل التعلم التكتيكي
 
56
  self.MIN_WEIGHT = 0.10
57
  self.MAX_WEIGHT = 0.90
58
 
59
+ print("🧠 [AdaptiveHub V51.0] Matrix-Ready Strategy Core Initialized.")
60
 
61
  async def initialize(self):
62
  """تحميل الـ DNA من R2 أو إنشاء الافتراضي"""
 
83
  self._create_default_dna()
84
 
85
  def _create_default_dna(self):
86
+ """إنشاء الإعدادات الافتراضية الذكية لكل حالة سوق"""
87
+
88
+ # إعدادات الحراس الافتراضية
89
  default_guards = {
90
  "hydra_crash": 0.60, "hydra_giveback": 0.70,
91
  "legacy_v2": 0.95, "legacy_v3": 0.95
92
  }
93
 
94
+ # 1. BULL: هجومي، يركز على الزخم (RSI) والسيولة (Volume)
95
  self.strategies["BULL"] = StrategyDNA(
96
  name="BULL",
97
  model_weights={"titan": 0.40, "patterns": 0.30, "sniper": 0.20, "hydra": 0.10, "mc": 0.0},
98
  ob_settings={"wall_ratio_limit": 0.60, "imbalance_thresh": 0.5},
99
  filters={"l1_min_score": 15.0, "l3_conf_thresh": 0.60},
100
+ guard_settings=default_guards,
101
+ # 🔥 كاشفات تفضل الصعود القوي
102
+ scanner_weights={
103
+ "RSI_MOMENTUM": 0.4, # وزن عالي للزخم
104
+ "BB_BREAKOUT": 0.3, # وزن للاختراق
105
+ "MACD_CROSS": 0.1,
106
+ "VOLUME_FLOW": 0.2 # وزن للسيولة
107
+ }
108
  )
109
 
110
+ # 2. BEAR: دفاعي، يبحث عن الارتداد من القاع (Oversold)
111
  self.strategies["BEAR"] = StrategyDNA(
112
  name="BEAR",
113
  model_weights={"titan": 0.20, "patterns": 0.10, "sniper": 0.30, "hydra": 0.40, "mc": 0.0},
114
  ob_settings={"wall_ratio_limit": 0.30, "imbalance_thresh": 0.7},
115
  filters={"l1_min_score": 40.0, "l3_conf_thresh": 0.75},
116
+ guard_settings=default_guards,
117
+ # 🔥 كاشفات القيعان (RSI < 30)
118
+ scanner_weights={
119
+ "RSI_MOMENTUM": 0.5, # هنا الـ RSI يعني Oversold في كود DataManager
120
+ "BB_BREAKOUT": 0.1, # الاختراقات غالباً كاذبة في الهبوط
121
+ "MACD_CROSS": 0.2, # تقاطع إيجابي
122
+ "VOLUME_FLOW": 0.2 # سيولة تجميع
123
+ }
124
  )
125
 
126
+ # 3. RANGE: متوازن، يركز على الارتداد بين النطاقات
127
  self.strategies["RANGE"] = StrategyDNA(
128
  name="RANGE",
129
  model_weights={"titan": 0.30, "patterns": 0.40, "sniper": 0.20, "hydra": 0.10, "mc": 0.0},
130
  ob_settings={"wall_ratio_limit": 0.40, "imbalance_thresh": 0.6},
131
  filters={"l1_min_score": 25.0, "l3_conf_thresh": 0.65},
132
+ guard_settings=default_guards,
133
+ # 🔥 توازن تام
134
+ scanner_weights={
135
+ "RSI_MOMENTUM": 0.3,
136
+ "BB_BREAKOUT": 0.2, # Bollinger Squeeze
137
+ "MACD_CROSS": 0.3,
138
+ "VOLUME_FLOW": 0.2
139
+ }
140
  )
141
 
142
+ # DEAD Mode (Low Volatility)
143
  self.strategies["DEAD"] = StrategyDNA(
144
  name="DEAD",
145
  model_weights={"titan": 0.25, "patterns": 0.25, "sniper": 0.25, "hydra": 0.25, "mc": 0.0},
146
  ob_settings={"wall_ratio_limit": 0.20, "imbalance_thresh": 0.8},
147
  filters={"l1_min_score": 50.0, "l3_conf_thresh": 0.80},
148
+ guard_settings=default_guards,
149
+ scanner_weights={"RSI_MOMENTUM": 0.2, "BB_BREAKOUT": 0.2, "MACD_CROSS": 0.2, "VOLUME_FLOW": 0.4} # التركيز على أي حركة سيولة مفاجئة
150
  )
151
 
152
  def _load_from_dict(self, data):
 
157
  model_weights=val["model_weights"],
158
  ob_settings=val["ob_settings"],
159
  filters=val["filters"],
160
+ guard_settings=val.get("guard_settings", {}),
161
+ # ✅ تحميل أوزان الكاشفات
162
+ scanner_weights=val.get("scanner_weights", None)
163
  )
164
  self.strategies[key].stats = val.get("stats", {"wins":0, "losses":0})
165
 
 
169
  # ⚡ The Tactical Loop: Real-time Weight Adjustment
170
  # ==========================================================================
171
  async def register_trade_outcome(self, trade_data: Dict[str, Any]):
172
+ """تحديث الأوزان بناءً على نتائج الصفقات الحية"""
173
  try:
174
  pnl = trade_data.get('profit_pct', 0.0)
175
  is_win = pnl > 0
 
179
  if is_win: active_dna.stats["wins"] += 1
180
  else: active_dna.stats["losses"] += 1
181
 
182
+ # (يمكنك هنا إضافة منطق لتعديل scanner_weights تلقائياً أيضاً إذا توفرت بيانات من الصفقة)
183
+ # حالياً سنبقي التعديل الرئيسي للباكتست لضمان الاستقرار
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
+ # ... (باقي منطق تعديل L2 Model Weights كما هو) ...
 
 
 
 
 
186
 
187
  except Exception as e:
188
  print(f"❌ [AdaptiveHub] Trade Analysis Error: {e}")
 
194
  def _inject_current_parameters(self):
195
  """
196
  نقل الإعدادات من الـ DNA النشط إلى SystemLimits
197
+ ليستخدمها DataManager و Processor.
198
  """
199
  if self.current_market_regime not in self.strategies:
 
200
  return
201
 
202
  active_dna = self.strategies[self.current_market_regime]
 
210
  SystemLimits.L2_WEIGHT_TITAN = mw.get("titan", 0.4) / total_w
211
  SystemLimits.L2_WEIGHT_PATTERNS = mw.get("patterns", 0.3) / total_w
212
  SystemLimits.L2_WEIGHT_MC = mw.get("mc", 0.1) / total_w
 
213
 
214
+ # 2. حقن عتبات الفلتر الأولي (L1 Score Threshold)
215
  SystemLimits.L1_MIN_AFFINITY_SCORE = active_dna.filters.get("l1_min_score", 20.0)
216
 
217
+ # 3. 🔥 حقن أوزان مصفوفة الكاشفات (Scanner Matrix Weights)
218
+ # هذا هو الرابط الذي يجعل DataManager يعمل وفقاً للباكتست
219
+ if hasattr(active_dna, 'scanner_weights') and active_dna.scanner_weights:
220
+ SystemLimits.SCANNER_WEIGHTS = active_dna.scanner_weights
221
+ # print(f" -> Scanner Matrix: {active_dna.scanner_weights}")
222
+
223
+ # 4. حقن النظام الحالي
224
+ SystemLimits.CURRENT_REGIME = self.current_market_regime
225
 
226
+ # 5. حقن باقي الإعدادات (Sniper, Oracle, Guards)
227
+ SystemLimits.L3_CONFIDENCE_THRESHOLD = active_dna.filters.get("l3_conf_thresh", 0.65)
228
  SystemLimits.L4_OB_WALL_RATIO = active_dna.ob_settings.get("wall_ratio_limit", 0.4)
229
 
 
230
  gs = active_dna.guard_settings
231
  if gs:
232
  SystemLimits.HYDRA_CRASH_THRESH = gs.get('hydra_crash', 0.60)
233
  SystemLimits.HYDRA_GIVEBACK_THRESH = gs.get('hydra_giveback', 0.70)
234
  SystemLimits.LEGACY_V2_PANIC_THRESH = gs.get('legacy_v2', 0.95)
235
  SystemLimits.LEGACY_V3_HARD_THRESH = gs.get('legacy_v3', 0.95)
 
 
 
 
 
236
 
237
  # ==========================================================================
238
+ # 🎮 Utilities
239
  # ==========================================================================
240
  def update_market_regime(self, new_regime: str):
241
  if new_regime in self.strategies:
242
  self.current_market_regime = new_regime
243
  print(f"🔄 [AdaptiveHub] Regime Switched to: {new_regime}")
244
  self._inject_current_parameters()
 
 
245
 
246
  def get_status(self):
247
  dna = self.strategies.get(self.current_market_regime)
248
  if not dna: return "System Initializing..."
249
  mw = dna.model_weights
 
250
  return (f"Regime: {self.current_market_regime} | "
251
+ f"L1 Thresh: {dna.filters.get('l1_min_score',0):.1f} | "
252
+ f"Titan W: {mw.get('titan'):.2f}")
 
253
 
254
  async def _save_state_to_r2(self):
255
  if not self.r2: return