reab5555 commited on
Commit
e6aa77e
·
verified ·
1 Parent(s): 1fef11f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -20
app.py CHANGED
@@ -7,32 +7,57 @@ import yfinance as yf
7
  from datetime import datetime, timedelta
8
  import random
9
  import gradio as gr
10
- import io
11
- import base64
12
 
13
- # Keep all the existing functions (fetch_data, calculate_beta, calculate_r_squared,
14
- # determine_optimal_clusters, align_data, risk_level) as they are
15
-
16
- # Modify the main function to work with Gradio
17
- def analyze_stocks(stocks_filepath, index_symbol, years=5, progress=gr.Progress()):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  end_date = datetime.now()
19
  start_date = end_date - timedelta(days=365 * years)
20
 
21
  stock_symbols_df = pd.read_csv(stocks_filepath)
22
  stock_symbols = stock_symbols_df['Symbol'].tolist()
23
 
24
- progress(0, desc="Fetching market index data")
25
  index_data = fetch_data(index_symbol, start_date, end_date)
26
  index_data = index_data['Close'].to_frame(name='Close_index')
27
 
28
  betas = {}
29
  r_squared_values = {}
30
  latest_close_values = {}
31
- symbols = {}
32
  valid_stocks_count = 0
33
 
34
- for i, symbol in enumerate(stock_symbols):
35
- progress((i + 1) / len(stock_symbols), desc=f"Processing {symbol}")
36
  stock_data = fetch_data(symbol, start_date, end_date)
37
  stock_data = stock_data['Close'].to_frame(name='Close_stock')
38
 
