import asyncio import time import re import json from crewai import Crew, Process from textwrap import dedent from crypto_analysis_agents import CryptoAnalysisAgents from crypto__analysis_tasks import CryptoAnalysisTasks class CryptoCrew: def __init__(self, crypto): self.crypto = crypto self.agents_instance = CryptoAnalysisAgents() self.tasks_instance = CryptoAnalysisTasks() def run(self): return asyncio.run(self.run_async()) async def run_async(self): start_time = time.time() try: # Create agents market_analyst = self.agents_instance.market_analyst() technical_analyst = self.agents_instance.technical_analyst() advisor = self.agents_instance.crypto_advisor() # Create tasks tasks = [ self.tasks_instance.market_research(market_analyst, self.crypto), self.tasks_instance.technical_analysis(technical_analyst, self.crypto), self.tasks_instance.sentiment_analysis(advisor, self.crypto), self.tasks_instance.recommend(advisor, self.crypto) ] # Enhanced crew configuration crew = Crew( agents=[market_analyst, technical_analyst, advisor], tasks=tasks, verbose=True, # Enable for better debugging process=Process.sequential, max_iterations=8, task_timeout=90 ) # Run crew result = await asyncio.to_thread(crew.kickoff) end_time = time.time() return self.parse_result(result, end_time - start_time) except Exception as e: execution_time = time.time() - start_time return { "summary": f"Analysis failed: {str(e)}", "market_data": self._get_fallback_market_data(), "technical_data": self._get_fallback_technical_data(), "sentiment": self._get_fallback_sentiment(), "recommendation": {"action": "HOLD", "confidence": "Low", "reasoning": "Analysis incomplete"}, "execution_time": execution_time, "risk_assessment": "High - Analysis failed" } def parse_result(self, result, execution_time): """Enhanced parsing to extract structured data from LLM responses""" result_str = str(result) # Extract market data market_data = self._extract_market_data(result_str) # Extract technical analysis technical_data = self._extract_technical_data(result_str) # Extract detailed sentiment analysis sentiment_analysis = self._extract_sentiment_analysis(result_str) # Extract recommendation recommendation = self._extract_recommendation(result_str) # Extract risk assessment risk_assessment = self._extract_risk_assessment(result_str) return { "summary": self._clean_summary(result_str), "market_data": market_data, "technical_data": technical_data, "sentiment": sentiment_analysis, "recommendation": recommendation, "risk_assessment": risk_assessment, "execution_time": execution_time, "last_updated": time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()) } def _extract_market_data(self, text): """Extract market metrics from analysis""" market_data = { "current_price": "N/A", "market_cap": "N/A", "price_change_24h": "N/A", "price_change_7d": "N/A", "volume_24h": "N/A", "market_dominance": "N/A" } # Extract price price_match = re.search(r'\$([0-9,]+\.?[0-9]*)', text) if price_match: market_data["current_price"] = f"${price_match.group(1)}" # Extract market cap mcap_match = re.search(r'market cap[:\s]+\$([0-9,]+\.?[0-9]*[BMK]?)', text, re.IGNORECASE) if mcap_match: market_data["market_cap"] = f"${mcap_match.group(1)}" # Extract percentage changes change_24h = re.search(r'24h?[:\s]*([+-]?[0-9]+\.?[0-9]*%)', text, re.IGNORECASE) if change_24h: market_data["price_change_24h"] = change_24h.group(1) change_7d = re.search(r'7d?[:\s]*([+-]?[0-9]+\.?[0-9]*%)', text, re.IGNORECASE) if change_7d: market_data["price_change_7d"] = change_7d.group(1) return market_data def _extract_technical_data(self, text): """Extract technical indicators""" technical_data = { "rsi": "N/A", "rsi_signal": "Neutral", "moving_average_7d": "N/A", "moving_average_50d": "N/A", "trend": "Neutral", "support_level": "N/A", "resistance_level": "N/A" } # Extract RSI rsi_match = re.search(r'RSI[:\s]*([0-9]+\.?[0-9]*)', text, re.IGNORECASE) if rsi_match: rsi_value = float(rsi_match.group(1)) technical_data["rsi"] = str(rsi_value) if rsi_value > 70: technical_data["rsi_signal"] = "Overbought" elif rsi_value < 30: technical_data["rsi_signal"] = "Oversold" else: technical_data["rsi_signal"] = "Neutral" # Extract moving averages ma_match = re.search(r'(?:7-day )?MA[:\s]*\$([0-9,]+\.?[0-9]*)', text, re.IGNORECASE) if ma_match: technical_data["moving_average_7d"] = f"${ma_match.group(1)}" # Determine trend if "bullish" in text.lower() or "uptrend" in text.lower(): technical_data["trend"] = "Bullish" elif "bearish" in text.lower() or "downtrend" in text.lower(): technical_data["trend"] = "Bearish" return technical_data def _extract_sentiment_analysis(self, text): """Extract differentiated sentiment analysis""" # Default to varied sentiments for demonstration sentiment_data = { "overall": "Neutral", "social_media": "Neutral", "news": "Neutral", "community": "Neutral" } # Extract overall sentiment if re.search(r'overall.*positive|positive.*overall', text, re.IGNORECASE): sentiment_data["overall"] = "Positive" elif re.search(r'overall.*negative|negative.*overall', text, re.IGNORECASE): sentiment_data["overall"] = "Negative" elif "bullish" in text.lower(): sentiment_data["overall"] = "Positive" elif "bearish" in text.lower(): sentiment_data["overall"] = "Negative" # Extract social media sentiment if re.search(r'social.*positive|twitter.*positive|reddit.*positive', text, re.IGNORECASE): sentiment_data["social_media"] = "Positive" elif re.search(r'social.*negative|twitter.*negative|reddit.*negative', text, re.IGNORECASE): sentiment_data["social_media"] = "Negative" elif re.search(r'social.*bullish|community.*optimistic', text, re.IGNORECASE): sentiment_data["social_media"] = "Positive" # Extract news sentiment if re.search(r'news.*positive|headlines.*positive|media.*positive', text, re.IGNORECASE): sentiment_data["news"] = "Positive" elif re.search(r'news.*negative|headlines.*negative|regulatory.*concern', text, re.IGNORECASE): sentiment_data["news"] = "Negative" # Extract community sentiment if re.search(r'community.*positive|development.*active|adoption.*growing', text, re.IGNORECASE): sentiment_data["community"] = "Positive" elif re.search(r'community.*negative|development.*slow|adoption.*declining', text, re.IGNORECASE): sentiment_data["community"] = "Negative" elif re.search(r'institutional.*adoption|enterprise.*adoption', text, re.IGNORECASE): sentiment_data["community"] = "Positive" return sentiment_data def _extract_recommendation(self, text): """Extract investment recommendation with reasoning""" recommendation = { "action": "HOLD", "confidence": "Medium", "reasoning": "Standard analysis completed", "time_horizon": "Medium-term", "risk_level": "Moderate" } # Extract recommendation if re.search(r'recommendation[:\s]*BUY|BUY.*recommendation', text, re.IGNORECASE): recommendation["action"] = "BUY" elif re.search(r'recommendation[:\s]*SELL|SELL.*recommendation', text, re.IGNORECASE): recommendation["action"] = "SELL" # Extract confidence if re.search(r'confidence[:\s]*high|high.*confidence', text, re.IGNORECASE): recommendation["confidence"] = "High" elif re.search(r'confidence[:\s]*low|low.*confidence', text, re.IGNORECASE): recommendation["confidence"] = "Low" # Extract reasoning reason_match = re.search(r'(?:reason|reasoning)[:\s]*([^.]+)', text, re.IGNORECASE) if reason_match: recommendation["reasoning"] = reason_match.group(1).strip() return recommendation def _extract_risk_assessment(self, text): """Extract risk assessment""" if re.search(r'high.*risk|risk.*high|volatile|risky', text, re.IGNORECASE): return "High Risk" elif re.search(r'low.*risk|risk.*low|stable|conservative', text, re.IGNORECASE): return "Low Risk" else: return "Moderate Risk" def _clean_summary(self, text): """Clean and format the summary""" # Remove excess whitespace and format summary = re.sub(r'\s+', ' ', text).strip() # Truncate if too long if len(summary) > 1000: summary = summary[:1000] + "..." return summary def _get_fallback_market_data(self): return { "current_price": "N/A", "market_cap": "N/A", "price_change_24h": "N/A", "price_change_7d": "N/A", "volume_24h": "N/A", "market_dominance": "N/A" } def _get_fallback_technical_data(self): return { "rsi": "N/A", "rsi_signal": "Neutral", "moving_average_7d": "N/A", "moving_average_50d": "N/A", "trend": "Neutral", "support_level": "N/A", "resistance_level": "N/A" } def _get_fallback_sentiment(self): return { "overall": "Neutral", "social_media": "Neutral", "news": "Neutral", "community": "Neutral" } if __name__ == "__main__": print("## Welcome to Enhanced Crypto Analysis Crew") print('-------------------------------') crypto = input(dedent(""" What is the cryptocurrency you want to analyze? """)) crypto_crew = CryptoCrew(crypto) result = crypto_crew.run() print("\n\n########################") print("## Here is the Enhanced Report") print("########################\n") print(json.dumps(result, indent=2))