os1187's picture
Update app.py
ada01c4 verified
raw
history blame
6.77 kB
import streamlit as st
import yfinance as yf
import pandas as pd
# Define the path to your CSV file
sp500_averages_path = 'sp500_averages.csv'
def load_sp500_averages(filepath):
# Load the CSV without specifying an index column name
return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
# Fetch financial data for a single stock
def fetch_stock_data(ticker_symbol):
ticker = yf.Ticker(ticker_symbol)
info = ticker.info
# Calculate Book-to-Market Ratio
pb_ratio = info.get('priceToBook')
book_to_market_ratio = 1 / pb_ratio if pb_ratio and pb_ratio > 0 else None
# Extract relevant financial information, including Book-to-Market Ratio
financials = {
'P/E Ratio': info.get('forwardPE'),
'P/B Ratio': pb_ratio,
'P/S Ratio': info.get('priceToSalesTrailing12Months'),
'Debt to Equity Ratio': info.get('debtToEquity'),
'Return on Equity': info.get('returnOnEquity'),
'Book-to-Market Ratio': book_to_market_ratio,
}
return financials, info
# Update the cache decorator
@st.experimental_memo
def get_sp500_list():
table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
return table[0]['Symbol'].tolist()
# Use the updated cache function and define the CSV path
sp500_list = get_sp500_list()
sp500_averages = load_sp500_averages(sp500_averages_path)
# Calculate combined scores for stocks in the S&P 500
scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
# Use columns for side-by-side layout
col1, col2 = st.columns([1, 3])
# First column for the sorted overview
with col1:
st.subheader("Stock Overview")
# Create a DataFrame for the sidebar with color-coded combined scores
scores_df_sorted['color'] = scores_df_sorted['Combined Score'].apply(
lambda x: 'green' if x > 0 else 'red' if x < 0 else 'grey')
for index, row in scores_df_sorted.iterrows():
color = row['color']
st.markdown(f"<span style='color: {color};'>{row['Stock']}: {row['Combined Score']}</span>", unsafe_allow_html=True)
# Second column for detailed financial ratios and company information
with col2:
st.subheader("Stock Details")
# Dropdown to select stock for details
ticker_symbol = st.selectbox('Select a stock for details', options=sp500_list)
if ticker_symbol:
with st.spinner(f'Fetching data for {ticker_symbol}...'):
stock_data, info = fetch_stock_data(ticker_symbol)
comparison, _ = compare_to_index(stock_data, sp500_averages)
# Display company name and description
st.write(f"**{info.get('longName')}**")
st.write(info.get('longBusinessSummary'))
# Display financial ratios in a table
st.table(pd.DataFrame.from_dict(stock_data, orient='index', columns=['Value']))
import streamlit as st
import yfinance as yf
import pandas as pd
# Define the path to your CSV file with S&P 500 averages
sp500_averages_path = 'sp500_averages.csv'
# Define the function to load S&P 500 averages from a CSV file
@st.experimental_memo
def get_sp500_list():
table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
return table[0]['Symbol'].tolist()
# Define the function to load S&P 500 averages from a CSV file
sp500_averages_path = 'sp500_averages.csv'
def load_sp500_averages(filepath):
return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
# Define the function to fetch financial data for a single stock
def fetch_stock_data(ticker_symbol):
ticker = yf.Ticker(ticker_symbol)
info = ticker.info
financials = {
'P/E Ratio': info.get('forwardPE'),
'P/B Ratio': info.get('priceToBook'),
'P/S Ratio': info.get('priceToSalesTrailing12Months'),
'Debt to Equity Ratio': info.get('debtToEquity'),
'Return on Equity': info.get('returnOnEquity'),
'Book-to-Market Ratio': 1 / info.get('priceToBook') if info.get('priceToBook') else None
}
return financials
# Define the function to compare stock ratios to S&P 500 averages
def compare_to_index(stock_ratios, index_averages):
comparison = {}
score = 0
for ratio, value in stock_ratios.items():
if pd.notna(value):
average = index_averages.loc[ratio, 'Average']
if value < average: # For ratios where lower is better
comparison[ratio] = 'Undervalued'
score += 1
elif value > average: # For ratios where higher is not better
comparison[ratio] = 'Overvalued'
score -= 1
else:
comparison[ratio] = 'Data not available'
return comparison, score
# Define the function to calculate combined scores for stocks
def calculate_combined_scores_for_stocks(stocks, index_averages):
scores = []
for ticker_symbol in stocks:
stock_data = fetch_stock_data(ticker_symbol)
comparison, score = compare_to_index(stock_data, index_averages)
scores.append({'Stock': ticker_symbol, 'Combined Score': score})
return pd.DataFrame(scores)
# User interface in Streamlit
st.title('S&P 500 Stock Comparison Tool')
# Fetch the current S&P 500 list and load the averages
sp500_list = get_sp500_list()
sp500_averages = load_sp500_averages(sp500_averages_path)
# Calculate combined scores for all S&P 500 stocks
scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
# Use columns for side-by-side layout
col1, col2 = st.columns([1, 3])
# First column for the sorted overview
with col1:
st.subheader("Stock Overview")
st.dataframe(scores_df_sorted.style.applymap(lambda x: 'background-color: green' if x > 0
else ('background-color: red' if x < 0 else '')))
# Second column for detailed financial ratios and company information
with col2:
st.subheader("Stock Details")
ticker_symbol = st.selectbox('Select a stock for details', options=sp500_list)
if ticker_symbol:
with st.spinner(f'Fetching data for {ticker_symbol}...'):
stock_data = fetch_stock_data(ticker_symbol)
comparison, _ = compare_to_index(stock_data, sp500_averages)
st.write(f"**{ticker_symbol} - {yf.Ticker(ticker_symbol).info['longName']}**")
st.write("Financial Ratios compared to S&P 500 averages:")
for ratio, status in comparison.items():
st.write(f"{ratio}: {status}")