Deepvest/ProfilingAI
0
1import streamlit as st2import os3import sys4import asyncio5import numpy as np6import pandas as pd7import matplotlib.pyplot as plt8from datetime import datetime, timedelta9from pathlib import Path10 11# Ajouter le répertoire src au path pour l'importation des modules12current_dir = Path(__file__).parent.absolute()13sys.path.append(str(current_dir))14 15# Import des modules DeepVest16try:17 from src.core.profiling import DeepVestConfig, LLMProfileAnalyzer, DeepVestProfiler18except ImportError:19 st.error("Impossible d'importer les modules DeepVest. Vérifiez que le dossier src est correctement structuré.")20 21 # Version simplifiée pour la démo si imports échoués22 class DeepVestConfig:23 def __init__(self, **kwargs):24 for key, value in kwargs.items():25 setattr(self, key, value)26 27 class LLMProfileAnalyzer:28 def __init__(self, config):29 self.config = config30 31 async def analyze_profile(self, data):32 return {33 "risk_score": data.get("risk_tolerance", 3)/5,34 "investment_horizon": data.get("investment_horizon", 5),35 "primary_goals": data.get("investment_goals", []),36 "recommendations": [37 "Diversifier votre portefeuille",38 "Maintenir une épargne de sécurité",39 "Investir régulièrement"40 ],41 "explanation": "Analyse simulée pour la démonstration."42 }43 44 class DeepVestProfiler:45 def __init__(self, config):46 self.config = config47 self.analyzer = LLMProfileAnalyzer(config)48 49 async def create_profile(self, data):50 analysis = await self.analyzer.analyze_profile(data)51 profile = type('Profile', (), {52 "id": "demo-profile",53 "risk_tolerance": data.get("risk_tolerance", 3),54 "investment_horizon": data.get("investment_horizon", 5),55 "risk_score": analysis["risk_score"],56 "investment_goals": data.get("investment_goals", []),57 "llm_analysis_results": type('LLMResults', (), analysis)58 })59 return profile60 61 async def generate_investment_strategy(self, profile):62 risk_score = getattr(profile, "risk_score", 0.5)63 64 # Allocation basée sur le score de risque65 stocks = risk_score66 bonds = (1 - risk_score) * 0.867 cash = (1 - risk_score) * 0.268 69 allocation = {70 'Actions': stocks,71 'Obligations': bonds,72 'Liquidités': cash73 }74 75 return {76 "risk_profile": {77 "score": risk_score,78 "category": "Dynamique" if risk_score > 0.6 else "Modéré" if risk_score > 0.4 else "Conservateur"79 },80 "asset_allocation": allocation,81 "recommendations": [82 "Diversifier votre portefeuille selon votre profil de risque",83 "Maintenir une épargne de sécurité",84 "Investir régulièrement"85 ]86 }87 88# Configurer la page Streamlit89st.set_page_config(90 page_title="DeepVest - IA d'Investissement Personnalisé",91 page_icon="💼",92 layout="wide",93 initial_sidebar_state="expanded"94)95 96# Titre et présentation97st.title("DeepVest - Assistant d'Investissement Intelligent")98st.markdown("""99Cette plateforme analyse en temps réel votre situation personnelle, financière et professionnelle 100pour vous proposer une stratégie d'investissement sur mesure qui s'adapte dynamiquement aux événements de votre vie.101""")102 103# Initialisation de la session state si elle n'existe pas déjà104if 'profile' not in st.session_state:105 st.session_state.profile = None106if 'analyzer' not in st.session_state:107 config = DeepVestConfig(108 debug_mode=True,109 log_prompts=True,110 db_path="profiles_db"111 )112 st.session_state.analyzer = LLMProfileAnalyzer(config)113 st.session_state.profiler = DeepVestProfiler(config)114 115# Navigation par onglets116tabs = st.tabs(["Profil Investisseur", "Analyse de Portefeuille", "Simulation d'Objectifs", "Marché en Temps Réel"])117 118with tabs[0]:119 st.header("Votre Profil Investisseur")120 121 # Formulaire de profil122 with st.form("profile_form"):123 col1, col2 = st.columns(2)124 125 with col1:126 st.subheader("Informations personnelles")127 age = st.number_input("Âge", min_value=18, max_value=100, value=30)128 annual_income = st.number_input("Revenu annuel (€)", min_value=0, value=50000)129 monthly_savings = st.number_input("Épargne mensuelle (€)", min_value=0, value=500)130 family_status = st.selectbox("Situation familiale", ["Célibataire", "Marié(e)", "Divorcé(e)", "Veuf/Veuve"])131 dependents = st.number_input("Personnes à charge", min_value=0, max_value=10, value=0)132 133 with col2:134 st.subheader("Profil d'investissement")135 risk_tolerance = st.slider("Tolérance au risque", min_value=1, max_value=5, value=3, 136 help="1: Très prudent, 5: Très dynamique")137 investment_horizon = st.slider("Horizon d'investissement (années)", min_value=1, max_value=30, value=10)138 financial_knowledge = st.slider("Connaissances financières", min_value=1, max_value=5, value=3,139 help="1: Débutant, 5: Expert")140 investment_goals = st.multiselect("Objectifs d'investissement", 141 ["Retraite", "Achat immobilier", "Études des enfants", 142 "Épargne générale", "Revenus passifs", "Croissance patrimoine"])143 esg_preferences = st.checkbox("Préférences ESG (investissement responsable)")144 145 submitted = st.form_submit_button("Créer mon profil")146 147 if submitted:148 with st.spinner("Analyse de votre profil en cours..."):149 # Préparer les données du profil150 profile_data = {151 "age": age,152 "annual_income": annual_income,153 "monthly_savings": monthly_savings,154 "marital_status": family_status,155 "number_of_dependents": dependents,156 "risk_tolerance": risk_tolerance,157 "investment_horizon": investment_horizon,158 "financial_knowledge": financial_knowledge,159 "investment_goals": investment_goals,160 "esg_preferences": esg_preferences,161 "total_assets": 0, # À compléter plus tard162 "total_debt": 0, # À compléter plus tard163 }164 165 # Créer le profil166 async def create_profile():167 return await st.session_state.profiler.create_profile(profile_data)168 169 # Exécuter la fonction asynchrone170 loop = asyncio.new_event_loop()171 asyncio.set_event_loop(loop)172 try:173 st.session_state.profile = loop.run_until_complete(create_profile())174 st.success("Profil créé avec succès!")175 except Exception as e:176 st.error(f"Erreur lors de la création du profil: {str(e)}")177 finally:178 loop.close()179 180 # Affichage du profil si disponible181 if st.session_state.profile:182 profile = st.session_state.profile183 184 st.subheader("Analyse de votre profil")185 186 col1, col2, col3 = st.columns(3)187 with col1:188 st.metric("Score de risque", f"{profile.risk_score:.2f}/1.00")189 with col2:190 st.metric("Horizon recommandé", f"{profile.investment_horizon} ans")191 with col3:192 st.metric("Capacité d'investissement", f"{monthly_savings} €/mois")193 194 # Affichage des recommandations si disponibles195 if hasattr(profile, 'llm_analysis_results') and hasattr(profile.llm_analysis_results, 'recommendations'):196 st.subheader("Recommandations personnalisées")197 for i, rec in enumerate(profile.llm_analysis_results.recommendations[:5], 1):198 st.write(f"{i}. {rec}")199 200 # Génération de la stratégie d'investissement201 if st.button("Générer ma stratégie d'investissement"):202 with st.spinner("Génération de la stratégie en cours..."):203 async def generate_strategy():204 return await st.session_state.profiler.generate_investment_strategy(profile)205 206 loop = asyncio.new_event_loop()207 asyncio.set_event_loop(loop)208 try:209 strategy = loop.run_until_complete(generate_strategy())210 211 # Affichage de la stratégie212 st.subheader("Stratégie d'investissement recommandée")213 214 # Affichage de l'allocation d'actifs215 st.write("**Allocation d'actifs recommandée:**")216 217 # Préparation des données pour le graphique218 labels = list(strategy['asset_allocation'].keys())219 sizes = [round(v * 100, 1) for v in strategy['asset_allocation'].values()]220 221 # Création du graphique222 fig, ax = plt.subplots(figsize=(8, 6))223 wedges, texts, autotexts = ax.pie(sizes, autopct='%1.1f%%', 224 textprops={'fontsize': 9, 'weight': 'bold'})225 ax.axis('equal')226 ax.legend(wedges, labels, loc="center left", bbox_to_anchor=(1, 0, 0.5, 1))227 st.pyplot(fig)228 229 # Affichage des recommandations230 st.write("**Recommandations clés:**")231 for i, rec in enumerate(strategy.get('recommendations', []), 1):232 st.write(f"{i}. {rec}")233 except Exception as e:234 st.error(f"Erreur lors de la génération de la stratégie: {str(e)}")235 finally:236 loop.close()237 238with tabs[1]:239 st.header("Analyse de Portefeuille")240 241 # Simulation d'un portefeuille existant242 st.subheader("Votre portefeuille actuel")243 244 # Exemple de portefeuille pour démonstration245 with st.expander("Ajouter des actifs à votre portefeuille"):246 with st.form("portfolio_form"):247 asset_type = st.selectbox("Type d'actif", ["Actions", "Obligations", "ETF", "Fonds", "Immobilier", "Autres"])248 asset_name = st.text_input("Nom/Ticker")249 asset_value = st.number_input("Valeur (€)", min_value=0.0, value=1000.0)250 add_asset = st.form_submit_button("Ajouter")251 252 # Affichage d'un portefeuille exemple253 portfolio_data = {254 "Actions": {"AAPL": 5000, "MSFT": 3000, "GOOGL": 4000},255 "ETF": {"VWCE": 10000, "AGGH": 5000},256 "Liquidités": {"EUR": 2000}257 }258 259 st.write("Portefeuille actuel:")260 261 # Création d'un DataFrame pour l'affichage262 portfolio_df = []263 for category, assets in portfolio_data.items():264 for asset, value in assets.items():265 portfolio_df.append({"Catégorie": category, "Actif": asset, "Valeur (€)": value})266 267 portfolio_df = pd.DataFrame(portfolio_df)268 st.dataframe(portfolio_df)269 270 # Calcul des statistiques du portefeuille271 total_value = portfolio_df["Valeur (€)"].sum()272 st.metric("Valeur totale du portefeuille", f"{total_value:,.2f} €")273 274 # Graphique de répartition275 st.subheader("Répartition du portefeuille")276 277 # Par catégorie278 category_allocation = portfolio_df.groupby("Catégorie")["Valeur (€)"].sum()279 category_allocation_pct = category_allocation / total_value * 100280 281 fig, ax = plt.subplots(figsize=(8, 6))282 wedges, texts, autotexts = ax.pie(category_allocation_pct, autopct='%1.1f%%',283 textprops={'fontsize': 9, 'weight': 'bold'})284 ax.axis('equal')285 ax.legend(wedges, category_allocation.index, loc="center left", bbox_to_anchor=(1, 0, 0.5, 1))286 st.pyplot(fig)287 288 # Analyse de performance simulée289 st.subheader("Performance historique simulée")290 291 # Données simulées pour la démonstration292 dates = pd.date_range(start=datetime.now() - timedelta(days=365), end=datetime.now(), freq='D')293 performance = 100 * (1 + np.cumsum(np.random.normal(0.0003, 0.01, size=len(dates))))294 benchmark = 100 * (1 + np.cumsum(np.random.normal(0.0002, 0.008, size=len(dates))))295 296 performance_df = pd.DataFrame({297 'Date': dates,298 'Portefeuille': performance,299 'Benchmark': benchmark300 })301 302 st.line_chart(performance_df.set_index('Date'))303 304 # Recommandations d'optimisation305 st.subheader("Recommandations d'optimisation")306 307 if st.session_state.profile:308 st.write("Basé sur votre profil, nous recommandons les ajustements suivants:")309 310 st.markdown("""311 1. **Rééquilibrage recommandé**: Réduire l'exposition aux actions technologiques312 2. **Diversification géographique**: Augmenter l'exposition aux marchés émergents313 3. **Allocation tactique**: Augmenter la part des obligations face aux incertitudes actuelles314 """)315 else:316 st.info("Créez d'abord votre profil d'investisseur pour obtenir des recommandations personnalisées.")317 318with tabs[2]:319 st.header("Simulation d'Objectifs de Vie")320 321 st.subheader("Définissez vos objectifs financiers")322 323 # Sélection d'objectif324 goal_type = st.selectbox("Type d'objectif", [325 "Retraite", 326 "Achat immobilier", 327 "Études des enfants", 328 "Création d'entreprise",329 "Voyage/Sabbatique",330 "Achat important"331 ])332 333 # Configuration de l'objectif334 col1, col2 = st.columns(2)335 336 with col1:337 amount = st.number_input("Montant cible (€)", min_value=0, value=100000)338 years = st.slider("Horizon (années)", min_value=1, max_value=40, value=10)339 340 with col2:341 monthly_contribution = st.number_input("Contribution mensuelle (€)", min_value=0, value=500)342 initial_capital = st.number_input("Capital initial (€)", min_value=0, value=10000)343 344 # Calcul de simulation345 if st.button("Simuler l'atteinte de l'objectif"):346 if st.session_state.profile:347 risk_profile = st.session_state.profile.risk_score348 else:349 risk_profile = 0.5 # Valeur par défaut350 351 # Estimation du taux de rendement en fonction du profil de risque352 expected_return = 0.02 + risk_profile * 0.08 # Entre 2% et 10%353 354 # Simulation355 periods = years * 12356 future_value_formula = initial_capital * (1 + expected_return/12) ** periods357 contribution_future_value = monthly_contribution * ((1 + expected_return/12) ** periods - 1) / (expected_return/12)358 total_future_value = future_value_formula + contribution_future_value359 360 # Affichage des résultats361 success_rate = min(100, total_future_value / amount * 100)362 363 col1, col2, col3 = st.columns(3)364 365 with col1:366 st.metric("Montant projeté", f"{total_future_value:,.2f} €")367 with col2:368 st.metric("Objectif", f"{amount:,.2f} €")369 with col3:370 st.metric("Taux de réussite", f"{success_rate:.1f}%")371 372 # Graphique de progression373 st.subheader("Projection de votre épargne dans le temps")374 375 # Données pour le graphique376 months = range(0, periods + 1)377 cumulative_values = []378 379 for t in months:380 value = initial_capital * (1 + expected_return/12) ** t381 contrib = monthly_contribution * ((1 + expected_return/12) ** t - 1) / (expected_return/12) if expected_return > 0 else monthly_contribution * t382 cumulative_values.append(value + contrib)383 384 # Création d'un DataFrame pour le graphique385 projection_df = pd.DataFrame({386 'Mois': months,387 'Valeur Projetée': cumulative_values,388 'Objectif': [amount] * len(months)389 })390 391 # Graphique392 st.line_chart(projection_df.set_index('Mois'))393 394 # Recommandations395 st.subheader("Recommandations pour atteindre votre objectif")396 397 if total_future_value < amount:398 shortfall = amount - total_future_value399 increased_contribution = monthly_contribution * amount / total_future_value400 401 st.warning(f"Avec les paramètres actuels, vous n'atteindrez pas complètement votre objectif. Il manquera environ {shortfall:,.2f} €.")402 st.markdown(f"""403 Pour atteindre votre objectif, vous pourriez:404 1. **Augmenter votre contribution mensuelle** à environ {increased_contribution:.2f} €405 2. **Allonger votre horizon d'investissement** de quelques années406 3. **Ajuster votre profil de risque** pour viser un rendement plus élevé407 """)408 else:409 surplus = total_future_value - amount410 reduced_contribution = monthly_contribution * amount / total_future_value411 412 st.success(f"Félicitations ! Vous êtes sur la bonne voie pour atteindre votre objectif, avec un surplus potentiel de {surplus:,.2f} €.")413 st.markdown(f"""414 Options à considérer:415 1. **Réduire votre contribution mensuelle** à environ {reduced_contribution:.2f} € tout en atteignant votre objectif416 2. **Augmenter votre objectif** pour mettre à profit votre capacité d'épargne417 3. **Réduire votre profil de risque** pour une approche plus conservatrice418 """)419 420with tabs[3]:421 st.header("Marché en Temps Réel")422 423 # Tableau de bord du marché424 st.subheader("Tableau de bord du marché")425 426 # Indices principaux (données simulées)427 col1, col2, col3, col4 = st.columns(4)428 429 with col1:430 st.metric("S&P 500", "4,782.21", "+0.42%")431 with col2:432 st.metric("CAC 40", "7,596.91", "-0.15%")433 with col3:434 st.metric("DAX", "16,752.23", "+0.21%")435 with col4:436 st.metric("Nikkei 225", "33,408.39", "-0.54%")437 438 # Conditions de marché439 st.subheader("Conditions de marché actuelles")440 441 # Simulations de données pour démonstration442 market_sentiment = 0.65 # 0 à 1443 volatility_level = 0.4 # 0 à 1444 market_regime = "Bull Market" # Bull/Bear/Neutre445 446 col1, col2, col3 = st.columns(3)447 448 with col1:449 st.write("**Sentiment de marché**")450 sentiment_color = "green" if market_sentiment > 0.5 else "red"451 st.markdown(f"<h3 style='text-align: center; color: {sentiment_color};'>{market_sentiment:.0%}</h3>", unsafe_allow_html=True)452 453 with col2:454 st.write("**Niveau de volatilité**")455 volatility_color = "red" if volatility_level > 0.5 else "green"456 st.markdown(f"<h3 style='text-align: center; color: {volatility_color};'>{volatility_level:.0%}</h3>", unsafe_allow_html=True)457 458 with col3:459 st.write("**Régime de marché**")460 regime_color = "green" if market_regime == "Bull Market" else "red" if market_regime == "Bear Market" else "orange"461 st.markdown(f"<h3 style='text-align: center; color: {regime_color};'>{market_regime}</h3>", unsafe_allow_html=True)462 463 # Analyse des actifs464 st.subheader("Analyse des actifs en temps réel")465 466 # Sélection d'actif467 asset_to_analyze = st.selectbox("Sélectionnez un actif à analyser", ["AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "VWCE", "AGGH"])468 469 if asset_to_analyze:470 # Données simulées pour démonstration471 asset_data = {472 "price": 178.92,473 "change": 0.87,474 "change_percent": 0.49,475 "volume": 58234567,476 "pe_ratio": 28.5,477 "dividend_yield": 0.51,478 "market_cap": "2.82T",479 "52w_high": 199.62,480 "52w_low": 124.17481 }482 483 # Affichage des données484 col1, col2, col3 = st.columns(3)485 486 with col1:487 st.metric("Prix", f"${asset_data['price']}", f"{asset_data['change_percent']}%")488 st.metric("Volume", f"{asset_data['volume']:,}")489 490 with col2:491 st.metric("P/E Ratio", f"{asset_data['pe_ratio']}")492 st.metric("Rendement du dividende", f"{asset_data['dividend_yield']}%")493 494 with col3:495 st.metric("Capitalisation", asset_data['market_cap'])496 st.metric("52 semaines", f"${asset_data['52w_low']} - ${asset_data['52w_high']}")497 498 # Graphique de prix (données simulées)499 st.subheader(f"Évolution du prix de {asset_to_analyze}")500 501 # Données simulées pour le graphique502 dates = pd.date_range(start=datetime.now() - timedelta(days=90), end=datetime.now(), freq='D')503 prices = asset_data['price'] * (1 + np.cumsum(np.random.normal(0, 0.015, size=len(dates))))504 volumes = np.random.randint(30000000, 90000000, size=len(dates))505 506 asset_df = pd.DataFrame({507 'Date': dates,508 'Prix': prices,509 'Volume': volumes510 })511 512 # Graphique de prix513 st.line_chart(asset_df.set_index('Date')['Prix'])514 515 # Recommandations516 st.subheader517 518 if st.session_state.profile:519 # Recommandations personnalisées basées sur le profil520 if st.session_state.profile.risk_score > 0.7:521 recommendation = "Achat" if asset_data['change_percent'] > 0 else "Conserver"522 reasoning = "Votre profil de risque élevé vous permet de profiter des opportunités de croissance de cet actif."523 elif st.session_state.profile.risk_score < 0.3:524 recommendation = "Conserver" if asset_data['change_percent'] > 0 else "Vente"525 reasoning = "Votre profil de risque conservateur suggère une approche prudente avec cet actif."526 else:527 recommendation = "Conserver"528 reasoning = "Cet actif correspond à votre profil de risque modéré et peut contribuer à la diversification de votre portefeuille."529 else:530 # Recommandation générique531 recommendation = "Conserver"532 reasoning = "Créez votre profil pour obtenir des recommandations personnalisées."533 534 st.write(f"**Recommandation**: {recommendation}")535 st.write(f"**Justification**: {reasoning}")536 537# Sidebar pour les filtres et les options538with st.sidebar:539 st.header("DeepVest")540 st.image("https://img.icons8.com/color/96/000000/financial-growth.png", width=100)541 542 st.subheader("Options")543 544 # Filtres de marché545 st.write("**Filtres de marché**")546 market_filter = st.multiselect("Marchés", ["Actions", "Obligations", "Matières premières", "Crypto-monnaies", "Devises"])547 region_filter = st.multiselect("Régions", ["Amérique du Nord", "Europe", "Asie-Pacifique", "Marchés émergents"])548 549 # Paramètres avancés550 st.write("**Paramètres avancés**")551 show_advanced = st.checkbox("Afficher les métriques avancées")552 553 # À propos554 st.write("---")555 st.write("*DeepVest - ©2025 - version 1.0*")556 st.write("[Documentation](https://www.example.com) | [Support](mailto:support@deepvest.ai)")