Riy777 commited on
Commit
3d13538
·
verified ·
1 Parent(s): d14627b

Update learning_hub/adaptive_hub.py

Browse files
Files changed (1) hide show
  1. learning_hub/adaptive_hub.py +64 -43
learning_hub/adaptive_hub.py CHANGED
@@ -1,6 +1,6 @@
1
  # ==============================================================================
2
  # 🧠 learning_hub/adaptive_hub.py
3
- # (V60.1 - GEM-Architect: Full Sync [Base + Deltas + Fast])
4
  # ==============================================================================
5
 
6
  import json
@@ -10,7 +10,7 @@ import traceback
10
  from collections import deque
11
  from typing import Dict, Any, List
12
 
13
- # محاولة استيراد SystemLimits
14
  try:
15
  from ml_engine.processor import SystemLimits
16
  except ImportError:
@@ -52,19 +52,9 @@ class StrategyDNA:
52
  def get_final_guards(self):
53
  final = {}
54
  for k, v in self.base_guards.items():
 
55
  d_fast = self.delta_guards_fast.get(k, 0.0)
56
- # Periodic tuner updates base directly or needs delta logic?
57
- # V3.3 tuner updates delta via update_periodic_delta, so we assume deltas exist for guards too?
58
- # Note: For simplicity, Periodic Tuner currently updates 'Deltas' passed to hub.
59
- # We need to support Weekly/Monthly deltas for guards too if Tuner sends them.
60
- # Let's keep it simple: Base + Fast + (Weekly/Monthly if implemented in map)
61
- # Since Tuner V3.3 passes new_deltas map, we handle it in update_periodic_delta
62
-
63
  val = v + d_fast
64
- # Check if we stored weekly/monthly for guards in a generic way?
65
- # Currently structure is separate. To avoid complexity, we rely on Base updates from Tuner
66
- # OR we assume Tuner updates delta_weekly dict which contains ALL keys.
67
-
68
  final[k] = max(0.1, min(0.99, val))
69
  return final
70
 
@@ -89,31 +79,75 @@ class AdaptiveHub:
89
  self.dna_file_key = "learning/strategic_dna_v60_layered.json"
90
  self.current_market_regime = "RANGE"
91
  self.strategies: Dict[str, StrategyDNA] = {}
92
- print("🧠 [AdaptiveHub V60.1] Full Sync Architecture Initialized.")
93
 
94
  async def initialize(self):
95
  try:
96
  if self.r2:
97
  data_bytes = await self.r2.get_file_async(self.dna_file_key)
98
  if data_bytes:
99
- self._load_from_dict(json.loads(data_bytes))
 
 
100
  else:
101
  self._create_default_dna()
 
102
  else:
103
  self._create_default_dna()
104
  self._inject_current_parameters()
105
- except Exception:
 
106
  self._create_default_dna()
107
 
108
  def _create_default_dna(self):
109
- # Golden Values (Base)
110
- d_guards = {"hydra_crash": 0.60, "hydra_giveback": 0.60, "legacy_v2": 0.85}
 
 
 
 
111
  d_filters_bull = {"l1_min_score": 0.60, "l3_oracle_thresh": 0.75, "l4_sniper_thresh": 0.50}
112
 
113
- self.strategies["BULL"] = StrategyDNA("BULL", {"titan": 0.5, "structure": 0.1}, {"wall_ratio_limit": 0.6}, d_filters_bull, d_guards)
114
- self.strategies["BEAR"] = StrategyDNA("BEAR", {"titan": 0.1, "structure": 0.1}, {"wall_ratio_limit": 0.3}, d_filters_bull, d_guards)
115
- self.strategies["RANGE"] = StrategyDNA("RANGE", {"titan": 0.3, "structure": 0.3}, {"wall_ratio_limit": 0.4}, d_filters_bull, d_guards)
116
- self.strategies["DEAD"] = StrategyDNA("DEAD", {"titan": 0.1, "structure": 0.1}, {"wall_ratio_limit": 0.2}, d_filters_bull, d_guards)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  def _load_from_dict(self, data):
119
  for key, val in data.get("strategies", {}).items():
@@ -132,41 +166,31 @@ class AdaptiveHub:
132
  self.current_market_regime = data.get("current_regime", "RANGE")
133
 
134
  # ============================================================
135
- # 🧪 STRATEGIC BACKTEST LINK (Base Updater) - RESTORED!
136
  # ============================================================
137
  def submit_challenger(self, regime: str, new_config: dict, new_stats: dict) -> bool:
138
- """
139
- Called by HeavyDutyBacktester (Strategic Run).
140
- Updates BASE values and resets Deltas (Clean Slate).
141
- """
142
  if regime not in self.strategies: return False
