Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Support for Open AI #5

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
303 changes: 303 additions & 0 deletions OpenAI_Investor.ipynb
@@ -0,0 +1,303 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "view-in-github"
},
"source": [
"<a href=\"https://colab.research.google.com/github/mshumer/gpt-investor/blob/main/Claude_Investor.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"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 = \"<Your_API_key>\" # Replace with your OpenAI API or AzureOpenAI key\n",
"client = OpenAI(api_key = API_KEY)\n",
"\n",
"API_MODEL=\"<Your_Azure_API_model_name>\"\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= \"<Your_Azure_API_endpoint>\"\n",
" API_VERSION=\"<Your_Azure_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
}