os1187 commited on
Commit
958b14a
1 Parent(s): 7cf670a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -91
app.py CHANGED
@@ -2,34 +2,20 @@ import streamlit as st
2
  import yfinance as yf
3
  import pandas as pd
4
 
5
- # Predefined list of S&P 500 stocks for selection
6
- stocks = ['AAPL', 'MSFT', 'AMZN', 'GOOGL', 'FB', 'BRK.B', 'JNJ', 'V', 'PG', 'JPM',
7
- 'UNH', 'MA', 'INTC', 'VZ', 'HD', 'T', 'DIS', 'MRK', 'PFE', 'BAC',
8
- 'KO', 'WMT', 'MCD', 'ABT', 'CSCO', 'PEP', 'NFLX', 'XOM', 'CVX', 'NKE',
9
- 'LLY', 'ADBE', 'CMCSA', 'ORCL', 'CRM', 'TMO', 'ACN', 'ABBV', 'AVGO', 'TXN',
10
- 'COST', 'DHR', 'MDT', 'NEE', 'PYPL', 'AMGN', 'HON', 'LIN', 'PM', 'BA',
11
- 'UNP', 'IBM', 'QCOM', 'LMT', 'BMY', 'SBUX', 'MMM', 'GE', 'CAT', 'CVS',
12
- 'WFC', 'SCHW', 'RTX', 'AMT', 'GS', 'DE', 'C', 'MS', 'GILD', 'UPS',
13
- 'BLK', 'MO', 'MDLZ', 'INTU', 'TGT', 'AXP', 'ANTM', 'ISRG', 'SYK', 'CI',
14
- 'PGR', 'BKNG', 'CL', 'SPGI', 'MMC', 'BDX', 'ADP', 'CME', 'USB', 'TJX',
15
- 'ZTS', 'FIS', 'GM', 'CB', 'CHTR', 'PLD', 'SO', 'COP', 'DUK', 'EL']
16
-
17
- # Assuming you have an updated CSV with S&P 500 averages for financial ratios
18
- sp500_averages_path = 'sp500_averages.csv'
19
-
20
  def load_sp500_averages(filepath):
21
- # Load the CSV without specifying an index column name
22
  return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
23
 
24
-
25
  def fetch_stock_data(ticker_symbol):
26
- # Fetch financial data for a single stock
27
  ticker = yf.Ticker(ticker_symbol)
28
  info = ticker.info
29
 
 
30
  pb_ratio = info.get('priceToBook')
31
  book_to_market_ratio = 1 / pb_ratio if pb_ratio and pb_ratio > 0 else None
32
 
 
33
  financials = {
34
  'P/E Ratio': info.get('forwardPE'),
35
  'P/B Ratio': pb_ratio,
@@ -38,104 +24,58 @@ def fetch_stock_data(ticker_symbol):
38
  'Return on Equity': info.get('returnOnEquity'),
39
  'Book-to-Market Ratio': book_to_market_ratio,
40
  }
41
- return financials
42
-
43
- def compare_to_index(stock_ratios, index_averages):
44
- comparison = {}
45
- undervalued_count = 0
46
- overvalued_count = 0
47
-
48
- for ratio, value in stock_ratios.items():
49
- if ratio in index_averages.index and value is not None:
50
- average = index_averages.loc[ratio]['Average']
51
- # Interpretation for most ratios (higher = overvalued)
52
- if value > average:
53
- interpretation = 'Overvalued'
54
- overvalued_count += 1
55
- else:
56
- interpretation = 'Undervalued'
57
- undervalued_count += 1
58
-
59
- # Adjust interpretation for specific ratios
60
- if ratio in ['Book-to-Market Ratio']: # Example: higher means undervalued
61
- interpretation = 'Undervalued' if value > average else 'Overvalued'
62
- if interpretation == 'Undervalued':
63
- undervalued_count += 1 # Correct previous count if needed
64
- overvalued_count -= 1
65
- else:
66
- undervalued_count -= 1
67
- overvalued_count += 1
68
-
69
- comparison[ratio] = f"{interpretation} (Your Ratio: {value}, S&P 500 Avg: {average})"
70
- else:
71
- comparison[ratio] = 'N/A'
72
 
73
- # Calculate combined score
74
- combined_score = undervalued_count - overvalued_count
75
- comparison['Combined Score'] = combined_score
76
-
77
- return comparison, combined_score
78
 
 
79
 
80
- def calculate_combined_scores_for_stocks(stocks, index_averages):
81
- scores = []
82
 
83
- for ticker_symbol in stocks:
84
- try:
85
- stock_data = fetch_stock_data(ticker_symbol)
86
- _, combined_score = compare_to_index(stock_data, index_averages)
87
- scores.append([ticker_symbol, combined_score])
88
- except Exception as e:
89
- print(f"Error fetching data for {ticker_symbol}: {e}")
90
-
91
- scores_df = pd.DataFrame(scores, columns=['Stock', 'Combined Score'])
92
- return scores_df
93
 
 
94
 
95
  # Load S&P 500 averages
96
  sp500_averages = load_sp500_averages(sp500_averages_path)
97
 
98
- # User interface in Streamlit
99
- st.title('S&P 500 Stock Comparison Tool')
100
-
101
- # Fetch combined scores and overview if not already in session state
102
- if 'scores_df' not in st.session_state:
103
- st.session_state['scores_df'] = calculate_combined_scores_for_stocks(stocks, sp500_averages)
104
-
105
- # Sort the DataFrame by combined score for the overview
106
- scores_df_sorted = st.session_state['scores_df'].sort_values(by='Combined Score', ascending=False)
107
 
