Spaces:
Sleeping
Sleeping
| 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""" | |
| <style> | |
| .reportview-container {{ | |
| background-color: {background_color}; | |
| }} | |
| .main {{ | |
| background-color: {background_color}; | |
| padding: 2rem; | |
| }} | |
| h1 {{ | |
| color: {primary_color}; | |
| text-align: center; | |
| margin-bottom: 2.5rem; | |
| }} | |
| h2 {{ | |
| color: {text_color}; | |
| margin-top: 2rem; | |
| border-bottom: 2px solid {secondary_color}; | |
| padding-bottom: 0.75rem; | |
| margin-bottom: 1.5rem; | |
| }} | |
| .st-sidebar h1 {{ | |
| color: {primary_color}; | |
| text-align: left; | |
| margin-bottom: 1rem; | |
| }} | |
| .st-sidebar .st-header {{ | |
| color: {primary_color}; | |
| }} | |
| .st-multiselect > div > div > div {{ | |
| background-color: {card_bg_color}; | |
| border: 1px solid #ced4da; | |
| border-radius: {border_radius}; | |
| color: {text_color}; | |
| padding: 0.75rem; | |
| font-size: 1rem; | |
| box-shadow: {card_shadow}; | |
| }} | |
| .st-slider > div > div > div > div {{ | |
| background-color: {card_bg_color}; | |
| border: 1px solid #ced4da; | |
| border-radius: {border_radius}; | |
| padding: 0.75rem; | |
| font-size: 1rem; | |
| box-shadow: {card_shadow}; | |
| }} | |
| .st-button > button {{ | |
| background-color: {primary_color}; | |
| color: white; | |
| border: none; | |
| border-radius: {border_radius}; | |
| padding: 0.75rem 1.5rem; | |
| font-size: 1rem; | |
| box-shadow: {card_shadow}; | |
| cursor: pointer; | |
| transition: background-color 0.3s ease; | |
| }} | |
| .st-button > button:hover {{ | |
| background-color: #0056b3; | |
| }} | |
| .plot-container {{ | |
| background-color: {card_bg_color}; | |
| border-radius: {border_radius}; | |
| box-shadow: {card_shadow}; | |
| padding: 1.5rem; | |
| margin-top: 1rem; | |
| }} | |
| .dataframe-container {{ | |
| background-color: {card_bg_color}; | |
| border-radius: {border_radius}; | |
| box-shadow: {card_shadow}; | |
| padding: 1.5rem; | |
| margin-top: 1rem; | |
| overflow-x: auto; | |
| }} | |
| .dataframe-container table {{ | |
| width: 100%; | |
| }} | |
| .link-button {{ | |
| display: inline-block; | |
| padding: 0.5rem 1rem; | |
| color: {primary_color}; | |
| text-decoration: none; | |
| border: 1px solid {primary_color}; | |
| border-radius: {border_radius}; | |
| font-size: 0.9rem; | |
| margin-top: 1rem; | |
| transition: background-color 0.3s ease, color 0.3s ease; | |
| }} | |
| .link-button:hover {{ | |
| background-color: {primary_color}; | |
| color: white; | |
| }} | |
| </style> | |
| """, | |
| 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'<a href="https://huggingface.co/spaces/Yves-Tana/Yahoo_finance" class="link-button" target="_blank">Source des Données</a>', unsafe_allow_html=True) | |
| # --- Sidebar pour les Filtres --- | |
| with st.sidebar: | |
| st.header('⚙️ Filtres') | |
| # Sélection du secteur d'activité sur le sidebar | |
| 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'<a href="data:file/csv;base64,{b64}" download="entreprises_sp500.csv">Télécharger les Données CSV</a>' | |
| 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.") |