os1187 commited on
Commit
f77f56c
1 Parent(s): ada01c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -110
app.py CHANGED
@@ -2,100 +2,18 @@ import streamlit as st
2
  import yfinance as yf
3
  import pandas as pd
4
 
5
- # Define the path to your CSV file
6
- sp500_averages_path = 'sp500_averages.csv'
7
-
8
- def load_sp500_averages(filepath):
9
- # Load the CSV without specifying an index column name
10
- return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
11
-
12
- # Fetch financial data for a single stock
13
- def fetch_stock_data(ticker_symbol):
14
- ticker = yf.Ticker(ticker_symbol)
15
- info = ticker.info
16
-
17
- # Calculate Book-to-Market Ratio
18
- pb_ratio = info.get('priceToBook')
19
- book_to_market_ratio = 1 / pb_ratio if pb_ratio and pb_ratio > 0 else None
20
-
21
- # Extract relevant financial information, including Book-to-Market Ratio
22
- financials = {
23
- 'P/E Ratio': info.get('forwardPE'),
24
- 'P/B Ratio': pb_ratio,
25
- 'P/S Ratio': info.get('priceToSalesTrailing12Months'),
26
- 'Debt to Equity Ratio': info.get('debtToEquity'),
27
- 'Return on Equity': info.get('returnOnEquity'),
28
- 'Book-to-Market Ratio': book_to_market_ratio,
29
- }
30
-
31
- return financials, info
32
-
33
-
34
- # Update the cache decorator
35
- @st.experimental_memo
36
  def get_sp500_list():
37
  table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
38
  return table[0]['Symbol'].tolist()
39
 
40
- # Use the updated cache function and define the CSV path
41
- sp500_list = get_sp500_list()
42
- sp500_averages = load_sp500_averages(sp500_averages_path)
43
-
44
- # Calculate combined scores for stocks in the S&P 500
45
- scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
46
- scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
47
-
48
- # Use columns for side-by-side layout
49
- col1, col2 = st.columns([1, 3])
50
-
51
- # First column for the sorted overview
52
- with col1:
53
- st.subheader("Stock Overview")
54
- # Create a DataFrame for the sidebar with color-coded combined scores
55
- scores_df_sorted['color'] = scores_df_sorted['Combined Score'].apply(
56
- lambda x: 'green' if x > 0 else 'red' if x < 0 else 'grey')
57
- for index, row in scores_df_sorted.iterrows():
58
- color = row['color']
59
- st.markdown(f"<span style='color: {color};'>{row['Stock']}: {row['Combined Score']}</span>", unsafe_allow_html=True)
60
-
61
- # Second column for detailed financial ratios and company information
62
- with col2:
63
- st.subheader("Stock Details")
64
- # Dropdown to select stock for details
65
- ticker_symbol = st.selectbox('Select a stock for details', options=sp500_list)
66
- if ticker_symbol:
67
- with st.spinner(f'Fetching data for {ticker_symbol}...'):
68
- stock_data, info = fetch_stock_data(ticker_symbol)
69
- comparison, _ = compare_to_index(stock_data, sp500_averages)
70
-
71
- # Display company name and description
72
- st.write(f"**{info.get('longName')}**")
73
- st.write(info.get('longBusinessSummary'))
74
-
75
- # Display financial ratios in a table
76
- st.table(pd.DataFrame.from_dict(stock_data, orient='index', columns=['Value']))
77
-
78
-
79
-
80
- import streamlit as st
81
- import yfinance as yf
82
- import pandas as pd
83
-
84
  # Define the path to your CSV file with S&P 500 averages
85
  sp500_averages_path = 'sp500_averages.csv'
86
 
87
- # Define the function to load S&P 500 averages from a CSV file
88
- @st.experimental_memo
89
- def get_sp500_list():
90
- table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
91
- return table[0]['Symbol'].tolist()
92
-
93
- # Define the function to load S&P 500 averages from a CSV file
94
- sp500_averages_path = 'sp500_averages.csv'
95
  def load_sp500_averages(filepath):
96
  return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
97
 
98
- # Define the function to fetch financial data for a single stock
99
  def fetch_stock_data(ticker_symbol):
100
  ticker = yf.Ticker(ticker_symbol)
101
  info = ticker.info
@@ -107,30 +25,23 @@ def fetch_stock_data(ticker_symbol):
107
  'Return on Equity': info.get('returnOnEquity'),
108
  'Book-to-Market Ratio': 1 / info.get('priceToBook') if info.get('priceToBook') else None
109
  }
110
- return financials
111
 
112
- # Define the function to compare stock ratios to S&P 500 averages
113
  def compare_to_index(stock_ratios, index_averages):
114
  comparison = {}
115
  score = 0
116
  for ratio, value in stock_ratios.items():
117
- if pd.notna(value):
118
  average = index_averages.loc[ratio, 'Average']
