Spaces:
Paused
Paused
Update ml_engine/data_manager.py
Browse files- ml_engine/data_manager.py +52 -7
ml_engine/data_manager.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
# ============================================================
|
| 2 |
# 📂 ml_engine/data_manager.py
|
| 3 |
-
# (V63.
|
| 4 |
# ============================================================
|
| 5 |
|
| 6 |
import asyncio
|
|
@@ -44,7 +44,7 @@ class DataManager:
|
|
| 44 |
'UP', 'DOWN', 'BEAR', 'BULL', '3S', '3L'
|
| 45 |
]
|
| 46 |
|
| 47 |
-
print(f"📦 [DataManager V63.
|
| 48 |
|
| 49 |
async def initialize(self):
|
| 50 |
print(" > [DataManager] Starting initialization...")
|
|
@@ -79,7 +79,7 @@ class DataManager:
|
|
| 79 |
self.adaptive_hub_ref = adaptive_hub_ref
|
| 80 |
print(f"🔍 [Layer 1] Screening for High Vol Assets (Bottom/Acc/Mom)...")
|
| 81 |
|
| 82 |
-
# 1. فلتر السيولة الأساسي (
|
| 83 |
initial_candidates = await self._stage0_universe_filter()
|
| 84 |
if not initial_candidates:
|
| 85 |
print("⚠️ [Layer 1] Stage 0 returned 0 candidates.")
|
|
@@ -96,7 +96,9 @@ class DataManager:
|
|
| 96 |
classification = self._classify_opportunity_type(item)
|
| 97 |
|
| 98 |
if classification['type'] != 'NONE':
|
|
|
|
| 99 |
regime_info = self._diagnose_asset_regime(item)
|
|
|
|
| 100 |
item['asset_regime'] = regime_info['regime']
|
| 101 |
item['asset_regime_conf'] = regime_info['conf']
|
| 102 |
|
|
@@ -115,7 +117,7 @@ class DataManager:
|
|
| 115 |
final_list = []
|
| 116 |
# نأخذ أفضل 50 مرشحاً لفحص دفتر الطلبات
|
| 117 |
semi_final_list.sort(key=lambda x: x['l1_sort_score'], reverse=True)
|
| 118 |
-
candidates_for_depth = semi_final_list[:
|
| 119 |
|
| 120 |
if candidates_for_depth:
|
| 121 |
print(f" 🛡️ [Layer 1.5] Checking Depth Support for {len(candidates_for_depth)} candidates...")
|
|
@@ -144,7 +146,7 @@ class DataManager:
|
|
| 144 |
final_list.append(item)
|
| 145 |
|
| 146 |
final_list.sort(key=lambda x: x['l1_sort_score'], reverse=True)
|
| 147 |
-
selection = final_list[:
|
| 148 |
|
| 149 |
print(f"✅ [Layer 1] Passed {len(selection)} active candidates.")
|
| 150 |
return selection
|
|
@@ -231,8 +233,8 @@ class DataManager:
|
|
| 231 |
# ==================================================================
|
| 232 |
async def _stage0_universe_filter(self) -> List[Dict[str, Any]]:
|
| 233 |
try:
|
| 234 |
-
# 🔥 إعداد الحد الأدنى لحجم التداول
|
| 235 |
-
MIN_VOLUME_THRESHOLD =
|
| 236 |
|
| 237 |
print(f" 🛡️ [Stage 0] Fetching Tickers (Min Vol: ${MIN_VOLUME_THRESHOLD:,.0f})...")
|
| 238 |
tickers = await self.exchange.fetch_tickers()
|
|
@@ -284,6 +286,47 @@ class DataManager:
|
|
| 284 |
traceback.print_exc()
|
| 285 |
return []
|
| 286 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
# ------------------------------------------------------------------
|
| 288 |
# Helpers & Indicators
|
| 289 |
# ------------------------------------------------------------------
|
|
@@ -305,6 +348,8 @@ class DataManager:
|
|
| 305 |
c['ohlcv'] = {'1h': h1, '15m': m15}
|
| 306 |
c['ohlcv_1h_raw'] = h1
|
| 307 |
c['ohlcv_15m_raw'] = m15
|
|
|
|
|
|
|
| 308 |
return c
|
| 309 |
except: return None
|
| 310 |
|
|
|
|
| 1 |
# ============================================================
|
| 2 |
# 📂 ml_engine/data_manager.py
|
| 3 |
+
# (V63.1 - GEM-Architect: Fixed Missing Attribute & Full Integrity)
|
| 4 |
# ============================================================
|
| 5 |
|
| 6 |
import asyncio
|
|
|
|
| 44 |
'UP', 'DOWN', 'BEAR', 'BULL', '3S', '3L'
|
| 45 |
]
|
| 46 |
|
| 47 |
+
print(f"📦 [DataManager V63.1] Integrity Restored (Regime Fix).")
|
| 48 |
|
| 49 |
async def initialize(self):
|
| 50 |
print(" > [DataManager] Starting initialization...")
|
|
|
|
| 79 |
self.adaptive_hub_ref = adaptive_hub_ref
|
| 80 |
print(f"🔍 [Layer 1] Screening for High Vol Assets (Bottom/Acc/Mom)...")
|
| 81 |
|
| 82 |
+
# 1. فلتر السيولة الأساسي (1 مليون دولار)
|
| 83 |
initial_candidates = await self._stage0_universe_filter()
|
| 84 |
if not initial_candidates:
|
| 85 |
print("⚠️ [Layer 1] Stage 0 returned 0 candidates.")
|
|
|
|
| 96 |
classification = self._classify_opportunity_type(item)
|
| 97 |
|
| 98 |
if classification['type'] != 'NONE':
|
| 99 |
+
# ✅ استدعاء الدالة المفقودة سابقاً
|
| 100 |
regime_info = self._diagnose_asset_regime(item)
|
| 101 |
+
|
| 102 |
item['asset_regime'] = regime_info['regime']
|
| 103 |
item['asset_regime_conf'] = regime_info['conf']
|
| 104 |
|
|
|
|
| 117 |
final_list = []
|
| 118 |
# نأخذ أفضل 50 مرشحاً لفحص دفتر الطلبات
|
| 119 |
semi_final_list.sort(key=lambda x: x['l1_sort_score'], reverse=True)
|
| 120 |
+
candidates_for_depth = semi_final_list[:300]
|
| 121 |
|
| 122 |
if candidates_for_depth:
|
| 123 |
print(f" 🛡️ [Layer 1.5] Checking Depth Support for {len(candidates_for_depth)} candidates...")
|
|
|
|
| 146 |
final_list.append(item)
|
| 147 |
|
| 148 |
final_list.sort(key=lambda x: x['l1_sort_score'], reverse=True)
|
| 149 |
+
selection = final_list[:300]
|
| 150 |
|
| 151 |
print(f"✅ [Layer 1] Passed {len(selection)} active candidates.")
|
| 152 |
return selection
|
|
|
|
| 233 |
# ==================================================================
|
| 234 |
async def _stage0_universe_filter(self) -> List[Dict[str, Any]]:
|
| 235 |
try:
|
| 236 |
+
# 🔥 إعداد الحد الأدنى لحجم التداول
|
| 237 |
+
MIN_VOLUME_THRESHOLD = 5000000.0 # 1 Million USDT
|
| 238 |
|
| 239 |
print(f" 🛡️ [Stage 0] Fetching Tickers (Min Vol: ${MIN_VOLUME_THRESHOLD:,.0f})...")
|
| 240 |
tickers = await self.exchange.fetch_tickers()
|
|
|
|
| 286 |
traceback.print_exc()
|
| 287 |
return []
|
| 288 |
|
| 289 |
+
# ------------------------------------------------------------------
|
| 290 |
+
# 🧭 The Diagnoser (تمت استعادتها)
|
| 291 |
+
# ------------------------------------------------------------------
|
| 292 |
+
def _diagnose_asset_regime(self, item: Dict[str, Any]) -> Dict[str, Any]:
|
| 293 |
+
"""
|
| 294 |
+
تقوم بتشخيص حالة السوق للأصل (Regime) لتحديد ما إذا كان مناسباً للدخول
|
| 295 |
+
"""
|
| 296 |
+
try:
|
| 297 |
+
if 'df_1h' not in item:
|
| 298 |
+
# محاولة استخراج الداتا فريم إذا لم تكن موجودة
|
| 299 |
+
if 'ohlcv_1h_raw' in item:
|
| 300 |
+
item['df_1h'] = self._calc_indicators(item['ohlcv_1h_raw'])
|
| 301 |
+
else:
|
| 302 |
+
return {'regime': 'RANGE', 'conf': 0.0}
|
| 303 |
+
|
| 304 |
+
df = item['df_1h']
|
| 305 |
+
if df.empty: return {'regime': 'RANGE', 'conf': 0.0}
|
| 306 |
+
|
| 307 |
+
curr = df.iloc[-1]
|
| 308 |
+
price = curr['close']
|
| 309 |
+
ema20 = curr['ema20']
|
| 310 |
+
ema50 = curr['ema50']
|
| 311 |
+
rsi = curr['rsi']
|
| 312 |
+
atr = curr['atr']
|
| 313 |
+
atr_pct = (atr / price) * 100 if price > 0 else 0
|
| 314 |
+
|
| 315 |
+
regime = "RANGE"
|
| 316 |
+
conf = 0.5
|
| 317 |
+
|
| 318 |
+
if atr_pct < 0.4: return {'regime': 'DEAD', 'conf': 0.9}
|
| 319 |
+
|
| 320 |
+
if price > ema20 and ema20 > ema50 and rsi > 50:
|
| 321 |
+
regime = "BULL"
|
| 322 |
+
conf = 0.8 if rsi > 55 else 0.6
|
| 323 |
+
elif price < ema20 and ema20 < ema50 and rsi < 50:
|
| 324 |
+
regime = "BEAR"
|
| 325 |
+
conf = 0.8 if rsi < 45 else 0.6
|
| 326 |
+
|
| 327 |
+
return {'regime': regime, 'conf': conf}
|
| 328 |
+
except Exception: return {'regime': 'RANGE', 'conf': 0.0}
|
| 329 |
+
|
| 330 |
# ------------------------------------------------------------------
|
| 331 |
# Helpers & Indicators
|
| 332 |
# ------------------------------------------------------------------
|
|
|
|
| 348 |
c['ohlcv'] = {'1h': h1, '15m': m15}
|
| 349 |
c['ohlcv_1h_raw'] = h1
|
| 350 |
c['ohlcv_15m_raw'] = m15
|
| 351 |
+
# حساب المؤشرات هنا لتوفير الوقت لاحقاً
|
| 352 |
+
c['df_1h'] = self._calc_indicators(h1)
|
| 353 |
return c
|
| 354 |
except: return None
|
| 355 |
|