Skip to content

Commit

Permalink
feat: Add notebook for claude investor
Browse files Browse the repository at this point in the history
  • Loading branch information
YeonwooSung committed Mar 25, 2024
1 parent 2b2406c commit 2765815
Showing 1 changed file with 348 additions and 0 deletions.
348 changes: 348 additions & 0 deletions LLMs/claude/Claude_Investor.ipynb
Original file line number Diff line number Diff line change
@@ -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": []
}
]
}

0 comments on commit 2765815

Please sign in to comment.