143
  champion = self.strategies[regime]
144
 
145
- # Logic to accept new config (Always accept if from manual Strategic run)
146
  print(f" ⚖️ [Strategic Update] Updating BASE DNA for {regime}...")
147
 
148
- # 1. Update Base Weights
149
  champion.model_weights['titan'] = new_config['w_titan']
150
  champion.model_weights['structure'] = new_config['w_struct']
151
-
152
- # 2. Update Base Filters
153
  champion.base_filters['l1_min_score'] = new_config['thresh']
154
  champion.base_filters['l3_oracle_thresh'] = new_config.get('oracle_thresh', 0.65)
155
  champion.base_filters['l4_sniper_thresh'] = new_config.get('sniper_thresh', 0.40)
156
-
157
- # 3. Update Base Guards
158
  champion.base_guards['hydra_crash'] = new_config['hydra_thresh']
159
- champion.base_guards['hydra_giveback'] = new_config['hydra_thresh'] # Unified in backtest
160
  champion.base_guards['legacy_v2'] = new_config['legacy_thresh']
161
-
162
  champion.backtest_performance = new_stats
163
 
164
- # 4. RESET DELTAS (New Base = New Start)
165
  for k in champion.delta_weekly: champion.delta_weekly[k] = 0.0
166
  for k in champion.delta_monthly: champion.delta_monthly[k] = 0.0
167
  for k in champion.delta_fast: champion.delta_fast[k] = 0.0
168
 
169
- # 5. Save & Inject Immediately
170
  asyncio.create_task(self._save_state_to_r2())
171
  self._inject_current_parameters()
172
  return True
@@ -180,14 +204,13 @@ class AdaptiveHub:
180
  dna.trade_buffer.append(trade_data)
181
 
182
  if len(dna.trade_buffer) >= 100:
183
- print(f"🎓 [Fast Learner] Batch of 100 trades reached for {self.current_market_regime}. Analyzing...")
184
  self._process_fast_learning_batch(dna)
185
  dna.trade_buffer.clear()
186
  await self._save_state_to_r2()
187
  self._inject_current_parameters()
188
 
189
  def _process_fast_learning_batch(self, dna: StrategyDNA):
190
- # Simple Logic: Check Oracle & Sniper
191
  models = ['l3_oracle_thresh', 'l4_sniper_thresh']
192
  performance = {m: {'wins': 0, 'total': 0, 'pnl_sum': 0.0} for m in models}
193
 
@@ -220,10 +243,8 @@ class AdaptiveHub:
220
 
221
  if win_rate < TARGET_HIT_LOW and avg_pnl < 0:
222
  dna.delta_fast[model] = min(dna.delta_fast[model] + 0.01, 0.05)
223
- print(f" 📉 {model} performing poorly (WR {win_rate:.2%}). Tightening +1%")
224
  elif win_rate > TARGET_HIT_HIGH and avg_pnl > 0.5:
225
  dna.delta_fast[model] = max(dna.delta_fast[model] - 0.01, -0.05)
226
- print(f" 📈 {model} performing great (WR {win_rate:.2%}). Loosening -1%")
227
 
228
  # ============================================================
229
  # 🗓️ PERIODIC UPDATES (Weekly/Monthly)
@@ -235,9 +256,7 @@ class AdaptiveHub:
235
  target_dict = dna.delta_weekly if update_type == 'weekly' else dna.delta_monthly
236
  limit = 0.03 if update_type == 'weekly' else 0.05
237
 
238
- # Handles both Filters and Guards based on key names
239
  for k, v in new_deltas.items():
240
- # If key exists in filters or guards, update it
241
  if k in dna.base_filters or k in dna.base_guards:
242
  target_dict[k] = max(-limit, min(limit, v))
243
 
@@ -257,6 +276,7 @@ class AdaptiveHub:
257
 
258
  mw = dna.model_weights
259
  total_w = sum(mw.values()) or 1.0
 
260
  SystemLimits.L2_WEIGHT_TITAN = mw.get("titan", 0.4) / total_w
261
  SystemLimits.L2_WEIGHT_PATTERNS = mw.get("structure", 0.3) / total_w
262
 
@@ -268,6 +288,7 @@ class AdaptiveHub:
268
  SystemLimits.L4_OB_WALL_RATIO = dna.ob_settings.get("wall_ratio_limit", 0.4)
269
 
270
  SystemLimits.HYDRA_CRASH_THRESH = final_guards.get('hydra_crash', 0.85)
 
271
  SystemLimits.LEGACY_V2_PANIC_THRESH = final_guards.get('legacy_v2', 0.95)
272
 
