├── .gitignore ├── Crypto_Bot_Analyzer ├── DejaVuSansCondensed.ttf ├── README.md ├── agents.py ├── analysis_report .pdf ├── coin_screenshot.jpeg ├── gauge_1.jpeg ├── gauge_2.jpeg ├── gauge_3.jpeg ├── line_chart.jpeg ├── main.py ├── points.txt ├── requirements.txt ├── sma.jpeg ├── tasks.py ├── tools.py └── trained_agents_data.pkl /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .myenv 3 | .env 4 | -------------------------------------------------------------------------------- /Crypto_Bot_Analyzer: -------------------------------------------------------------------------------- 1 | Cryptocurrency Bot Analyzer: 2 | This tool allows users to simply enter the name of a cryptocurrency, and the analyzer generates a comprehensive report consisting of the following components: 3 | 4 | 1. Market Analysis: This section determines the intrinsic value of the selected coin, providing insights into its overall market position. 5 | 6 | 2. Technical Analysis: The analyzer accesses a cryptocurrency stock platform to capture a screenshot of the 1-month candlestick chart. It then evaluates this chart to deliver detailed insights, including: 7 | - Trend Strength 8 | - Support and Resistance Levels 9 | - Candlestick Patterns 10 | - Moving Averages 11 | - Volume Analysis 12 | - Risk Assessment 13 | - Summary and Recommendations 14 | 15 | 3. Sentiment Analysis: This feature extracts and analyzes the latest news and top stories related to the coin, assessing whether the market sentiment is positive, neutral, or negative based on the gathered information. 16 | 17 | 4. Final Report: After completing the analyses, the tool generates a comprehensive report summarizing all findings. Users can easily download this report as a PDF with a simple click of a button. 18 | 19 | 20 | -------------------------------------------------------------------------------- /DejaVuSansCondensed.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/DejaVuSansCondensed.ttf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Crypto Bot Analyzer Project 2 | 3 | This project uses Crew AI to analyze cryptocurrency coin input by the user through three specialized agents and create a comprehensive report based on it analyses. The agents involved are Market_Analysis_Agent, Technical_Analysis_Agent, Sentiment_Analysis_Agent, and Write_Report_Agent. Each agent is tasked with specific functions and uses designated tools to fulfill their roles. 4 | 5 | ## Agents and Their Tasks 6 | 7 | ### 1. Market_Analysis_Agent 8 | 9 | Analyze the market of the given crypto coin. 10 | 11 | **Task:** 12 | - Obtain a URL using the `Extract_url` tool. 13 | - Fetch real-time data from the designated website using the `Scrap_data` tool. 14 | - Generate a report using the fetched content. 15 | 16 | **Tools:** 17 | - `Extract_url`: Extracts the URL needed for analysis. 18 | - `Scrap_data`: Scrapes real-time data from the extracted URL. 19 | 20 | ### 2. Technical_Analysis_Agent 21 | 22 | Analyze the crypto coin's candlestick chart from Binance. 23 | 24 | **Task:** 25 | - Extract a symbol from the provided data. 26 | - Take a screenshot of the candlestick chart from the given Binance website using the `Take_ss` tool. 27 | - Analyze candlestick charts to understand market sentiment and price movements. 28 | 29 | **Tools:** 30 | - `Take_ss`: Open Binance Website using selenium and takes a screenshot of the candlestick chart. 31 | - `Get_Pic_Content`: Analyzes the screenshot to extract relevant information. 32 | 33 | ### 3. Sentiment_Analysis_Agent 34 | 35 | Analyze the market of the coin from the news and articles rencently published on it. 36 | 37 | **Task:** 38 | - Use the `search` tool to find recent blogs and news websites(articles) related to the given coin name. 39 | - Extract relevant content from these sources using the `find_similar` and `get_contents` tools. 40 | 41 | **Tools:** 42 | - `search`: Finds recent websites and blogs. 43 | - `find_similar`: Identifies similar content related to the search query. 44 | - `get_contents`: Extracts content from the identified websites. 45 | 46 | ### 4. Write_Report_Agent 47 | 48 | Create an extensive report on the cryptocurrency and generate a downloadable PDF document. 49 | 50 | **Task:** 51 | - Create a detailed report by integrating analyses from Market_Analysis_Agent, Technical_Analysis_Agent, and Sentiment_Analysis_Agent. 52 | - Provide an additional comprehensive analysis based on the integrated data. 53 | 54 | ## How to Run 55 | 56 | 1. **Setup Environment:** 57 | Ensure you have Python installed and set up a virtual environment. 58 | 59 | ```bash 60 | python -m venv venv 61 | source venv/bin/activate # On Windows use `venv\Scripts\activate` 62 | ``` 63 | 64 | 2. **Install Dependencies:** 65 | Install the required packages using pip. 66 | 67 | ```bash 68 | pip install -r requirements.txt 69 | ``` 70 | 71 | 3. **Run the Main Script:** 72 | 73 | ```bash 74 | streamlit run main.py 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /agents.py: -------------------------------------------------------------------------------- 1 | from textwrap import dedent 2 | from crewai import Agent 3 | from tools import CryptoTradingTools 4 | from langchain_openai import ChatOpenAI 5 | import os 6 | from dotenv import load_dotenv 7 | 8 | load_dotenv() 9 | 10 | 11 | class CryptoTradingAgents(): 12 | def __init__(self) -> None: 13 | openai_api_key = os.getenv("OPENAI_API_KEY") 14 | self.llm = ChatOpenAI(model_name="gpt-4-1106-preview", temperature=0.3, openai_api_key=openai_api_key) 15 | self.llm1 = ChatOpenAI(model_name="gpt-4o", temperature=0.3, openai_api_key=openai_api_key) 16 | self.llm2 = ChatOpenAI(model_name="gpt-4-turbo", temperature=0.3, openai_api_key=openai_api_key) 17 | 18 | 19 | def Market_Analysis_Agent(self): 20 | return Agent( 21 | llm=self.llm, 22 | role="Cryptocurrency Market Analysis Specialist", 23 | goal="Perform a comprehensive market analysis for the specified cryptocurrency.", 24 | backstory=dedent(f""" 25 | You are a fundamental analyzer of cryptocurrency with a deep understanding of the cryptocurrency landscape. Your role involves 26 | utilizing an API to fetch real-time data from a designated website. Your expertise 27 | lies in transforming this data into precise required values. Then generate a response using that values. 28 | """), 29 | tools=[CryptoTradingTools.Extract_url, CryptoTradingTools.Scrap_data], 30 | verbose=True 31 | ) 32 | 33 | def Technical_Analysis_Agent(self): 34 | return Agent( 35 | llm = self.llm1, 36 | role = "Cryptocurrency Chart Analysis Specialist", 37 | goal = "Your goal or task is to perform a comprehensive Chart analysis for the specified cryptocurrency from its candlestick chart screenshot.", 38 | backstory = dedent(f""" 39 | You an automate the process of analyzing technical indicators (e.g.RSI, MACD) and 40 | chart patterns to identify trends and potential buy or sell signals in cryptocurrency price charts. 41 | These models can help traders make decisions based on technical analysis."""), 42 | 43 | tools = [CryptoTradingTools.Create_Candlestick, CryptoTradingTools.Get_Pic_Content], 44 | 45 | verbose = True 46 | ) 47 | 48 | def Moving_Average_Analysis_Agent(self): 49 | return Agent( 50 | llm=self.llm1, 51 | role="Cryptocurrency Moving Average Specialist", 52 | goal="Your goal or task is to perform a comprehensive analysis on the simple moving average for the specified cryptocurrency from its chart screenshot.", 53 | backstory=dedent(""" 54 | As a Cryptocurrency Moving Average Specialist, you possess deep expertise in analyzing and interpreting moving average charts for cryptocurrencies. Your role involves evaluating the performance of a specified cryptocurrency based on its simple moving average (SMA) chart, which is provided as a screenshot. 55 | 56 | You are adept at identifying key trends, patterns, and anomalies within the SMA data. Your analysis should consider various factors such as crossovers, trend direction, and historical performance. You will use this analysis to make informed recommendations on potential buy or sell actions based on the observed trends and average movements. 57 | 58 | Additionally, you are skilled in contextualizing your findings within broader market trends and offering actionable insights to help in strategic decision-making. Your ultimate goal is to provide a detailed and accurate assessment of the cryptocurrency's performance as reflected by its simple moving average. 59 | """), 60 | tools=[CryptoTradingTools.Create_Sma, CryptoTradingTools.Get_Sma_Content], 61 | verbose=True 62 | ) 63 | def Sentiment_Analysis_Agent(self): 64 | return Agent( 65 | 66 | llm = self.llm, 67 | role = "Cryptocurrency Sentiment Analysis Specialist", 68 | goal = "Your goal is to analyze latest news articles, social media posts, forums, and other sources of textual data", 69 | backstory = dedent(f""" 70 | You use an api to get the news content. Then seperate top stores and recent news headings 71 | from it and later make a report from that content. 72 | You're widely accepted as the best cryptocurrency analyst that 73 | understands the market and have tracked every asset for more than 10 years. 74 | You understand news, their titles and information, but you look at those with a 75 | healthy dose of skepticism."""), 76 | tools=[CryptoTradingTools.extract_contents], 77 | verbose = True 78 | ) 79 | 80 | def Report_Agent(self): 81 | return Agent( 82 | 83 | llm = self.llm, 84 | role= "Cryptocurrency Analysis Report Writer", 85 | goal= "make an insightful, compelling and long report based on the previous context.", 86 | backstory = dedent(f"""You are an expert when it comes to report writing and can generate 87 | of depth, accuracy, and actionable insights using the content from the previous agent"""), 88 | 89 | verbose = True 90 | ) 91 | 92 | 93 | def Gauge_Agent1(self): 94 | return Agent( 95 | llm = self.llm, 96 | role = "You create a gauge chart for the specified cryptocurrency.", 97 | goal = "Create a gauge chart for the specified cryptocurrency.", 98 | backstory = dedent(""" 99 | You are an expert in creating gauge charts. You check the response generated by the 100 | technical indicators and whether the response is Strong Sell, Sell, Neutral, 101 | Buy, or Strong Buy. Then, create a gauge chart based on the response. 102 | """), 103 | tools = [CryptoTradingTools.generate_gauge], 104 | verbose = True 105 | ) 106 | 107 | def Gauge_Agent2(self): 108 | return Agent( 109 | llm = self.llm, 110 | role = "You create a gauge chart for the specified cryptocurrency.", 111 | goal = "Create a gauge chart for the specified cryptocurrency.", 112 | backstory = dedent(""" 113 | You are an expert in creating gauge charts. You check the response generated by the 114 | moving analysis agent and whether the response is Strong Sell, Sell, Neutral, 115 | Buy, or Strong Buy. Then, create a gauge chart based on the response. 116 | """), 117 | tools = [CryptoTradingTools.generate_gauge], 118 | verbose = True 119 | ) 120 | 121 | def Gauge_Agent3(self): 122 | return Agent( 123 | llm = self.llm, 124 | role = "You create a gauge chart for the specified cryptocurrency from report agent.", 125 | goal = "Create a gauge chart for the specified cryptocurrency from report agent.", 126 | backstory = dedent(""" 127 | You are an expert in creating gauge charts. You check the response generated by the 128 | write report and whether the response is Strong Sell, Sell, Neutral, 129 | Buy, or Strong Buy. Then, create a gauge chart based on the response. 130 | """), 131 | tools = [CryptoTradingTools.generate_gauge], 132 | verbose =True 133 | ) 134 | 135 | def Closing_Price_Analysis_Agent(self): 136 | return Agent( 137 | llm = self.llm2, 138 | role = "Create a closing analysis chart for a specified cryptocurrency.", 139 | goal = "Generate a closing analysis chart for the given cryptocurrency.", 140 | backstory = dedent(""" 141 | You are an expert in generating closing analysis charts using an API. 142 | First, create a line chart based on the provided data. Analyze this line chart and 143 | summarize the findings in Dict format. 144 | Next, using the points from the DICT summary, create a new closing analysis chart 145 | with these points plotted on it. 146 | """), 147 | tools = [CryptoTradingTools.generate_line_chart,CryptoTradingTools.analyze_line_chart ,CryptoTradingTools.generate_new_line_chart], 148 | verbose = True 149 | ) 150 | 151 | 152 | -------------------------------------------------------------------------------- /analysis_report .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/analysis_report .pdf -------------------------------------------------------------------------------- /coin_screenshot.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/coin_screenshot.jpeg -------------------------------------------------------------------------------- /gauge_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/gauge_1.jpeg -------------------------------------------------------------------------------- /gauge_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/gauge_2.jpeg -------------------------------------------------------------------------------- /gauge_3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/gauge_3.jpeg -------------------------------------------------------------------------------- /line_chart.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/line_chart.jpeg -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from crewai import Crew 2 | import streamlit as st 3 | from fpdf import FPDF 4 | from PIL import Image 5 | from agents import CryptoTradingAgents 6 | from tasks import CryptoTradingTasks 7 | from PIL import Image 8 | import os 9 | 10 | 11 | def crop_image(number): 12 | image_path = 'gauge.jpeg' 13 | image = Image.open(image_path) 14 | 15 | # Define the crop area (left, upper, right, lower) 16 | crop_box = (10, 10, 2700, 1700) 17 | 18 | # Crop the image 19 | cropped_image = image.crop(crop_box) 20 | 21 | # Save or display the cropped image 22 | cropped_image.save(f'gauge_{number}.jpeg') 23 | 24 | 25 | 26 | 27 | def main(): 28 | st.title("Cryptocurrency Analysis Report") 29 | 30 | coin_name = st.text_input("Enter the coin name:").encode('utf-8').decode('utf-8') 31 | 32 | 33 | if st.button("Run Analysis"): 34 | agents = CryptoTradingAgents() 35 | tasks = CryptoTradingTasks() 36 | file_path = "gauge.jpeg" 37 | 38 | Market_Analysis_Agent = agents.Market_Analysis_Agent() 39 | Technical_Analysis_Agent = agents.Technical_Analysis_Agent() 40 | Moving_Average_Analysis_Agent = agents.Moving_Average_Analysis_Agent() 41 | Closing_Price_Analysis_Agent = agents.Closing_Price_Analysis_Agent() 42 | Sentiment_Analysis_Agent = agents.Sentiment_Analysis_Agent() 43 | Report_Agent = agents.Report_Agent() 44 | Gauge_Agent1 = agents.Gauge_Agent1() 45 | Gauge_Agent2 = agents.Gauge_Agent2() 46 | Gauge_Agent3 = agents.Gauge_Agent3() 47 | 48 | Perform_Market_Analysis = tasks.Perform_Market_Analysis(Market_Analysis_Agent, coin_name) 49 | Perform_Chart_Analysis = tasks.Perform_Chart_Analysis(Technical_Analysis_Agent, coin_name) 50 | Moving_Average_Analysis = tasks.Moving_Average_Analysis(Moving_Average_Analysis_Agent, coin_name) 51 | Closing_Price_Analysis = tasks.Closing_Price_Analysis(Closing_Price_Analysis_Agent, coin_name) 52 | Get_News = tasks.Get_News(Sentiment_Analysis_Agent, coin_name) 53 | Write_Rport = tasks.Write_Rport(Report_Agent) 54 | Create_Gauge1 = tasks.Create_Gauge1(Gauge_Agent1) 55 | Create_Gauge2 = tasks.Create_Gauge2(Gauge_Agent2) 56 | Create_Gauge3 = tasks.Create_Gauge3(Gauge_Agent3) 57 | 58 | 59 | Create_Gauge1.context = [Perform_Chart_Analysis] 60 | Create_Gauge2.context = [Moving_Average_Analysis] 61 | Write_Rport.context = [Perform_Market_Analysis, Perform_Chart_Analysis, Get_News] 62 | Create_Gauge3.context = [Write_Rport] 63 | 64 | 65 | crew1 = Crew( 66 | 67 | agents=[Market_Analysis_Agent], 68 | tasks=[Perform_Market_Analysis], 69 | verbose=True 70 | 71 | ) 72 | 73 | result1 = crew1.kickoff() 74 | st.subheader("Market Analysis Results") 75 | st.write(result1) 76 | 77 | crew2 = Crew( 78 | 79 | agents=[Technical_Analysis_Agent], 80 | tasks=[Perform_Chart_Analysis], 81 | verbose=True 82 | 83 | ) 84 | 85 | result2 = crew2.kickoff() 86 | st.subheader("Technical Analysis Results") 87 | st.write(result2) 88 | image = Image.open("coin_screenshot.jpeg") 89 | st.image(image, caption='Technical Analysis', use_column_width=True) 90 | 91 | 92 | 93 | crew3 = Crew( 94 | 95 | agents=[Gauge_Agent1], 96 | tasks=[Create_Gauge1], 97 | verbose=True 98 | 99 | ) 100 | 101 | result3 = crew3.kickoff() 102 | st.subheader("Gauge Results") 103 | crop_image(1) 104 | image = Image.open("gauge_1.jpeg") 105 | st.image(image, caption='Gaugemeter for Technical Analysis', use_column_width=True) 106 | os.remove(file_path) 107 | 108 | 109 | crew4 = Crew( 110 | 111 | agents = [Moving_Average_Analysis_Agent], 112 | tasks = [Moving_Average_Analysis], 113 | verbose = True 114 | ) 115 | result4 = crew4.kickoff() 116 | st.subheader("Moving Average Analysis Results") 117 | st.write(result4) 118 | image = Image.open("sma.jpeg") 119 | st.image(image, caption='Moving Average Chart', use_column_width=True) 120 | 121 | 122 | crew5 = Crew( 123 | 124 | agents=[Gauge_Agent2], 125 | tasks=[Create_Gauge2], 126 | verbose=True 127 | 128 | ) 129 | 130 | result5 = crew5.kickoff() 131 | st.subheader("Gauge Results") 132 | st.write(result5) 133 | crop_image(2) 134 | image = Image.open("gauge_2.jpeg") 135 | st.image(image, caption='Gaugemeter for Moving Average', use_column_width=True) 136 | os.remove(file_path) 137 | 138 | crew6 = Crew( 139 | 140 | agents=[Closing_Price_Analysis_Agent], 141 | tasks=[Closing_Price_Analysis], 142 | verbose=True 143 | 144 | ) 145 | 146 | result6 = crew6.kickoff() 147 | st.subheader("Closing Chart Results") 148 | st.write(result6) 149 | image = Image.open("line_chart.jpeg") 150 | st.image(image, caption = 'Closing Chart', use_column_width=True) 151 | 152 | 153 | 154 | crew7 = Crew( 155 | 156 | agents=[Sentiment_Analysis_Agent], 157 | tasks=[Get_News], 158 | verbose=True 159 | 160 | ) 161 | 162 | result7 = crew7.kickoff() 163 | st.subheader("Sentiment Analysis Results") 164 | st.write(result7) 165 | 166 | crew8 = Crew( 167 | 168 | agents=[Report_Agent], 169 | tasks=[Write_Rport], 170 | verbose=True 171 | 172 | ) 173 | 174 | result8 = crew8.kickoff() 175 | st.subheader("Final Report") 176 | st.write(result8) 177 | 178 | crew9 = Crew( 179 | 180 | agents=[Gauge_Agent3], 181 | tasks=[Create_Gauge3], 182 | verbose=True 183 | 184 | ) 185 | 186 | result9 = crew9.kickoff() 187 | st.subheader("Gauge Results") 188 | st.write(result9) 189 | crop_image(3) 190 | image = Image.open("gauge_3.jpeg") 191 | st.image(image, caption='Gaugemeter for Summary', use_column_width=True) 192 | os.remove(file_path) 193 | 194 | 195 | # Save results to PDF 196 | pdf_file = save_to_pdf(result1, result2, result4, result5, result6, result7, result8, result9) 197 | st.success(f"Results saved to {pdf_file}") 198 | 199 | # Add download button 200 | with open(pdf_file, "rb") as f: 201 | pdf_data = f.read() 202 | 203 | st.download_button( 204 | label="Download PDF", 205 | data=pdf_data, 206 | file_name=pdf_file, 207 | mime="application/pdf", 208 | ) 209 | 210 | def save_to_pdf(result1, result2, result4, result5, result6, result7, result8, result9): 211 | pdf = FPDF() 212 | pdf.add_page() 213 | pdf.set_auto_page_break(auto=True, margin=15) 214 | pdf.add_font("DejaVu", "", "DejaVuSansCondensed.ttf", uni=True) 215 | pdf.set_font("DejaVu", size=12) 216 | 217 | def write_unicode(text): 218 | pdf.multi_cell(0, 10, text.encode('latin-1', 'replace').decode('latin-1')) 219 | 220 | write_unicode("Market Analysis Results:\n" + str(result1)) 221 | pdf.add_page() 222 | 223 | write_unicode("Technical Analysis Results:\n" + str(result2)) 224 | pdf.add_page() 225 | pdf.image("coin_screenshot.jpeg", x=10, y=pdf.get_y(), w=190) 226 | pdf.add_page() 227 | 228 | write_unicode("Gauge Results (Technical Analysis):\n") 229 | pdf.image("gauge_1.jpeg", x=10, y=pdf.get_y(), w=190) 230 | pdf.add_page() 231 | 232 | write_unicode("Moving Average Analysis Results:\n" + str(result4)) 233 | pdf.add_page() 234 | pdf.image("sma.jpeg", x=10, y=pdf.get_y(), w=190) 235 | pdf.add_page() 236 | 237 | write_unicode("Gauge Results (Moving Average):\n" + str(result5)) 238 | pdf.image("gauge_2.jpeg", x=10, y=pdf.get_y(), w=190) 239 | pdf.add_page() 240 | 241 | write_unicode("Closing Chart Results:\n" + str(result6)) 242 | pdf.add_page() 243 | pdf.image("line_chart.jpeg", x=10, y=pdf.get_y(), w=190) 244 | pdf.add_page() 245 | 246 | write_unicode("Sentiment Analysis Results:\n" + str(result7)) 247 | pdf.add_page() 248 | 249 | write_unicode("Final Report:\n" + str(result8)) 250 | pdf.add_page() 251 | write_unicode("Gauge Results (Summary):\n" + str(result9)) 252 | pdf.image("gauge_3.jpeg", x=10, y=pdf.get_y(), w=190) 253 | 254 | filename = "analysis_report.pdf" 255 | pdf.output(filename) 256 | return filename 257 | 258 | if __name__ == "__main__": 259 | main() 260 | -------------------------------------------------------------------------------- /points.txt: -------------------------------------------------------------------------------- 1 | { 2 | "support_price": 56000, 3 | "consolidation_points_price": 64000, 4 | "major_resistance_price": 68000, 5 | "psychological_break_price": 60000, 6 | "immediate_resistance": 62000 7 | } 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | langchain_community 3 | crewai 4 | google.generativeai 5 | exa_py 6 | langchain_google_genai 7 | fpdf 8 | langchain 9 | embedchain 10 | playwright 11 | beautifulsoup4 12 | selenium 13 | webdriver_manager 14 | pymupdf 15 | streamlit 16 | mplfinance 17 | plotly -------------------------------------------------------------------------------- /sma.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/sma.jpeg -------------------------------------------------------------------------------- /tasks.py: -------------------------------------------------------------------------------- 1 | from textwrap import dedent 2 | from crewai import Task 3 | 4 | class CryptoTradingTasks(): 5 | def Perform_Market_Analysis(self, agent, coin): 6 | return Task( 7 | description=dedent(f""" 8 | Your role involves obtaining a URL using a tool and fetching real-time data from a designated website using another tool. 9 | Continue this task until you successfully retrieve the content from the website; do not proceed to the next task until this is accomplished. 10 | Your expertise lies in extracting the following values from the retrieved content and generate a report using these: 11 | 1. Current Price(Live Price) and Percentage Change 12 | 2. Market Capitalization (MARKETCAP) 13 | 3. Circulating Supply 14 | 4. 24-Hour Trading Volume 15 | 5. Total Supply 16 | 6. Fully Diluted Valuation 17 | 7. 24-Hour High and Low Prices 18 | 8. All-Time High and Low Prices 19 | Print these values after extracting them. Ensure accuracy; the values will be provided in the website's content. 20 | Coin: {coin} 21 | """), 22 | expected_output=dedent(f""" 23 | Make a report using these values. 24 | Also tell about if the asset is undervalued or overvalued: 25 | 26 | 27 | 28 | """), 29 | agent=agent 30 | ) 31 | 32 | 33 | def Perform_Chart_Analysis(self, agent, coin): 34 | return Task( 35 | description= dedent(f""" 36 | Your role involves extracting a symbol and then create candlestick chart with volume 37 | sing a tool. You analyze candlestick charts to understand market sentiment 38 | and price movements. By interpreting the patterns formed by candlesticks, they can make informed predictions 39 | about future price directions. You assess the overall trend of the market (uptrend, downtrend, 40 | or sideways) by analyzing the candlestick patterns over various time frames. You can also detect 41 | crucial support and resistance levels by analyzing where prices have historically reversed or stalled. 42 | You can generate buy or sell signals based on predefined criteria and candlestick patterns. 43 | 44 | Coin: {coin} 45 | """), 46 | expected_output = dedent(f""" 47 | 48 | 1. Trend Analysis: 49 | - Identify the current trend (uptrend, downtrend, or sideways). 50 | - Determine trend strength and potential reversal points. 51 | 52 | 2. Support and Resistance Levels: 53 | - Identify major support and resistance levels. 54 | - Highlight any significant breakouts or breakdowns. 55 | 56 | 3. Candlestick Patterns: 57 | - Detect and interpret common candlestick patterns (e.g., Doji, Hammer, Engulfing patterns, Harami etc). 58 | - Provide insights on potential bullish or bearish signals based on these patterns. 59 | 60 | 61 | 5. Volume Analysis: 62 | - Analyze volume trends to confirm price movements. 63 | - Highlight any unusual volume spikes and their potential impact. 64 | 65 | 6. Risk Assessment: 66 | - Assess potential risks and provide suggestions for risk management (e.g., stop-loss levels). 67 | 68 | 7. Summary and Recommendations: 69 | - Summarize key findings from the analysis. 70 | - Provide actionable trading recommendations based on the analysis. 71 | 72 | 73 | Generate a comprehensive report from the analysis which includes: 74 | - Identification of the overall market trend (uptrend, downtrend, or sideways) across different time frames. 75 | - Key candlestick patterns detected and their interpretations. 76 | - Crucial support and resistance levels identified based on historical price reversals or stalls. 77 | - Buy or sell signals generated based on predefined criteria and candlestick patterns. 78 | - A summary of the potential future price directions with rationale. 79 | """), 80 | agent = agent 81 | ) 82 | 83 | 84 | def Moving_Average_Analysis(self, agent, coin): 85 | return Task( 86 | description=dedent(f""" 87 | Analyze the moving average chart for the specified cryptocurrency, {coin}. 88 | The task involves evaluating the simple moving average (SMA) data presented in the chart screenshot for {coin}. 89 | 90 | Your analysis should include: 91 | - Identifying key trends and patterns in the SMA data. 92 | - Noting any significant crossovers, trend reversals, or anomalies. 93 | - Providing a summary of the current market position based on the SMA. 94 | - Making actionable recommendations based on the observed SMA trends. 95 | 96 | Use your expertise to deliver a comprehensive assessment of the cryptocurrency's performance as indicated by the moving average data. 97 | 98 | """), 99 | expected_output=dedent(f""" 100 | The expected output is a detailed analysis report of the simple moving average for {coin}. 101 | The report should include: 102 | - A summary of key trends and patterns identified in the SMA data. 103 | - Observations of any significant crossovers or anomalies. 104 | - An assessment of the cryptocurrency's market position based on the SMA. 105 | - Actionable recommendations for trading or investment based on the SMA analysis. 106 | 107 | The report should be clear, concise, and tailored to assist in strategic decision-making regarding the cryptocurrency. 108 | """), 109 | agent=agent 110 | ) 111 | 112 | 113 | def Get_News(self, agent, coin): 114 | return Task( 115 | description=dedent(f""" 116 | Using the provided coin ({coin}), extract the news using the api already provided. 117 | your task is to extract title and text content related to the topic '{coin}'. 118 | After extracting format the content format them in a concise manner with the title and text format. 119 | Ensure that the extracted content is organized, cleaned, and formatted appropriately for further processing. 120 | 121 | """), 122 | expected_output = dedent(""" 123 | First mention the list of top stories of the coin plus the latest stories too. 124 | - Title: 125 | - Text: 126 | 127 | Then generate the report of the following sections: 128 | 129 | 1. Summary of Content: Provide a summary of the key points from the extracted content. 130 | 131 | 2. Sentiment Analysis: Evaluate the overall sentiment of the news articles. Indicate whether the sentiment is neutral, negative, or positive. 132 | 133 | 3. Key Insights: Highlight any significant trends, insights, or notable information from the content. 134 | 135 | Make sure your report is clear, concise, and organized. Provide specific examples or quotes from the content to support your analysis. 136 | """), 137 | agent=agent 138 | ) 139 | 140 | 141 | def Write_Rport(self, agent): 142 | return Task( 143 | 144 | description = dedent(f""" 145 | Use the previous context to create a detailed report. You should tell the user how to approach to buy 146 | that coin based on the analysis you have done from the content The report should include: 147 | 1. Market Analysis (summary) 148 | 2. Chart Analysis (summary) 149 | 3. Sentiment Analysis (summary) 150 | These three will be copied from the previous context and the next analysis you will provide will be your overview 151 | on whether to buy this coin or sell it and give the reason behind your answer. Answer from the context of the previous analyses. 152 | Give a detailed analysis so that the user can feel confident what to decision to take. 153 | 4. AI Analysis 154 | """), 155 | 156 | expected_output=dedent(f""" 157 | The expected output is a comprehensive report of atleast 4 pages that includes the following sections: 158 | 1. Market Analysis (summary) 159 | 2. Chart Analysis (summary) 160 | 3. Sentiment Analysis (summary) 161 | 4. Your Analysis (detailed) 162 | """), 163 | 164 | agent=agent 165 | 166 | ) 167 | 168 | 169 | def Create_Gauge1(self, agent): 170 | return Task( 171 | description=dedent(""" 172 | Use the context of technical analysis to recommend an approach to the user. 173 | The possible approaches are Strong Buy, Buy, Neutral, Sell, and Strong Sell. 174 | Convert this recommendation into a dictionary and pass it to a tool that creates 175 | a gauge chart. 176 | """), 177 | expected_output=dedent(""" 178 | The expected output is a gauge chart that has been created. 179 | """), 180 | agent=agent 181 | ) 182 | 183 | 184 | def Create_Gauge2(self, agent): 185 | return Task( 186 | description=dedent(""" 187 | Use the context of simple moving average analysis to recommend an approach to the user. 188 | The possible approaches are Strong Buy, Buy, Neutral, Sell, and Strong Sell. 189 | Convert this recommendation into a dictionary and pass it to a tool that creates 190 | a gauge chart. 191 | """), 192 | expected_output=dedent(""" 193 | The expected output is a gauge chart that has been created. 194 | """), 195 | agent=agent 196 | ) 197 | 198 | def Create_Gauge3(self, agent): 199 | return Task( 200 | description=dedent(""" 201 | Use the context of write report to recommend an approach to the user. 202 | The possible approaches are Strong Buy, Buy, Neutral, Sell, and Strong Sell. 203 | Convert this recommendation into a dictionary and pass it to a tool that creates 204 | a gauge chart. 205 | """), 206 | expected_output=dedent(""" 207 | The expected output is a gauge chart that has been created. 208 | """), 209 | agent=agent 210 | ) 211 | 212 | 213 | def Closing_Price_Analysis(self, agent, coin): 214 | return Task( 215 | description=dedent(f""" 216 | The task involves analyzing closing prices for a specified cryptocurrency. 217 | The agent will follow these steps: 218 | 1. Create a closing analysis chart for the given cryptocurrency using an API. 219 | 2. Analyze the generated line chart and summarize the findings in DICT format. 220 | 3. Using the points from the DICT summary, generate a new closing analysis chart 221 | with these points plotted on it. 222 | 4. Ensure the final output includes both the updated line chart and a detailed 223 | report of the points in dict format 224 | 225 | {coin} 226 | """), 227 | expected_output=dedent(""" 228 | The output should include: 229 | 1. A detailed JSON report summarizing the analysis of the initial closing chart. 230 | """), 231 | agent=agent 232 | ) 233 | -------------------------------------------------------------------------------- /tools.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from langchain_text_splitters import RecursiveCharacterTextSplitter 3 | from langchain_community.document_loaders import WebBaseLoader 4 | from urllib.parse import urlparse 5 | from langchain.agents import tool 6 | from exa_py import Exa 7 | from openai import OpenAI 8 | import base64 9 | import os 10 | import requests 11 | import pandas as pd 12 | import mplfinance as mpf 13 | import matplotlib.pyplot as plt 14 | from matplotlib.dates import DateFormatter 15 | import json 16 | 17 | 18 | 19 | class CryptoTradingTools(): 20 | 21 | @tool("Extract URL") 22 | def Extract_url(coin_name :str): 23 | """Extract the url of the website.""" 24 | tokenmetrics_api_key = os.getenv('TOKENMETRICS_API_KEY') 25 | url = "https://api.tokenmetrics.com/v2/tokens?category=yield%20farming%2Cdefi&exchange=binance%2Cgate&blockchain_address=binance-smart-chain%3A0x57185189118c7e786cafd5c71f35b16012fa95ad&limit=10000&page=0" 26 | 27 | headers = { 28 | "accept": "application/json", 29 | "api_key": tokenmetrics_api_key 30 | } 31 | if coin_name.lower() == "bnb": 32 | return f"https://coinmarketcap.com/currencies/{coin_name}/" 33 | 34 | response = requests.get(url, headers=headers) 35 | if response.status_code == 200: 36 | data = response.json() 37 | if data["success"]: 38 | for coin in data["data"]: 39 | if coin["TOKEN_NAME"].lower() == coin_name.lower(): 40 | part = coin['TM_LINK'] 41 | parsed_url = urlparse(part) 42 | path = parsed_url.path 43 | last_word = path.split('/')[-1] 44 | return f"https://coinmarketcap.com/currencies/{last_word}/" 45 | 46 | 47 | else: 48 | return "Failed to fetch data. API response indicates failure." 49 | else: 50 | return f"Failed to fetch data. Status code: {response.status_code}" 51 | 52 | @tool("Scrap data from the Website") 53 | def Scrap_data(url: str): 54 | """Scrap data from the Website and print it.""" 55 | 56 | loader = WebBaseLoader(url) 57 | data = loader.load() 58 | splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0) 59 | splits = splitter.split_documents(data) 60 | 61 | return splits 62 | 63 | @tool("Extract symbol and create candlestick chart from api") 64 | def Create_Candlestick(coin_name: str): 65 | """Extract symbol and create candelstick chart from the api""" 66 | tokenmetrics_api_key = os.getenv('TOKENMETRICS_API_KEY') 67 | url = "https://api.tokenmetrics.com/v2/tokens?category=yield%20farming%2Cdefi&exchange=binance%2Cgate&blockchain_address=binance-smart-chain%3A0x57185189118c7e786cafd5c71f35b16012fa95ad&limit=10000&page=0" 68 | 69 | headers = { 70 | "accept": "application/json", 71 | "api_key": tokenmetrics_api_key 72 | } 73 | 74 | response = requests.get(url, headers=headers) 75 | if response.status_code == 200: 76 | data = response.json() 77 | if data["success"]: 78 | for coin in data["data"]: 79 | if coin["TOKEN_NAME"].lower() == coin_name.lower(): 80 | token = coin["TOKEN_SYMBOL"] 81 | 82 | api_url = f'https://financialmodelingprep.com/api/v3/historical-price-full/{token}USD?apikey=ba164bccb40cdf9d0adc2a9a8cb39060' 83 | 84 | # Make a GET request to the API endpoint 85 | response = requests.get(api_url) 86 | 87 | # Check if the request was successful (status code 200) 88 | if response.status_code == 200: 89 | # Parse the JSON data from the response 90 | data = response.json() 91 | 92 | # Extract the historical data 93 | historical_data = data.get('historical', []) 94 | 95 | # Create a DataFrame from the data 96 | df = pd.DataFrame(historical_data) 97 | df['date'] = pd.to_datetime(df['date']) 98 | df = df.sort_values('date') 99 | df.set_index('date', inplace=True) 100 | 101 | # Get the last 30 days of data 102 | last_30_days_data = df.tail(30) 103 | 104 | # Create a custom style for the candlestick chart 105 | custom_style = mpf.make_mpf_style( 106 | base_mpl_style='default', 107 | rc={'font.size': 8}, 108 | marketcolors=mpf.make_marketcolors( 109 | up='lime', 110 | down='red', 111 | wick={'up':'lime', 'down':'red'}, 112 | volume='skyblue' 113 | ) 114 | ) 115 | 116 | # Create a figure with 2 subplots 117 | fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12), gridspec_kw={'height_ratios': [2, 1]}) 118 | 119 | # Plot the candlestick chart 120 | mpf.plot(last_30_days_data, type='candle', style=custom_style, ax=ax1, volume=False) 121 | ax1.set_title(f'{token}/USD Price', fontsize=16) 122 | ax1.set_ylabel('Price', fontsize=12) 123 | 124 | # Plot the volume bar chart 125 | ax2.bar(df.index, df['volume'], width=0.8, align='center', color='skyblue', edgecolor='navy') 126 | ax2.set_title(f'{token}/USD Trading Volume', fontsize=16) 127 | ax2.set_xlabel('Date', fontsize=12) 128 | ax2.set_ylabel('Volume', fontsize=12) 129 | 130 | # Format x-axis for volume chart 131 | ax2.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d')) 132 | plt.setp(ax2.xaxis.get_majorticklabels(), rotation=45, ha='right') 133 | 134 | # Format y-axis labels for volume chart 135 | ax2.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'{x/1e9:.1f}B')) 136 | 137 | # Add grid lines to volume chart 138 | ax2.grid(axis='y', linestyle='--', alpha=0.7) 139 | 140 | # Adjust layout and display the plot 141 | plt.tight_layout() 142 | plt.savefig('coin_screenshot.jpeg') 143 | else: 144 | print(f"Failed to retrieve data. Status code: {response.status_code}") 145 | 146 | 147 | @tool("Making small moving average chart") 148 | def Create_Sma(coin_name: str): 149 | """Generate the moving average chart then save it""" 150 | tokenmetrics_api_key = os.getenv('TOKENMETRICS_API_KEY') 151 | url = "https://api.tokenmetrics.com/v2/tokens?category=yield%20farming%2Cdefi&exchange=binance%2Cgate&blockchain_address=binance-smart-chain%3A0x57185189118c7e786cafd5c71f35b16012fa95ad&limit=10000&page=0" 152 | 153 | headers = { 154 | "accept": "application/json", 155 | "api_key": tokenmetrics_api_key 156 | } 157 | 158 | response = requests.get(url, headers=headers) 159 | if response.status_code == 200: 160 | data = response.json() 161 | if data["success"]: 162 | for coin in data["data"]: 163 | if coin["TOKEN_NAME"].lower() == coin_name.lower(): 164 | token = coin["TOKEN_SYMBOL"] 165 | technical_indicator_name = "sma" 166 | url = f"https://financialmodelingprep.com/api/v3/technical_indicator/1day/{token}USD?type=sma&period=5&apikey=ba164bccb40cdf9d0adc2a9a8cb39060" 167 | 168 | response = requests.get(url) 169 | if response.status_code == 200: 170 | data = response.json() 171 | df = pd.DataFrame(data) 172 | df = df[:30] 173 | df['date'] = pd.to_datetime(df['date']) 174 | df.set_index('date', inplace=True) 175 | 176 | # Plot the data 177 | plt.figure(figsize=(14, 7)) 178 | 179 | plt.plot(df.index, df['close'], label='Close Price', color='blue') 180 | 181 | if technical_indicator_name in df.columns: 182 | plt.plot(df.index, df[technical_indicator_name], label=f'{technical_indicator_name.upper()} (5)', color='orange') 183 | else: 184 | print(f"{technical_indicator_name.upper()} data not available.") 185 | exit() 186 | 187 | plt.title(f'last 1 month Closing Prices of {token}/USD and {technical_indicator_name.upper()} (5-day)') 188 | plt.xlabel('Date') 189 | plt.ylabel('Price (USD)') 190 | plt.legend() 191 | plt.grid(True) 192 | plt.savefig("sma.jpeg") 193 | 194 | else: 195 | raise Exception(f"Error fetching data: {response.status_code}") 196 | 197 | 198 | @tool("Extract the content from the image") 199 | def Get_Sma_Content(): 200 | "Extract the content from the image" 201 | image_path = "sma.jpeg" 202 | client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) 203 | 204 | 205 | with open(image_path, 'rb') as image_file: 206 | image_base64 = base64.b64encode(image_file.read()).decode('utf-8') 207 | 208 | 209 | response = client.chat.completions.create( 210 | model='gpt-4o', 211 | response_format={"type": "text"}, 212 | messages=[ 213 | { 214 | "role": "user", 215 | "content": [ 216 | {"type": "text", "text": 217 | """ 218 | Please analyze the following image of a cryptocurrency moving average chart and provide a detailed summary. 219 | The analysis should include: 220 | - Key trends and patterns observed in the chart. 221 | - Any significant crossovers or anomalies. 222 | - An assessment of the current market position based on the chart. 223 | - Provide specific recommendations based on the analysis, such as: 224 | - Buy or sell signals based on trend and pattern analysis, give one word answer for this from these five options: Strong Sell, Sell, Neutral, Buy, Strong Buy. 225 | - Recommendations based on the moving average data. 226 | 227 | Review the image carefully and provide a comprehensive report. 228 | 229 | """ 230 | }, 231 | { 232 | "type": "image_url", 233 | "image_url": { 234 | "url": f"data:image/jpeg;base64,{image_base64}" 235 | } 236 | } 237 | ] 238 | } 239 | ], 240 | max_tokens=800, 241 | ) 242 | 243 | 244 | return response.choices[0].message.content 245 | 246 | 247 | @tool("Extract the content from the image") 248 | def Get_Pic_Content(): 249 | "Extract the content from the image" 250 | image_path = "coin_screenshot.jpeg" 251 | client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) 252 | 253 | 254 | with open(image_path, 'rb') as image_file: 255 | image_base64 = base64.b64encode(image_file.read()).decode('utf-8') 256 | 257 | 258 | response = client.chat.completions.create( 259 | model='gpt-4o', 260 | response_format={"type": "text"}, 261 | messages=[ 262 | { 263 | "role": "user", 264 | "content": [ 265 | {"type": "text", "text": 266 | """ 267 | To perform a comprehensive technical analysis of a provided candlestick chart and to generate the required outputs, you would typically use specialized software or tools like TradingView, MetaTrader, or similar platforms. Since I don't have access to view or analyze specific images directly, I will provide a detailed framework for how you can conduct this analysis: 268 | 269 | ### 1. Trend Analysis 270 | **Current Trend**: 271 | - Identify whether the market is in an uptrend, downtrend, or moving sideways. This can be done by observing the direction of the price movement over time. 272 | - **Uptrend**: Higher highs and higher lows. 273 | - **Downtrend**: Lower highs and lower lows. 274 | - **Sideways**: Horizontal movement with no clear direction. 275 | 276 | **Trend Strength and Potential Reversal Points**: 277 | - Use trend strength indicators like the Average Directional Index (ADX). A high ADX indicates a strong trend. 278 | - Look for patterns like Head and Shoulders, Double Tops/Bottoms to identify potential reversal points. 279 | 280 | ### 2. Support and Resistance Levels 281 | **Major Support and Resistance Levels**: 282 | - Identify key price levels where the market has repeatedly bounced off (support) or reversed from (resistance). 283 | 284 | **Significant Breakouts or Breakdowns**: 285 | - Highlight any recent price movements that have broken through established support or resistance levels, which may indicate strong future price movement. 286 | 287 | ### 3. Candlestick Patterns 288 | **Common Candlestick Patterns**: 289 | - **Doji**: Indicates indecision in the market, potential reversal signal. 290 | - **Hammer**: Bullish reversal pattern after a downtrend. 291 | - **Engulfing Patterns**: Bullish or bearish, indicating strong reversal potential. 292 | 293 | **Insights on Potential Bullish or Bearish Signals**: 294 | - Bullish patterns suggest potential buying opportunities. 295 | - Bearish patterns suggest potential selling opportunities. 296 | 297 | ### 5. Volume Analysis 298 | **Analyze Volume Trends**: 299 | - Confirm price movements with corresponding volume. An increase in volume confirms the strength of the price movement. 300 | 301 | **Unusual Volume Spikes**: 302 | - Identify significant volume spikes which can indicate strong buying/selling pressure and potential trend changes. 303 | 304 | ### 6. Risk Assessment 305 | **Potential Risks and Suggestions for Risk Management**: 306 | - Identify levels for stop-loss orders to manage downside risk. 307 | - Suggest appropriate position sizing based on volatility and risk tolerance. 308 | 309 | Explain these words too given below 310 | - support_price: 311 | - consolidation_points_price: 312 | - major_resistance_price: 313 | - psychological_break_price: 314 | - immediate_resistance: 315 | 316 | 317 | ### 7. Summary and Recommendations 318 | **Key Findings**: 319 | - Summarize the identified trend, key support and resistance levels, significant candlestick patterns, and volume analysis. 320 | 321 | **Actionable Trading Recommendations**: 322 | - Provide specific recommendations based on the analysis, such as: 323 | - Buy or sell signals based on trend and pattern analysis, give one word answer for this from these five options: Strong Sell, Sell, Neutral, Buy, Strong Buy. 324 | - Suggested entry and exit points. 325 | - Risk management strategies like stop-loss levels. 326 | 327 | By following this framework, you can systematically analyze a candlestick chart and derive actionable insights for trading decisions. 328 | """ 329 | }, 330 | { 331 | "type": "image_url", 332 | "image_url": { 333 | "url": f"data:image/jpeg;base64,{image_base64}" 334 | } 335 | } 336 | ] 337 | } 338 | ], 339 | max_tokens=800, 340 | ) 341 | 342 | 343 | return response.choices[0].message.content 344 | 345 | @tool("Extract the symbol and extract the data using api") 346 | def extract_contents(coin_name: str): 347 | """Extract the symbol and extract the data using api""" 348 | 349 | tokenmetrics_api_key = os.getenv('TOKENMETRICS_API_KEY') 350 | url = "https://api.tokenmetrics.com/v2/tokens?category=yield%20farming%2Cdefi&exchange=binance%2Cgate&blockchain_address=binance-smart-chain%3A0x57185189118c7e786cafd5c71f35b16012fa95ad&limit=10000&page=0" 351 | 352 | headers = { 353 | "accept": "application/json", 354 | "api_key": tokenmetrics_api_key 355 | } 356 | 357 | response = requests.get(url, headers=headers) 358 | if response.status_code == 200: 359 | data = response.json() 360 | if data["success"]: 361 | for coin in data["data"]: 362 | if coin["TOKEN_NAME"].lower() == coin_name.lower(): 363 | token = coin["TOKEN_SYMBOL"] 364 | 365 | url = f"https://financialmodelingprep.com/api/v4/crypto_news?page=1&symbol={token}USD&apikey=ba164bccb40cdf9d0adc2a9a8cb39060" 366 | response = requests.get(url) 367 | 368 | 369 | if response.status_code == 200: 370 | data = response.json() 371 | top_items = data[:5] 372 | combined_list = [] 373 | 374 | for item in top_items: 375 | 376 | title = item.get('title', 'No Title Found') 377 | text = item.get('text', 'No Text Found') 378 | 379 | # Combine title and text into one string 380 | combined = f"Title: {title}\nText: {text}" 381 | 382 | # Append the combined string to the list 383 | combined_list.append(combined) 384 | 385 | return combined_list 386 | 387 | 388 | 389 | # coin_name = str(coin_name) 390 | 391 | # try: 392 | # loader1 = WebBaseLoader(f"https://crypto.news/tag/{coin_name}/") 393 | # data1 = loader1.load() 394 | # loader2 = WebBaseLoader(f"https://decrypt.co/crypto-news/{coin_name}") 395 | # data2 = loader2.load() 396 | 397 | # content1 = data1[0].page_content if data1 else "No content found at the first URL." 398 | # content2 = data2[0].page_content if data2 else "No content found at the second URL." 399 | 400 | # return content1 + content2 401 | # except Exception as e: 402 | # return f"An error occurred while extracting content: {str(e)}" 403 | 404 | 405 | @tool("Create a gauge chart") 406 | def generate_gauge(context: str): 407 | """Create a gauge chart from the context or approach received and save it""" 408 | colors = ['#4dab6d', "#72c66e", "#f6ee54", "#f36d54", "#ee4d55"] 409 | words = ["strong sell", "sell", "neutral", "buy", "strong buy"] 410 | 411 | context = context.lower() 412 | value = 0 413 | 414 | for word in words: 415 | if word in context: 416 | if word == "strong buy": 417 | value = 2.85 418 | elif word == "strong sell": 419 | value = 0.25 420 | elif word == "buy": 421 | value = 2.20 422 | elif word == "sell": 423 | value = 0.90 424 | elif word == "neutral": 425 | value = 1.55 426 | 427 | fig = plt.figure(figsize=(10, 10)) 428 | ax = fig.add_subplot(projection="polar") 429 | 430 | # Adjusting the positions and widths 431 | x = [0, 0.6, 1.2, 1.9, 2.5] # Starting positions 432 | widths = [0.7, 0.7, 0.7, 0.7, 0.65] # Widths of segments 433 | 434 | # Use polar bar plot 435 | bars = ax.bar(x=x, width=widths, height=0.5, bottom=2, 436 | linewidth=3, edgecolor="white", 437 | color=colors[::-1], align="edge") # Reversing color order 438 | 439 | # Adjusting text positions and rotations 440 | plt.annotate("STRONG SELL", xy=(0.2, 2.1), rotation=-70, color="white", fontweight="bold") 441 | plt.annotate("SELL", xy=(0.89, 2.14), rotation=-40, color="white", fontweight="bold") 442 | plt.annotate("NEUTRAL", xy=(1.6, 2.2), rotation=0, color="white", fontweight="bold") 443 | plt.annotate("BUY", xy=(2.3, 2.25), rotation=40, color="white", fontweight="bold") 444 | plt.annotate("STRONG BUY", xy=(2.9, 2.25), rotation=70, color="white", fontweight="bold") 445 | 446 | # Add a needle or indicator 447 | plt.annotate("", xytext=(0, 0), xy=(value, 2.0), 448 | arrowprops=dict(arrowstyle="wedge,tail_width=0.5", color="black", shrinkA=0), 449 | bbox=dict(boxstyle="circle", facecolor="black", linewidth=2.0), 450 | fontsize=45, color="white", ha="center" 451 | ) 452 | 453 | plt.title("Performance Gauge Chart", loc="center", pad=20, fontsize=35, fontweight="bold") 454 | 455 | # Hide the polar axes 456 | ax.set_axis_off() 457 | 458 | # Adjust layout and save the plot to a file 459 | plt.tight_layout() 460 | plt.savefig('gauge.jpeg', dpi=300, bbox_inches='tight') # Save with high resolution and tight bounding box 461 | plt.close(fig) # Close the figure to free up memory 462 | return "gauge has been created" 463 | 464 | 465 | @tool("make a line chart and save it") 466 | def generate_line_chart(coin_name: str): 467 | """Extract the symbol and create a line chart from the api and save it""" 468 | tokenmetrics_api_key = os.getenv('TOKENMETRICS_API_KEY') 469 | url = "https://api.tokenmetrics.com/v2/tokens?category=yield%20farming%2Cdefi&exchange=binance%2Cgate&blockchain_address=binance-smart-chain%3A0x57185189118c7e786cafd5c71f35b16012fa95ad&limit=10000&page=0" 470 | 471 | headers = { 472 | "accept": "application/json", 473 | "api_key": tokenmetrics_api_key 474 | } 475 | 476 | response = requests.get(url, headers=headers) 477 | if response.status_code == 200: 478 | data = response.json() 479 | if data["success"]: 480 | for coin in data["data"]: 481 | if coin["TOKEN_NAME"].lower() == coin_name.lower(): 482 | token = coin["TOKEN_SYMBOL"] 483 | 484 | url = f"https://financialmodelingprep.com/api/v3/historical-price-full/{token}USD?apikey=ba164bccb40cdf9d0adc2a9a8cb39060" 485 | response = requests.get(url) 486 | if response.status_code == 200: 487 | historical_data = response.json()['historical'] 488 | df_historical = pd.DataFrame(historical_data) 489 | df_historical['date'] = pd.to_datetime(df_historical['date']) 490 | df_historical.set_index('date', inplace=True) 491 | df_historical = df_historical.sort_index() # Ensure data is sorted by date 492 | df_historical = df_historical[-30:] 493 | plt.figure(figsize=(12, 6)) 494 | plt.plot(df_historical.index, df_historical['close'], color='green', linewidth=2) 495 | 496 | # Format the date on the x-axis 497 | date_form = DateFormatter("%Y-%m-%d") 498 | plt.gca().xaxis.set_major_formatter(date_form) 499 | plt.gca().xaxis.set_tick_params(rotation=45) 500 | 501 | # Set plot labels and title 502 | plt.xlabel('Date') 503 | plt.ylabel('Closing Price (USD)') 504 | plt.title(f'{token}/USD Closing Prices (Last 30 Days)') 505 | 506 | # Show plot 507 | plt.grid(True) 508 | plt.tight_layout() 509 | plt.savefig("line_chart.jpeg") 510 | else: 511 | raise Exception(f"Failed to retrieve data. Status code: {response.status_code}") 512 | 513 | @tool("analyze the line chart") 514 | def analyze_line_chart(): 515 | """Analyze the line chart and provide the values in JSON format""" 516 | image_path = "line_chart.jpeg" 517 | client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) 518 | 519 | 520 | with open(image_path, 'rb') as image_file: 521 | image_base64 = base64.b64encode(image_file.read()).decode('utf-8') 522 | 523 | 524 | response = client.chat.completions.create( 525 | model='gpt-4o', 526 | response_format={"type": "text"}, 527 | messages=[ 528 | { 529 | "role": "user", 530 | "content": [ 531 | {"type": "text", "text": 532 | """ 533 | Analyze the line chart of the specified cryptocurrency. The analysis should focus on identifying key price points. The output should be provided in DICT format, 534 | following the structure below: 535 | Ouput should be in this format: 536 | 537 | "support_price": , 538 | "consolidation_points_price": , 539 | "major_resistance_price": , 540 | "psychological_break_price": , 541 | "immediate_resistance": 542 | 543 | 544 | 545 | Replace `` with the respective price points identified from the analysis. Ensure that each key is clearly defined and corresponds to the correct price point on the chart. 546 | 547 | 548 | 549 | """ 550 | }, 551 | { 552 | "type": "image_url", 553 | "image_url": { 554 | "url": f"data:image/jpeg;base64,{image_base64}" 555 | } 556 | } 557 | ] 558 | } 559 | ], 560 | max_tokens=800, 561 | ) 562 | with open('points.txt', 'w') as f: 563 | f.write(response.choices[0].message.content) 564 | return response.choices[0].message.content 565 | 566 | 567 | @tool("Create a new line chart by the values given and save it") 568 | def generate_new_line_chart(coin_name: str): 569 | """Create a new line chart by the values and save it""" 570 | tokenmetrics_api_key = os.getenv('TOKENMETRICS_API_KEY') 571 | url = "https://api.tokenmetrics.com/v2/tokens?category=yield%20farming%2Cdefi&exchange=binance%2Cgate&blockchain_address=binance-smart-chain%3A0x57185189118c7e786cafd5c71f35b16012fa95ad&limit=10000&page=0" 572 | 573 | headers = { 574 | "accept": "application/json", 575 | "api_key": tokenmetrics_api_key 576 | } 577 | 578 | response = requests.get(url, headers=headers) 579 | if response.status_code == 200: 580 | data = response.json() 581 | if data["success"]: 582 | for coin in data["data"]: 583 | if coin["TOKEN_NAME"].lower() == coin_name.lower(): 584 | token = coin["TOKEN_SYMBOL"] 585 | 586 | historical_url = f'https://financialmodelingprep.com/api/v3/historical-price-full/{token}USD?apikey=ba164bccb40cdf9d0adc2a9a8cb39060' 587 | response = requests.get(historical_url) 588 | if response.status_code == 200: 589 | historical_data = response.json()['historical'] 590 | df_historical = pd.DataFrame(historical_data) 591 | df_historical['date'] = pd.to_datetime(df_historical['date']) 592 | df_historical.set_index('date', inplace=True) 593 | df_historical = df_historical.sort_index() 594 | df_historical = df_historical[-30:] 595 | 596 | with open('points.txt', 'r') as file: 597 | json_data = file.read() 598 | 599 | 600 | data = json.loads(json_data) 601 | 602 | 603 | support_price = data['support_price'] 604 | consolidation_points_price = data['consolidation_points_price'] 605 | major_resistance_price = data['major_resistance_price'] 606 | psychological_break_price = data['psychological_break_price'] 607 | immediate_resistance = data['immediate_resistance'] 608 | 609 | plt.figure(figsize=(12, 6)) 610 | plt.plot(df_historical.index, df_historical['close'], color='green', linewidth=2, label='Closing Price') 611 | 612 | 613 | plt.axhline(y=support_price, color='red', linestyle='--', linewidth=1, label='Support Price') 614 | plt.axhline(y=consolidation_points_price, color='blue', linestyle='--', linewidth=1, label='Consolidation Price') 615 | plt.axhline(y=major_resistance_price, color='purple', linestyle='--', linewidth=1, label='Major Resistance Price') 616 | plt.axhline(y=psychological_break_price, color='orange', linestyle='--', linewidth=1, label='Psychological Break Price') 617 | plt.axhline(y=immediate_resistance, color='brown', linestyle='--', linewidth=1, label='Immediate Resistance Price') 618 | 619 | 620 | date_form = DateFormatter("%Y-%m-%d") 621 | plt.gca().xaxis.set_major_formatter(date_form) 622 | plt.gca().xaxis.set_tick_params(rotation=45) 623 | 624 | plt.xlabel('Date') 625 | plt.ylabel('Closing Price (USD)') 626 | plt.title(f'{token}/USD Closing Prices (Last 30 Days)') 627 | 628 | 629 | plt.legend() 630 | 631 | plt.grid(True) 632 | plt.tight_layout() 633 | plt.savefig("line_chart.jpeg") 634 | 635 | 636 | else: 637 | raise Exception(f"Failed to retrieve data. Status code: {response.status_code}") 638 | 639 | 640 | def _exa(): 641 | api_key = os.getenv('EXA_API_KEY') 642 | return Exa(api_key=api_key) 643 | 644 | -------------------------------------------------------------------------------- /trained_agents_data.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arham2211/crypto-bot-analyzer/6fb5ff12a31e75b3ed65778dbb803022d8a235a6/trained_agents_data.pkl --------------------------------------------------------------------------------