CCockrum commited on
Commit
8817f6b
·
verified ·
1 Parent(s): 67a8285

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -3
app.py CHANGED
@@ -39,6 +39,7 @@ sector_averages = {
39
  "Energy": {"P/E Ratio": 12, "P/S Ratio": 1.2, "P/B Ratio": 1.3},
40
  }
41
 
 
42
  # Safe Request Function
43
  def safe_request(url):
44
  try:
@@ -50,7 +51,9 @@ def safe_request(url):
50
 
51
  # Fetch Functions
52
  # (functions unchanged)
 
53
 
 
54
  # Financial Calculations
55
  def calculate_ratios(market_cap, total_revenue, price, dividend_amount, eps=5.0, growth=0.1, book_value=500000000):
56
  pe = price / eps if eps else 0
@@ -82,6 +85,152 @@ if selected_theme == "dark":
82
  else:
83
  theme = gr.themes.Soft(primary_hue="blue")
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  # Gradio UI
86
  with gr.Blocks(theme=theme) as iface:
87
  with gr.Row():
@@ -129,7 +278,13 @@ with gr.Blocks(theme=theme) as iface:
129
 
130
  reset_btn.click(fn=reset_fields, inputs=[], outputs=[symbol, eps, growth, book, output_summary, output_info, output_ratios, output_sector, output_chart])
131
 
132
- if __name__ == "__main__":
133
- iface.launch()
134
 
135
- # Note: Smooth historical price chart and rounding ratios in output is planned. Financial Health metrics added.
 
 
 
 
 
 
 
 
 
39
  "Energy": {"P/E Ratio": 12, "P/S Ratio": 1.2, "P/B Ratio": 1.3},
40
  }
41
 
42
+
43
  # Safe Request Function
44
  def safe_request(url):
45
  try:
 
51
 
52
  # Fetch Functions
53
  # (functions unchanged)
54
+ # ...
55
 
56
+ # Financial Calculations
57
  # Financial Calculations
58
  def calculate_ratios(market_cap, total_revenue, price, dividend_amount, eps=5.0, growth=0.1, book_value=500000000):
59
  pe = price / eps if eps else 0
 
85
  else:
86
  theme = gr.themes.Soft(primary_hue="blue")
87
 
