import streamlit as st import os import sys import asyncio import numpy as np import pandas as pd import matplotlib.pyplot as plt from datetime import datetime, timedelta from pathlib import Path # Ajouter le répertoire src au path pour l'importation des modules current_dir = Path(__file__).parent.absolute() sys.path.append(str(current_dir)) # Import des modules DeepVest try: from src.core.profiling import DeepVestConfig, LLMProfileAnalyzer, DeepVestProfiler except ImportError: st.error("Impossible d'importer les modules DeepVest. Vérifiez que le dossier src est correctement structuré.") # Version simplifiée pour la démo si imports échoués class DeepVestConfig: def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) class LLMProfileAnalyzer: def __init__(self, config): self.config = config async def analyze_profile(self, data): return { "risk_score": data.get("risk_tolerance", 3)/5, "investment_horizon": data.get("investment_horizon", 5), "primary_goals": data.get("investment_goals", []), "recommendations": [ "Diversifier votre portefeuille", "Maintenir une épargne de sécurité", "Investir régulièrement" ], "explanation": "Analyse simulée pour la démonstration." } class DeepVestProfiler: def __init__(self, config): self.config = config self.analyzer = LLMProfileAnalyzer(config) async def create_profile(self, data): analysis = await self.analyzer.analyze_profile(data) profile = type('Profile', (), { "id": "demo-profile", "risk_tolerance": data.get("risk_tolerance", 3), "investment_horizon": data.get("investment_horizon", 5), "risk_score": analysis["risk_score"], "investment_goals": data.get("investment_goals", []), "llm_analysis_results": type('LLMResults', (), analysis) }) return profile async def generate_investment_strategy(self, profile): risk_score = getattr(profile, "risk_score", 0.5) # Allocation basée sur le score de risque stocks = risk_score bonds = (1 - risk_score) * 0.8 cash = (1 - risk_score) * 0.2 allocation = { 'Actions': stocks, 'Obligations': bonds, 'Liquidités': cash } return { "risk_profile": { "score": risk_score, "category": "Dynamique" if risk_score > 0.6 else "Modéré" if risk_score > 0.4 else "Conservateur" }, "asset_allocation": allocation, "recommendations": [ "Diversifier votre portefeuille selon votre profil de risque", "Maintenir une épargne de sécurité", "Investir régulièrement" ] } # Configurer la page Streamlit st.set_page_config( page_title="DeepVest - IA d'Investissement Personnalisé", page_icon="💼", layout="wide", initial_sidebar_state="expanded" ) # Titre et présentation st.title("DeepVest - Assistant d'Investissement Intelligent") st.markdown(""" Cette plateforme analyse en temps réel votre situation personnelle, financière et professionnelle pour vous proposer une stratégie d'investissement sur mesure qui s'adapte dynamiquement aux événements de votre vie. """) # Initialisation de la session state si elle n'existe pas déjà if 'profile' not in st.session_state: st.session_state.profile = None if 'analyzer' not in st.session_state: config = DeepVestConfig( debug_mode=True, log_prompts=True, db_path="profiles_db" ) st.session_state.analyzer = LLMProfileAnalyzer(config) st.session_state.profiler = DeepVestProfiler(config) # Navigation par onglets tabs = st.tabs(["Profil Investisseur", "Analyse de Portefeuille", "Simulation d'Objectifs", "Marché en Temps Réel"]) with tabs[0]: st.header("Votre Profil Investisseur") # Formulaire de profil with st.form("profile_form"): col1, col2 = st.columns(2) with col1: st.subheader("Informations personnelles") age = st.number_input("Âge", min_value=18, max_value=100, value=30) annual_income = st.number_input("Revenu annuel (€)", min_value=0, value=50000) monthly_savings = st.number_input("Épargne mensuelle (€)", min_value=0, value=500) family_status = st.selectbox("Situation familiale", ["Célibataire", "Marié(e)", "Divorcé(e)", "Veuf/Veuve"]) dependents = st.number_input("Personnes à charge", min_value=0, max_value=10, value=0) with col2: st.subheader("Profil d'investissement") risk_tolerance = st.slider("Tolérance au risque", min_value=1, max_value=5, value=3, help="1: Très prudent, 5: Très dynamique") investment_horizon = st.slider("Horizon d'investissement (années)", min_value=1, max_value=30, value=10) financial_knowledge = st.slider("Connaissances financières", min_value=1, max_value=5, value=3, help="1: Débutant, 5: Expert") investment_goals = st.multiselect("Objectifs d'investissement", ["Retraite", "Achat immobilier", "Études des enfants", "Épargne générale", "Revenus passifs", "Croissance patrimoine"]) esg_preferences = st.checkbox("Préférences ESG (investissement responsable)") submitted = st.form_submit_button("Créer mon profil") if submitted: with st.spinner("Analyse de votre profil en cours..."): # Préparer les données du profil profile_data = { "age": age, "annual_income": annual_income, "monthly_savings": monthly_savings, "marital_status": family_status, "number_of_dependents": dependents, "risk_tolerance": risk_tolerance, "investment_horizon": investment_horizon, "financial_knowledge": financial_knowledge, "investment_goals": investment_goals, "esg_preferences": esg_preferences, "total_assets": 0, # À compléter plus tard "total_debt": 0, # À compléter plus tard } # Créer le profil async def create_profile(): return await st.session_state.profiler.create_profile(profile_data) # Exécuter la fonction asynchrone loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: st.session_state.profile = loop.run_until_complete(create_profile()) st.success("Profil créé avec succès!") except Exception as e: st.error(f"Erreur lors de la création du profil: {str(e)}") finally: loop.close() # Affichage du profil si disponible if st.session_state.profile: profile = st.session_state.profile st.subheader("Analyse de votre profil") col1, col2, col3 = st.columns(3) with col1: st.metric("Score de risque", f"{profile.risk_score:.2f}/1.00") with col2: st.metric("Horizon recommandé", f"{profile.investment_horizon} ans") with col3: st.metric("Capacité d'investissement", f"{monthly_savings} €/mois") # Affichage des recommandations si disponibles if hasattr(profile, 'llm_analysis_results') and hasattr(profile.llm_analysis_results, 'recommendations'): st.subheader("Recommandations personnalisées") for i, rec in enumerate(profile.llm_analysis_results.recommendations[:5], 1): st.write(f"{i}. {rec}") # Génération de la stratégie d'investissement if st.button("Générer ma stratégie d'investissement"): with st.spinner("Génération de la stratégie en cours..."): async def generate_strategy(): return await st.session_state.profiler.generate_investment_strategy(profile) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: strategy = loop.run_until_complete(generate_strategy()) # Affichage de la stratégie st.subheader("Stratégie d'investissement recommandée") # Affichage de l'allocation d'actifs st.write("**Allocation d'actifs recommandée:**") # Préparation des données pour le graphique labels = list(strategy['asset_allocation'].keys()) sizes = [round(v * 100, 1) for v in strategy['asset_allocation'].values()] # Création du graphique fig, ax = plt.subplots(figsize=(8, 6)) wedges, texts, autotexts = ax.pie(sizes, autopct='%1.1f%%', textprops={'fontsize': 9, 'weight': 'bold'}) ax.axis('equal') ax.legend(wedges, labels, loc="center left", bbox_to_anchor=(1, 0, 0.5, 1)) st.pyplot(fig) # Affichage des recommandations st.write("**Recommandations clés:**") for i, rec in enumerate(strategy.get('recommendations', []), 1): st.write(f"{i}. {rec}") except Exception as e: st.error(f"Erreur lors de la génération de la stratégie: {str(e)}") finally: loop.close() with tabs[1]: st.header("Analyse de Portefeuille") # Simulation d'un portefeuille existant st.subheader("Votre portefeuille actuel") # Exemple de portefeuille pour démonstration with st.expander("Ajouter des actifs à votre portefeuille"): with st.form("portfolio_form"): asset_type = st.selectbox("Type d'actif", ["Actions", "Obligations", "ETF", "Fonds", "Immobilier", "Autres"]) asset_name = st.text_input("Nom/Ticker") asset_value = st.number_input("Valeur (€)", min_value=0.0, value=1000.0) add_asset = st.form_submit_button("Ajouter") # Affichage d'un portefeuille exemple portfolio_data = { "Actions": {"AAPL": 5000, "MSFT": 3000, "GOOGL": 4000}, "ETF": {"VWCE": 10000, "AGGH": 5000}, "Liquidités": {"EUR": 2000} } st.write("Portefeuille actuel:") # Création d'un DataFrame pour l'affichage portfolio_df = [] for category, assets in portfolio_data.items(): for asset, value in assets.items(): portfolio_df.append({"Catégorie": category, "Actif": asset, "Valeur (€)": value}) portfolio_df = pd.DataFrame(portfolio_df) st.dataframe(portfolio_df) # Calcul des statistiques du portefeuille total_value = portfolio_df["Valeur (€)"].sum() st.metric("Valeur totale du portefeuille", f"{total_value:,.2f} €") # Graphique de répartition st.subheader("Répartition du portefeuille") # Par catégorie category_allocation = portfolio_df.groupby("Catégorie")["Valeur (€)"].sum() category_allocation_pct = category_allocation / total_value * 100 fig, ax = plt.subplots(figsize=(8, 6)) wedges, texts, autotexts = ax.pie(category_allocation_pct, autopct='%1.1f%%', textprops={'fontsize': 9, 'weight': 'bold'}) ax.axis('equal') ax.legend(wedges, category_allocation.index, loc="center left", bbox_to_anchor=(1, 0, 0.5, 1)) st.pyplot(fig) # Analyse de performance simulée st.subheader("Performance historique simulée") # Données simulées pour la démonstration dates = pd.date_range(start=datetime.now() - timedelta(days=365), end=datetime.now(), freq='D') performance = 100 * (1 + np.cumsum(np.random.normal(0.0003, 0.01, size=len(dates)))) benchmark = 100 * (1 + np.cumsum(np.random.normal(0.0002, 0.008, size=len(dates)))) performance_df = pd.DataFrame({ 'Date': dates, 'Portefeuille': performance, 'Benchmark': benchmark }) st.line_chart(performance_df.set_index('Date')) # Recommandations d'optimisation st.subheader("Recommandations d'optimisation") if st.session_state.profile: st.write("Basé sur votre profil, nous recommandons les ajustements suivants:") st.markdown(""" 1. **Rééquilibrage recommandé**: Réduire l'exposition aux actions technologiques 2. **Diversification géographique**: Augmenter l'exposition aux marchés émergents 3. **Allocation tactique**: Augmenter la part des obligations face aux incertitudes actuelles """) else: st.info("Créez d'abord votre profil d'investisseur pour obtenir des recommandations personnalisées.") with tabs[2]: st.header("Simulation d'Objectifs de Vie") st.subheader("Définissez vos objectifs financiers") # Sélection d'objectif goal_type = st.selectbox("Type d'objectif", [ "Retraite", "Achat immobilier", "Études des enfants", "Création d'entreprise", "Voyage/Sabbatique", "Achat important" ]) # Configuration de l'objectif col1, col2 = st.columns(2) with col1: amount = st.number_input("Montant cible (€)", min_value=0, value=100000) years = st.slider("Horizon (années)", min_value=1, max_value=40, value=10) with col2: monthly_contribution = st.number_input("Contribution mensuelle (€)", min_value=0, value=500) initial_capital = st.number_input("Capital initial (€)", min_value=0, value=10000) # Calcul de simulation if st.button("Simuler l'atteinte de l'objectif"): if st.session_state.profile: risk_profile = st.session_state.profile.risk_score else: risk_profile = 0.5 # Valeur par défaut # Estimation du taux de rendement en fonction du profil de risque expected_return = 0.02 + risk_profile * 0.08 # Entre 2% et 10% # Simulation periods = years * 12 future_value_formula = initial_capital * (1 + expected_return/12) ** periods contribution_future_value = monthly_contribution * ((1 + expected_return/12) ** periods - 1) / (expected_return/12) total_future_value = future_value_formula + contribution_future_value # Affichage des résultats success_rate = min(100, total_future_value / amount * 100) col1, col2, col3 = st.columns(3) with col1: st.metric("Montant projeté", f"{total_future_value:,.2f} €") with col2: st.metric("Objectif", f"{amount:,.2f} €") with col3: st.metric("Taux de réussite", f"{success_rate:.1f}%") # Graphique de progression st.subheader("Projection de votre épargne dans le temps") # Données pour le graphique months = range(0, periods + 1) cumulative_values = [] for t in months: value = initial_capital * (1 + expected_return/12) ** t contrib = monthly_contribution * ((1 + expected_return/12) ** t - 1) / (expected_return/12) if expected_return > 0 else monthly_contribution * t cumulative_values.append(value + contrib) # Création d'un DataFrame pour le graphique projection_df = pd.DataFrame({ 'Mois': months, 'Valeur Projetée': cumulative_values, 'Objectif': [amount] * len(months) }) # Graphique st.line_chart(projection_df.set_index('Mois')) # Recommandations st.subheader("Recommandations pour atteindre votre objectif") if total_future_value < amount: shortfall = amount - total_future_value increased_contribution = monthly_contribution * amount / total_future_value st.warning(f"Avec les paramètres actuels, vous n'atteindrez pas complètement votre objectif. Il manquera environ {shortfall:,.2f} €.") st.markdown(f""" Pour atteindre votre objectif, vous pourriez: 1. **Augmenter votre contribution mensuelle** à environ {increased_contribution:.2f} € 2. **Allonger votre horizon d'investissement** de quelques années 3. **Ajuster votre profil de risque** pour viser un rendement plus élevé """) else: surplus = total_future_value - amount reduced_contribution = monthly_contribution * amount / total_future_value st.success(f"Félicitations ! Vous êtes sur la bonne voie pour atteindre votre objectif, avec un surplus potentiel de {surplus:,.2f} €.") st.markdown(f""" Options à considérer: 1. **Réduire votre contribution mensuelle** à environ {reduced_contribution:.2f} € tout en atteignant votre objectif 2. **Augmenter votre objectif** pour mettre à profit votre capacité d'épargne 3. **Réduire votre profil de risque** pour une approche plus conservatrice """) with tabs[3]: st.header("Marché en Temps Réel") # Tableau de bord du marché st.subheader("Tableau de bord du marché") # Indices principaux (données simulées) col1, col2, col3, col4 = st.columns(4) with col1: st.metric("S&P 500", "4,782.21", "+0.42%") with col2: st.metric("CAC 40", "7,596.91", "-0.15%") with col3: st.metric("DAX", "16,752.23", "+0.21%") with col4: st.metric("Nikkei 225", "33,408.39", "-0.54%") # Conditions de marché st.subheader("Conditions de marché actuelles") # Simulations de données pour démonstration market_sentiment = 0.65 # 0 à 1 volatility_level = 0.4 # 0 à 1 market_regime = "Bull Market" # Bull/Bear/Neutre col1, col2, col3 = st.columns(3) with col1: st.write("**Sentiment de marché**") sentiment_color = "green" if market_sentiment > 0.5 else "red" st.markdown(f"

