Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
import gradio as gr
|
4 |
+
import matplotlib.pyplot as plt
|
5 |
+
import requests
|
6 |
+
import os
|
7 |
+
from transformers import pipeline
|
8 |
+
import datetime
|
9 |
+
|
10 |
+
# Initialize Summarizer
|
11 |
+
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
|
12 |
+
|
13 |
+
# Polygon API Key
|
14 |
+
POLYGON_API_KEY = os.getenv("POLYGON_API_KEY")
|
15 |
+
|
16 |
+
# Helper Functions
|
17 |
+
def get_company_info(symbol):
|
18 |
+
url = f"https://api.polygon.io/v3/reference/tickers/{symbol}?apiKey={POLYGON_API_KEY}"
|
19 |
+
try:
|
20 |
+
response = requests.get(url)
|
21 |
+
response.raise_for_status()
|
22 |
+
data = response.json()['results']
|
23 |
+
return {
|
24 |
+
'Name': data.get('name', 'N/A'),
|
25 |
+
'Industry': data.get('sic_description', 'N/A'),
|
26 |
+
'Market Cap': data.get('market_cap', 0),
|
27 |
+
'Total Revenue': data.get('total_employees', 0) * 100000 # Rough estimation
|
28 |
+
}
|
29 |
+
except Exception as e:
|
30 |
+
print(f"DEBUG: Error fetching company info: {e}")
|
31 |
+
return None
|
32 |
+
|
33 |
+
def get_current_price(symbol):
|
34 |
+
url = f"https://api.polygon.io/v2/aggs/ticker/{symbol}/prev?adjusted=true&apiKey={POLYGON_API_KEY}"
|
35 |
+
try:
|
36 |
+
response = requests.get(url)
|
37 |
+
response.raise_for_status()
|
38 |
+
data = response.json()['results'][0]
|
39 |
+
return float(data['c'])
|
40 |
+
except Exception as e:
|
41 |
+
print(f"DEBUG: Error fetching price: {e}")
|
42 |
+
return None
|
43 |
+
|
44 |
+
def get_dividends(symbol):
|
45 |
+
url = f"https://api.polygon.io/v3/reference/dividends?ticker={symbol}&apiKey={POLYGON_API_KEY}"
|
46 |
+
try:
|
47 |
+
response = requests.get(url)
|
48 |
+
response.raise_for_status()
|
49 |
+
data = response.json()['results'][0]
|
50 |
+
return {
|
51 |
+
'Dividend Amount': data.get('cash_amount', 0),
|
52 |
+
'Ex-Dividend Date': data.get('ex_dividend_date', 'N/A')
|
53 |
+
}
|
54 |
+
except Exception as e:
|
55 |
+
print(f"DEBUG: Error fetching dividends: {e}")
|
56 |
+
return {'Dividend Amount': 0, 'Ex-Dividend Date': 'N/A'}
|
57 |
+
|
58 |
+
def get_historical_prices(symbol):
|
59 |
+
end = datetime.date.today()
|
60 |
+
start = end - datetime.timedelta(days=365)
|
61 |
+
url = f"https://api.polygon.io/v2/aggs/ticker/{symbol}/range/1/day/{start}/{end}?adjusted=true&sort=asc&apiKey={POLYGON_API_KEY}"
|
62 |
+
try:
|
63 |
+
response = requests.get(url)
|
64 |
+
response.raise_for_status()
|
65 |
+
results = response.json()['results']
|
66 |
+
dates = [datetime.datetime.fromtimestamp(r['t']/1000) for r in results]
|
67 |
+
prices = [r['c'] for r in results]
|
68 |
+
return dates, prices
|
69 |
+
except Exception as e:
|
70 |
+
print(f"DEBUG: Error fetching historical prices: {e}")
|
71 |
+
return [], []
|
72 |
+
|
73 |
+
def calculate_ratios(market_cap, total_revenue, price, assumed_eps=5.0, growth_rate=0.1, book_value=500000000):
|
74 |
+
pe_ratio = price / assumed_eps if assumed_eps else 0
|
75 |
+
ps_ratio = market_cap / total_revenue if total_revenue else 0
|
76 |
+
pb_ratio = market_cap / book_value if book_value else 0
|
77 |
+
peg_ratio = pe_ratio / (growth_rate * 100) if growth_rate else 0
|
78 |
+
return {
|
79 |
+
'P/E Ratio': pe_ratio,
|
80 |
+
'P/S Ratio': ps_ratio,
|
81 |
+
'P/B Ratio': pb_ratio,
|
82 |
+
'PEG Ratio': peg_ratio
|
83 |
+
}
|
84 |
+
|
85 |
+
def generate_summary(info, ratios):
|
86 |
+
text = (f"{info['Name']} operates in the {info['Industry']} sector. It has a market capitalization of "
|
87 |
+
f"${info['Market Cap']:,.2f}. The company exhibits a P/E ratio of {ratios['P/E Ratio']:.2f}, "
|
88 |
+
f"P/S ratio of {ratios['P/S Ratio']:.2f}, and P/B ratio of {ratios['P/B Ratio']:.2f}. "
|
89 |
+
f"This suggests a {'potential undervaluation' if ratios['P/E Ratio'] < 20 else 'higher valuation'} relative to the market.")
|
90 |
+
summary = summarizer(text, max_length=120, min_length=30, do_sample=False)[0]['summary_text']
|
91 |
+
return summary
|
92 |
+
|
93 |
+
def stock_research(symbol, assumed_eps=5.0, growth_rate=0.1, book_value=500000000):
|
94 |
+
info = get_company_info(symbol)
|
95 |
+
price = get_current_price(symbol)
|
96 |
+
dividends = get_dividends(symbol)
|
97 |
+
dates, prices = get_historical_prices(symbol)
|
98 |
+
|
99 |
+
if not info or not price:
|
100 |
+
return "Error fetching stock information.", None, None, None
|
101 |
+
|
102 |
+
ratios = calculate_ratios(info['Market Cap'], info['Total Revenue'], price, assumed_eps, growth_rate, book_value)
|
103 |
+
summary = generate_summary(info, ratios)
|
104 |
+
|
105 |
+
# Create historical price chart
|
106 |
+
fig, ax = plt.subplots()
|
107 |
+
ax.plot(dates, prices, label=f"{symbol} Price")
|
108 |
+
ax.set_title(f"{symbol} Historical Price (1 Year)")
|
109 |
+
ax.set_xlabel("Date")
|
110 |
+
ax.set_ylabel("Price ($)")
|
111 |
+
ax.legend()
|
112 |
+
ax.grid(True)
|
113 |
+
|
114 |
+
info_table = pd.DataFrame({"Metric": list(info.keys()), "Value": list(info.values())})
|
115 |
+
ratios_table = pd.DataFrame({"Ratio": list(ratios.keys()), "Value": list(ratios.values())})
|
116 |
+
|
117 |
+
return summary, info_table, ratios_table, fig
|
118 |
+
|
119 |
+
iface = gr.Interface(
|
120 |
+
fn=stock_research,
|
121 |
+
inputs=[
|
122 |
+
gr.Textbox(label="Stock Symbol (e.g., AAPL)"),
|
123 |
+
gr.Number(label="Assumed EPS (default 5.0)"),
|
124 |
+
gr.Number(label="Assumed Growth Rate (e.g., 0.1 for 10%)"),
|
125 |
+
gr.Number(label="Assumed Book Value ($, default 500M)")
|
126 |
+
],
|
127 |
+
outputs=[
|
128 |
+
gr.Textbox(label="AI Research Summary"),
|
129 |
+
gr.Dataframe(label="Company Snapshot"),
|
130 |
+
gr.Dataframe(label="Valuation Ratios"),
|
131 |
+
gr.Plot(label="Historical Price Chart")
|
132 |
+
],
|
133 |
+
title="AI-Powered Stock Researcher",
|
134 |
+
description="Enter a stock symbol to get company info, valuation ratios, a 1-year price chart, and an AI-generated research summary based on live Polygon.io data."
|
135 |
+
)
|
136 |
+
|
137 |
+
if __name__ == "__main__":
|
138 |
+
iface.launch()
|