108
  # Use columns for side-by-side layout
109
- col1, col2 = st.columns([2, 3])
110
 
111
  # First column for the sorted overview
112
  with col1:
113
  st.subheader("Stock Overview")
114
- for _, row in scores_df_sorted.iterrows():
115
- color = "green" if row['Combined Score'] > 0 else "red" if row['Combined Score'] < 0 else "grey"
 
 
 
116
  st.markdown(f"<span style='color: {color};'>{row['Stock']}: {row['Combined Score']}</span>", unsafe_allow_html=True)
117
 
118
  # Second column for detailed financial ratios and company information
119
  with col2:
120
  st.subheader("Stock Details")
121
- ticker_symbol = st.selectbox('Select a stock for details', options=scores_df_sorted['Stock'].tolist())
 
122
  if ticker_symbol:
123
  with st.spinner(f'Fetching data for {ticker_symbol}...'):
124
- stock_data = fetch_stock_data(ticker_symbol)
125
  comparison, _ = compare_to_index(stock_data, sp500_averages)
126
 
127
- # Fetch additional information such as company name and description
128
- company_info = yf.Ticker(ticker_symbol).info
129
- company_name = company_info.get('longName')
130
- company_description = company_info.get('longBusinessSummary')
131
-
132
- st.write(f"**{company_name}**")
133
- st.write(company_description)
134
 
135
- st.write(f"**Financial Ratios for {ticker_symbol}:**")
136
- for ratio, result in comparison.items():
137
- if ratio != 'Combined Score': # Avoid repeating the combined score
138
- st.write(f"{ratio}: {result}")
139
 
140
 
141
 
 
2
  import yfinance as yf
3
  import pandas as pd
4
 
5
+ # Load S&P 500 averages from a CSV file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  def load_sp500_averages(filepath):
 
7
  return pd.read_csv(filepath, header=0, names=['Ratio', 'Average']).set_index('Ratio')
8
 
9
+ # Fetch financial data for a single stock
10
  def fetch_stock_data(ticker_symbol):
 
11
  ticker = yf.Ticker(ticker_symbol)
12
  info = ticker.info
13
 
14
+ # Calculate Book-to-Market Ratio
15
  pb_ratio = info.get('priceToBook')
16
  book_to_market_ratio = 1 / pb_ratio if pb_ratio and pb_ratio > 0 else None
17
 
18
+ # Extract relevant financial information, including Book-to-Market Ratio
19
  financials = {
20
  'P/E Ratio': info.get('forwardPE'),
21
  'P/B Ratio': pb_ratio,
 
24
  'Return on Equity': info.get('returnOnEquity'),
25
  'Book-to-Market Ratio': book_to_market_ratio,
26
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ return financials, info
 
 
 
 
29
 
30
+ # ... rest of your existing functions ...
31
 
32
+ # User interface in Streamlit
33
+ st.title('S&P 500 Stock Comparison Tool')
34
 
35
+ # Check if companies are in the S&P 500
36
+ @st.cache
37
+ def get_sp500_list():
38
+ table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
39
+ return table[0]['Symbol'].tolist()
 
 
 
 
 
40
 
41
+ sp500_list = get_sp500_list()
42
 
43
  # Load S&P 500 averages
44
  sp500_averages = load_sp500_averages(sp500_averages_path)
45
 
46
+ # Calculate combined scores for stocks in the S&P 500
47
+ scores_df = calculate_combined_scores_for_stocks(sp500_list, sp500_averages)
48
+ scores_df_sorted = scores_df.sort_values(by='Combined Score', ascending=False)
 
 
 
 
 
 
49
 
50
  # Use columns for side-by-side layout
51
+ col1, col2 = st.columns([1, 3])
52
 
53
  # First column for the sorted overview
54
  with col1:
55
  st.subheader("Stock Overview")
56
+ # Create a DataFrame for the sidebar with color-coded combined scores
57
+ scores_df_sorted['color'] = scores_df_sorted['Combined Score'].apply(
58
+ lambda x: 'green' if x > 0 else 'red' if x < 0 else 'grey')
59
+ for index, row in scores_df_sorted.iterrows():
60
+ color = row['color']
61
  st.markdown(f"<span style='color: {color};'>{row['Stock']}: {row['Combined Score']}</span>", unsafe_allow_html=True)
62
 
63
  # Second column for detailed financial ratios and company information
64
  with col2:
65
  st.subheader("Stock Details")
66
+ # Dropdown to select stock for details
67
+ ticker_symbol = st.selectbox('Select a stock for details', options=sp500_list)
68
  if ticker_symbol:
69
  with st.spinner(f'Fetching data for {ticker_symbol}...'):
70
+ stock_data, info = fetch_stock_data(ticker_symbol)
71
  comparison, _ = compare_to_index(stock_data, sp500_averages)
72
 
73
+ # Display company name and description
74
+ st.write(f"**{info.get('longName')}**")
75
+ st.write(info.get('longBusinessSummary'))
 
 
 
 
76
 
77
+ # Display financial ratios in a table
78
+ st.table(pd.DataFrame.from_dict(stock_data, orient='index', columns=['Value']))
 
 
79
 
80
 
81