{market_sentiment:.0%}

", unsafe_allow_html=True) with col2: st.write("**Niveau de volatilité**") volatility_color = "red" if volatility_level > 0.5 else "green" st.markdown(f"

{volatility_level:.0%}

", unsafe_allow_html=True) with col3: st.write("**Régime de marché**") regime_color = "green" if market_regime == "Bull Market" else "red" if market_regime == "Bear Market" else "orange" st.markdown(f"

{market_regime}

", unsafe_allow_html=True) # Analyse des actifs st.subheader("Analyse des actifs en temps réel") # Sélection d'actif asset_to_analyze = st.selectbox("Sélectionnez un actif à analyser", ["AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "VWCE", "AGGH"]) if asset_to_analyze: # Données simulées pour démonstration asset_data = { "price": 178.92, "change": 0.87, "change_percent": 0.49, "volume": 58234567, "pe_ratio": 28.5, "dividend_yield": 0.51, "market_cap": "2.82T", "52w_high": 199.62, "52w_low": 124.17 } # Affichage des données col1, col2, col3 = st.columns(3) with col1: st.metric("Prix", f"${asset_data['price']}", f"{asset_data['change_percent']}%") st.metric("Volume", f"{asset_data['volume']:,}") with col2: st.metric("P/E Ratio", f"{asset_data['pe_ratio']}") st.metric("Rendement du dividende", f"{asset_data['dividend_yield']}%") with col3: st.metric("Capitalisation", asset_data['market_cap']) st.metric("52 semaines", f"${asset_data['52w_low']} - ${asset_data['52w_high']}") # Graphique de prix (données simulées) st.subheader(f"Évolution du prix de {asset_to_analyze}") # Données simulées pour le graphique dates = pd.date_range(start=datetime.now() - timedelta(days=90), end=datetime.now(), freq='D') prices = asset_data['price'] * (1 + np.cumsum(np.random.normal(0, 0.015, size=len(dates)))) volumes = np.random.randint(30000000, 90000000, size=len(dates)) asset_df = pd.DataFrame({ 'Date': dates, 'Prix': prices, 'Volume': volumes }) # Graphique de prix st.line_chart(asset_df.set_index('Date')['Prix']) # Recommandations st.subheader if st.session_state.profile: # Recommandations personnalisées basées sur le profil if st.session_state.profile.risk_score > 0.7: recommendation = "Achat" if asset_data['change_percent'] > 0 else "Conserver" reasoning = "Votre profil de risque élevé vous permet de profiter des opportunités de croissance de cet actif." elif st.session_state.profile.risk_score < 0.3: recommendation = "Conserver" if asset_data['change_percent'] > 0 else "Vente" reasoning = "Votre profil de risque conservateur suggère une approche prudente avec cet actif." else: recommendation = "Conserver" reasoning = "Cet actif correspond à votre profil de risque modéré et peut contribuer à la diversification de votre portefeuille." else: # Recommandation générique recommendation = "Conserver" reasoning = "Créez votre profil pour obtenir des recommandations personnalisées." st.write(f"**Recommandation**: {recommendation}") st.write(f"**Justification**: {reasoning}") # Sidebar pour les filtres et les options with st.sidebar: st.header("DeepVest") st.image("https://img.icons8.com/color/96/000000/financial-growth.png", width=100) st.subheader("Options") # Filtres de marché st.write("**Filtres de marché**") market_filter = st.multiselect("Marchés", ["Actions", "Obligations", "Matières premières", "Crypto-monnaies", "Devises"]) region_filter = st.multiselect("Régions", ["Amérique du Nord", "Europe", "Asie-Pacifique", "Marchés émergents"]) # Paramètres avancés st.write("**Paramètres avancés**") show_advanced = st.checkbox("Afficher les métriques avancées") # À propos st.write("---") st.write("*DeepVest - ©2025 - version 1.0*") st.write("[Documentation](https://www.example.com) | [Support](mailto:support@deepvest.ai)")