File size: 11,572 Bytes
095163f
487144c
 
 
24a1671
3af55de
d5baf5f
487144c
3af55de
 
 
 
cf65c76
 
3af55de
3078761
 
 
871ea65
cf65c76
2022169
095163f
cf65c76
 
 
 
 
 
 
 
 
 
 
 
 
487144c
cf65c76
 
 
487144c
cf65c76
487144c
 
cf65c76
 
 
3078761
cf65c76
 
487144c
 
3078761
2022169
cf65c76
 
487144c
 
 
 
 
 
cf65c76
8afb178
487144c
 
cf65c76
487144c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2022169
487144c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2022169
487144c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2022169
487144c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2022169
487144c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cf65c76
487144c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bb5a46
 
3af55de
487144c
3af55de
095163f
 
 
3af55de
871ea65
3af55de
487144c
3af55de
487144c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
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))