Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,139 +1,53 @@
|
|
1 |
import streamlit as st
|
2 |
-
import
|
3 |
-
import
|
4 |
-
import json
|
5 |
import requests
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
#
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
else:
|
24 |
-
st.
|
25 |
-
return
|
26 |
-
|
27 |
-
#
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
price = data['data'][0]['p']
|
33 |
-
real_time_data[symbol] = price
|
34 |
-
|
35 |
-
# WebSocket setup to fetch real-time data
|
36 |
-
def on_error(ws, error):
|
37 |
-
print(f"Error: {error}")
|
38 |
-
|
39 |
-
def on_close(ws):
|
40 |
-
print("### closed ###")
|
41 |
-
|
42 |
-
def on_open(ws):
|
43 |
-
# Subscribe to tickers dynamically fetched
|
44 |
-
for ticker in tickers:
|
45 |
-
ws.send(json.dumps({"type": "subscribe", "symbol": ticker}))
|
46 |
-
|
47 |
-
# WebSocket thread function
|
48 |
-
def start_websocket():
|
49 |
-
websocket.enableTrace(True)
|
50 |
-
ws = websocket.WebSocketApp(f"wss://ws.finnhub.io?token={FINNHUB_API_KEY}",
|
51 |
-
on_message=on_message,
|
52 |
-
on_error=on_error,
|
53 |
-
on_close=on_close)
|
54 |
-
ws.on_open = on_open
|
55 |
-
ws.run_forever()
|
56 |
-
|
57 |
-
# Function to start WebSocket in a separate thread
|
58 |
-
def run_websocket_thread():
|
59 |
-
websocket_thread = threading.Thread(target=start_websocket)
|
60 |
-
websocket_thread.daemon = True
|
61 |
-
websocket_thread.start()
|
62 |
-
|
63 |
-
# Function to fetch stock data for a given ticker (HTTP request)
|
64 |
-
def get_stock_data(tickers):
|
65 |
-
stock_data = []
|
66 |
-
for ticker in tickers:
|
67 |
-
url = f'https://finnhub.io/api/v1/quote'
|
68 |
-
params = {'symbol': ticker, 'token': FINNHUB_API_KEY}
|
69 |
-
response = requests.get(url, params=params)
|
70 |
-
if response.status_code == 200:
|
71 |
-
data = response.json()
|
72 |
-
stock_data.append({
|
73 |
-
'Ticker': ticker,
|
74 |
-
'Current Price': data.get('c', 'N/A'),
|
75 |
-
'High Price': data.get('h', 'N/A'),
|
76 |
-
'Low Price': data.get('l', 'N/A'),
|
77 |
-
'Open Price': data.get('o', 'N/A'),
|
78 |
-
'Previous Close Price': data.get('pc', 'N/A')
|
79 |
-
})
|
80 |
-
return stock_data
|
81 |
-
|
82 |
-
# Investment advice logic
|
83 |
-
def investment_advice(stock_data):
|
84 |
-
recommendations = []
|
85 |
-
for stock in stock_data:
|
86 |
-
ticker = stock['Ticker']
|
87 |
-
current_price = stock['Current Price']
|
88 |
-
if current_price == 'N/A':
|
89 |
-
recommendations.append(f"Data not available for {ticker}.")
|
90 |
-
elif float(current_price) > 1000: # Example threshold for high-priced stock
|
91 |
-
recommendations.append(f"Stock {ticker} has a high current price ({current_price}). Caution: Potential overvaluation.")
|
92 |
-
elif float(current_price) < 50: # Example threshold for low-priced stock
|
93 |
-
recommendations.append(f"Stock {ticker} has a low current price ({current_price}). Caution: Potential undervaluation.")
|
94 |
-
else:
|
95 |
-
recommendations.append(f"Stock {ticker} has a moderate current price ({current_price}). Consider for investment.")
|
96 |
-
return recommendations
|
97 |
-
|
98 |
-
# Streamlit UI setup
|
99 |
-
st.title("AI-Powered Investment Advisory App")
|
100 |
-
|
101 |
-
# User input for investment amount and desired return
|
102 |
-
investment_amount = st.number_input("Enter investment amount ($):", min_value=100, value=1000)
|
103 |
-
desired_return = st.number_input("Enter desired return (%):", min_value=0.0, value=5.0)
|
104 |
-
|
105 |
-
# Fetch top 5 tickers dynamically
|
106 |
-
st.subheader("Fetching top 5 trending stock tickers...")
|
107 |
-
tickers = fetch_top_tickers()
|
108 |
-
|
109 |
-
if tickers:
|
110 |
-
# Start WebSocket thread to listen to real-time data
|
111 |
-
run_websocket_thread()
|
112 |
-
|
113 |
-
# Fetch initial stock data (for a snapshot of stock details)
|
114 |
-
st.subheader("Fetching stock data for top 5 tickers...")
|
115 |
-
stock_data = get_stock_data(tickers)
|
116 |
-
|
117 |
-
# Display fetched stock data
|
118 |
-
st.subheader("Top 5 Stocks Based on Current Market Data")
|
119 |
-
for stock in stock_data:
|
120 |
-
st.write(stock)
|
121 |
-
|
122 |
-
# Display real-time stock prices
|
123 |
-
st.subheader("Real-Time Stock Prices")
|
124 |
-
for ticker in tickers:
|
125 |
-
if ticker in real_time_data:
|
126 |
-
st.write(f"Real-time price of {ticker}: {real_time_data[ticker]}")
|
127 |
-
|
128 |
-
# Provide investment advice based on stock data
|
129 |
-
st.subheader("Investment Advice")
|
130 |
-
recommendations = investment_advice(stock_data)
|
131 |
-
for recommendation in recommendations:
|
132 |
-
st.write(recommendation)
|
133 |
-
|
134 |
-
# Portfolio allocation suggestion
|
135 |
-
st.subheader("Portfolio Allocation Recommendation")
|
136 |
-
allocation = investment_amount / len(tickers) # Equal allocation for simplicity
|
137 |
-
st.write(f"Recommended Portfolio Allocation (per stock): ${allocation:.2f}")
|
138 |
else:
|
139 |
-
st.
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
+
from transformers import pipeline
|
3 |
+
import yfinance as yf
|
|
|
4 |
import requests
|
5 |
+
from bs4 import BeautifulSoup
|
6 |
+
import xml.etree.ElementTree as ET
|
7 |
+
import datetime
|
8 |
+
|
9 |
+
# Set up the models for Named Entity Recognition, Sentiment Analysis, and Text Generation
|
10 |
+
ner_model = "Cassie-0121/fin-bert-finetuned-ner"
|
11 |
+
sentiment_model = "yiyanghkust/finbert-tone"
|
12 |
+
text_gen_model = "gpt2"
|
13 |
+
|
14 |
+
ner = pipeline("ner", model=ner_model)
|
15 |
+
sentiment_analyzer = pipeline("sentiment-analysis", model=sentiment_model)
|
16 |
+
text_generator = pipeline("text-generation", model=text_gen_model)
|
17 |
+
|
18 |
+
# App title
|
19 |
+
st.title("AI-Powered Financial Analysis App")
|
20 |
+
|
21 |
+
# Sidebar for selecting stock
|
22 |
+
st.sidebar.header("Select Stock for Analysis")
|
23 |
+
top_25_stocks = [
|
24 |
+
"AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "META", "NVDA", "BRK-B", "JNJ", "JPM",
|
25 |
+
"V", "PG", "UNH", "DIS", "MA", "HD", "BAC", "XOM", "VZ", "PFE",
|
26 |
+
"KO", "PEP", "MRK", "WMT", "CSCO"
|
27 |
+
]
|
28 |
+
selected_stock = st.sidebar.selectbox("Choose a stock for analysis:", top_25_stocks)
|
29 |
+
|
30 |
+
# Function to fetch the latest stock data using yfinance with dynamic date handling
|
31 |
+
def get_stock_data(ticker):
|
32 |
+
stock = yf.Ticker(ticker)
|
33 |
+
today = datetime.datetime.now().date()
|
34 |
+
|
35 |
+
# Try fetching the data for today, but fall back to the most recent available date if markets are closed
|
36 |
+
stock_info = stock.history(period="5d") # Fetch data for the last 5 days to account for weekends or holidays
|
37 |
+
if not stock_info.empty:
|
38 |
+
# Get the most recent available data
|
39 |
+
latest_data = stock_info.iloc[-1]
|
40 |
+
return latest_data
|
41 |
else:
|
42 |
+
st.warning("No recent stock data available. Please try again later.")
|
43 |
+
return None
|
44 |
+
|
45 |
+
# Display stock data
|
46 |
+
st.header(f"Latest Stock Data for {selected_stock}")
|
47 |
+
stock_data = get_stock_data(selected_stock)
|
48 |
+
if stock_data is not None:
|
49 |
+
st.write(stock_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
else:
|
51 |
+
st.write("Could not retrieve stock data at this time.")
|
52 |
+
|
53 |
+
# Other components like fetching news, NER, and sentiment analysis would remain the same
|