os1187 commited on
Commit
94126ed
1 Parent(s): 55e99f6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -37
app.py CHANGED
@@ -2,15 +2,11 @@ import streamlit as st
2
  import yfinance as yf
3
  import pandas as pd
4
 
5
- # Correctly using st.cache_data as per Streamlit's new caching mechanism
6
- @st.cache_data
7
  def get_sp500_list():
8
  table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
9
  return table[0]['Symbol'].tolist()
10
 
11
- # Define the path to your CSV file with S&P 500 averages
12
- sp500_averages_path = 'sp500_averages.csv'
13
-
14
  def load_sp500_averages(filepath):
15
  return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
16
 
@@ -37,7 +33,6 @@ def compare_to_index(stock_ratios, index_averages):
37
  score += 1 if value < average else -1
38
  return comparison, score
39
 
40
- # Ensure this function is defined before it's called in the script
41
  def calculate_combined_scores_for_stocks(stocks, index_averages):
42
  scores = []
43
  for ticker_symbol in stocks:
@@ -46,63 +41,54 @@ def calculate_combined_scores_for_stocks(stocks, index_averages):
46
  scores.append({'Stock': ticker_symbol, 'Combined Score': score})
47
  return pd.DataFrame(scores)
48
 
49
- # Define the color-coding function for the 'Combined Score' column
50
  def color_combined_score(value):
51
- """Colors the combined score cell based on its value."""
52
  if value > 0:
53
  color = 'green'
54
  elif value < 0:
55
  color = 'red'
56
  else:
57
- color = 'none'
58
  return f'background-color: {color};'
59
 
60
- def filter_incomplete_stocks(df):
61
- # Assuming that 'N/A' represents missing data, replace it with NaN
62
- df.replace('N/A', pd.NA, inplace=True)
63
- # Drop rows with any NaN values in the specified columns
64
- return df.dropna(subset=['P/E Ratio', 'P/B Ratio', 'P/S Ratio', 'Debt to Equity Ratio', 'Return on Equity', 'Book-to-Market Ratio'])
65
-
66
- # User interface in Streamlit
67
- st.title('S&P 500 Stock Comparison Tool')
68
 
 
69
 
70
- # Load the current S&P 500 list and averages
71
  sp500_list = get_sp500_list()
72
- sp500_averages = load_sp500_averages(sp500_averages_path)
73
 
74
- # Calculate combined scores for all S&P 500 stocks
75
  scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
76
- scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
77
 
78
- # Filter out stocks with incomplete data
79
- scores_df_filtered = filter_incomplete_stocks(scores_df_sorted)
 
80
 
81
- # Layout for displaying overview and details
82
- col1, col2 = st.columns([3, 5]) # For example, this will give the first column 3/8 of the width
83
 
84
  with col1:
85
  st.subheader("Stock Overview")
86
- # Apply color based on 'Combined Score' value and display the DataFrame
87
- styled_scores_df = scores_df_filtered.style.applymap(color_combined_score, subset=['Combined Score'])
88
  st.dataframe(styled_scores_df)
89
 
90
  with col2:
91
  st.subheader("Stock Details")
92
- # Use the filtered DataFrame to create the dropdown for stock selection
93
- sorted_tickers = scores_df_filtered['Stock'].tolist()
94
  ticker_symbol = st.selectbox('Select a stock for details', options=sorted_tickers)
95
  if ticker_symbol:
96
  with st.spinner(f'Fetching data for {ticker_symbol}...'):
97
- stock_data, _ = fetch_stock_data(ticker_symbol)
98
  comparison, _ = compare_to_index(stock_data, sp500_averages)
99
 
100
- # Display the company name and ticker symbol
101
- st.write(f"**{ticker_symbol}**")
102
 
103
- # Display each financial ratio, its value, and the S&P 500 average
104
- for ratio in stock_data.keys():
105
- value = stock_data[ratio]
106
  average = sp500_averages.loc[ratio, 'Average'] if ratio in sp500_averages.index else 'N/A'
107
- comparison_result = comparison[ratio] if ratio in comparison else 'N/A'
108
- st.write(f"{ratio}: {value} (Your Ratio) | {average} (S&P 500 Avg) - {comparison_result}")
 
 
2
  import yfinance as yf
3
  import pandas as pd
4
 
5
+ @st.experimental_singleton
 
6
  def get_sp500_list():
7
  table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
8
  return table[0]['Symbol'].tolist()
9
 
 
 
 
10
  def load_sp500_averages(filepath):
11
  return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
12
 
 
33
  score += 1 if value < average else -1
34
  return comparison, score
35
 
 
36
  def calculate_combined_scores_for_stocks(stocks, index_averages):
37
  scores = []
38
  for ticker_symbol in stocks:
 
41
  scores.append({'Stock': ticker_symbol, 'Combined Score': score})
42
  return pd.DataFrame(scores)
43
 
 
44
  def color_combined_score(value):
 
45
  if value > 0:
46
  color = 'green'
47
  elif value < 0:
48
  color = 'red'
49
  else:
50
+ color = 'lightgrey'
51
  return f'background-color: {color};'
52
 
53
+ def filter_incomplete_stocks(df, required_columns):
54
+ df = df.dropna(subset=required_columns)
55
+ return df
 
 
 
 
 
56
 
57
+ st.title('S&P 500 Stock Comparison Tool')
58
 
 
59
  sp500_list = get_sp500_list()
60
+ sp500_averages = load_sp500_averages('sp500_averages.csv')
61
 
 
62
  scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
63
+ required_columns = ['P/E Ratio', 'P/B Ratio', 'P/S Ratio', 'Debt to Equity Ratio', 'Return on Equity', 'Book-to-Market Ratio']
64
 
65
+ # Ensure filtering is done correctly with complete data
66
+ scores_df_filtered = filter_incomplete_stocks(scores_df, required_columns)
67
+ scores_df_sorted = scores_df_filtered.sort_values(by='Combined Score', ascending=False)
68
 
69
+ col1, col2 = st.columns([3, 5])
 
70
 
71
  with col1:
72
  st.subheader("Stock Overview")
73
+ styled_scores_df = scores_df_sorted.style.applymap(color_combined_score, subset=['Combined Score'])
 
74
  st.dataframe(styled_scores_df)
75
 
76
  with col2:
77
  st.subheader("Stock Details")
78
+ sorted_tickers = scores_df_sorted['Stock'].tolist()
 
79
  ticker_symbol = st.selectbox('Select a stock for details', options=sorted_tickers)
80
  if ticker_symbol:
81
  with st.spinner(f'Fetching data for {ticker_symbol}...'):
82
+ stock_data, info = fetch_stock_data(ticker_symbol)
83
  comparison, _ = compare_to_index(stock_data, sp500_averages)
84
 
85
+ st.write(f"**{info.get('longName', 'N/A')}** ({ticker_symbol})")
86
+ st.write(info.get('longBusinessSummary', 'N/A'))
87
 
88
+ # Iterate over required_columns instead of required_ratios
89
+ for ratio in required_columns:
90
+ value = stock_data.get(ratio, 'N/A')
91
  average = sp500_averages.loc[ratio, 'Average'] if ratio in sp500_averages.index else 'N/A'
92
+ status = comparison.get(ratio, 'N/A')
93
+ st.write(f"{ratio}: {value} (Your Ratio) | {average} (S&P 500 Avg) - {status}")
94
+