import streamlit as st
import pandas as pd
import yfinance as yf
from datetime import date
import base64
import plotly.graph_objects as go
from streamlit_extras.stylable_container import stylable_container
# --- Configuration de la Page ---
st.set_page_config(
page_title="Analyse des Actions du S&P 500",
page_icon="📈",
layout="wide",
initial_sidebar_state="expanded",
)
# --- Thème de Couleur Professionnel ---
primary_color = "#007bff"
secondary_color = "#6c757d"
background_color = "#f8f9fa"
text_color = "#343a40"
card_bg_color = "white"
card_shadow = "0 0.5rem 1rem rgba(0, 0, 0, 0.05)"
border_radius = "0.5rem"
# --- Styles CSS Personnalisés ---
st.markdown(
f"""
""",
unsafe_allow_html=True,
)
# --- Conteneur Principal ---
with stylable_container(key="main_container", css_styles=f"""
padding: 2rem;
border-radius: {border_radius};
background-color: {background_color};
"""):
# --- Titre de l'Application ---
st.title('📊 Analyse des Actions du S&P 500')
st.write('Explorez les données et les prix de clôture des entreprises du S&P 500.')
# --- Lien vers la Source ---
st.markdown(f'Source des Données', unsafe_allow_html=True)
# --- Sidebar pour les Filtres ---
with st.sidebar:
st.header('⚙️ Filtres')
# Sélection du secteur d'activité sur le sidebar
@st.cache_data
def load_sp500_data():
url = 'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies'
tables = pd.read_html(url)
df = tables[0]
return df
sp500_df = load_sp500_data()
sorted_sector_unique = sorted(sp500_df['GICS Sector'].unique())
selected_sector = st.sidebar.multiselect('Sélectionner le(s) Secteur(s)', sorted_sector_unique)
# Sélection des secteurs d'activité et shape
df_selected_sector = sp500_df[(sp500_df['GICS Sector'].isin(selected_sector))]
num_companies = st.sidebar.slider('Nombre d\'Entreprises à Afficher', 1, 5)
# --- Affichage des Données Sélectionnées ---
st.subheader('🏢 Entreprises Sélectionnées')
if not df_selected_sector.empty:
st.markdown(f"Nombre d'entreprises sélectionnées : **{df_selected_sector.shape[0]}**")
with st.container(border=True, height=300):
st.dataframe(df_selected_sector[['Symbol', 'Security', 'GICS Sector']], height=300)
# --- Téléchargement des Données ---
def filedownload(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode()
href = f'Télécharger les Données CSV'
return href
st.markdown(filedownload(df_selected_sector), unsafe_allow_html=True)
# --- Affichage des Graphiques ---
if st.button('Afficher les Graphiques de Prix'):
st.subheader('📈 Prix de Clôture des Actions')
try:
data = yf.download(
tickers=list(df_selected_sector[:num_companies].Symbol),
period="ytd",
interval="1d",
group_by="ticker",
auto_adjust=True,
prepost=True,
threads=True,
proxy=None
)
for company in list(df_selected_sector.Symbol)[:num_companies]:
if company in data:
df_plot = pd.DataFrame(data[company].Close)
df_plot['Date'] = df_plot.index
fig = go.Figure()
fig.add_trace(go.Scatter(x=df_plot['Date'], y=df_plot['Close'], mode='lines+markers', name='Prix de Clôture', line=dict(color=primary_color)))
fig.update_layout(
title=f'Prix de Clôture de {company}',
xaxis_title='Date',
yaxis_title='Prix de Clôture',
xaxis_rangeslider_visible=True,
template="plotly_white"
)
with st.container(border=True, height=400):
st.plotly_chart(fig, use_container_width=True)
else:
st.warning(f"Les données pour l'action **{company}** n'ont pas pu être récupérées.")
except Exception as e:
st.error(f"Une erreur s'est produite lors de la récupération des données boursières : {e}")
else:
st.info("Veuillez sélectionner au moins un secteur dans la barre latérale pour afficher les entreprises.")
st.markdown("---")
st.caption("Application développée avec Streamlit.")