pschofield2 commited on
Commit
35cd772
·
verified ·
1 Parent(s): a7105b6

create app.py

Browse files
Files changed (1) hide show
  1. app.py +204 -0
app.py ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from typing import Dict, Any
4
+ import snowflake.connector
5
+ import openai
6
+ import gradio as gr
7
+
8
+ def get_financial_data(ticker: str, api_key: str, period: str = 'annual') -> Dict[str, Any]:
9
+ base_url = "https://financialmodelingprep.com/api/v3/"
10
+ endpoints = {
11
+ "profile": f"profile/{ticker}?apikey={api_key}",
12
+ "balance_sheet": f"balance-sheet-statement/{ticker}?period={period}&apikey={api_key}",
13
+ "income_statement": f"income-statement/{ticker}?period={period}&apikey={api_key}"
14
+ }
15
+
16
+ results = {}
17
+
18
+ for key, endpoint in endpoints.items():
19
+ url = base_url + endpoint
20
+ response = requests.get(url)
21
+ if response.status_code == 200:
22
+ data = response.json()
23
+ if data:
24
+ if key == "profile":
25
+ results[key] = data[0]
26
+ elif key == "balance_sheet":
27
+ results[key] = data[0] # Get the most recent balance sheet statement
28
+ elif key == "income_statement":
29
+ results[key] = data[0] # Get the most recent income statement
30
+ else:
31
+ results[key] = None
32
+ else:
33
+ raise Exception(f"Failed to fetch data from {key} endpoint for ticker {ticker}. HTTP Status Code: {response.status_code}")
34
+
35
+ return results
36
+
37
+ def get_proprietary_indicators(ticker: str) -> str:
38
+ connection = snowflake.connector.connect(
39
+ user=os.getenv('SNOWFLAKE_USER'),
40
+ password=os.getenv('SNOWFLAKE_PASSWORD'),
41
+ account=os.getenv('SNOWFLAKE_ACCOUNT'),
42
+ warehouse=os.getenv('SNOWFLAKE_WAREHOUSE'),
43
+ database=os.getenv('SNOWFLAKE_DATABASE')
44
+ )
45
+ query = f"""
46
+ SELECT prompt
47
+ FROM researchdata.TS_INDICATORS_FOR_GPT_PROMPT_SVIEW
48
+ WHERE SYMBOL = '{ticker}'
49
+ """
50
+ cursor = connection.cursor()
51
+ cursor.execute(query)
52
+ result = cursor.fetchone()
53
+ connection.close()
54
+
55
+ if result:
56
+ return result[0]
57
+ else:
58
+ return "No proprietary indicators available for this ticker."
59
+
60
+ def format_for_gpt_prompt(financial_data: Dict[str, Any], proprietary_indicators: str) -> str:
61
+ profile = financial_data.get('profile', {})
62
+ balance_sheet = financial_data.get('balance_sheet', {})
63
+ income_statement = financial_data.get('income_statement', {})
64
+
65
+ company_name = profile.get('companyName', 'N/A')
66
+ company_description = profile.get('description', 'N/A')
67
+ ticker = profile.get('symbol', 'N/A')
68
+ market_cap = profile.get('mktCap', 'N/A')
69
+ ceo = profile.get('ceo', 'N/A')
70
+ beta = profile.get('beta', 'N/A')
71
+
72
+ financial_data_str = f"""
73
+ Balance Sheet:
74
+ Total Assets: {balance_sheet.get('totalAssets', 'N/A')}
75
+ Total Liabilities: {balance_sheet.get('totalLiabilities', 'N/A')}
76
+ Total Equity: {balance_sheet.get('totalEquity', 'N/A')}
77
+ Cash and Cash Equivalents: {balance_sheet.get('cashAndCashEquivalents', 'N/A')}
78
+ Cash and Short Term Investments: {balance_sheet.get('cashAndShortTermInvestments', 'N/A')}
79
+ Inventory: {balance_sheet.get('inventory', 'N/A')}
80
+ Net Receivables: {balance_sheet.get('netReceivables', 'N/A')}
81
+ Total Current Assets: {balance_sheet.get('totalCurrentAssets', 'N/A')}
82
+ Total Current Liabilities: {balance_sheet.get('totalCurrentLiabilities', 'N/A')}
83
+ Long Term Debt: {balance_sheet.get('longTermDebt', 'N/A')}
84
+ Short Term Debt: {balance_sheet.get('shortTermDebt', 'N/A')}
85
+ Total Debt: {balance_sheet.get('totalDebt', 'N/A')}
86
+ Property, Plant, and Equipment Net: {balance_sheet.get('propertyPlantEquipmentNet', 'N/A')}
87
+ Deferred Revenue: {balance_sheet.get('deferredRevenue', 'N/A')}
88
+ Accumulated Other Comprehensive Income Loss: {balance_sheet.get('accumulatedOtherComprehensiveIncomeLoss', 'N/A')}
89
+ Retained Earnings: {balance_sheet.get('retainedEarnings', 'N/A')}
90
+ Total Non-Current Assets: {balance_sheet.get('totalNonCurrentAssets', 'N/A')}
91
+ Total Non-Current Liabilities: {balance_sheet.get('totalNonCurrentLiabilities', 'N/A')}
92
+ Goodwill and Intangible Assets: {balance_sheet.get('goodwillAndIntangibleAssets', 'N/A')}
93
+
94
+ Income Statement:
95
+ Revenue: {income_statement.get('revenue', 'N/A')}
96
+ Cost of Revenue: {income_statement.get('costOfRevenue', 'N/A')}
97
+ Gross Profit: {income_statement.get('grossProfit', 'N/A')}
98
+ Gross Profit Ratio: {income_statement.get('grossProfitRatio', 'N/A')}
99
+ Operating Income: {income_statement.get('operatingIncome', 'N/A')}
100
+ Operating Income Ratio: {income_statement.get('operatingIncomeRatio', 'N/A')}
101
+ Net Income: {income_statement.get('netIncome', 'N/A')}
102
+ Net Income Ratio: {income_statement.get('netIncomeRatio', 'N/A')}
103
+ EBITDA: {income_statement.get('ebitda', 'N/A')}
104
+ EBITDA Ratio: {income_statement.get('ebitdaratio', 'N/A')}
105
+ Earnings Per Share (EPS): {income_statement.get('eps', 'N/A')}
106
+ Diluted EPS: {income_statement.get('epsdiluted', 'N/A')}
107
+ Cost and Expenses: {income_statement.get('costAndExpenses', 'N/A')}
108
+ Depreciation and Amortization: {income_statement.get('depreciationAndAmortization', 'N/A')}
109
+ Income Before Tax: {income_statement.get('incomeBeforeTax', 'N/A')}
110
+ Income Before Tax Ratio: {income_statement.get('incomeBeforeTaxRatio', 'N/A')}
111
+ Income Tax Expense: {income_statement.get('incomeTaxExpense', 'N/A')}
112
+ Operating Expenses: {income_statement.get('operatingExpenses', 'N/A')}
113
+ Research and Development Expenses: {income_statement.get('researchAndDevelopmentExpenses', 'N/A')}
114
+ Selling, General, and Administrative Expenses: {income_statement.get('sellingGeneralAndAdministrativeExpenses', 'N/A')}
115
+ Total Other Income Expenses Net: {income_statement.get('totalOtherIncomeExpensesNet', 'N/A')}
116
+ Weighted Average Shares Outstanding: {income_statement.get('weightedAverageShsOut', 'N/A')}
117
+ Weighted Average Shares Outstanding Diluted: {income_statement.get('weightedAverageShsOutDil', 'N/A')}
118
+ """
119
+
120
+ prompt = f"""
121
+ You are an expert stock analyst AI that has been tasked with analyzing a specific company and providing an investment recommendation for potential investors. Start with a company description and include the ticker, CEO, Market Cap and beta. Then provide an analysis based on the information provided to you. Your analysis and recommendation should be based solely on the company information, financial data, and news articles provided to you. Do not make assumptions or incorporate any outside knowledge.
122
+
123
+ Here is the company you will be analyzing:
124
+
125
+ <company>
126
+ Name: {company_name} ({ticker})
127
+ Description: {company_description}
128
+ Market Cap: {market_cap}
129
+ CEO: {ceo}
130
+ Beta: {beta}
131
+ </company>
132
+
133
+ Please carefully review this background information on the company.
134
+
135
+ Next, here is some recent financial data on the company:
136
+
137
+ <financial_data>
138
+ {financial_data_str}
139
+ </financial_data>
140
+
141
+ Carefully analyze the key financial metrics and KPIs provided above, looking for significant trends, strengths and weaknesses. Consider metrics like revenue growth, profit margins, debt levels, etc.
142
+
143
+ Next, here are the proprietary indicators for the company:
144
+
145
+ <proprietary_indicators>
146
+
147
+ {proprietary_indicators}
148
+
149
+ </proprietary_indicators>
150
+
151
+ <reasoning>
152
+
153
+ Synthesize your analysis of the company background, financial data, and proprietary indicators here. Discuss the key factors that will likely impact the company's future stock price. Weigh the potential rewards of investing against the risks. Show your analytical thought process.
154
+
155
+ </reasoning>
156
+
157
+ <prediction>
158
+
159
+ Considering everything, what prediction would you make for this stock's return over the next 21 trading days? Provide a clear, justified recommendation based solely on the information provided. Do not hedge or equivocate.
160
+
161
+ </prediction>
162
+
163
+ Remember, your role is to be an objective, expert stock analyst. Explain your reasoning so that investors can understand the key factors driving your recommendation.
164
+ """
165
+
166
+ return prompt
167
+
168
+ def generate_gpt_prompt(ticker: str, api_key: str) -> str:
169
+ financial_data = get_financial_data(ticker, api_key)
170
+ proprietary_indicators = get_proprietary_indicators(ticker)
171
+ return format_for_gpt_prompt(financial_data, proprietary_indicators)
172
+
173
+ def run_gpt_model(prompt: str, api_key: str) -> str:
174
+ openai.api_key = api_key
175
+ system_prompt = (
176
+ "You are an expert stock analyst with a high degree of familiarity with TradeSmith and InvestorPlace products and services. "
177
+ "You help subscribers of these businesses analyze stocks. "
178
+ "You speak concisely and your output should use line breaks after each sentence to keep the text within a readable width. "
179
+ )
180
+
181
+ response = openai.Completion.create(
182
+ model="gpt-4", # or another model
183
+ prompt=prompt,
184
+ max_tokens=1500,
185
+ temperature=0.7,
186
+ stream=False,
187
+ stop=None
188
+ )
189
+
190
+ return response['choices'][0]['text']
191
+
192
+ def analyze_stock(ticker: str) -> str:
193
+ fmp_api_key = os.getenv('FMP_API_KEY')
194
+ openai_api_key = os.getenv('OPENAI_API_KEY')
195
+ prompt = generate_gpt_prompt(ticker, fmp_api_key)
196
+ analysis = run_gpt_model(prompt, openai_api_key)
197
+ return analysis
198
+
199
+ # Gradio Interface
200
+ iface = gr.Interface(fn=analyze_stock, inputs="text", outputs="text", title="Stock Analysis GPT Model",
201
+ description="Enter a stock ticker to get an analysis from the GPT model.")
202
+
203
+ if __name__ == "__main__":
204
+ iface.launch()