Riy777 commited on
Commit
3bf4b49
·
verified ·
1 Parent(s): a0188c4

Update LLM.py

Browse files
Files changed (1) hide show
  1. LLM.py +113 -13
LLM.py CHANGED
@@ -1,19 +1,21 @@
1
  # LLM.py (Updated to integrate LearningHub and English-only prompts)
2
  import os, traceback, asyncio, json, time
3
- import re
4
  from datetime import datetime
5
  from functools import wraps
6
  from backoff import on_exception, expo
7
  from openai import OpenAI, RateLimitError, APITimeoutError
8
  import numpy as np
9
  from sentiment_news import NewsFetcher
 
10
  from helpers import validate_required_fields, format_technical_indicators, format_strategy_scores, format_candle_data_for_pattern_analysis, format_whale_analysis_for_llm, parse_json_from_response
11
- from ml_engine.processor import safe_json_parse
 
 
 
12
 
13
- # (Note: PatternAnalysisEngine code remains unchanged, so it is omitted here for brevity)
14
- # ... (PatternAnalysisEngine class code as before) ...
15
  class PatternAnalysisEngine:
16
- # --- (كود PatternAnalysisEngine كما هو بدون تغيير) ---
17
  def __init__(self, llm_service):
18
  self.llm = llm_service
19
 
@@ -163,9 +165,11 @@ class PatternAnalysisEngine:
163
  }
164
 
165
  async def analyze_chart_patterns(self, symbol, ohlcv_data):
 
166
  pass
167
 
168
  def _parse_pattern_response(self, response_text):
 
169
  pass
170
 
171
 
@@ -331,8 +335,16 @@ class LLMService:
331
  return None
332
 
333
  async def _get_pattern_analysis(self, data_payload):
334
- # (Omitted for brevity - same as original file)
335
- pass
 
 
 
 
 
 
 
 
336
 
337
  # 🔴 --- START OF PROMPT CHANGE --- 🔴
338
  def _create_comprehensive_trading_prompt(
@@ -458,16 +470,104 @@ OUTPUT FORMAT (JSON - SPOT ONLY - INCLUDE EXIT PROFILE AND SELF-CRITIQUE):
458
 
459
 
460
  def _format_candle_data_comprehensive(self, ohlcv_data):
461
- # (Omitted for brevity - same as original file)
462
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
 
464
  def _analyze_timeframe_candles(self, candles, timeframe):
465
- # (Omitted for brevity - same as original file)
466
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
  def _format_market_context(self, sentiment_data):
469
- # (Omitted for brevity - same as original file)
470
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
 
472
 
473
  async def re_analyze_trade_async(self, trade_data: dict, processed_data: dict):
 
1
  # LLM.py (Updated to integrate LearningHub and English-only prompts)
2
  import os, traceback, asyncio, json, time
3
+ import re # ✅ استيراد مكتبة re
4
  from datetime import datetime
5
  from functools import wraps
6
  from backoff import on_exception, expo
7
  from openai import OpenAI, RateLimitError, APITimeoutError
8
  import numpy as np
9
  from sentiment_news import NewsFetcher
10
+ # ✅ تعديل الاستيراد: parse_json_from_response لم يعد مستخدماً هنا بشكل مباشر لتحليل استجابة النموذج الرئيسية
11
  from helpers import validate_required_fields, format_technical_indicators, format_strategy_scores, format_candle_data_for_pattern_analysis, format_whale_analysis_for_llm, parse_json_from_response
12
+ from ml_engine.processor import safe_json_parse # ✅ الإصلاح: استيراد المحلل الآمن من الموجه الجديد
13
+
14
+ NVIDIA_API_KEY = os.getenv("NVIDIA_API_KEY")
15
+ PRIMARY_MODEL = "nvidia/llama-3.1-nemotron-ultra-253b-v1"
16
 
 
 
17
  class PatternAnalysisEngine:
18
+ # --- (هذا الكلاس جزء من LLM.py ومطلوب لتحليل الشموع) ---
19
  def __init__(self, llm_service):
20
  self.llm = llm_service
21
 
 
165
  }
166
 
167
  async def analyze_chart_patterns(self, symbol, ohlcv_data):
168
+ """(تم تركها فارغة عمداً لأن النموذج الضخم يقوم بها الآن)"""
169
  pass
170
 
171
  def _parse_pattern_response(self, response_text):
172
+ """(تم تركها فارغة عمداً)"""
173
  pass
174
 
175
 
 
335
  return None
336
 
337
  async def _get_pattern_analysis(self, data_payload):
338
+ try:
339
+ symbol = data_payload['symbol']
340
+ ohlcv_data = data_payload.get('raw_ohlcv') or data_payload.get('ohlcv')
341
+ if ohlcv_data:
342
+ # (This is a placeholder, as PatternAnalysisEngine.analyze_chart_patterns is not implemented)
343
+ return None
344
+ return None
345
+ except Exception as e:
346
+ print(f"❌ Pattern analysis failed for {data_payload.get('symbol')}: {e}")
347
+ return None
348
 
349
  # 🔴 --- START OF PROMPT CHANGE --- 🔴
