From 27658158820d81e7a683ba86f481391274911f72 Mon Sep 17 00:00:00 2001 From: YeonwooSung Date: Mon, 25 Mar 2024 21:36:15 +0900 Subject: [PATCH] feat: Add notebook for claude investor --- LLMs/claude/Claude_Investor.ipynb | 348 ++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 LLMs/claude/Claude_Investor.ipynb diff --git a/LLMs/claude/Claude_Investor.ipynb b/LLMs/claude/Claude_Investor.ipynb new file mode 100644 index 0000000..ab6dc26 --- /dev/null +++ b/LLMs/claude/Claude_Investor.ipynb @@ -0,0 +1,348 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "## claude-investor" + ], + "metadata": { + "id": "gQWLeJCFS6C4" + } + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rlKQLdG8v23g" + }, + "outputs": [], + "source": [ + "!pip install yfinance requests beautifulsoup4" + ] + }, + { + "cell_type": "code", + "source": [ + "ANTHROPIC_API_KEY = \"YOUR_API_KEY\" # Replace with your Anthropic API key" + ], + "metadata": { + "id": "50ZEVdt53Xkr" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "import yfinance as yf\n", + "from datetime import datetime, timedelta\n", + "import requests\n", + "from bs4 import BeautifulSoup\n", + "import ast\n", + "import json\n", + "\n", + "\n", + "def get_article_text(url):\n", + " try:\n", + " response = requests.get(url)\n", + " soup = BeautifulSoup(response.content, 'html.parser')\n", + " article_text = ' '.join([p.get_text() for p in soup.find_all('p')])\n", + " return article_text\n", + " except:\n", + " return \"Error retrieving article text.\"\n", + "\n", + "def get_stock_data(ticker, years):\n", + " end_date = datetime.now().date()\n", + " start_date = end_date - timedelta(days=years*365)\n", + "\n", + " stock = yf.Ticker(ticker)\n", + "\n", + " # Retrieve historical price data\n", + " hist_data = stock.history(start=start_date, end=end_date)\n", + "\n", + " # Retrieve balance sheet\n", + " balance_sheet = stock.balance_sheet\n", + "\n", + " # Retrieve financial statements\n", + " financials = stock.financials\n", + "\n", + " # Retrieve news articles\n", + " news = stock.news\n", + "\n", + " return hist_data, balance_sheet, financials, news\n", + "\n", + "def get_claude_comps_analysis(ticker, hist_data, balance_sheet, financials, news):\n", + " system_prompt = f\"You are a financial analyst assistant. Analyze the given data for {ticker} and suggest a few comparable companies to consider. Do so in a Python-parseable list.\"\n", + "\n", + " news = \"\"\n", + "\n", + " for article in news:\n", + " article_text = get_article_text(article['link'])\n", + " news = news + f\"\\n\\n---\\n\\nTitle: {article['title']}\\nText: {article_text}\"\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"Historical price data:\\n{hist_data.tail().to_string()}\\n\\nBalance Sheet:\\n{balance_sheet.to_string()}\\n\\nFinancial Statements:\\n{financials.to_string()}\\n\\nNews articles:\\n{news.strip()}\\n\\n----\\n\\nNow, suggest a few comparable companies to consider, in a Python-parseable list. Return nothing but the list. Make sure the companies are in the form of their tickers.\"},\n", + " ]\n", + "\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-haiku-20240307',\n", + " \"max_tokens\": 2000,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " return ast.literal_eval(response_text)\n", + "\n", + "def compare_companies(main_ticker, main_data, comp_ticker, comp_data):\n", + " system_prompt = f\"You are a financial analyst assistant. Compare the data of {main_ticker} against {comp_ticker} and provide a detailed comparison, like a world-class analyst would. Be measured and discerning. Truly think about the positives and negatives of each company. Be sure of your analysis. You are a skeptical investor.\"\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"Data for {main_ticker}:\\n\\nHistorical price data:\\n{main_data['hist_data'].tail().to_string()}\\n\\nBalance Sheet:\\n{main_data['balance_sheet'].to_string()}\\n\\nFinancial Statements:\\n{main_data['financials'].to_string()}\\n\\n----\\n\\nData for {comp_ticker}:\\n\\nHistorical price data:\\n{comp_data['hist_data'].tail().to_string()}\\n\\nBalance Sheet:\\n{comp_data['balance_sheet'].to_string()}\\n\\nFinancial Statements:\\n{comp_data['financials'].to_string()}\\n\\n----\\n\\nNow, provide a detailed comparison of {main_ticker} against {comp_ticker}. Explain your thinking very clearly.\"},\n", + " ]\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-haiku-20240307',\n", + " \"max_tokens\": 3000,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " # return json.loads(response_text)\n", + " return response_text\n", + "\n", + "def get_sentiment_analysis(ticker, news):\n", + " system_prompt = f\"You are a sentiment analysis assistant. Analyze the sentiment of the given news articles for {ticker} and provide a summary of the overall sentiment and any notable changes over time. Be measured and discerning. You are a skeptical investor.\"\n", + "\n", + " news_text = \"\"\n", + " for article in news:\n", + " article_text = get_article_text(article['link'])\n", + " timestamp = datetime.fromtimestamp(article['providerPublishTime']).strftime(\"%Y-%m-%d\")\n", + " news_text += f\"\\n\\n---\\n\\nDate: {timestamp}\\nTitle: {article['title']}\\nText: {article_text}\"\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"News articles for {ticker}:\\n{news_text}\\n\\n----\\n\\nProvide a summary of the overall sentiment and any notable changes over time.\"},\n", + " ]\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-haiku-20240307',\n", + " \"max_tokens\": 2000,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " return response_text\n", + "\n", + "def get_analyst_ratings(ticker):\n", + " stock = yf.Ticker(ticker)\n", + " recommendations = stock.recommendations\n", + " if recommendations is None or recommendations.empty:\n", + " return \"No analyst ratings available.\"\n", + "\n", + " latest_rating = recommendations.iloc[-1]\n", + "\n", + " firm = latest_rating.get('Firm', 'N/A')\n", + " to_grade = latest_rating.get('To Grade', 'N/A')\n", + " action = latest_rating.get('Action', 'N/A')\n", + "\n", + " rating_summary = f\"Latest analyst rating for {ticker}:\\nFirm: {firm}\\nTo Grade: {to_grade}\\nAction: {action}\"\n", + "\n", + " return rating_summary\n", + "\n", + "def get_industry_analysis(ticker):\n", + "\n", + " ### update to use search to find recent data!!\n", + "\n", + " stock = yf.Ticker(ticker)\n", + " industry = stock.info['industry']\n", + " sector = stock.info['sector']\n", + "\n", + " system_prompt = f\"You are an industry analysis assistant. Provide an analysis of the {industry} industry and {sector} sector, including trends, growth prospects, regulatory changes, and competitive landscape. Be measured and discerning. Truly think about the positives and negatives of the stock. Be sure of your analysis. You are a skeptical investor.\"\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"Provide an analysis of the {industry} industry and {sector} sector.\"},\n", + " ]\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-haiku-20240307',\n", + " \"max_tokens\": 2000,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " return response_text\n", + "\n", + "\n", + "def get_final_analysis(ticker, comparisons, sentiment_analysis, analyst_ratings, industry_analysis):\n", + " system_prompt = f\"You are a financial analyst providing a final investment recommendation for {ticker} based on the given data and analyses. Be measured and discerning. Truly think about the positives and negatives of the stock. Be sure of your analysis. You are a skeptical investor.\"\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"Ticker: {ticker}\\n\\nComparative Analysis:\\n{json.dumps(comparisons, indent=2)}\\n\\nSentiment Analysis:\\n{sentiment_analysis}\\n\\nAnalyst Ratings:\\n{analyst_ratings}\\n\\nIndustry Analysis:\\n{industry_analysis}\\n\\nBased on the provided data and analyses, please provide a comprehensive investment analysis and recommendation for {ticker}. Consider the company's financial strength, growth prospects, competitive position, and potential risks. Provide a clear and concise recommendation on whether to buy, hold, or sell the stock, along with supporting rationale.\"},\n", + " ]\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-opus-20240229',\n", + " \"max_tokens\": 3000,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " return response_text\n", + "\n", + "def generate_ticker_ideas(industry):\n", + " system_prompt = f\"You are a financial analyst assistant. Generate a list of 5 ticker symbols for major companies in the {industry} industry, as a Python-parseable list.\"\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"Please provide a list of 5 ticker symbols for major companies in the {industry} industry as a Python-parseable list. Only respond with the list, no other text.\"},\n", + " ]\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-haiku-20240307',\n", + " \"max_tokens\": 200,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " ticker_list = ast.literal_eval(response_text)\n", + " return [ticker.strip() for ticker in ticker_list]\n", + "\n", + "def get_current_price(ticker):\n", + " stock = yf.Ticker(ticker)\n", + " data = stock.history(period='1d', interval='1m')\n", + " return data['Close'][-1]\n", + "\n", + "def rank_companies(industry, analyses, prices):\n", + " system_prompt = f\"You are a financial analyst providing a ranking of companies in the {industry} industry based on their investment potential. Be discerning and sharp. Truly think about whether a stock is valuable or not. You are a skeptical investor.\"\n", + "\n", + " analysis_text = \"\\n\\n\".join(\n", + " f\"Ticker: {ticker}\\nCurrent Price: {prices.get(ticker, 'N/A')}\\nAnalysis:\\n{analysis}\"\n", + " for ticker, analysis in analyses.items()\n", + " )\n", + "\n", + " messages = [\n", + " {\"role\": \"user\", \"content\": f\"Industry: {industry}\\n\\nCompany Analyses:\\n{analysis_text}\\n\\nBased on the provided analyses, please rank the companies from most attractive to least attractive for investment. Provide a brief rationale for your ranking. In each rationale, include the current price (if available) and a price target.\"},\n", + " ]\n", + "\n", + " headers = {\n", + " \"x-api-key\": ANTHROPIC_API_KEY,\n", + " \"anthropic-version\": \"2023-06-01\",\n", + " \"content-type\": \"application/json\"\n", + " }\n", + " data = {\n", + " \"model\": 'claude-3-opus-20240229',\n", + " \"max_tokens\": 3000,\n", + " \"temperature\": 0.5,\n", + " \"system\": system_prompt,\n", + " \"messages\": messages,\n", + " }\n", + " response = requests.post(\"https://api.anthropic.com/v1/messages\", headers=headers, json=data)\n", + " response_text = response.json()['content'][0]['text']\n", + "\n", + " return response_text\n", + "\n", + "# User input\n", + "industry = input(\"Enter the industry to analyze: \")\n", + "years = 1 # int(input(\"Enter the number of years for analysis: \"))\n", + "\n", + "# Generate ticker ideas for the industry\n", + "tickers = generate_ticker_ideas(industry)\n", + "print(f\"\\nTicker Ideas for {industry} Industry:\")\n", + "print(\", \".join(tickers))\n", + "\n", + "# Perform analysis for each company\n", + "analyses = {}\n", + "prices = {}\n", + "for ticker in tickers:\n", + " try:\n", + " print(f\"\\nAnalyzing {ticker}...\")\n", + " hist_data, balance_sheet, financials, news = get_stock_data(ticker, years)\n", + " main_data = {\n", + " 'hist_data': hist_data,\n", + " 'balance_sheet': balance_sheet,\n", + " 'financials': financials,\n", + " 'news': news\n", + " }\n", + " sentiment_analysis = get_sentiment_analysis(ticker, news)\n", + " analyst_ratings = get_analyst_ratings(ticker)\n", + " industry_analysis = get_industry_analysis(ticker)\n", + " final_analysis = get_final_analysis(ticker, {}, sentiment_analysis, analyst_ratings, industry_analysis)\n", + " analyses[ticker] = final_analysis\n", + " prices[ticker] = get_current_price(ticker)\n", + " except:\n", + " pass\n", + "\n", + "# Rank the companies based on their analyses\n", + "ranking = rank_companies(industry, analyses, prices)\n", + "print(f\"\\nRanking of Companies in the {industry} Industry:\")\n", + "print(ranking)" + ], + "metadata": { + "id": "tg78Hup6xona" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file