273
  print(f" 💉 [System Updated] {self.current_market_regime} | Oracle: {SystemLimits.L3_CONFIDENCE_THRESHOLD:.3f} | Sniper: {SystemLimits.L4_ENTRY_THRESHOLD:.3f}")
 
1
  # ==============================================================================
2
  # 🧠 learning_hub/adaptive_hub.py
3
+ # (V60.1 - GEM-Architect: Golden Values + Full Sync)
4
  # ==============================================================================
5
 
6
  import json
 
10
  from collections import deque
11
  from typing import Dict, Any, List
12
 
13
+ # محاولة استيراد SystemLimits لتحديث النظام الحي
14
  try:
15
  from ml_engine.processor import SystemLimits
16
  except ImportError:
 
52
  def get_final_guards(self):
53
  final = {}
54
  for k, v in self.base_guards.items():
55
+ # For guards, we rely on Base updates mostly, but structure supports delta
56
  d_fast = self.delta_guards_fast.get(k, 0.0)
 
 
 
 
 
 
 
57
  val = v + d_fast
 
 
 
 
58
  final[k] = max(0.1, min(0.99, val))
59
  return final
60
 
 
79
  self.dna_file_key = "learning/strategic_dna_v60_layered.json"
80
  self.current_market_regime = "RANGE"
81
  self.strategies: Dict[str, StrategyDNA] = {}
82
+ print("🧠 [AdaptiveHub V60.1] Golden DNA Injection Active.")
83
 
84
  async def initialize(self):
85
  try:
86
  if self.r2:
87
  data_bytes = await self.r2.get_file_async(self.dna_file_key)
88
  if data_bytes:
89
+ saved_data = json.loads(data_bytes)
90
+ self._load_from_dict(saved_data)
91
+ print(" 📂 Loaded DNA from R2.")
92
  else:
93
  self._create_default_dna()
94
+ print(" ⚠️ No R2 file. Created Golden Defaults.")
95
  else:
96
  self._create_default_dna()
97
  self._inject_current_parameters()
98
+ except Exception as e:
99
+ print(f" ❌ Init Error: {e}")
100
  self._create_default_dna()
101
 
102
  def _create_default_dna(self):
103
+ """
104
+ 💎 GEM-Architect: الحقن المباشر للقيم الذهبية (Golden Values)
105
+ """
106
+
107
+ # 1. BULL MARKET (Golden Config)
108
+ d_guards_bull = {"hydra_crash": 0.60, "hydra_giveback": 0.60, "legacy_v2": 0.85}
109
  d_filters_bull = {"l1_min_score": 0.60, "l3_oracle_thresh": 0.75, "l4_sniper_thresh": 0.50}
110
 
111
+ self.strategies["BULL"] = StrategyDNA(
112
+ "BULL",
113
+ {"titan": 0.50, "structure": 0.10},
114
+ {"wall_ratio_limit": 0.60},
115
+ d_filters_bull,
116
+ d_guards_bull
117
+ )
118
+
119
+ # 2. BEAR MARKET (Golden Config)
120
+ d_guards_bear = {"hydra_crash": 0.60, "hydra_giveback": 0.60, "legacy_v2": 0.85}
121
+ d_filters_bear = {"l1_min_score": 0.60, "l3_oracle_thresh": 0.75, "l4_sniper_thresh": 0.30} # Sniper lower
122
+
123
+ self.strategies["BEAR"] = StrategyDNA(
124
+ "BEAR",
125
+ {"titan": 0.10, "structure": 0.10},
126
+ {"wall_ratio_limit": 0.30},
127
+ d_filters_bear,
128
+ d_guards_bear
129
+ )
130
+
131
+ # 3. RANGE/DEAD (Conservative Defaults)
132
+ d_guards_def = {"hydra_crash": 0.70, "hydra_giveback": 0.70, "legacy_v2": 0.90}
133
+ d_filters_range = {"l1_min_score": 0.65, "l3_oracle_thresh": 0.70, "l4_sniper_thresh": 0.40}
134
+
135
+ self.strategies["RANGE"] = StrategyDNA(
136
+ "RANGE",
137
+ {"titan": 0.30, "structure": 0.30},
138
+ {"wall_ratio_limit": 0.40},
139
+ d_filters_range,
140
+ d_guards_def
141
+ )
142
+
143
+ d_filters_dead = {"l1_min_score": 0.80, "l3_oracle_thresh": 0.80, "l4_sniper_thresh": 0.50}
144
+ self.strategies["DEAD"] = StrategyDNA(
145
+ "DEAD",
146
+ {"titan": 0.10, "structure": 0.10},
147
+ {"wall_ratio_limit": 0.20},
148
+ d_filters_dead,
149
+ {"hydra_crash": 0.50, "hydra_giveback": 0.50, "legacy_v2": 0.80}
150
+ )
151
 
