menikev commited on
Commit
487144c
·
verified ·
1 Parent(s): b014f3b

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +230 -44
main.py CHANGED
@@ -1,23 +1,19 @@
1
  import asyncio
2
- import time # <-- Add this line to import the time module
 
 
3
  from crewai import Crew, Process
4
  from textwrap import dedent
5
- import json
6
  from crypto_analysis_agents import CryptoAnalysisAgents
7
- from crypto__analysis_tasks import CryptoAnalysisTasks # <-- Corrected the import name based on previous feedback
8
 
9
  class CryptoCrew:
10
  def __init__(self, crypto):
11
  self.crypto = crypto
12
- # Initialize agents once for reuse
13
  self.agents_instance = CryptoAnalysisAgents()
14
  self.tasks_instance = CryptoAnalysisTasks()
15
 
16
  def run(self):
17
- # Using asyncio.run() is fine for a standalone script,
18
- # but can cause issues in environments that already have an event loop (like Streamlit).
19
- # It's better to manage the loop explicitly when integrating.
20
- # However, for now, we'll keep it as is since your app.py calls it simply.
21
  return asyncio.run(self.run_async())
22
 
23
  async def run_async(self):
@@ -37,65 +33,255 @@ class CryptoCrew:
37
  self.tasks_instance.recommend(advisor, self.crypto)
38
  ]
39
 
40
- # Optimized crew configuration
41
  crew = Crew(
42
  agents=[market_analyst, technical_analyst, advisor],
43
  tasks=tasks,
44
- verbose=False,
45
  process=Process.sequential,
46
- max_iterations=5,
47
- task_timeout=60
48
  )
49
 
50
  # Run crew
51
  result = await asyncio.to_thread(crew.kickoff)
52
-
53
  end_time = time.time()
54
- print(f"Analysis completed in {end_time - start_time:.2f} seconds")
55
 
56
- return self.parse_result(result)
 
57
  except Exception as e:
58
- # When an exception occurs, calculate duration up to the point of failure
59
  execution_time = time.time() - start_time
60
  return {
61
  "summary": f"Analysis failed: {str(e)}",
62
- "sentiment": {"overall": "Neutral", "confidence": "Low"},
63
- "recommendation": "HOLD",
64
- "execution_time": execution_time
 
 
 
65
  }
66
 
