Riy777 commited on
Commit
48fc686
·
verified ·
1 Parent(s): 3175274

Create adaptive_hub.py

Browse files
Files changed (1) hide show
  1. learning_hub/adaptive_hub.py +155 -0
learning_hub/adaptive_hub.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # learning_hub/adaptive_hub.py
2
+ # (V33.0 - R2 Persistence Enabled)
3
+
4
+ import json
5
+ import asyncio
6
+ import traceback
7
+ from datetime import datetime
8
+ from collections import deque
9
+ from typing import Dict, Any, List
10
+
11
+ from ml_engine.processor import SystemLimits
12
+
13
+ class AdaptiveHub:
14
+ def __init__(self, r2_service=None):
15
+ self.r2 = r2_service
16
+ # اسم الملف الذي سنحفظ فيه الأوزان والعتبات في R2
17
+ self.config_key = "learning/adaptive_system_config.json"
18
+
19
+ self.recent_results = deque(maxlen=20)
20
+ self.current_regime = "NEUTRAL"
21
+ self.wins = 0
22
+ self.losses = 0
23
+ self.consecutive_losses = 0
24
+
25
+ print("🧠 [AdaptiveHub] Meta-Learner Online (R2 Persistence).")
26
+
27
+ async def initialize(self):
28
+ """تحميل الإعدادات المحفوظة من R2 عند بدء التشغيل"""
29
+ if not self.r2: return
30
+
31
+ print(f"📥 [AdaptiveHub] Loading config from R2: {self.config_key}...")
32
+ try:
33
+ # 1. جلب الملف من R2
34
+ # ملاحظة: تأكد أن r2_service لديه دالة get_file_async وتعمل بشكل صحيح
35
+ data_bytes = await self.r2.get_file_async(self.config_key)
36
+
37
+ if data_bytes:
38
+ saved_state = json.loads(data_bytes)
39
+
40
+ # A. استعادة حالة التعلم (الذاكرة)
41
+ self.current_regime = saved_state.get("regime", "NEUTRAL")
42
+ self.wins = saved_state.get("stats", {}).get("wins", 0)
43
+ self.losses = saved_state.get("stats", {}).get("losses", 0)
44
+ self.recent_results = deque(saved_state.get("history", []), maxlen=20)
45
+
46
+ # B. استعادة عتبات النظام (تطبيقها على SystemLimits)
47
+ thresholds = saved_state.get("thresholds", {})
48
+ SystemLimits.update_from_dict(thresholds)
49
+
50
+ print(f"✅ [AdaptiveHub] Restored Regime: {self.current_regime}")
51
+ else:
52
+ print("⚠️ [AdaptiveHub] No saved config found. Using defaults.")
53
+ self._apply_neutral_settings() # البدء بوضع محايد
54
+
55
+ except Exception as e:
56
+ print(f"❌ [AdaptiveHub] Load failed: {e}")
57
+ # في حال الفشل، نعود للافتراضي للأمان
58
+ self._apply_neutral_settings()
59
+
60
+ async def register_trade_outcome(self, trade_data: Dict[str, Any]):
61
+ try:
62
+ pnl = trade_data.get('profit_pct', 0.0)
63
+ is_win = pnl > 0
64
+
65
+ self.recent_results.append(1 if is_win else 0)
66
+ if is_win:
67
+ self.wins += 1
68
+ self.consecutive_losses = 0
69
+ else:
70
+ self.losses += 1
71
+ self.consecutive_losses += 1
72
+
73
+ # تقييم وتعديل (في الذاكرة)
74
+ await self._evaluate_and_adapt()
75
+
76
+ # حفظ الحالة الجديدة (في R2)
77
+ await self._save_state_to_r2()
78
+
79
+ except Exception as e:
80
+ print(f"❌ [AdaptiveHub] Error analyzing trade: {e}")
81
+
82
+ async def _evaluate_and_adapt(self):
83
+ # ... (نفس منطق التقييم السابق: DEFENSIVE / AGGRESSIVE / NEUTRAL) ...
84
+ # (الكود هنا مطابق للرد السابق، لا تغيير في المنطق، فقط نستدعي Apply settings)
85
+
86
+ win_rate_window = sum(self.recent_results) / len(self.recent_results) if self.recent_results else 0.5
87
+
88
+ if self.consecutive_losses >= 3 or (len(self.recent_results) >= 10 and win_rate_window < 0.3):
89
+ if self.current_regime != "DEFENSIVE":
90
+ print("🛡️ [AdaptiveHub] -> DEFENSIVE Mode.")
91
+ self.current_regime = "DEFENSIVE"
92
+ self._apply_defensive_settings()
93
+
94
+ elif len(self.recent_results) >= 10 and win_rate_window > 0.7:
95
+ if self.current_regime != "AGGRESSIVE":
96
+ print("🚀 [AdaptiveHub] -> AGGRESSIVE Mode.")
97
+ self.current_regime = "AGGRESSIVE"
98
+ self._apply_aggressive_settings()
99
+ else:
100
+ if self.current_regime != "NEUTRAL":
101
+ print("⚖️ [AdaptiveHub] -> NEUTRAL Mode.")
102
+ self.current_regime = "NEUTRAL"
103
+ self._apply_neutral_settings()
104
+
105
+ def _apply_defensive_settings(self):
106
+ # تطبيق القيم في الذاكرة (RAM)
107
+ SystemLimits.L1_MIN_QUOTE_VOLUME = 5_000_000
108
+ SystemLimits.L1_MAX_PUMP_4H = 5.0
109
+ SystemLimits.L1_MAX_RSI = 60.0
110
+ SystemLimits.L3_CONFIDENCE_THRESHOLD = 0.75
111
+ SystemLimits.L4_ENTRY_THRESHOLD = 0.55
112
+ SystemLimits.HYDRA_CRASH_THRESH = 0.50
113
+
114
+ def _apply_aggressive_settings(self):
115
+ SystemLimits.L1_MIN_QUOTE_VOLUME = 500_000
116
+ SystemLimits.L1_MAX_PUMP_4H = 15.0
117
+ SystemLimits.L1_MAX_RSI = 75.0
118
+ SystemLimits.L3_CONFIDENCE_THRESHOLD = 0.55
119
+ SystemLimits.L4_ENTRY_THRESHOLD = 0.40
120
+ SystemLimits.HYDRA_CRASH_THRESH = 0.75
121
+
122
+ def _apply_neutral_settings(self):
123
+ SystemLimits.L1_MIN_QUOTE_VOLUME = 1_000_000
124
+ SystemLimits.L1_MAX_PUMP_4H = 8.0
125
+ SystemLimits.L1_MAX_RSI = 70.0
126
+ SystemLimits.L3_CONFIDENCE_THRESHOLD = 0.65
127
+ SystemLimits.L4_ENTRY_THRESHOLD = 0.45
128
+ SystemLimits.HYDRA_CRASH_THRESH = 0.60
129
+
130
+ async def _save_state_to_r2(self):
131
+ """حفظ الحالة الحالية + قيم العتبات في ملف JSON"""
132
+ if not self.r2: return
133
+
134
+ try:
135
+ # تجميع البيانات
136
+ state_packet = {
137
+ "last_updated": datetime.now().isoformat(),
138
+ "regime": self.current_regime,
139
+ "history": list(self.recent_results),
140
+ "stats": {"wins": self.wins, "losses": self.losses},
141
+
142
+ # ✅ الأهم: حفظ القيم الحالية للعتبات
143
+ "thresholds": SystemLimits.to_dict()
144
+ }
145
+
146
+ # رفع الملف
147
+ await self.r2.upload_json_async(state_packet, self.config_key)
148
+ # print("💾 [AdaptiveHub] System State & Thresholds Saved to R2.")
149
+
150
+ except Exception as e:
151
+ print(f"❌ [AdaptiveHub] Save to R2 failed: {e}")
152
+
153
+ def get_status(self):
154
+ win_rate = (self.wins / (self.wins + self.losses)) * 100 if (self.wins + self.losses) > 0 else 0
155
+ return f"Regime: {self.current_regime} | WR: {win_rate:.1f}% | Trend: {sum(self.recent_results)}/{len(self.recent_results)}"