152
  def _load_from_dict(self, data):
153
  for key, val in data.get("strategies", {}).items():
 
166
  self.current_market_regime = data.get("current_regime", "RANGE")
167
 
168
  # ============================================================
169
+ # 🧪 STRATEGIC BACKTEST LINK (Base Updater)
170
  # ============================================================
171
  def submit_challenger(self, regime: str, new_config: dict, new_stats: dict) -> bool:
 
 
 
 
172
  if regime not in self.strategies: return False
173
  champion = self.strategies[regime]
174
 
 
175
  print(f" ⚖️ [Strategic Update] Updating BASE DNA for {regime}...")
176
 
177
+ # Update Base
178
  champion.model_weights['titan'] = new_config['w_titan']
179
  champion.model_weights['structure'] = new_config['w_struct']
 
 
180
  champion.base_filters['l1_min_score'] = new_config['thresh']
181
  champion.base_filters['l3_oracle_thresh'] = new_config.get('oracle_thresh', 0.65)
182
  champion.base_filters['l4_sniper_thresh'] = new_config.get('sniper_thresh', 0.40)
 
 
183
  champion.base_guards['hydra_crash'] = new_config['hydra_thresh']
184
+ champion.base_guards['hydra_giveback'] = new_config['hydra_thresh']
185
  champion.base_guards['legacy_v2'] = new_config['legacy_thresh']
 
186
  champion.backtest_performance = new_stats
187
 
188
+ # Reset Deltas
189
  for k in champion.delta_weekly: champion.delta_weekly[k] = 0.0
190
  for k in champion.delta_monthly: champion.delta_monthly[k] = 0.0
191
  for k in champion.delta_fast: champion.delta_fast[k] = 0.0
192
 
193
+ # Save & Inject
194
  asyncio.create_task(self._save_state_to_r2())
195
  self._inject_current_parameters()
196
  return True
 
204
  dna.trade_buffer.append(trade_data)
205
 
206
  if len(dna.trade_buffer) >= 100:
207
+ print(f"🎓 [Fast Learner] Batch of 100 trades reached. Analyzing...")
208
  self._process_fast_learning_batch(dna)
209
  dna.trade_buffer.clear()
210
  await self._save_state_to_r2()
211
  self._inject_current_parameters()
212
 
213
  def _process_fast_learning_batch(self, dna: StrategyDNA):
 
214
  models = ['l3_oracle_thresh', 'l4_sniper_thresh']
215
  performance = {m: {'wins': 0, 'total': 0, 'pnl_sum': 0.0} for m in models}
216
 
 
243
 
244
  if win_rate < TARGET_HIT_LOW and avg_pnl < 0:
245
  dna.delta_fast[model] = min(dna.delta_fast[model] + 0.01, 0.05)
 
246
  elif win_rate > TARGET_HIT_HIGH and avg_pnl > 0.5:
247
  dna.delta_fast[model] = max(dna.delta_fast[model] - 0.01, -0.05)
 
248
 
249
  # ============================================================
250
  # 🗓️ PERIODIC UPDATES (Weekly/Monthly)
 
256
  target_dict = dna.delta_weekly if update_type == 'weekly' else dna.delta_monthly
257
  limit = 0.03 if update_type == 'weekly' else 0.05
258
 
 
259
  for k, v in new_deltas.items():
 
260
  if k in dna.base_filters or k in dna.base_guards:
261
  target_dict[k] = max(-limit, min(limit, v))
262
 
 
276
 
277
  mw = dna.model_weights
278
  total_w = sum(mw.values()) or 1.0
279
+
280
  SystemLimits.L2_WEIGHT_TITAN = mw.get("titan", 0.4) / total_w
281
  SystemLimits.L2_WEIGHT_PATTERNS = mw.get("structure", 0.3) / total_w
282
 
 
288
  SystemLimits.L4_OB_WALL_RATIO = dna.ob_settings.get("wall_ratio_limit", 0.4)
289
 
290
  SystemLimits.HYDRA_CRASH_THRESH = final_guards.get('hydra_crash', 0.85)
291
+ SystemLimits.HYDRA_GIVEBACK_THRESH = final_guards.get('hydra_giveback', 0.70)
292
  SystemLimits.LEGACY_V2_PANIC_THRESH = final_guards.get('legacy_v2', 0.95)
293
 
294
  print(f" 💉 [System Updated] {self.current_market_regime} | Oracle: {SystemLimits.L3_CONFIDENCE_THRESHOLD:.3f} | Sniper: {SystemLimits.L4_ENTRY_THRESHOLD:.3f}")