119
- if value < average: # For ratios where lower is better
120
- comparison[ratio] = 'Undervalued'
121
- score += 1
122
- elif value > average: # For ratios where higher is not better
123
- comparison[ratio] = 'Overvalued'
124
- score -= 1
125
- else:
126
- comparison[ratio] = 'Data not available'
127
  return comparison, score
128
 
129
- # Define the function to calculate combined scores for stocks
130
  def calculate_combined_scores_for_stocks(stocks, index_averages):
131
  scores = []
132
  for ticker_symbol in stocks:
133
- stock_data = fetch_stock_data(ticker_symbol)
134
  comparison, score = compare_to_index(stock_data, index_averages)
135
  scores.append({'Stock': ticker_symbol, 'Combined Score': score})
136
  return pd.DataFrame(scores)
@@ -138,7 +49,7 @@ def calculate_combined_scores_for_stocks(stocks, index_averages):
138
  # User interface in Streamlit
139
  st.title('S&P 500 Stock Comparison Tool')
140
 
141
- # Fetch the current S&P 500 list and load the averages
142
  sp500_list = get_sp500_list()
143
  sp500_averages = load_sp500_averages(sp500_averages_path)
144
 
@@ -146,28 +57,24 @@ sp500_averages = load_sp500_averages(sp500_averages_path)
146
  scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
147
  scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
148
 
149
- # Use columns for side-by-side layout
150
  col1, col2 = st.columns([1, 3])
151
 
152
- # First column for the sorted overview
153
  with col1:
154
  st.subheader("Stock Overview")
155
  st.dataframe(scores_df_sorted.style.applymap(lambda x: 'background-color: green' if x > 0
156
- else ('background-color: red' if x < 0 else '')))
157
 
158
- # Second column for detailed financial ratios and company information
159
  with col2:
160
  st.subheader("Stock Details")
161
  ticker_symbol = st.selectbox('Select a stock for details', options=sp500_list)
162
  if ticker_symbol:
163
- with st.spinner(f'Fetching data for {ticker_symbol}...'):
164
- stock_data = fetch_stock_data(ticker_symbol)
165
- comparison, _ = compare_to_index(stock_data, sp500_averages)
166
-
167
- st.write(f"**{ticker_symbol} - {yf.Ticker(ticker_symbol).info['longName']}**")
168
- st.write("Financial Ratios compared to S&P 500 averages:")
169
- for ratio, status in comparison.items():
170
- st.write(f"{ratio}: {status}")
171
 
172
 
173
 
 
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
 
 
17
  def fetch_stock_data(ticker_symbol):
18
  ticker = yf.Ticker(ticker_symbol)
19
  info = ticker.info
 
25
  'Return on Equity': info.get('returnOnEquity'),
26
  'Book-to-Market Ratio': 1 / info.get('priceToBook') if info.get('priceToBook') else None
27
  }
28
+ return financials, info
29
 
 
30
  def compare_to_index(stock_ratios, index_averages):
31
  comparison = {}
32
  score = 0
33
  for ratio, value in stock_ratios.items():
34
+ if ratio in index_averages.index and pd.notna(value):
35
  average = index_averages.loc[ratio, 'Average']
36
+ comparison[ratio] = 'Undervalued' if value < average else 'Overvalued'
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:
44
+ stock_data, _ = fetch_stock_data(ticker_symbol)
45
  comparison, score = compare_to_index(stock_data, index_averages)
46
  scores.append({'Stock': ticker_symbol, 'Combined Score': score})
47
  return pd.DataFrame(scores)
 
49
  # User interface in Streamlit
50
  st.title('S&P 500 Stock Comparison Tool')
51
 
52
+ # Load the current S&P 500 list and averages
53
  sp500_list = get_sp500_list()
54
  sp500_averages = load_sp500_averages(sp500_averages_path)
55
 
 
57
  scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
58
  scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
59
 
60
+ # Layout for displaying overview and details
61
  col1, col2 = st.columns([1, 3])
62
 
 
63
  with col1:
64
  st.subheader("Stock Overview")
65
  st.dataframe(scores_df_sorted.style.applymap(lambda x: 'background-color: green' if x > 0
66
+ else 'background-color: red' if x < 0 else 'none'), height=600)
67
 
 
68
  with col2:
69
  st.subheader("Stock Details")
70
  ticker_symbol = st.selectbox('Select a stock for details', options=sp500_list)
71
  if ticker_symbol:
72
+ stock_data, info = fetch_stock_data(ticker_symbol)
73
+ comparison, _ = compare_to_index(stock_data, sp500_averages)
74
+ st.write(f"**{info['longName']}** ({ticker_symbol})")
75
+ st.write(info['longBusinessSummary'])
76
+ for ratio, status in comparison.items():
77
+ st.write(f"{ratio}: {status}")
 
 
78
 
79
 
80