88
+
89
+ # Fetch Functions
90
+ def get_company_info(symbol):
91
+ url = f"https://api.polygon.io/v3/reference/tickers/{symbol}?apiKey={POLYGON_API_KEY}"
92
+ response = safe_request(url)
93
+ if response:
94
+ data = response.json().get('results', {})
95
+ sector = data.get('market', 'Technology')
96
+ if sector.lower() == 'stocks':
97
+ sector = 'Technology'
98
+ return {
99
+ 'Name': data.get('name', 'N/A'),
100
+ 'Industry': data.get('sic_description', 'N/A'),
101
+ 'Sector': sector,
102
+ 'Market Cap': data.get('market_cap', 0),
103
+ 'Total Revenue': data.get('total_employees', 0) * 100000
104
+ }
105
+ return None
106
+
107
+ def get_current_price(symbol):
108
+ url = f"https://api.polygon.io/v2/aggs/ticker/{symbol}/prev?adjusted=true&apiKey={POLYGON_API_KEY}"
109
+ response = safe_request(url)
110
+ if response:
111
+ return response.json()['results'][0]['c']
112
+ return None
113
+
114
+ def get_dividends(symbol):
115
+ url = f"https://api.polygon.io/v3/reference/dividends?ticker={symbol}&apiKey={POLYGON_API_KEY}"
116
+ response = safe_request(url)
117
+ if response:
118
+ return response.json()['results'][0].get('cash_amount', 0)
119
+ return 0
120
+
121
+ def get_historical_prices(symbol):
122
+ end = datetime.date.today()
123
+ start = end - datetime.timedelta(days=365)
124
+ url = f"https://api.polygon.io/v2/aggs/ticker/{symbol}/range/1/day/{start}/{end}?adjusted=true&sort=asc&apiKey={POLYGON_API_KEY}"
125
+ response = safe_request(url)
126
+ if response:
127
+ results = response.json()['results']
128
+ dates = [datetime.datetime.fromtimestamp(r['t']/1000) for r in results]
129
+ prices = [r['c'] for r in results]
130
+ return dates, prices
131
+ return [], []
132
+
133
+ # Financial Calculations
134
+ def calculate_ratios(market_cap, total_revenue, price, dividend_amount, eps=5.0, growth=0.1, book_value=500000000):
135
+ pe = price / eps if eps else 0
136
+ ps = market_cap / total_revenue if total_revenue else 0
137
+ pb = market_cap / book_value if book_value else 0
138
+ peg = pe / (growth * 100) if growth else 0
139
+ div_yield = (dividend_amount / price) * 100 if price else 0
140
+ return {
141
+ 'P/E Ratio': pe,
142
+ 'P/S Ratio': ps,
143
+ 'P/B Ratio': pb,
144
+ 'PEG Ratio': peg,
145
+ 'Dividend Yield': div_yield
146
+ }
147
+
148
+ def compare_to_sector(sector, ratios):
149
+ if sector.lower() == 'stocks':
150
+ sector = 'Technology'
151
+ averages = sector_averages.get(sector, {})
152
+ if not averages:
153
+ return pd.DataFrame({"Metric": ["Sector data not available"], "Value": ["N/A"]})
154
+
155
+ data = {
156
+ "Ratio": [],
157
+ "Stock Value": [],
158
+ "Sector Average": [],
159
+ "Difference": []
160
+ }
161
+ for key in averages:
162
+ stock_value = ratios.get(key, 0)
163
+ sector_value = averages.get(key, 0)
164
+ diff = stock_value - sector_value
165
+
166
+ # Add emoji based on difference
167
+ if diff < 0:
168
+ diff_display = f"{diff:.2f} 🟢"
169
+ elif diff > 0:
170
+ diff_display = f"{diff:.2f} 🔴"
171
+ else:
172
+ diff_display = f"{diff:.2f} ⚪"
173
+
174
+ data["Ratio"].append(key)
175
+ data["Stock Value"].append(round(stock_value, 2))
176
+ data["Sector Average"].append(round(sector_value, 2))
177
+ data["Difference"].append(diff_display)
178
+
179
+ return pd.DataFrame(data)
180
+
181
+ def generate_summary(info, ratios):
182
+ recommendation = "Hold"
183
+ if ratios['P/E Ratio'] < 15 and ratios['P/B Ratio'] < 2 and ratios['PEG Ratio'] < 1.0 and ratios['Dividend Yield'] > 2:
184
+ recommendation = "Buy"
185
+ elif ratios['P/E Ratio'] > 30 and ratios['P/B Ratio'] > 5 and ratios['PEG Ratio'] > 2.0:
186
+ recommendation = "Sell"
187
+
188
+ report = (
189
+ f"Company Overview:\n"
190
+ f"Name: {info['Name']}\n"
191
+ f"Industry: {info['Industry']}\n"
192
+ f"Sector: {info['Sector']}\n"
193
+ f"Market Cap: ${info['Market Cap']:,.2f}\n\n"
194
+ f"Financial Metrics:\n"
195
+ f"P/E Ratio: {ratios['P/E Ratio']:.2f}\n"
196
+ f"P/S Ratio: {ratios['P/S Ratio']:.2f}\n"
197
+ f"P/B Ratio: {ratios['P/B Ratio']:.2f}\n"
198
+ f"PEG Ratio: {ratios['PEG Ratio']:.2f}\n"
199
+ f"Dividend Yield: {ratios['Dividend Yield']:.2f}%\n\n"
200
+ f"Recommended Investment Action: {recommendation}.\n"
201
+ )
202
+
203
+ # Use Mistral to generate the summary
204
+ summary_prompt = f"Summarize the following financial report clearly and briefly:\n\n{report}"
205
+ return query_mistral(summary_prompt)
206
+
207
+ def stock_research(symbol, eps=5.0, growth=0.1, book=500000000):
208
+ info = get_company_info(symbol)
209
+ price = get_current_price(symbol)
210
+ dividends = get_dividends(symbol)
211
+ dates, prices = get_historical_prices(symbol)
212
+
213
+ if not info or not price:
214
+ return "⚠️ Error fetching stock info", None, None, None, None
215
+
216
+ ratios = calculate_ratios(info['Market Cap'], info['Total Revenue'], price, dividends, eps, growth, book)
217
+ summary = generate_summary(info, ratios)
218
+ sector_comp = compare_to_sector(info['Sector'], ratios)
219
+
220
+ fig, ax = plt.subplots()
221
+ ax.plot(dates, prices)
222
+ ax.set_title(f"{symbol} Historical Price (1Y)")
223
+ ax.set_xlabel("Date")
224
+ ax.set_ylabel("Price ($)")
225
+ ax.grid(True)
226
+
227
+ info_table = pd.DataFrame(info.items(), columns=["Metric", "Value"])
228
+ ratios_table = pd.DataFrame(ratios.items(), columns=["Ratio", "Value"])
229
+
230
+ return summary, info_table, ratios_table, sector_comp, fig
231
+
232
+
233
+
234
  # Gradio UI
235
  with gr.Blocks(theme=theme) as iface:
236
  with gr.Row():
 
278
 
279
  reset_btn.click(fn=reset_fields, inputs=[], outputs=[symbol, eps, growth, book, output_summary, output_info, output_ratios, output_sector, output_chart])
280
 
 
 
281
 
282
+ def reset_fields():
283
+ return "", 5.0, 0.1, 500000000, "", "", "", "", None
284
+
285
+ reset_btn.click(fn=reset_fields, inputs=[], outputs=[symbol, eps, growth, book, output_summary, output_info, output_ratios, output_sector, output_chart])
286
+
287
+
288
+
289
+ if __name__ == "__main__":
290
+ iface.launch()