diff --git a/OpenAI_Investor.ipynb b/OpenAI_Investor.ipynb
new file mode 100644
index 0000000..c28c808
--- /dev/null
+++ b/OpenAI_Investor.ipynb
@@ -0,0 +1,303 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "colab_type": "text",
+ "id": "view-in-github"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gQWLeJCFS6C4"
+ },
+ "source": [
+ "## claude-investor\n",
+ "By Matt Shumer (https://twitter.com/mattshumer_)\n",
+ "\n",
+ "Github repo: https://github.com/mshumer/gpt-investor"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "rlKQLdG8v23g"
+ },
+ "outputs": [],
+ "source": [
+ "!pip install yfinance requests beautifulsoup4\n",
+ "!pip install openai"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "id": "50ZEVdt53Xkr"
+ },
+ "outputs": [],
+ "source": [
+ "from openai import AzureOpenAI, OpenAI\n",
+ "\n",
+ "API_KEY = \"\" # Replace with your OpenAI API or AzureOpenAI key\n",
+ "client = OpenAI(api_key = API_KEY)\n",
+ "\n",
+ "API_MODEL=\"\"\n",
+ "\n",
+ "HOSTED_IN_AZURE_PLATFORM = True # Make it to True/False if your service is Azure Open AI or OpenAI respectively.\n",
+ "if(HOSTED_IN_AZURE_PLATFORM):\n",
+ " API_ENDPOINT= \"\"\n",
+ " API_VERSION=\"\"\n",
+ "\n",
+ " client = AzureOpenAI(api_key = API_KEY,api_version=API_VERSION,azure_endpoint=API_ENDPOINT)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "tg78Hup6xona"
+ },
+ "outputs": [],
+ "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",
+ "\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\n",
+ "\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\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",
+ " response = client.chat.completions.create(model=API_MODEL, messages = messages)\n",
+ " response_text = response.choices[0].message.content\n",
+ "\n",
+ " return response_text\n",
+ "\n",
+ "# User input\n",
+ "industry = input(\"Enter the industry to analyze: \")\n",
+ "\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": {
+ "colab": {
+ "authorship_tag": "ABX9TyPuI82WtCRP7mS26mCp9B+j",
+ "include_colab_link": true,
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}