Spaces:
Sleeping
Sleeping
File size: 4,531 Bytes
c0c59ce 85b7a89 3c4450e 958b14a 011359b ada01c4 3c4450e ada01c4 3c4450e f77f56c ada01c4 f77f56c ada01c4 f77f56c ada01c4 f77f56c ada01c4 45ab29a 94126ed 45ab29a 0424c3b 94126ed 602a247 ada01c4 94126ed 55e99f6 ada01c4 94126ed ada01c4 3c4450e 94126ed ada01c4 3c4450e 94126ed 55e99f6 3c4450e 94126ed 261a5a7 ada01c4 3c4450e ada01c4 3c4450e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
import streamlit as st
import yfinance as yf
import pandas as pd
@st.experimental_singleton
def get_sp500_list():
table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
return table[0]['Symbol'].tolist()
def load_sp500_averages(filepath):
return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
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
}
# Debug: Print to see if financials are fetched correctly
print(f"Financials for {ticker_symbol}: {financials}")
return financials, info
def compare_to_index(stock_ratios, index_averages):
comparison = {}
score = 0
for ratio, value in stock_ratios.items():
if ratio in index_averages.index and pd.notna(value):
average = index_averages.loc[ratio, 'Average']
comparison[ratio] = 'Undervalued' if value < average else 'Overvalued'
score += 1 if value < average else -1
return comparison, score
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)
def color_combined_score(value):
if value > 0:
color = 'green'
elif value < 0:
color = 'red'
else:
color = 'lightgrey'
return f'background-color: {color};'
def filter_incomplete_stocks(df, required_columns):
# Ensure all required columns exist in the DataFrame
for column in required_columns:
if column not in df.columns:
df[column] = pd.NA
return df.dropna(subset=required_columns)
st.title('S&P 500 Stock Comparison Tool')
sp500_list = get_sp500_list()
sp500_averages = load_sp500_averages('sp500_averages.csv')
scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
# Debug: Print the DataFrame before filtering to see its content
print("Scores DataFrame before filtering:", scores_df.head())
required_columns = ['P/E Ratio', 'P/B Ratio', 'P/S Ratio', 'Debt to Equity Ratio', 'Return on Equity', 'Book-to-Market Ratio']
# Attempt a lenient filtering approach or skip filtering to debug
# scores_df_filtered = filter_incomplete_stocks(scores_df, required_columns)
scores_df_filtered = scores_df # Temporarily bypass filtering to debug
scores_df_sorted = scores_df_filtered.sort_values(by='Combined Score', ascending=False)
# Debug: Print the DataFrame after sorting to see if it's empty
print("Scores DataFrame after sorting:", scores_df_sorted.head())
col1, col2 = st.columns([3, 5])
with col1:
st.subheader("Stock Overview")
if not scores_df_sorted.empty:
styled_scores_df = scores_df_sorted.style.applymap(color_combined_score, subset=['Combined Score'])
st.dataframe(styled_scores_df)
else:
st.write("No data available after filtering.")
with col2:
st.subheader("Stock Details")
if not scores_df_sorted.empty:
sorted_tickers = scores_df_sorted['Stock'].tolist()
ticker_symbol = st.selectbox('Select a stock for details', options=sorted_tickers)
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)
st.write(f"**{info.get('longName', 'N/A')}** ({ticker_symbol})")
st.write(info.get('longBusinessSummary', 'N/A'))
for ratio in required_columns:
value = stock_data.get(ratio, 'N/A')
average = sp500_averages.loc[ratio, 'Average'] if ratio in sp500_averages.index else 'N/A'
status = comparison.get(ratio, 'N/A')
st.write(f"{ratio}: {value} (Your Ratio) | {average} (S&P 500 Avg) - {status}")
else:
st.write("No stocks to display.") |