67
- def parse_result(self, result):
68
- # Enhanced parsing logic
69
  result_str = str(result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- # Extract key information using simple parsing
72
- sentiment = "Neutral"
73
- recommendation = "HOLD"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- if "Positive" in result_str or "bullish" in result_str.lower():
76
- sentiment = "Positive"
77
- elif "Negative" in result_str or "bearish" in result_str.lower():
78
- sentiment = "Negative"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- if "BUY" in result_str:
81
- recommendation = "BUY"
82
- elif "SELL" in result_str:
83
- recommendation = "SELL"
 
 
 
 
 
 
 
 
 
 
 
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  return {
86
- "summary": result_str,
87
- "sentiment": {
88
- "overall": sentiment,
89
- "social_media": sentiment,
90
- "news": sentiment,
91
- "community": sentiment
92
- },
93
- "recommendation": recommendation,
94
- "confidence": "Medium"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
  if __name__ == "__main__":
98
- print("## Welcome to Crypto Analysis Crew")
99
  print('-------------------------------')
100
  crypto = input(dedent("""
101
  What is the cryptocurrency you want to analyze?
@@ -103,6 +289,6 @@ if __name__ == "__main__":
103
  crypto_crew = CryptoCrew(crypto)
104
  result = crypto_crew.run()
105
  print("\n\n########################")
106
- print("## Here is the Report")
107
  print("########################\n")
108
- print(json.dumps(result, indent=2))
 
1
  import asyncio
2
+ import time
3
+ import re
4
+ import json
5
  from crewai import Crew, Process
6
  from textwrap import dedent
 
7
  from crypto_analysis_agents import CryptoAnalysisAgents
8
+ from crypto__analysis_tasks import CryptoAnalysisTasks
9
 
10
  class CryptoCrew:
11
  def __init__(self, crypto):
12
  self.crypto = crypto
 
13
  self.agents_instance = CryptoAnalysisAgents()
14
  self.tasks_instance = CryptoAnalysisTasks()
15
 
16
  def run(self):
 
 
 
 
17
  return asyncio.run(self.run_async())
18
 
19
  async def run_async(self):
 
33
  self.tasks_instance.recommend(advisor, self.crypto)
34
  ]
35
 
36
+ # Enhanced crew configuration
37
  crew = Crew(
38
  agents=[market_analyst, technical_analyst, advisor],
39
  tasks=tasks,
40
+ verbose=True, # Enable for better debugging
41
  process=Process.sequential,
42
+ max_iterations=8,
43
+ task_timeout=90
44
  )
45
 
46
  # Run crew
47
  result = await asyncio.to_thread(crew.kickoff)
 
48
  end_time = time.time()
 
49
 
50
+ return self.parse_result(result, end_time - start_time)
51
+
52
  except Exception as e:
 
53
  execution_time = time.time() - start_time
54
  return {
55
  "summary": f"Analysis failed: {str(e)}",
56
+ "market_data": self._get_fallback_market_data(),
57
+ "technical_data": self._get_fallback_technical_data(),
58
+ "sentiment": self._get_fallback_sentiment(),
59
+ "recommendation": {"action": "HOLD", "confidence": "Low", "reasoning": "Analysis incomplete"},
60
+ "execution_time": execution_time,
61
+ "risk_assessment": "High - Analysis failed"
62
  }
63
 
64
+ def parse_result(self, result, execution_time):
65
+ """Enhanced parsing to extract structured data from LLM responses"""
66
  result_str = str(result)
67
+
68
+ # Extract market data
69
+ market_data = self._extract_market_data(result_str)
70
+
71
+ # Extract technical analysis
72
+ technical_data = self._extract_technical_data(result_str)
73
+
74
+ # Extract detailed sentiment analysis
75
+ sentiment_analysis = self._extract_sentiment_analysis(result_str)
76
+
77
+ # Extract recommendation
78
+ recommendation = self._extract_recommendation(result_str)
79
+
80
+ # Extract risk assessment
81
+ risk_assessment = self._extract_risk_assessment(result_str)
82
+
83
+ return {
84
+ "summary": self._clean_summary(result_str),
85
+ "market_data": market_data,
86
+ "technical_data": technical_data,
87
+ "sentiment": sentiment_analysis,
88
+ "recommendation": recommendation,
89
+ "risk_assessment": risk_assessment,
90
+ "execution_time": execution_time,
91
+ "last_updated": time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime())
92
+ }
93
 
94
+ def _extract_market_data(self, text):
95
+ """Extract market metrics from analysis"""
96
+ market_data = {
97
+ "current_price": "N/A",
98
+ "market_cap": "N/A",
99
+ "price_change_24h": "N/A",
100
+ "price_change_7d": "N/A",
101
+ "volume_24h": "N/A",
102
+ "market_dominance": "N/A"
103
+ }
104
+
105
+ # Extract price
106
+ price_match = re.search(r'\$([0-9,]+\.?[0-9]*)', text)
107
+ if price_match:
108
+ market_data["current_price"] = f"${price_match.group(1)}"
109
+
110
+ # Extract market cap
111
+ mcap_match = re.search(r'market cap[:\s]+\$([0-9,]+\.?[0-9]*[BMK]?)', text, re.IGNORECASE)
112
+ if mcap_match:
113
+ market_data["market_cap"] = f"${mcap_match.group(1)}"
114
+
115
+ # Extract percentage changes
116
+ change_24h = re.search(r'24h?[:\s]*([+-]?[0-9]+\.?[0-9]*%)', text, re.IGNORECASE)
117
+ if change_24h:
118
+ market_data["price_change_24h"] = change_24h.group(1)
119
+
120
+ change_7d = re.search(r'7d?[:\s]*([+-]?[0-9]+\.?[0-9]*%)', text, re.IGNORECASE)
121
+ if change_7d:
122
+ market_data["price_change_7d"] = change_7d.group(1)
123
+
124
+ return market_data
125
+
126
+ def _extract_technical_data(self, text):
127
+ """Extract technical indicators"""
128
+ technical_data = {
129
+ "rsi": "N/A",
130
+ "rsi_signal": "Neutral",
131
+ "moving_average_7d": "N/A",
132
+ "moving_average_50d": "N/A",
133
+ "trend": "Neutral",
134
+ "support_level": "N/A",
135
+ "resistance_level": "N/A"
136
+ }
137
+
138
+ # Extract RSI
139
+ rsi_match = re.search(r'RSI[:\s]*([0-9]+\.?[0-9]*)', text, re.IGNORECASE)
140
+ if rsi_match:
141
+ rsi_value = float(rsi_match.group(1))
142
+ technical_data["rsi"] = str(rsi_value)
143
+ if rsi_value > 70:
144
+ technical_data["rsi_signal"] = "Overbought"
145
+ elif rsi_value < 30:
146
+ technical_data["rsi_signal"] = "Oversold"
147
+ else:
148
+ technical_data["rsi_signal"] = "Neutral"
149
+
150
+ # Extract moving averages
151
+ ma_match = re.search(r'(?:7-day )?MA[:\s]*\$([0-9,]+\.?[0-9]*)', text, re.IGNORECASE)
152
+ if ma_match:
153
+ technical_data["moving_average_7d"] = f"${ma_match.group(1)}"
154
+
155
+ # Determine trend
156
+ if "bullish" in text.lower() or "uptrend" in text.lower():
157
+ technical_data["trend"] = "Bullish"
158
+ elif "bearish" in text.lower() or "downtrend" in text.lower():
159
+ technical_data["trend"] = "Bearish"
160
+
161
+ return technical_data
162
 
163
+ def _extract_sentiment_analysis(self, text):
164
+ """Extract differentiated sentiment analysis"""
165
+ # Default to varied sentiments for demonstration
166
+ sentiment_data = {
167
+ "overall": "Neutral",
168
+ "social_media": "Neutral",
169
+ "news": "Neutral",
170
+ "community": "Neutral"
171
+ }
172
+
173
+ # Extract overall sentiment
174
+ if re.search(r'overall.*positive|positive.*overall', text, re.IGNORECASE):
175
+ sentiment_data["overall"] = "Positive"
176
+ elif re.search(r'overall.*negative|negative.*overall', text, re.IGNORECASE):
177
+ sentiment_data["overall"] = "Negative"
178
+ elif "bullish" in text.lower():
179
+ sentiment_data["overall"] = "Positive"
180
+ elif "bearish" in text.lower():
181
+ sentiment_data["overall"] = "Negative"
182
+
183
+ # Extract social media sentiment
184
+ if re.search(r'social.*positive|twitter.*positive|reddit.*positive', text, re.IGNORECASE):
185
+ sentiment_data["social_media"] = "Positive"
186
+ elif re.search(r'social.*negative|twitter.*negative|reddit.*negative', text, re.IGNORECASE):
187
+ sentiment_data["social_media"] = "Negative"
188
+ elif re.search(r'social.*bullish|community.*optimistic', text, re.IGNORECASE):
189
+ sentiment_data["social_media"] = "Positive"
190
+
191
+ # Extract news sentiment
192
+ if re.search(r'news.*positive|headlines.*positive|media.*positive', text, re.IGNORECASE):
193
+ sentiment_data["news"] = "Positive"
194
+ elif re.search(r'news.*negative|headlines.*negative|regulatory.*concern', text, re.IGNORECASE):
195
+ sentiment_data["news"] = "Negative"
196
+
197
+ # Extract community sentiment
198
+ if re.search(r'community.*positive|development.*active|adoption.*growing', text, re.IGNORECASE):
199
+ sentiment_data["community"] = "Positive"
200
+ elif re.search(r'community.*negative|development.*slow|adoption.*declining', text, re.IGNORECASE):
201
+ sentiment_data["community"] = "Negative"
202
+ elif re.search(r'institutional.*adoption|enterprise.*adoption', text, re.IGNORECASE):
203
+ sentiment_data["community"] = "Positive"
204
+
205
+ return sentiment_data
206
 
207
+ def _extract_recommendation(self, text):
208
+ """Extract investment recommendation with reasoning"""
209
+ recommendation = {
210
+ "action": "HOLD",
211
+ "confidence": "Medium",
212
+ "reasoning": "Standard analysis completed",
213
+ "time_horizon": "Medium-term",
214
+ "risk_level": "Moderate"
215
+ }
216
+
217
+ # Extract recommendation
218
+ if re.search(r'recommendation[:\s]*BUY|BUY.*recommendation', text, re.IGNORECASE):
219
+ recommendation["action"] = "BUY"
220
+ elif re.search(r'recommendation[:\s]*SELL|SELL.*recommendation', text, re.IGNORECASE):
221
+ recommendation["action"] = "SELL"
222
 
223
+ # Extract confidence
224
+ if re.search(r'confidence[:\s]*high|high.*confidence', text, re.IGNORECASE):
225
+ recommendation["confidence"] = "High"
226
+ elif re.search(r'confidence[:\s]*low|low.*confidence', text, re.IGNORECASE):
227
+ recommendation["confidence"] = "Low"
228
+
229
+ # Extract reasoning
230
+ reason_match = re.search(r'(?:reason|reasoning)[:\s]*([^.]+)', text, re.IGNORECASE)
231
+ if reason_match:
232
+ recommendation["reasoning"] = reason_match.group(1).strip()
233
+
234
+ return recommendation
235
+
236
+ def _extract_risk_assessment(self, text):
237
+ """Extract risk assessment"""
238
+ if re.search(r'high.*risk|risk.*high|volatile|risky', text, re.IGNORECASE):
239
+ return "High Risk"
240
+ elif re.search(r'low.*risk|risk.*low|stable|conservative', text, re.IGNORECASE):
241
+ return "Low Risk"
242
+ else:
243
+ return "Moderate Risk"
244
+
245
+ def _clean_summary(self, text):
246
+ """Clean and format the summary"""
247
+ # Remove excess whitespace and format
248
+ summary = re.sub(r'\s+', ' ', text).strip()
249
+ # Truncate if too long
250
+ if len(summary) > 1000:
251
+ summary = summary[:1000] + "..."
252
+ return summary
253
+
254
+ def _get_fallback_market_data(self):
255
  return {
256
+ "current_price": "N/A",
257
+ "market_cap": "N/A",
258
+ "price_change_24h": "N/A",
259
+ "price_change_7d": "N/A",
260
+ "volume_24h": "N/A",
261
+ "market_dominance": "N/A"
262
+ }
263
+
264
+ def _get_fallback_technical_data(self):
265
+ return {
266
+ "rsi": "N/A",
267
+ "rsi_signal": "Neutral",
268
+ "moving_average_7d": "N/A",
269
+ "moving_average_50d": "N/A",
270
+ "trend": "Neutral",
271
+ "support_level": "N/A",
272
+ "resistance_level": "N/A"
273
+ }
274
+
275
+ def _get_fallback_sentiment(self):
276
+ return {
277
+ "overall": "Neutral",
278
+ "social_media": "Neutral",
279
+ "news": "Neutral",
280
+ "community": "Neutral"
281
  }
282
 
283
  if __name__ == "__main__":
284
+ print("## Welcome to Enhanced Crypto Analysis Crew")
285
  print('-------------------------------')
286
  crypto = input(dedent("""
287
  What is the cryptocurrency you want to analyze?
 
289
  crypto_crew = CryptoCrew(crypto)
290
  result = crypto_crew.run()
291
  print("\n\n########################")
292
+ print("## Here is the Enhanced Report")
293
  print("########################\n")
294
+ print(json.dumps(result, indent=2))