350
  def _create_comprehensive_trading_prompt(
 
470
 
471
 
472
  def _format_candle_data_comprehensive(self, ohlcv_data):
473
+ """تنسيق شامل لبيانات الشموع الخام"""
474
+ if not ohlcv_data:
475
+ return "No raw candle data available for analysis"
476
+
477
+ try:
478
+ timeframes_available = []
479
+ total_candles = 0
480
+
481
+ for timeframe, candles in ohlcv_data.items():
482
+ if candles and len(candles) >= 5:
483
+ timeframes_available.append(f"{timeframe.upper()} ({len(candles)} candles)")
484
+ total_candles += len(candles)
485
+
486
+ if not timeframes_available:
487
+ return "Insufficient candle data across all timeframes"
488
+
489
+ summary = f"📊 Available Timeframes: {', '.join(timeframes_available)}\n"
490
+ summary += f"📈 Total Candles Available: {total_candles}\n\n"
491
+
492
+ raw_candle_analysis_text = self.pattern_engine._format_chart_data_for_llm(ohlcv_data)
493
+
494
+ summary += raw_candle_analysis_text
495
+
496
+ return summary
497
+ except Exception as e:
498
+ return f"Error formatting raw candle data: {str(e)}"
499
 
500
  def _analyze_timeframe_candles(self, candles, timeframe):
501
+ """تحليل الشموع لإطار زمني محدد - (تستخدم داخلياً بواسطة _format_raw_candle_data)"""
502
+ try:
503
+ if len(candles) < 10:
504
+ return f"Insufficient data ({len(candles)} candles)"
505
+
506
+ recent_candles = candles[-15:]
507
+
508
+ closes = [c[4] for c in recent_candles]
509
+ opens = [c[1] for c in recent_candles]
510
+ highs = [c[2] for c in recent_candles]
511
+ lows = [c[3] for c in recent_candles]
512
+ volumes = [c[5] for c in recent_candles]
513
+
514
+ current_price = closes[-1]
515
+ first_price = closes[0]
516
+ price_change = ((current_price - first_price) / first_price) * 100 if first_price > 0 else 0
517
+
518
+ if price_change > 2: trend = "🟢 UPTREND"
519
+ elif price_change < -2: trend = "🔴 DOWNTREND"
520
+ else: trend = "⚪ SIDEWAYS"
521
+
522
+ high_max = max(highs)
523
+ low_min = min(lows)
524
+ volatility = ((high_max - low_min) / low_min) * 100 if low_min > 0 else 0
525
+
526
+ avg_volume = sum(volumes) / len(volumes) if volumes else 1
527
+ current_volume = volumes[-1] if volumes else 0
528
+ volume_ratio = current_volume / avg_volume if avg_volume > 0 else 1
529
+
530
+ green_candles = sum(1 for i in range(len(closes)) if closes[i] > opens[i])
531
+ red_candles = len(closes) - green_candles
532
+ candle_ratio = green_candles / len(closes) if closes else 0
533
+
534
+ analysis = [
535
+ f"📈 Trend: {trend} ({price_change:+.2f}%)",
536
+ f"🌊 Volatility: {volatility:.2f}%",
537
+ f"📦 Volume: {volume_ratio:.2f}x average",
538
+ f"🕯️ Candles: {green_candles}🟢/{red_candles}🔴 ({candle_ratio:.1%} green)",
539
+ f"💰 Range: {low_min:.6f} - {high_max:.6f}",
540
+ f"🎯 Current: {current_price:.6f}"
541
+ ]
542
+
543
+ return "\n".join(analysis)
544
+ except Exception as e:
545
+ return f"Analysis error: {str(e)}"
546
 
547
  def _format_market_context(self, sentiment_data):
548
+ """تنسيق سياق السوق"""
549
+ if not sentiment_data or sentiment_data.get('data_quality', 'LOW') == 'LOW':
550
+ return "Market context data not available or incomplete."
551
+
552
+ btc_sentiment = sentiment_data.get('btc_sentiment', 'N/A')
553
+ fear_greed = sentiment_data.get('fear_and_greed_index', 'N/A')
554
+ market_trend = sentiment_data.get('market_trend', 'N/A')
555
+
556
+ lines = [
557
+ f"• Bitcoin Sentiment: {btc_sentiment}",
558
+ f"• Fear & Greed Index: {fear_greed} ({sentiment_data.get('sentiment_class', 'Neutral')})",
559
+ f"• Overall Market Trend: {market_trend.replace('_', ' ').title() if isinstance(market_trend, str) else 'N/A'}"
560
+ ]
561
+
562
+ general_whale = sentiment_data.get('general_whale_activity', {})
563
+ if general_whale and general_whale.get('sentiment') != 'NEUTRAL':
564
+ whale_sentiment = general_whale.get('sentiment', 'N/A')
565
+ critical_alert = general_whale.get('critical_alert', False)
566
+ lines.append(f"• General Whale Sentiment: {whale_sentiment.replace('_', ' ').title() if isinstance(whale_sentiment, str) else 'N/A'}")
567
+ if critical_alert:
568
+ lines.append(" ⚠️ CRITICAL WHALE ALERT ACTIVE")
569
+
570
+ return "\n".join(lines)
571
 
572
 
573
  async def re_analyze_trade_async(self, trade_data: dict, processed_data: dict):