Spaces:
Running
Running
Update data_manager.py
Browse files- data_manager.py +68 -34
data_manager.py
CHANGED
|
@@ -601,34 +601,53 @@ class DataManager:
|
|
| 601 |
|
| 602 |
async def get_ohlcv_data_for_symbols(self, symbols: List[str]) -> List[Dict[str, Any]]:
|
| 603 |
"""
|
| 604 |
-
جلب بيانات OHLCV كاملة للرموز المحددة مع جميع الإطارات الزمنية
|
| 605 |
"""
|
| 606 |
-
|
| 607 |
-
|
| 608 |
-
print(f"📊 جلب بيانات OHLCV كاملة لـ {len(symbols)} عملة...")
|
| 609 |
print(" 📈 الإطارات الزمنية: 5m, 15m, 1h, 4h, 1d, 1w")
|
| 610 |
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 617 |
else:
|
| 618 |
-
print(f"
|
| 619 |
-
|
| 620 |
-
|
| 621 |
-
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
continue
|
| 626 |
|
| 627 |
-
print(f"✅ تم تجميع بيانات OHLCV كاملة لـ {len(
|
| 628 |
-
return
|
| 629 |
|
| 630 |
-
async def
|
| 631 |
-
"""جلب بيانات OHLCV كاملة مع جميع الإطارات الزمنية"""
|
| 632 |
try:
|
| 633 |
ohlcv_data = {}
|
| 634 |
|
|
@@ -642,19 +661,27 @@ class DataManager:
|
|
| 642 |
('1w', 50),
|
| 643 |
]
|
| 644 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 645 |
has_sufficient_data = True
|
| 646 |
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
except Exception as e:
|
| 658 |
has_sufficient_data = False
|
| 659 |
break
|
| 660 |
|
|
@@ -677,6 +704,13 @@ class DataManager:
|
|
| 677 |
except Exception as e:
|
| 678 |
return None
|
| 679 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 680 |
async def get_latest_price_async(self, symbol):
|
| 681 |
"""جلب السعر الحالي لعملة محددة"""
|
| 682 |
try:
|
|
@@ -729,4 +763,4 @@ class DataManager:
|
|
| 729 |
print(f"❌ خطأ في التحقق من الرمز {symbol}: {e}")
|
| 730 |
return False
|
| 731 |
|
| 732 |
-
print("✅ DataManager loaded -
|
|
|
|
| 601 |
|
| 602 |
async def get_ohlcv_data_for_symbols(self, symbols: List[str]) -> List[Dict[str, Any]]:
|
| 603 |
"""
|
| 604 |
+
جلب بيانات OHLCV كاملة للرموز المحددة مع جميع الإطارات الزمنية بشكل متوازي
|
| 605 |
"""
|
| 606 |
+
print(f"📊 جلب بيانات OHLCV كاملة لـ {len(symbols)} عملة بشكل متوازي...")
|
|
|
|
|
|
|
| 607 |
print(" 📈 الإطارات الزمنية: 5m, 15m, 1h, 4h, 1d, 1w")
|
| 608 |
|
| 609 |
+
# تقسيم الرموز إلى دفعات لتجنب rate limits
|
| 610 |
+
batch_size = 20 # 20 رمز في كل دفعة
|
| 611 |
+
batches = [symbols[i:i + batch_size] for i in range(0, len(symbols), batch_size)]
|
| 612 |
+
|
| 613 |
+
all_results = []
|
| 614 |
+
|
| 615 |
+
for batch_num, batch in enumerate(batches):
|
| 616 |
+
print(f" 🔄 معالجة الدفعة {batch_num + 1}/{len(batches)} ({len(batch)} عملة)...")
|
| 617 |
+
|
| 618 |
+
# إنشاء مهام للدفعة الحالية بشكل متوازي
|
| 619 |
+
batch_tasks = []
|
| 620 |
+
for symbol in batch:
|
| 621 |
+
task = asyncio.create_task(self._fetch_complete_ohlcv_parallel(symbol))
|
| 622 |
+
batch_tasks.append(task)
|
| 623 |
+
|
| 624 |
+
# انتظار انتهاء جميع مهام الدفعة الحالية
|
| 625 |
+
batch_results = await asyncio.gather(*batch_tasks, return_exceptions=True)
|
| 626 |
+
|
| 627 |
+
# معالجة نتائج الدفعة
|
| 628 |
+
successful_count = 0
|
| 629 |
+
for i, result in enumerate(batch_results):
|
| 630 |
+
symbol = batch[i]
|
| 631 |
+
if isinstance(result, Exception):
|
| 632 |
+
print(f" ❌ فشل جلب بيانات {symbol}: {result}")
|
| 633 |
+
elif result is not None:
|
| 634 |
+
all_results.append(result)
|
| 635 |
+
successful_count += 1
|
| 636 |
+
print(f" ✅ تم جلب بيانات {symbol}")
|
| 637 |
else:
|
| 638 |
+
print(f" ❌ فشل جلب بيانات {symbol}: لا توجد بيانات")
|
| 639 |
+
|
| 640 |
+
print(f" ✅ اكتملت الدفعة {batch_num + 1}: {successful_count}/{len(batch)} ناجحة")
|
| 641 |
+
|
| 642 |
+
# انتظار قصير بين الدفعات لتجنب rate limits
|
| 643 |
+
if batch_num < len(batches) - 1:
|
| 644 |
+
await asyncio.sleep(0.5)
|
|
|
|
| 645 |
|
| 646 |
+
print(f"✅ تم تجميع بيانات OHLCV كاملة لـ {len(all_results)} عملة")
|
| 647 |
+
return all_results
|
| 648 |
|
| 649 |
+
async def _fetch_complete_ohlcv_parallel(self, symbol: str) -> Dict[str, Any]:
|
| 650 |
+
"""جلب بيانات OHLCV كاملة مع جميع الإطارات الزمنية بشكل متوازي"""
|
| 651 |
try:
|
| 652 |
ohlcv_data = {}
|
| 653 |
|
|
|
|
| 661 |
('1w', 50),
|
| 662 |
]
|
| 663 |
|
| 664 |
+
# إنشاء مهام لجميع الإطارات الزمنية بشكل متوازي
|
| 665 |
+
timeframe_tasks = []
|
| 666 |
+
for timeframe, limit in timeframes:
|
| 667 |
+
task = asyncio.create_task(self._fetch_single_timeframe(symbol, timeframe, limit))
|
| 668 |
+
timeframe_tasks.append(task)
|
| 669 |
+
|
| 670 |
+
# انتظار جميع المهام
|
| 671 |
+
timeframe_results = await asyncio.gather(*timeframe_tasks, return_exceptions=True)
|
| 672 |
+
|
| 673 |
has_sufficient_data = True
|
| 674 |
|
| 675 |
+
# معالجة النتائج
|
| 676 |
+
for i, (timeframe, limit) in enumerate(timeframes):
|
| 677 |
+
result = timeframe_results[i]
|
| 678 |
+
if isinstance(result, Exception) or result is None:
|
| 679 |
+
has_sufficient_data = False
|
| 680 |
+
break
|
| 681 |
+
|
| 682 |
+
if result and len(result) >= 20:
|
| 683 |
+
ohlcv_data[timeframe] = result
|
| 684 |
+
else:
|
|
|
|
| 685 |
has_sufficient_data = False
|
| 686 |
break
|
| 687 |
|
|
|
|
| 704 |
except Exception as e:
|
| 705 |
return None
|
| 706 |
|
| 707 |
+
async def _fetch_single_timeframe(self, symbol: str, timeframe: str, limit: int):
|
| 708 |
+
"""جلب بيانات إطار زمني واحد"""
|
| 709 |
+
try:
|
| 710 |
+
return self.exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
|
| 711 |
+
except Exception:
|
| 712 |
+
return None
|
| 713 |
+
|
| 714 |
async def get_latest_price_async(self, symbol):
|
| 715 |
"""جلب السعر الحالي لعملة محددة"""
|
| 716 |
try:
|
|
|
|
| 763 |
print(f"❌ خطأ في التحقق من الرمز {symbol}: {e}")
|
| 764 |
return False
|
| 765 |
|
| 766 |
+
print("✅ DataManager loaded - Parallel OHLCV Fetching System")
|