-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinanceGPT.py
208 lines (191 loc) · 11.2 KB
/
financeGPT.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import yfinance as yf
from datetime import datetime, timedelta
import requests
from bs4 import BeautifulSoup
import ast
import json
from openai import OpenAI
from dotenv import load_dotenv
import os
# Get API key from environment variable
# Load environment variables from .env file
load_dotenv()
client = OpenAI(api_key = os.environ.get('OPENAI_API_KEY'))
def get_article_text(url):
try:
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
article_text = ' '.join([p.get_text() for p in soup.find_all('p')])
return article_text
except:
return "Error retrieving article text."
def get_stock_data(ticker, years):
end_date = datetime.now().date()
start_date = end_date - timedelta(days=years*365)
stock = yf.Ticker(ticker)
# Retrieve historical price data
hist_data = stock.history(start=start_date, end=end_date)
# Retrieve balance sheet
balance_sheet = stock.balance_sheet
# Retrieve financial statements
financials = stock.financials
# Retrieve news articles
news = stock.news
return hist_data, balance_sheet, financials, news
def get_final_analysis(ticker, comparisons, sentiment_analysis, analyst_ratings, industry_analysis):
news = ""
for article in news:
article_text = get_article_text(article['link'])
news = news + f"\n\n---\n\nTitle: {article['title']}\nText: {article_text}"
messages = [
{"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."},
{"role": "system", "content": 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."}
]
# Replace with your GPT-4 API key
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=3000,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
return response_text
def compare_companies(main_ticker, main_data, comp_ticker, comp_data):
messages = [
{"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."},
{"role": "system", "content":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."}
]
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=3000,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
return response_text
def get_sentiment_analysis(ticker, news):
news_text = ""
for article in news:
article_text = get_article_text(article['link'])
timestamp = datetime.fromtimestamp(article['providerPublishTime']).strftime("%Y-%m-%d")
news_text += f"\n\n---\n\nDate: {timestamp}\nTitle: {article['title']}\nText: {article_text}"
messages = [
{"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."},
{"role": "system", "content": 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."}
]
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=2000,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
return response_text
def get_analyst_ratings(ticker):
stock = yf.Ticker(ticker)
recommendations = stock.recommendations
if recommendations is None or recommendations.empty:
return "No analyst ratings available."
latest_rating = recommendations.iloc[-1]
firm = latest_rating.get('Firm', 'N/A')
to_grade = latest_rating.get('To Grade', 'N/A')
action = latest_rating.get('Action', 'N/A')
rating_summary = f"Latest analyst rating for {ticker}:\nFirm: {firm}\nTo Grade: {to_grade}\nAction: {action}"
return rating_summary
def get_industry_analysis(ticker):
stock = yf.Ticker(ticker)
industry = stock.info['industry']
sector = stock.info['sector']
messages = [
{"role": "user", "content": f"Provide an analysis of the {industry} industry and {sector} sector."},
{"role": "system", "content": 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."}
]
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=2000,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
return response_text
def get_final_analysis(ticker, comparisons, sentiment_analysis, analyst_ratings, industry_analysis):
messages = [
{"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."},
{"role": "system", "content": 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"}
]
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=3000,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
return response_text
def generate_ticker_ideas(industry):
messages = [
{"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."},
{"role": "system", "content": 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."}
]
# Replace with your GPT-4 API key
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=200,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
ticker_list = ast.literal_eval(response_text)
return [ticker.strip() for ticker in ticker_list]
def get_current_price(ticker):
stock = yf.Ticker(ticker)
data = stock.history(period='1d', interval='1m')
return data['Close'][-1]
def rank_companies(industry, analyses, prices):
analysis_text = "\n\n".join(
f"Ticker: {ticker}\nCurrent Price: {prices.get(ticker, 'N/A')}\nAnalysis:\n{analysis}"
for ticker, analysis in analyses.items()
)
messages = [
{"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."},
{"role": "system", "content": 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."}
]
response = client.chat.completions.create(
model="gpt-4-turbo-preview", # Adjust the engine to your preference
max_tokens=3000,
temperature=0.5,
messages=messages
)
response_text = response.choices[0].message.content.strip()
return response_text
# User input
industry = input("Enter the industry to analyze: ")
years = 1 # int(input("Enter the number of years for analysis: "))
# Generate ticker ideas for the industry
tickers = generate_ticker_ideas(industry)
print(f"\nTicker Ideas for {industry} Industry:")
print(", ".join(tickers))
# Perform analysis for each company
analyses = {}
prices = {}
for ticker in tickers:
try:
print(f"\nAnalyzing {ticker}...")
hist_data, balance_sheet, financials, news = get_stock_data(ticker, years)
main_data = {
'hist_data': hist_data,
'balance_sheet': balance_sheet,
'financials': financials,
'news': news
}
sentiment_analysis = get_sentiment_analysis(ticker, news)
analyst_ratings = get_analyst_ratings(ticker)
industry_analysis = get_industry_analysis(ticker)
final_analysis = get_final_analysis(ticker, {}, sentiment_analysis, analyst_ratings, industry_analysis)
analyses[ticker] = final_analysis
prices[ticker] = get_current_price(ticker)
except:
pass
# Rank the companies based on their analyses
ranking = rank_companies(industry, analyses, prices)
print(f"\nRanking of Companies in the {industry} Industry:")
print(ranking)