Update data_manager.py
Browse files- data_manager.py +14 -34
data_manager.py
CHANGED
|
@@ -6,9 +6,11 @@ import time
|
|
| 6 |
from datetime import datetime
|
| 7 |
import ccxt.pro as ccxt
|
| 8 |
import numpy as np
|
| 9 |
-
|
| 10 |
|
| 11 |
-
|
|
|
|
|
|
|
| 12 |
|
| 13 |
class DataManager:
|
| 14 |
def __init__(self, contracts_db, whale_monitor):
|
|
@@ -20,12 +22,10 @@ class DataManager:
|
|
| 20 |
'sandbox': False,
|
| 21 |
'enableRateLimit': True,
|
| 22 |
'timeout': 30000,
|
| 23 |
-
'verbose': False
|
| 24 |
})
|
| 25 |
self.exchange.rateLimit = 800
|
| 26 |
-
print("✅ تم تهيئة اتصال KuCoin بنجاح")
|
| 27 |
except Exception as e:
|
| 28 |
-
print(f"❌ فشل تهيئة اتصال KuCoin: {e}")
|
| 29 |
self.exchange = None
|
| 30 |
|
| 31 |
self._whale_data_cache = {}
|
|
@@ -50,9 +50,6 @@ class DataManager:
|
|
| 50 |
'INFURA_KEY': "🟢 متوفر" if os.getenv('INFURA_KEY') else "🔴 غير متوفر"
|
| 51 |
}
|
| 52 |
|
| 53 |
-
for key, status in api_status.items():
|
| 54 |
-
print(f" {key}: {status}")
|
| 55 |
-
|
| 56 |
await self._load_markets()
|
| 57 |
|
| 58 |
async def _load_markets(self):
|
|
@@ -60,14 +57,12 @@ class DataManager:
|
|
| 60 |
if not self.exchange:
|
| 61 |
return
|
| 62 |
|
| 63 |
-
print("🔄 جلب أحدث بيانات الأسواق من KuCoin...")
|
| 64 |
await self.exchange.load_markets()
|
| 65 |
self.market_cache = self.exchange.markets
|
| 66 |
self.last_market_load = datetime.now()
|
| 67 |
-
print(f"✅ تم تحميل {len(self.market_cache)} سوق من KuCoin")
|
| 68 |
|
| 69 |
except Exception as e:
|
| 70 |
-
|
| 71 |
|
| 72 |
async def close(self):
|
| 73 |
if self.http_client:
|
|
@@ -106,7 +101,6 @@ class DataManager:
|
|
| 106 |
return None
|
| 107 |
|
| 108 |
except Exception as e:
|
| 109 |
-
print(f"❌ فشل جلب سعر {network}: {e}")
|
| 110 |
return None
|
| 111 |
|
| 112 |
async def _get_price_from_kucoin(self, symbol):
|
|
@@ -230,7 +224,8 @@ class DataManager:
|
|
| 230 |
'data_sources': {
|
| 231 |
'prices': bitcoin_price is not None and ethereum_price is not None,
|
| 232 |
'sentiment': sentiment_data is not None,
|
| 233 |
-
'general_whale_data': general_whale_activity.get('data_available', False) if general_whale_activity else False
|
|
|
|
| 234 |
},
|
| 235 |
'data_quality': 'HIGH',
|
| 236 |
'risk_assessment': self._assess_market_risk(general_whale_activity, sentiment_data)
|
|
@@ -435,7 +430,8 @@ class DataManager:
|
|
| 435 |
'bitcoin_price_usd': None,
|
| 436 |
'ethereum_price_usd': None,
|
| 437 |
'fear_and_greed_index': None,
|
| 438 |
-
'sentiment_class': 'UNKNOWN'
|
|
|
|
| 439 |
}
|
| 440 |
|
| 441 |
def _determine_market_trend(self, bitcoin_price, sentiment_data, whale_activity):
|
|
@@ -568,8 +564,6 @@ class DataManager:
|
|
| 568 |
|
| 569 |
async def find_high_potential_candidates(self, count=20):
|
| 570 |
try:
|
| 571 |
-
print(f"🔍 البحث عن {count} رمز ذو إمكانات عالية بناءً على المؤشرات التقنية...")
|
| 572 |
-
|
| 573 |
if not self.exchange:
|
| 574 |
return []
|
| 575 |
|
|
@@ -581,16 +575,12 @@ class DataManager:
|
|
| 581 |
if symbol.endswith('/USDT') and self.market_cache[symbol].get('active', False)
|
| 582 |
]
|
| 583 |
|
| 584 |
-
print(f"✅ تم العثور على {len(usdt_symbols)} رمز USDT نشط في KuCoin")
|
| 585 |
-
|
| 586 |
candidates_with_scores = []
|
| 587 |
analyzed_count = 0
|
| 588 |
|
| 589 |
for symbol in usdt_symbols[:100]:
|
| 590 |
try:
|
| 591 |
analyzed_count += 1
|
| 592 |
-
if analyzed_count % 10 == 0:
|
| 593 |
-
print(f"📊 تم تحليل {analyzed_count} رمز من أصل {min(100, len(usdt_symbols))}")
|
| 594 |
|
| 595 |
ohlcv_1h = await self.exchange.fetch_ohlcv(symbol, '1h', limit=50)
|
| 596 |
|
|
@@ -627,20 +617,13 @@ class DataManager:
|
|
| 627 |
candidates_with_scores.sort(key=lambda x: x['technical_score'], reverse=True)
|
| 628 |
top_candidates = candidates_with_scores[:count]
|
| 629 |
|
| 630 |
-
print(f"✅ تم العثور على {len(top_candidates)} مرشح عالي الجودة")
|
| 631 |
-
|
| 632 |
-
for candidate in top_candidates[:5]:
|
| 633 |
-
print(f" 🥇 {candidate['symbol']}: درجة {candidate['technical_score']:.3f}")
|
| 634 |
-
|
| 635 |
return top_candidates
|
| 636 |
|
| 637 |
except Exception as e:
|
| 638 |
-
print(f"❌ خطأ في find_high_potential_candidates: {e}")
|
| 639 |
return []
|
| 640 |
|
| 641 |
async def get_fast_pass_data_async(self, candidates):
|
| 642 |
try:
|
| 643 |
-
print(f"📊 جلب بيانات OHLCV لـ {len(candidates)} مرشح من KuCoin...")
|
| 644 |
results = []
|
| 645 |
|
| 646 |
timeframes = [
|
|
@@ -648,7 +631,8 @@ class DataManager:
|
|
| 648 |
('15m', 200),
|
| 649 |
('1h', 200),
|
| 650 |
('4h', 200),
|
| 651 |
-
('1d', 200)
|
|
|
|
| 652 |
]
|
| 653 |
|
| 654 |
for candidate in candidates:
|
|
@@ -667,7 +651,8 @@ class DataManager:
|
|
| 667 |
break
|
| 668 |
|
| 669 |
ohlcv_data[timeframe] = ohlcv
|
| 670 |
-
|
|
|
|
| 671 |
|
| 672 |
except Exception as e:
|
| 673 |
has_sufficient_data = False
|
|
@@ -682,18 +667,13 @@ class DataManager:
|
|
| 682 |
}
|
| 683 |
|
| 684 |
results.append(result_data)
|
| 685 |
-
print(f"✅ تم تجميع بيانات {symbol} بنجاح")
|
| 686 |
-
else:
|
| 687 |
-
print(f"❌ فشل تجميع بيانات كافية لـ {symbol}")
|
| 688 |
|
| 689 |
except Exception as symbol_error:
|
| 690 |
continue
|
| 691 |
|
| 692 |
-
print(f"✅ تم تجميع بيانات لـ {len(results)} مرشح بنجاح")
|
| 693 |
return results
|
| 694 |
|
| 695 |
except Exception as e:
|
| 696 |
-
print(f"❌ خطأ في get_fast_pass_data_async: {e}")
|
| 697 |
return []
|
| 698 |
|
| 699 |
async def get_latest_price_async(self, symbol):
|
|
|
|
| 6 |
from datetime import datetime
|
| 7 |
import ccxt.pro as ccxt
|
| 8 |
import numpy as np
|
| 9 |
+
import logging
|
| 10 |
|
| 11 |
+
# تعطيل تسجيل HTTP المزعج
|
| 12 |
+
logging.getLogger("httpx").setLevel(logging.WARNING)
|
| 13 |
+
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
| 14 |
|
| 15 |
class DataManager:
|
| 16 |
def __init__(self, contracts_db, whale_monitor):
|
|
|
|
| 22 |
'sandbox': False,
|
| 23 |
'enableRateLimit': True,
|
| 24 |
'timeout': 30000,
|
| 25 |
+
'verbose': False # تعطيل التسجيل التفصيلي
|
| 26 |
})
|
| 27 |
self.exchange.rateLimit = 800
|
|
|
|
| 28 |
except Exception as e:
|
|
|
|
| 29 |
self.exchange = None
|
| 30 |
|
| 31 |
self._whale_data_cache = {}
|
|
|
|
| 50 |
'INFURA_KEY': "🟢 متوفر" if os.getenv('INFURA_KEY') else "🔴 غير متوفر"
|
| 51 |
}
|
| 52 |
|
|
|
|
|
|
|
|
|
|
| 53 |
await self._load_markets()
|
| 54 |
|
| 55 |
async def _load_markets(self):
|
|
|
|
| 57 |
if not self.exchange:
|
| 58 |
return
|
| 59 |
|
|
|
|
| 60 |
await self.exchange.load_markets()
|
| 61 |
self.market_cache = self.exchange.markets
|
| 62 |
self.last_market_load = datetime.now()
|
|
|
|
| 63 |
|
| 64 |
except Exception as e:
|
| 65 |
+
pass
|
| 66 |
|
| 67 |
async def close(self):
|
| 68 |
if self.http_client:
|
|
|
|
| 101 |
return None
|
| 102 |
|
| 103 |
except Exception as e:
|
|
|
|
| 104 |
return None
|
| 105 |
|
| 106 |
async def _get_price_from_kucoin(self, symbol):
|
|
|
|
| 224 |
'data_sources': {
|
| 225 |
'prices': bitcoin_price is not None and ethereum_price is not None,
|
| 226 |
'sentiment': sentiment_data is not None,
|
| 227 |
+
'general_whale_data': general_whale_activity.get('data_available', False) if general_whale_activity else False,
|
| 228 |
+
'netflow_analysis': general_whale_activity.get('netflow_analysis', {}).get('market_impact', 'UNKNOWN') if general_whale_activity else 'UNKNOWN'
|
| 229 |
},
|
| 230 |
'data_quality': 'HIGH',
|
| 231 |
'risk_assessment': self._assess_market_risk(general_whale_activity, sentiment_data)
|
|
|
|
| 430 |
'bitcoin_price_usd': None,
|
| 431 |
'ethereum_price_usd': None,
|
| 432 |
'fear_and_greed_index': None,
|
| 433 |
+
'sentiment_class': 'UNKNOWN',
|
| 434 |
+
'missing_data': ['غير متوفر - أسعار البيتكوين', 'غير متوفر - أسعار الإيثيريوم', 'غير متوفر - بيانات المشاعر', 'غير متوفر - بيانات الحيتان']
|
| 435 |
}
|
| 436 |
|
| 437 |
def _determine_market_trend(self, bitcoin_price, sentiment_data, whale_activity):
|
|
|
|
| 564 |
|
| 565 |
async def find_high_potential_candidates(self, count=20):
|
| 566 |
try:
|
|
|
|
|
|
|
| 567 |
if not self.exchange:
|
| 568 |
return []
|
| 569 |
|
|
|
|
| 575 |
if symbol.endswith('/USDT') and self.market_cache[symbol].get('active', False)
|
| 576 |
]
|
| 577 |
|
|
|
|
|
|
|
| 578 |
candidates_with_scores = []
|
| 579 |
analyzed_count = 0
|
| 580 |
|
| 581 |
for symbol in usdt_symbols[:100]:
|
| 582 |
try:
|
| 583 |
analyzed_count += 1
|
|
|
|
|
|
|
| 584 |
|
| 585 |
ohlcv_1h = await self.exchange.fetch_ohlcv(symbol, '1h', limit=50)
|
| 586 |
|
|
|
|
| 617 |
candidates_with_scores.sort(key=lambda x: x['technical_score'], reverse=True)
|
| 618 |
top_candidates = candidates_with_scores[:count]
|
| 619 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 620 |
return top_candidates
|
| 621 |
|
| 622 |
except Exception as e:
|
|
|
|
| 623 |
return []
|
| 624 |
|
| 625 |
async def get_fast_pass_data_async(self, candidates):
|
| 626 |
try:
|
|
|
|
| 627 |
results = []
|
| 628 |
|
| 629 |
timeframes = [
|
|
|
|
| 631 |
('15m', 200),
|
| 632 |
('1h', 200),
|
| 633 |
('4h', 200),
|
| 634 |
+
('1d', 200),
|
| 635 |
+
('1w', 200)
|
| 636 |
]
|
| 637 |
|
| 638 |
for candidate in candidates:
|
|
|
|
| 651 |
break
|
| 652 |
|
| 653 |
ohlcv_data[timeframe] = ohlcv
|
| 654 |
+
|
| 655 |
+
await asyncio.sleep(0.05)
|
| 656 |
|
| 657 |
except Exception as e:
|
| 658 |
has_sufficient_data = False
|
|
|
|
| 667 |
}
|
| 668 |
|
| 669 |
results.append(result_data)
|
|
|
|
|
|
|
|
|
|
| 670 |
|
| 671 |
except Exception as symbol_error:
|
| 672 |
continue
|
| 673 |
|
|
|
|
| 674 |
return results
|
| 675 |
|
| 676 |
except Exception as e:
|
|
|
|
| 677 |
return []
|
| 678 |
|
| 679 |
async def get_latest_price_async(self, symbol):
|