@@ -48,7 +73,6 @@ def analyze_stocks(stocks_filepath, index_symbol, years=5, progress=gr.Progress(
48
  betas[symbol] = round(beta, 3)
49
  r_squared_values[symbol] = round(calculate_r_squared(aligned_data['Close_stock'].dropna(), aligned_data['Close_index'].dropna()), 3)
50
  latest_close_values[symbol] = round(stock_data['Close_stock'].iloc[-1], 3)
51
- symbols[symbol] = symbol
52
  valid_stocks_count += 1
53
 
54
  results_df = pd.DataFrame({
@@ -65,15 +89,13 @@ def analyze_stocks(stocks_filepath, index_symbol, years=5, progress=gr.Progress(
65
  scaler = StandardScaler()
66
  features = scaler.fit_transform(features)
67
 
68
- progress(0.9, desc="Determining optimal clusters")
69
- optimal_clusters = determine_optimal_clusters(features)
70
 
71
  gmm = GaussianMixture(n_components=optimal_clusters, random_state=42)
72
  cluster_labels = gmm.fit_predict(features)
73
  results_df['Cluster'] = cluster_labels
74
  results_df['Risk Level'] = results_df['Beta'].apply(risk_level)
75
 
76
- progress(0.95, desc="Generating plot")
77
  custom_colors = [f'rgb({random.random()}, {random.random()}, {random.random()})' for _ in range(optimal_clusters)]
78
 
79
  traces = []
@@ -84,9 +106,9 @@ def analyze_stocks(stocks_filepath, index_symbol, years=5, progress=gr.Progress(
84
  mode='markers', marker=dict(size=cluster_df['Latest Close'],
85
  sizeref=2. * max(cluster_df['Latest Close']) / (60. ** 2),
86
  sizemode='area'),
87
- hovertext=cluster_df['Symbol'] + '<br>' + cluster_df['Name'] + '<br>Beta: ' + cluster_df[
88
- 'Beta'].astype(str) + '<br>R-Squared: ' + cluster_df['R-Squared'].astype(
89
- str) + '<br>Latest Close Price: ' + cluster_df['Latest Close'].astype(str) +
90
  '<br>Risk Level: ' + cluster_df['Risk Level'] +
91
  '<br>Cluster Prob: ' + cluster_probs[cluster_df.index, cluster].round(3).astype(str),
92
  showlegend=False,
@@ -109,10 +131,8 @@ def analyze_stocks(stocks_filepath, index_symbol, years=5, progress=gr.Progress(
109
  text=f"Valid Stocks: {valid_stocks_count} | Date: {latest_date}",
110
  showarrow=False, font=dict(size=14, color="black"))
111
 
112
- progress(1.0, desc="Analysis complete")
113
  return fig
114
 
115
- # Gradio interface
116
  def gradio_interface(years):
117
  stocks_filepath = "SP500_stock_list_Jan-1-2024.csv"
118
  index_symbol = "^GSPC"
 
7
  from datetime import datetime, timedelta
8
  import random
9
  import gradio as gr
 
 
10
 
11
+ def fetch_data(symbol, start_date, end_date):
12
+ return yf.download(symbol, start=start_date, end=end_date)
13
+
14
+ def calculate_beta(stock_returns, market_returns):
15
+ if len(stock_returns) < 2 or len(market_returns) < 2:
16
+ return np.nan, np.nan, np.nan
17
+ covariance_matrix = np.cov(stock_returns, market_returns)
18
+ beta = covariance_matrix[0, 1] / covariance_matrix[1, 1]
19
+ return beta, covariance_matrix[0, 1], covariance_matrix[1, 1]
20
+
21
+ def calculate_r_squared(stock_returns, market_returns):
22
+ if len(stock_returns) < 2 or len(market_returns) < 2:
23
+ return np.nan
24
+ correlation_matrix = np.corrcoef(stock_returns, market_returns)
25
+ correlation_xy = correlation_matrix[0, 1]
26
+ r_squared = correlation_xy ** 2
27
+ return r_squared
28
+
29
+ def align_data(stock_data, index_data):
30
+ aligned_data = stock_data.join(index_data, how='inner', lsuffix='_stock', rsuffix='_index')
31
+ return aligned_data
32
+
33
+ def risk_level(beta):
34
+ if beta < 0.5:
35
+ return "Very Low Risk"
36
+ elif beta < 1:
37
+ return "Low Risk"
38
+ elif beta < 1.5:
39
+ return "Moderate Risk"
40
+ elif beta < 2:
41
+ return "High Risk"
42
+ else:
43
+ return "Very High Risk"
44
+
45
+ def analyze_stocks(stocks_filepath, index_symbol, years=5):
46
  end_date = datetime.now()
47
  start_date = end_date - timedelta(days=365 * years)
48
 
49
  stock_symbols_df = pd.read_csv(stocks_filepath)
50
  stock_symbols = stock_symbols_df['Symbol'].tolist()
51
 
 
52
  index_data = fetch_data(index_symbol, start_date, end_date)
53
  index_data = index_data['Close'].to_frame(name='Close_index')
54
 
55
  betas = {}
56
  r_squared_values = {}
57
  latest_close_values = {}
 
58
  valid_stocks_count = 0
59
 
60
+ for symbol in stock_symbols:
 
61
  stock_data = fetch_data(symbol, start_date, end_date)
62
  stock_data = stock_data['Close'].to_frame(name='Close_stock')
63
 
 
73
  betas[symbol] = round(beta, 3)
74
  r_squared_values[symbol] = round(calculate_r_squared(aligned_data['Close_stock'].dropna(), aligned_data['Close_index'].dropna()), 3)
75
  latest_close_values[symbol] = round(stock_data['Close_stock'].iloc[-1], 3)
 
76
  valid_stocks_count += 1
77
 
78
  results_df = pd.DataFrame({
 
89
  scaler = StandardScaler()
90
  features = scaler.fit_transform(features)
91
 
92
+ optimal_clusters = 5 # You can implement a method to determine this dynamically
 
93
 
94
  gmm = GaussianMixture(n_components=optimal_clusters, random_state=42)
95
  cluster_labels = gmm.fit_predict(features)
96
  results_df['Cluster'] = cluster_labels
97
  results_df['Risk Level'] = results_df['Beta'].apply(risk_level)
98
 
 
99
  custom_colors = [f'rgb({random.random()}, {random.random()}, {random.random()})' for _ in range(optimal_clusters)]
100
 
101
  traces = []
 
106
  mode='markers', marker=dict(size=cluster_df['Latest Close'],
107
  sizeref=2. * max(cluster_df['Latest Close']) / (60. ** 2),
108
  sizemode='area'),
109
+ hovertext=cluster_df['Symbol'] + '<br>' + cluster_df['Name'] + '<br>Beta: ' + cluster_df['Beta'].astype(str) +
110
+ '<br>R-Squared: ' + cluster_df['R-Squared'].astype(str) +
111
+ '<br>Latest Close Price: ' + cluster_df['Latest Close'].astype(str) +
112
  '<br>Risk Level: ' + cluster_df['Risk Level'] +
113
  '<br>Cluster Prob: ' + cluster_probs[cluster_df.index, cluster].round(3).astype(str),
114
  showlegend=False,
 
131
  text=f"Valid Stocks: {valid_stocks_count} | Date: {latest_date}",
132
  showarrow=False, font=dict(size=14, color="black"))
133
 
 
134
  return fig
135
 
 
136
  def gradio_interface(years):
137
  stocks_filepath = "SP500_stock_list_Jan-1-2024.csv"
138
  index_symbol = "^GSPC"