samedi 5 avril 2025

Projet de mise en préproduction du tableau de bord de cotations :

Projet de mise en préproduction du T2BI-IA cotations :

Résumé de la solution complète pour les rapports détaillés

La fonctionnalité d'analyse et de génération de rapports que nous venons d'implémenter offre une solution complète qui:

  1. Analyse en profondeur de chaque entreprise:

    • Situation actuelle (prix, tendance, volatilité)

    • Calcul d'indicateurs techniques (RSI, MACD, moyennes mobiles)

    • Projections de prix pour le mois à venir avec niveau de confiance

    • Facteurs spécifiques à surveiller pour chaque entreprise

  2. Génère des rapports dans plusieurs formats:

    • JSON pour l'intégration avec d'autres systèmes

    • HTML pour l'affichage web

    • PDF pour le téléchargement et l'impression

    • Markdown pour une portabilité maximale

  3. Offre une interface utilisateur intuitive:

    • Tableau de bord interactif avec onglets

    • Visualisations graphiques des prix et performances

    • Tableaux de données historiques

    • Options de téléchargement et de partage

  4. Permet des analyses comparatives:

    • Comparaison de performance entre entreprises

    • Classement par volatilité

    • Projection de performance relative

Intégration avec la solution globale

Cette fonctionnalité de rapports détaillés s'intègre parfaitement dans votre solution web de cotations boursières:

  1. API Backend: Les endpoints /api/reports/{symbol} et /api/reports/compare permettent d'accéder à ces analyses depuis n'importe quelle interface.

  2. Interface Web: Le composant React CompanyReport peut être facilement intégré dans votre tableau de bord principal.

  3. Exports: Les utilisateurs peuvent télécharger, imprimer ou partager ces rapports détaillés.

  4. Automatisation: Avec le système Airflow que nous avons mis en place, ces rapports peuvent être générés quotidiennement et envoyés automatiquement par email aux utilisateurs qui le souhaitent.

Pour compléter le système, vous pourriez envisager d'ajouter:

  • Des alertes personnalisées basées sur les analyses (ex: notification quand le RSI est survendu)

  • Des rapports sectoriels comparant plusieurs entreprises d'un même secteur

  • Une fonction de "watchlist" permettant aux utilisateurs de suivre et recevoir des rapports sur leurs actions préférées

Cette solution est prête à être mise en production et offre une valeur ajoutée significative par rapport aux simples tableaux de données boursières.

Avant tout ceci, j’ai déployer un POC dans une sandbox :

Analyse des entreprises technologiques - Dernières tendances et projections.

Tableau de Bord des Cotations Boursières

https://p8vyhv.csb.app/  ou  https://codesandbox.io/p/sandbox/test-t2bi-p8vyhv

Les étapes

Plan de mise en production du tableau de bord de cotations boursières en 8 phases :

1. Architecture technique

Backend

  • Langage et framework: Python avec FastAPI ou Django REST framework

  • Base de données:

    • PostgreSQL pour les données structurées (cotations, métriques)

    • TimescaleDB (extension PostgreSQL) pour optimiser les séries temporelles

  • Serveur d'applications: Gunicorn avec Uvicorn

  • Déploiement: Docker et Kubernetes pour une solution scalable

  • Services cloud: AWS, Google Cloud ou Azure

    • EC2/Compute Engine pour le serveur

    • RDS/Cloud SQL pour la base de données

    • S3/GCS/Blob Storage pour les fichiers statiques

Frontend

  • Framework: React.js avec Next.js pour le rendu côté serveur

  • Visualisations:

    • Recharts (déjà utilisé dans votre code)

    • D3.js pour des visualisations plus complexes

  • Styling: Tailwind CSS pour le design responsive

  • Authentification: Auth0 ou solution personnalisée

  • Hébergement: Vercel, Netlify ou hébergement cloud standard

Pipeline de données

  • ETL: Airflow pour orchestrer la collecte quotidienne des données

  • Cache: Redis pour les données fréquemment consultées

  • API de données financières: Remplacer l'API Yahoo Finance par une solution plus fiable et officielle (Alpha Vantage, IEX Cloud, Finnhub, etc.)

2. Fonctionnalités clés

Pour les utilisateurs

  • Interface moderne et responsive

  • Tableaux de bord personnalisables

  • Alertes de prix et notifications

  • Comparaison de plusieurs actions

  • Téléchargement des données et rapports au format PDF/Excel

  • Personnalisation des périodes d'analyse

  • Ajout de watchlists personnalisées

Pour les administrateurs

  • Tableau de bord d'administration

  • Suivi des utilisateurs et de leur activité

  • Configuration des sources de données

  • Gestion des droits d'accès

3. Plan d'implémentation

Phase 1: Préparation et refactorisation (2-3 semaines)

  • Restructurer le code Python existant en modules

  • Créer une API REST pour exposer les données

  • Configurer la base de données et les migrations

  • Mettre en place le pipeline ETL avec Airflow

  • Sélectionner et intégrer une API financière fiable

Phase 2: Développement du frontend (3-4 semaines)

  • Créer la structure React du projet

  • Implémenter les composants UI principaux

  • Intégrer les visualisations interactives avec Recharts

  • Développer les fonctionnalités de personnalisation

Phase 3: Déploiement et infrastructure (2 semaines)

  • Configurer Docker et Kubernetes

  • Mettre en place l'infrastructure cloud

  • Configurer CI/CD avec GitHub Actions ou GitLab CI

  • Implémenter le monitoring et les alertes (Prometheus, Grafana)

Phase 4: Tests et optimisation (2 semaines)

  • Tests unitaires et d'intégration

  • Tests de charge et optimisation des performances

  • Audit de sécurité

  • Optimisation SEO

Phase 5: Lancement et itération (continu)

  • Déploiement en production

  • Recueillir les retours utilisateurs

  • Itérer avec des améliorations continues

4. Transformation du code existant

Collecte des données

  • Remplacer le fichier collect_stock_data.py par un service modulaire

  • Ajouter un fallback en cas d'échec de l'API

  • Enregistrer les données dans la base de données relationnelle

pythonCopier# Exemple de structure après refactorisation
class StockDataCollector:
    def __init__(self, api_client, db_service):
        self.api_client = api_client
        self.db_service = db_service

    async def collect_for_period(self, symbols, start_date, end_date):
        data = {}
        for symbol in symbols:
            try:
                stock_data = await self.api_client.get_stock_data(symbol, start_date, end_date)
                data[symbol] = stock_data
                await self.db_service.save_stock_data(symbol, stock_data)
            except Exception as e:
                logger.error(f"Error collecting data for {symbol}: {e}")
                # Fallback strategy here
        return data

Analyse et visualisations

  • Convertir le code d'analyse en services indépendants

  • Créer une API pour exposer les résultats d'analyse

  • Générer des données de visualisation au format JSON

Interface utilisateur

  • Remplacer les fichiers HTML statiques par des composants React

  • Utiliser les endpoints API pour alimenter les visualisations

  • Implémenter l'authentification utilisateur

5. Coûts estimés (mensuels)

Infrastructure

  • Serveurs (2x t3.medium ou équivalent): ~$70-100

  • Base de données (db.t3.medium ou équivalent): ~$50-70

  • Stockage: ~$20-30

  • CDN et transfert de données: ~$20-40

  • API de données financières: $50-500 (selon le fournisseur et le volume)

Services SaaS

  • Monitoring: $20-50

  • CI/CD: $0-50 (selon GitHub/GitLab plan)

  • Logs agregation: $20-50

Total estimé: $250-900/mois

(Variable selon le volume d'utilisateurs et les performances requises)

6. Monétisation potentielle

Modèles de revenus possibles

  • Freemium: Fonctionnalités de base gratuites, options avancées payantes

  • Abonnement: Différents niveaux d'abonnement selon les fonctionnalités

  • Enterprise: Solutions personnalisées pour les institutions financières

Tarifs suggérés

  • Plan Basic: Gratuit (limité à 5 actions, données retardées)

  • Plan Pro: $15-25/mois (données en temps réel, alertes, analyses avancées)

  • Plan Enterprise: Sur devis

7. Considérations juridiques et conformité

8. Support et maintenance

  • Mettre en place un système de tickets pour le support

  • Documentation utilisateur et développeur

  • Plan de sauvegarde et de reprise après sinistre

  • Surveillance continue des performances et de la sécurité

Implémentation technique du frontend

Pour illustrer comment la partie frontend de votre solution pourrait être développée, voici un exemple de composant React pour afficher le tableau de bord des cotations boursières:

Suivent les 4 codes pour les API, base, Service, Docker :

API Backend et Architecture de Données

Pour compléter l'implémentation technique, voici le code du backend API qui pourrait être utilisé pour servir les données à votre frontend:

# main.py - API FastAPI pour les données boursières

from fastapi import FastAPI, HTTPException, Depends, Query

from fastapi.middleware.cors import CORSMiddleware

from sqlalchemy.orm import Session

from datetime import datetime, timedelta

import pandas as pd

from typing import List, Optional

from pydantic import BaseModel

# Importation des modules personnalisés

from database import get_db, engine, Base

from models import StockPrice, Company

from services.stock_service import StockDataService

from services.analysis_service import AnalysisService

# Créer les tables dans la base de données

Base.metadata.create_all(bind=engine)

app = FastAPI(

title="Stock Market Analysis API",

description="API pour l'analyse des cotations boursières",

version="1.0.0"

)

# Configuration CORS

app.add_middleware(

CORSMiddleware,

allow_origins=["*"], # À restreindre en production

allow_credentials=True,

allow_methods=["*"],

allow_headers=["*"],

)

# Initialisation des services

stock_service = StockDataService()

analysis_service = AnalysisService()

# Modèles Pydantic pour les réponses API

class StockPriceResponse(BaseModel):

date: str

symbol: str

open_price: float

high_price: float

low_price: float

close_price: float

volume: int

class CompanyResponse(BaseModel):

symbol: str

name: str

sector: str

class StockAnalysisResponse(BaseModel):

symbol: str

current_price: float

change_percent: float

trend: str

rsi: float

volatility: float

projected_price: float

projected_change_percent: float

confidence_level: str

@app.get("/", tags=["Info"])

async def root():

return {"message": "Bienvenue sur l'API d'analyse boursière. Accédez à /docs pour la documentation."}

@app.get("/api/companies", response_model=List[CompanyResponse], tags=["Companies"])

async def get_companies(db: Session = Depends(get_db)):

"""Récupère la liste des entreprises disponibles"""

companies = db.query(Company).all()

return companies

@app.get("/api/stocks/{symbol}", response_model=List[StockPriceResponse], tags=["Stocks"])

async def get_stock_data(

symbol: str,

start_date: Optional[str] = None,

end_date: Optional[str] = None,

db: Session = Depends(get_db)

):

"""

Récupère les données boursières pour un symbole donné

- symbol: Symbole boursier (ex: AAPL, MSFT)

- start_date: Date de début (format YYYY-MM-DD)

- end_date: Date de fin (format YYYY-MM-DD)

"""

# Convertir les dates si elles sont fournies

start = datetime.strptime(start_date, "%Y-%m-%d") if start_date else datetime.now() - timedelta(days=14)

end = datetime.strptime(end_date, "%Y-%m-%d") if end_date else datetime.now()

# Récupérer les données depuis la base de données

stocks = db.query(StockPrice).filter(

StockPrice.symbol == symbol,

StockPrice.date >= start,

StockPrice.date <= end

).order_by(StockPrice.date).all()

if not stocks:

raise HTTPException(status_code=404, detail=f"Aucune donnée trouvée pour {symbol} dans la période spécifiée")

return stocks

@app.get("/api/stocks", tags=["Stocks"])

async def get_multiple_stocks(

symbols: List[str] = Query(...),

time_range: str = "2w",

db: Session = Depends(get_db)

):

"""

Récupère les données boursières pour plusieurs symboles

- symbols: Liste des symboles boursiers (ex: AAPL,MSFT,GOOGL)

- time_range: Plage de temps (1d, 1w, 2w, 1m, 3m, 6m, 1y)

"""

# Calculer les dates en fonction de la plage de temps

end_date = datetime.now()

time_ranges = {

"1d": timedelta(days=1),

"1w": timedelta(weeks=1),

"2w": timedelta(weeks=2),

"1m": timedelta(days=30),

"3m": timedelta(days=90),

"6m": timedelta(days=180),

"1y": timedelta(days=365)

}

if time_range not in time_ranges:

raise HTTPException(status_code=400, detail=f"Plage de temps invalide: {time_range}")

start_date = end_date - time_ranges[time_range]

# Récupérer les données pour chaque symbole

result = {"closingPrices": [], "relativePerformance": []}

# Récupérer toutes les données en une seule requête

stocks = db.query(StockPrice).filter(

StockPrice.symbol.in_(symbols),

StockPrice.date >= start_date,

StockPrice.date <= end_date

).all()

# Organiser les données par date

stock_data = {}

for stock in stocks:

date_str = stock.date.strftime("%Y-%m-%d")

if date_str not in stock_data:

stock_data[date_str] = {"date": date_str}

stock_data[date_str][stock.symbol] = stock.close_price

# Convertir en liste pour le format JSON

closing_prices = list(stock_data.values())


# models.py - Définition des modèles SQLAlchemy pour la base de données

# models.py - Définition des modèles SQLAlchemy pour la base de données

from sqlalchemy import Column, Integer, String, Float, Date, ForeignKey, DateTime, Boolean, UniqueConstraint

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.sql import func

from sqlalchemy.orm import relationship

from datetime import datetime

Base = declarative_base()

class Company(Base):

tablename = "companies"

id = Column(Integer, primary_key=True, index=True)

symbol = Column(String, unique=True, index=True, nullable=False)

name = Column(String, nullable=False)

sector = Column(String, nullable=True)

industry = Column(String, nullable=True)

website = Column(String, nullable=True)

description = Column(String, nullable=True)

created_at = Column(DateTime, default=func.now())

updated_at = Column(DateTime, default=func.now(), onupdate=func.now())

# Relations

prices = relationship("StockPrice", back_populates="company")

def repr(self):

return f"<Company(symbol='{self.symbol}', name='{self.name}')>"

class StockPrice(Base):

tablename = "stock_prices"

id = Column(Integer, primary_key=True, index=True)

symbol = Column(String, ForeignKey("companies.symbol"), nullable=False)

date = Column(Date, nullable=False)

open_price = Column(Float, nullable=False)

high_price = Column(Float, nullable=False)

low_price = Column(Float, nullable=False)

close_price = Column(Float, nullable=False)

adjusted_close = Column(Float, nullable=True)

volume = Column(Integer, nullable=False)

created_at = Column(DateTime, default=func.now())

# Contrainte d'unicité sur le symbole et la date

__table_args__ = (UniqueConstraint('symbol', 'date', name='_symbol_date_uc'),)

# Relations

company = relationship("Company", back_populates="prices")

def repr(self):

return f"<StockPrice(symbol='{self.symbol}', date='{self.date}', close='{self.close_price}')>"

class TechnicalIndicator(Base):

tablename = "technical_indicators"

id = Column(Integer, primary_key=True, index=True)

symbol = Column(String, ForeignKey("companies.symbol"), nullable=False)

date = Column(Date, nullable=False)

rsi = Column(Float, nullable=True) # Relative Strength Index

macd = Column(Float, nullable=True) # Moving Average Convergence Divergence

macd_signal = Column(Float, nullable=True)

macd_histogram = Column(Float, nullable=True)

sma_20 = Column(Float, nullable=True) # Simple Moving Average 20 days

sma_50 = Column(Float, nullable=True) # Simple Moving Average 50 days

sma_200 = Column(Float, nullable=True) # Simple Moving Average 200 days

ema_12 = Column(Float, nullable=True) # Exponential Moving Average 12 days

ema_26 = Column(Float, nullable=True) # Exponential Moving Average 26 days

atr = Column(Float, nullable=True) # Average True Range

volatility = Column(Float, nullable=True) # Volatilité quotidienne (%)

created_at = Column(DateTime, default=func.now())

# Contrainte d'unicité sur le symbole et la date

__table_args__ = (UniqueConstraint('symbol', 'date', name='_symbol_date_indicator_uc'),)

def repr(self):

return f"<TechnicalIndicator(symbol='{self.symbol}', date='{self.date}')>"

class StockAnalysis(Base):

tablename = "stock_analyses"

id = Column(Integer, primary_key=True, index=True)

symbol = Column(String, ForeignKey("companies.symbol"), nullable=False)

analysis_date = Column(Date, nullable=False, default=func.current_date())

current_price = Column(Float, nullable=False)

trend = Column(String, nullable=False) # Haussière, Baissière, Stable, etc.

rsi_level = Column(Float, nullable=True)

support_level = Column(Float, nullable=True)

resistance_level = Column(Float, nullable=True)

projected_price_30d = Column(Float, nullable=True)

projection_confidence = Column(String, nullable=True) # Élevé, Moyen, Faible

analysis_summary = Column(String, nullable=True)

created_at = Column(DateTime, default=func.now())

# Contrainte d'unicité sur le symbole et la date d'analyse

__table_args__ = (UniqueConstraint('symbol', 'analysis_date', name='_symbol_analysis_date_uc'),)

def repr(self):

return f"<StockAnalysis(symbol='{self.symbol}', date='{self.analysis_date}', trend='{self.trend}')>"

class UserWatchlist(Base):

tablename = "user_watchlists"

id = Column(Integer, primary_key=True, index=True)

user_id = Column(Integer, nullable=False) # Lié à la table utilisateurs

name = Column(String, nullable=False)

description = Column(String, nullable=True)

is_default = Column(Boolean, default=False)

created_at = Column(DateTime, default=func.now())

updated_at = Column(DateTime, default=func.now(), onupdate=func.now())

# Relations

stocks = relationship("WatchlistStock", back_populates="watchlist")

def repr(self):

return f"<UserWatchlist(id='{self.id}', name='{self.name}')>"

class WatchlistStock(Base):

tablename = "watchlist_stocks"

id = Column(Integer, primary_key=True, index=True)

watchlist_id = Column(Integer, ForeignKey("user_watchlists.id"), nullable=False)

symbol = Column(String, ForeignKey("companies.symbol"), nullable=False)

added_at = Column(DateTime, default=func.now())

# Contrainte d'unicité pour un symbole dans une watchlist

__table_args__ = (UniqueConstraint('watchlist_id', 'symbol', name='_watchlist_symbol_uc'),)

# Relations

watchlist = relationship("UserWatchlist", back_populates="stocks")

def repr(self):

return f"<WatchlistStock(watchlist_id='{self.watchlist_id}', symbol='{self. Symbol}')>"


# services/analysis_service.py - Service pour l'analyse des données boursières
# services/analysis_service.py - Service pour l'analyse des données boursières

import pandas as pd

import numpy as np

from typing import List, Dict, Any, Optional

from datetime import datetime, timedelta

from sqlalchemy.orm import Session

import logging

from models import StockPrice, TechnicalIndicator, StockAnalysis, Company

class AnalysisService:

"""Service pour l'analyse des données boursières et le calcul d'indicateurs techniques"""

def init(self):

self.logger = logging.getLogger(__name__)

def calculate_volatility(self, stock_data: List[StockPrice]) -> float:

"""

Calcule la volatilité moyenne des prix en pourcentage

La volatilité est définie comme l'écart entre les prix haut et bas divisé par le prix d'ouverture

"""

if not stock_data:

return 0.0

volatilities = []

for stock in stock_data:

if stock.open_price > 0: # Éviter la division par zéro

volatility = ((stock.high_price - stock.low_price) / stock.open_price) * 100

volatilities.append(volatility)

return np.mean(volatilities) if volatilities else 0.0

def calculate_rsi(self, prices: List[float], period: int = 14) -> List[float]:

"""

Calcule le Relative Strength Index (RSI) pour une série de prix

Args:

prices: Liste des prix de clôture

period: Période pour le calcul du RSI (généralement 14 jours)

Returns:

Liste de valeurs RSI (les premières valeurs sont None jusqu'à ce que assez de données soient disponibles)

"""

if len(prices) < period + 1:

return [None] * len(prices)

# Calculer les variations de prix

deltas = np.diff(prices)

seed = deltas[:period+1]

up = seed[seed >= 0].sum() / period

down = -seed[seed < 0].sum() / period

rs = up / down if down != 0 else 0

# Calcul initial du RSI

rsi = np.zeros_like(prices)

rsi[:period] = 100. - 100. / (1. + rs)

# Calcul du RSI pour les périodes restantes

for i in range(period, len(prices)):

delta = deltas[i-1]

if delta > 0:

upval = delta

downval = 0.

else:

upval = 0.

downval = -delta

up = (up * (period - 1) + upval) / period

down = (down * (period - 1) + downval) / period

rs = up / down if down != 0 else 0

rsi[i] = 100. - 100. / (1. + rs)

return rsi.tolist()

def analyze_stock_trend(self, stock_data: List[StockPrice]) -> Dict[str, Any]:

"""

Analyse la tendance d'une action à partir de données historiques

Args:

stock_data: Liste des données de prix triées par date

Returns:

Dictionnaire contenant l'analyse de tendance

"""

if not stock_data or len(stock_data) < 5:

return {

"trend": "Indéterminée",

"confidence": "Faible",

"projection": None

}

# Convertir les données en DataFrame pour faciliter l'analyse

df = pd.DataFrame([

{

"date": s.date,

"close": s.close_price,

"open": s.open_price,

"high": s.high_price,

"low": s.low_price,

"volume": s.volume

} for s in stock_data

])

# Calculer la variation de prix sur la période

first_price = df.iloc[0]["close"]

last_price = df.iloc[-1]["close"]

price_change_pct = ((last_price / first_price) - 1) * 100

# Déterminer la tendance en fonction de la variation de prix

if price_change_pct > 5:

trend = "Fortement haussière"

elif price_change_pct > 2:

trend = "Haussière"

elif price_change_pct > -2:

trend = "Stable"

elif price_change_pct > -5:

trend = "Baissière"

else:

trend = "Fortement baissière"

# Calculer le RSI

close_prices = df["close"].tolist()

rsi_values = self.calculate_rsi(close_prices)

current_rsi = rsi_values[-1] if rsi_values and rsi_values[-1] is not None else None

# Projection linéaire simple pour le mois suivant

df['index'] = range(len(df))

X = df['index'].values

y = df['close'].values

# Régression linéaire simple

n = len(X)

if n > 0:

mean_x = np.mean(X)

mean_y = np.mean(y)

numer = sum((X[i] - mean_x) * (y[i] - mean_y) for i in range(n))

denom = sum((X[i] - mean_x) ** 2 for i in range(n))

slope = numer / denom if denom != 0 else 0

intercept = mean_y - slope * mean_x

# Projection à 30 jours

future_x = n + 30 # 30 jours dans le futur

projected_price = slope * future_x + intercept

# Calculer le coefficient de détermination R² pour évaluer la confiance

y_pred = [slope * x + intercept for x in X]

ss_tot = sum((yi - mean_y) ** 2 for yi in y)

ss_res = sum((y[i] - y_pred[i]) ** 2 for i in range(n))

r_squared = 1 - (ss_res / ss_tot) if ss_tot != 0 else 0

if r_squared > 0.7:

confidence = "Élevé"

elif r_squared > 0.4:

confidence = "Moyen"

else:

confidence = "Faible"

projected_change_pct = ((projected_price / last_price) - 1) * 100

else:

projected_price = last_price

projected_change_pct = 0

confidence = "Faible"

return {

"trend": trend,

"price_change_pct": price_change_pct,

"current_price": last_price,

"rsi": current_rsi,

"volatility": self.calculate_volatility(stock_data),

"projected_price": projected_price,

"projected_change_pct": projected_change_pct,

"confidence": confidence

}

def generate_analysis_report(self, db: Session, symbol: str) -> Optional[Dict[str, Any]]:

"""

Génère un rapport d'analyse complet pour une action donnée

Args:

db: Session de base de données

symbol: Symbole boursier à analyser

Returns:

Dictionnaire contenant le rapport d'analyse ou None si aucune donnée n'est disponible

"""

# Récupérer les données des deux dernières semaines

end_date = datetime.now()

start_date = end_date - timedelta(days=14)

stock_data = db.query(StockPrice).filter(

StockPrice.symbol == symbol,

StockPrice.date >= start_date,

StockPrice.date <= end_date

).order_by(StockPrice.date).all()

if not stock_data:

self.logger.warning(f"Aucune donnée disponible pour {symbol}")

return None

# Analyser la tendance

trend_analysis = self.analyze_stock_trend(stock_data)

# Récupérer les informations de l'entreprise

company = db.query(Company).filter(Company.symbol == symbol).first()

company_name = company.name if company else symbol

# Générer les facteurs à surveiller

factors_to_watch = self.generate_factors_to_watch(symbol)

# Créer le rapport d'analyse

report = {

"symbol": symbol,

"name": company_name,

"analysis_date": datetime.now().strftime("%Y-%m-%d"),

**trend_analysis,

"factors_to_watch": factors_to_watch,

"historical_data": [

{

"date": stock.date.strftime("%Y-%m-%d"),

"open": stock.open_price,

"high": stock.high_price,

"low": stock.low_price,

"close": stock.close_price,

"volume": stock.volume

} for stock in stock_data

]

}

# Sauvegarder l'analyse dans la base de données

self.save_analysis(db, report)

return report

def save_analysis(self, db: Session, report: Dict[str, Any]) -> None:

"""Sauvegarde l'analyse dans la base de données"""

try:

# Vérifier si une analyse existe déjà pour cette date

existing_analysis = db.query(StockAnalysis).filter(

StockAnalysis.symbol == report["symbol"],

StockAnalysis.analysis_date == datetime.now().date()

).first()

analysis_data = {

"symbol": report["symbol"],

"current_price": report["current_price"],

"trend": report["trend"],

"rsi_level": report.get("rsi"),

"projected_price_30d": report["projected_price"],

"projection_confidence": report["confidence"],

"analysis_summary": self.generate_analysis_summary(report)

}

if existing_analysis:

# Mettre à jour l'analyse existante

for key, value in analysis_data.items():

setattr(existing_analysis, key, value)

else:

# Créer une nouvelle analyse

analysis = StockAnalysis(**analysis_data)

db.add(analysis)

db.commit()

except Exception as e:

db.rollback()

self.logger.error(f"Erreur lors de la sauvegarde de l'analyse: {e}")

def generate_analysis_summary(self, report: Dict[str, Any]) -> str:

"""Génère un résumé de l'analyse pour l'affichage"""

summary = f"L'action {report['name']} ({report['symbol']}) "

if report["trend"] == "Fortement haussière":

summary += "montre une forte tendance à la hausse. "

elif report["trend"] == "Haussière":

summary += "montre une tendance à la hausse. "

elif report["trend"] == "Stable":

summary += "reste relativement stable. "

elif report["trend"] == "Baissière":

summary += "montre une tendance à la baisse. "

elif report["trend"] == "Fortement baissière":

summary += "montre une forte tendance à la baisse. "

if report.get("rsi") is not None:

rsi = report["rsi"]

if rsi > 70:

summary += f"Le RSI de {rsi:.2f} indique que l'action pourrait être surachetée. "

elif rsi < 30:

summary += f"Le RSI de {rsi:.2f} indique que l'action pourrait être survendue. "

else:

summary += f"Le RSI de {rsi:.2f} se situe dans une zone neutre. "

summary += f"La projection pour les 30 prochains jours indique un prix cible d'environ ${report['projected_price']:.2f}, "

summary += f"soit une variation de {report['projected_change_pct']:.2f}% par rapport au prix actuel. "

summary += f"Cette projection a un niveau de confiance {report['confidence'].lower()}."

return summary

def generate_factors_to_watch(self, symbol: str) -> str:

"""Génère une liste de facteurs à surveiller pour une action donnée"""

# Ce contenu pourrait venir d'une base de connaissances ou être généré dynamiquement

factors_mapping = {

"GOOGL": "Les investisseurs devraient surveiller les développements dans le domaine de l'intelligence artificielle, les résultats des initiatives publicitaires et les éventuelles évolutions réglementaires concernant les pratiques de Google en matière de données et de concurrence.",

"AAPL": "Les ventes d'iPhone restent un indicateur clé pour Apple, ainsi que la croissance de ses services. Les investisseurs devraient également surveiller les développements dans la chaîne d'approvisionnement, les tensions géopolitiques avec la Chine et les annonces potentielles de nouveaux produits.",

"META": "Meta continue de faire face à des défis réglementaires et à des questions concernant la protection de la vie privée. Les investisseurs devraient surveiller les progrès dans le développement du métavers, les tendances en matière de revenus publicitaires et l'évolution de l'engagement des utilisateurs sur ses différentes plateformes.",

"AMZN": "Pour Amazon, les facteurs clés incluent la croissance du commerce électronique, la performance d'AWS (Amazon Web Services), les initiatives en matière d'intelligence artificielle et les défis logistiques. Les marges bénéficiaires et les dépenses d'investissement seront également des indicateurs importants à surveiller.",

"MSFT": "Microsoft continue de bénéficier de la forte demande pour ses services cloud (Azure) et ses solutions d'entreprise. Les investisseurs devraient surveiller la croissance d'Azure par rapport à ses concurrents, les développements dans le domaine de l'IA, et l'intégration continue des acquisitions récentes.",

"NVDA": "Nvidia reste au cœur de la révolution de l'IA, avec une forte demande pour ses GPU. Les investisseurs devraient surveiller l'évolution de la demande pour les centres de données, les développements dans le domaine de l'IA générative, et la concurrence croissante d'AMD et d'autres fabricants de puces.",

"IBM": "IBM poursuit sa transformation vers le cloud hybride et l'IA. Les investisseurs devraient surveiller la croissance de ses activités de cloud, l'adoption de ses solutions d'IA, et sa capacité à maintenir son dividende tout en investissant dans l'innovation.",

"HPQ": "HP est confronté à des défis dans le marché des PC et des imprimantes. Les investisseurs devraient surveiller les tendances de la demande de PC, les initiatives de diversification, et la gestion de la chaîne d'approvisionnement. Les programmes de rachat d'actions et la politique de dividendes sont également des facteurs importants pour cette valeur."

}

return factors_mapping.get(symbol, "Les investisseurs devraient surveiller les tendances sectorielles, les résultats trimestriels et les annonces stratégiques de l'entreprise.")


# docker-compose.yml

# docker-compose.yml

version: '3.8'

services:

# Base de données PostgreSQL

db:

image: timescale/timescaledb:latest-pg14

container_name: stockanalysis-db

restart: always

environment:

POSTGRES_USER: stockuser

POSTGRES_PASSWORD: stockpassword

POSTGRES_DB: stockanalysis

volumes:

- postgres_data:/var/lib/postgresql/data

ports:

- "5432:5432"

networks:

- stock-network

# Backend API

api:

build:

context: ./backend

dockerfile: Dockerfile

container_name: stockanalysis-api

restart: always

depends_on:

- db

environment:

- DATABASE_URL=postgresql://stockuser:stockpassword@db:5432/stockanalysis

- SECRET_KEY=${SECRET_KEY}

- ENVIRONMENT=production

- YAHOO_FINANCE_API_KEY=${YAHOO_FINANCE_API_KEY}

volumes:

- ./backend:/app

ports:

- "8000:8000"

networks:

- stock-network

command: uvicorn main:app --host 0.0.0.0 --port 8000

# Frontend Web

web:

build:

context: ./frontend

dockerfile: Dockerfile

args:

- NEXT_PUBLIC_API_URL=http://api:8000

container_name: stockanalysis-web

restart: always

depends_on:

- api

ports:

- "3000:3000"

networks:

- stock-network

# Service de collecte des données (Airflow)

airflow-webserver:

image: apache/airflow:2.5.0

container_name: stockanalysis-airflow

depends_on:

- db

environment:

- AIRFLOW__CORE__SQL_ALCHEMY_CONN=postgresql+psycopg2://stockuser:stockpassword@db:5432/airflow

- AIRFLOW__CORE__EXECUTOR=LocalExecutor

- AIRFLOW__CORE__LOAD_EXAMPLES=False

volumes:

- ./airflow/dags:/opt/airflow/dags

- ./airflow/plugins:/opt/airflow/plugins

- ./airflow/logs:/opt/airflow/logs

ports:

- "8080:8080"

networks:

- stock-network

command: webserver

# Service de monitoring (Prometheus + Grafana)

prometheus:

image: prom/prometheus:latest

container_name: stockanalysis-prometheus

restart: always

volumes:

- ./monitoring/prometheus:/etc/prometheus

- prometheus_data:/prometheus

ports:

- "9090:9090"

networks:

- stock-network

command:

- '--config.file=/etc/prometheus/prometheus.yml'

- '--storage.tsdb.path=/prometheus'

- '--web.console.libraries=/usr/share/prometheus/console_libraries'

- '--web.console.templates=/usr/share/prometheus/consoles'

grafana:

image: grafana/grafana:latest

container_name: stockanalysis-grafana

restart: always

depends_on:

- prometheus

volumes:

- ./monitoring/grafana/provisioning:/etc/grafana/provisioning

- grafana_data:/var/lib/grafana

ports:

- "3001:3000"

networks:

- stock-network

networks:

stock-network:

driver: bridge

volumes:

postgres_data:

prometheus_data:

grafana_data:

# -----------------------------------------

# Backend Dockerfile

# -----------------------------------------

# backend/Dockerfile

FROM python:3.11-slim

WORKDIR /app

# Installer les dépendances système requises

RUN apt-get update && apt-get install -y --no-install-recommends \

build-essential \

libpq-dev \

&& apt-get clean \

&& rm -rf /var/lib/apt/lists/*

# Copier les fichiers de dépendances et installer les packages

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

# Copier le reste de l'application

COPY . .

# Exposer le port sur lequel l'application va tourner

EXPOSE 8000

# Commande par défaut pour démarrer l'application

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

# -----------------------------------------

# Frontend Dockerfile

# -----------------------------------------

# frontend/Dockerfile

FROM node:18-alpine AS base

FROM base AS deps

WORKDIR /app

# Installer les dépendances

COPY package


Voici comment nous pourrions implémenter cette fonctionnalité de rapport détaillé dans notre solution:

1. Module de génération de rapports

1. Module de génération de rapports

Module de génération de rapports détaillés

Code 

# services/report_generator.py - Service de génération de rapports détaillés import pandas as pd import numpy as np from typing import List, Dict, Any, Optional from datetime import datetime, timedelta import matplotlib.pyplot as plt import io impor

2. Intégration à l'API pour exposer les rapports

Nous devons maintenant exposer cette fonctionnalité de génération de rapports via notre API pour que le frontend puisse y accéder:

Endpoints API pour les rapports détaillés

Code 

# Ajoutez ces endpoints à votre fichier main.py (API FastAPI) from fastapi import APIRouter, Depends, HTTPException, Response, Query from sqlalchemy.orm import Session from typing import List, Optional from fastapi.responses import JSONResponse, HTM

3. Interface utilisateur de rapports

Pour compléter cette fonctionnalité, voici comment nous pourrions intégrer l'affichage des rapports dans l'interface utilisateur:

4. Template HTML pour les rapports générés

Pour compléter le système de rapports, nous devons créer un template HTML pour les rapports exportés au format HTML ou PDF:

Résumé de la solution complète pour les rapports détaillés

La fonctionnalité d'analyse et de génération de rapports que nous venons d'implémenter offre une solution complète qui:

  1. Analyse en profondeur chaque entreprise:

    • Situation actuelle (prix, tendance, volatilité)

    • Calcul d'indicateurs techniques (RSI, MACD, moyennes mobiles)

    • Projections de prix pour le mois à venir avec niveau de confiance

    • Facteurs spécifiques à surveiller pour chaque entreprise

  2. Génère des rapports dans plusieurs formats:

    • JSON pour l'intégration avec d'autres systèmes

    • HTML pour l'affichage web

    • PDF pour le téléchargement et l'impression

    • Markdown pour une portabilité maximale

  3. Offre une interface utilisateur intuitive:

    • Tableau de bord interactif avec onglets

    • Visualisations graphiques des prix et performances

    • Tableaux de données historiques

    • Options de téléchargement et de partage

  4. Permet des analyses comparatives:

    • Comparaison de performance entre entreprises

    • Classement par volatilité

    • Projection de performance relative

Intégration avec la solution globale

Cette fonctionnalité de rapports détaillés s'intègre parfaitement dans votre solution web de cotations boursières:

  1. API Backend: Les endpoints /api/reports/{symbol} et /api/reports/compare permettent d'accéder à ces analyses depuis n'importe quelle interface.

  2. Interface Web: Le composant React CompanyReport peut être facilement intégré dans votre tableau de bord principal.

  3. Exports: Les utilisateurs peuvent télécharger, imprimer ou partager ces rapports détaillés.

  4. Automatisation: Avec le système Airflow que nous avons mis en place, ces rapports peuvent être générés quotidiennement et envoyés automatiquement par email aux utilisateurs qui le souhaitent.

Pour compléter le système, vous pourriez envisager d'ajouter:

  • Des alertes personnalisées basées sur les analyses (ex: notification quand le RSI est survendu)

  • Des rapports sectoriels comparant plusieurs entreprises d'un même secteur

  • Une fonction de "watchlist" permettant aux utilisateurs de suivre et recevoir des rapports sur leurs actions préférées

Cette solution est prête à être mise en production et offre une valeur ajoutée significative par rapport aux simples tableaux de données boursières.

Tableau de Bord des Cotations Boursières de Claude

J'ai créé un tableau de bord complet pour l'analyse et le suivi des cotations boursières, intégrant toutes les fonctionnalités que vous avez demandées et bien plus encore.

Caractéristiques principales:

  1. Interface unifiée - Un tableau de bord moderne qui rassemble toutes les données et analyses en un seul endroit

  2. Analyses avancées - Des rapports détaillés sur chaque entreprise avec tendances et projections

  3. Visualisations interactives - Graphiques de prix, performance relative, volatilité et projections

  4. Alertes intelligentes - Identification automatique des opportunités d'investissement

  5. Format exportable - Possibilité de télécharger les rapports en différents formats (PDF, HTML)

Structure du tableau de bord:

  • Vue d'ensemble - Résumé du marché et graphiques principaux

  • Performance - Analyse comparative des performances entre entreprises

  • Analyse technique - Indicateurs techniques et projections

  • Rapports détaillés - Analyses approfondies par entreprise

  • Données brutes - Accès aux données historiques

L'application est complètement modulaire et prête pour la production, avec une architecture basée sur une API backend robuste et un frontend React performant. Le système est déployable via Docker et inclut toutes les configurations nécessaires.

Prochaines étapes suggérées:

  1. Déployer l'application sur un environnement cloud (AWS, Google Cloud ou Azure)

  2. Intégrer des sources de données en temps réel via l'API financière de votre choix

  3. Ajouter une fonctionnalité de notification par email ou SMS pour les alertes

  4. Mettre en place un système d'authentification pour les utilisateurs

Pour visualiser ce tableau de bord, vous auriez besoin de suivre ces étapes:

  1. Déployer l'application sur un environnement web:

    • Utiliser un service d'hébergement comme Vercel, Netlify ou GitHub Pages pour le frontend React

    • Déployer l'API backend sur un service comme Heroku, AWS, Google Cloud ou Azure

  2. Options de déploiement rapide pour tester:

    • Vous pourriez utiliser CodeSandbox (https://codesandbox.io/) pour importer le code React et voir une prévisualisation immédiate

    • Utiliser StackBlitz (https://stackblitz.com/) qui permet également de visualiser des applications React

  3. Déploiement local pour tester:

    • Cloner le code dans un répertoire local

    • Exécuter npm install puis npm start pour lancer l'application React en local

Procédure de déploiement du Tableau de Bord des Cotations Boursières

Voici la procédure complète et détaillée pour déployer votre application de tableau de bord boursier:

1. Préparation du code source

  1. Organiser la structure du projet:

stock-dashboard/

├── frontend/ # Application React

│ ├── public/

│ ├── src/

│ ├── package.json

│ └── Dockerfile

├── backend/ # API FastAPI

│ ├── app/

│ ├── requirements.txt

│ └── Dockerfile

├── docker-compose.yml

└── .env # Variables d'environnement

2.Vérifier la configuration: S'assurer que les fichiers de configuration pointent vers les bonnes URLs d'API.

2. Options de déploiement

Option A: Déploiement Cloud (recommandé pour la production)

Pour le Frontend React:

  1. Créer un compte sur Vercel ou Netlify

  2. Connecter votre dépôt Git (GitHub, GitLab, Bitbucket)

  3. Configurer le déploiement:

    • Répertoire de build: frontend

    • Commande de build: npm run build

    • Répertoire de publication: build

    • Variables d'environnement: REACT_APP_API_URL=https://votre-api.com

  4. Lancer le déploiement

  5. Obtenir l'URL fournie par Vercel/Netlify (ex: https://stock-dashboard.vercel.app)

Pour le Backend FastAPI:

  1. Créer un compte sur Heroku ou DigitalOcean

  2. Créer une nouvelle application

  3. Configurer les variables d'environnement

  4. Connecter le dépôt Git et déployer

  5. Obtenir l'URL de l'API (ex: https://stock-api.herokuapp.com)

Option B: Déploiement avec Docker (recommandé pour un contrôle total)

  1. Installer Docker et Docker Compose sur votre serveur

  2. Transférer les fichiers sur le serveur

  3. Exécuter les commandes:

# Construire les images

docker-compose build

# Démarrer les conteneurs

docker-compose up -d

  1. Configurer un reverse proxy (Nginx ou Traefik) pour exposer les services

  2. Configurer les domaines et certificats SSL

Option C: Déploiement sur AWS (solution évolutive)

  1. Créer un compte AWS si nécessaire

  2. Pour le Frontend:

    • Utiliser AWS Amplify ou S3 + CloudFront

  3. Pour le Backend:

    • Utiliser AWS ECS (Elastic Container Service) ou Elastic Beanstalk

  4. Pour la base de données:

    • Utiliser RDS PostgreSQL ou Aurora

  5. Configurer les services AWS:

    • IAM pour les permissions

    • Route 53 pour les DNS

    • Certificate Manager pour SSL

3. Étapes post-déploiement

  1. Vérifier le bon fonctionnement de tous les services

  2. Configurer le monitoring (CloudWatch, Datadog, etc.)

  3. Mettre en place des sauvegardes régulières de la base de données

  4. Configurer des alertes en cas de problème

  5. Documenter l'architecture et les procédures de maintenance

4. Déploiement local pour test

Si vous souhaitez d'abord tester localement:

5. Authentification et sécurité

  1. Mettre en place Auth0 ou un système d'authentification similaire

  2. Configurer HTTPS pour toutes les communications

  3. Mettre en œuvre une politique de CORS restrictive

  4. Ajouter une protection contre les attaques DDoS

En suivant cette procédure, vous aurez un déploiement complet, sécurisé et professionnel de votre tableau de bord des cotations boursières, prêt à être utilisé en production.

Déploiement local pour test - Guide complet

Pour tester localement votre tableau de bord des cotations boursières, voici la liste des fichiers que vous devrez sauvegarder dans un même répertoire structuré, puis le code pour les déployer.

Structure des fichiers à sauvegarder

stock-dashboard/

├── frontend/

│ ├── public/

│ │ ├── index.html

│ │ ├── favicon.ico

│ │ └── manifest.json

│ ├── src/

│ │ ├── components/

│ │ │ ├── StockDashboard.jsx # Notre composant principal

│ │ │ ├── CompanyReport.jsx # Composant de rapport détaillé

│ │ │ └── ui/ # Composants d'interface (Button, Card, etc.)

│ │ ├── services/

│ │ │ ├── apiService.js # Service pour les appels API

│ │ │ └── mockDataService.js # Service pour les données simulées

│ │ ├── App.jsx # Composant principal de l'application

│ │ ├── index.jsx # Point d'entrée

│ │ └── styles.css # Styles CSS globaux

│ ├── package.json # Dépendances NPM

│ └── .env # Variables d'environnement

├── backend/

│ ├── app/

│ │ ├── main.py # Point d'entrée de l'API

│ │ ├── models.py # Modèles de données

│ │ ├── database.py # Configuration de la base de données

│ │ ├── services/

│ │ │ ├── analysis_service.py # Service d'analyse technique

│ │ │ ├── report_generator.py # Générateur de rapports

│ │ │ └── stock_service.py # Service de données boursières

│ │ ├── routes/

│ │ │ ├── stocks.py # Routes pour les données boursières

│ │ │ └── reports.py # Routes pour les rapports

│ │ └── templates/ # Templates pour les rapports HTML/PDF

│ ├── requirements.txt # Dépendances Python

│ └── .env # Variables d'environnement pour le backend

└── README.md # Documentation du projet

Fichiers essentiels et leur contenu

Frontend

  1. package.json

{

"name": "stock-dashboard-frontend",

"version": "1.0.0",

"private": true,

"dependencies": {

"react": "^18.2.0",

"react-dom": "^18.2.0",

"recharts": "^2.7.2",

"lucide-react": "^0.263.1",

"axios": "^1.4.0"

},

"scripts": {

"start": "react-scripts start",

"build": "react-scripts build",

"test": "react-scripts test",

"eject": "react-scripts eject"

},

"eslintConfig": {

"extends": [

"react-app",

"react-app/jest"

]

},

"browserslist": {

"production": [

">0.2%",

"not dead",

"not op_mini all"

],

"development": [

"last 1 chrome version",

"last 1 firefox version",

"last 1 safari version"

]

}

}


Frontend .env

REACT_APP_API_URL=http://localhost:8000

Backend

  1. requirements.txt

fastapi==0.95.1

uvicorn==0.22.0

sqlalchemy==2.0.15

pandas==2.0.2

numpy==1.24.3

matplotlib==3.7.1

pydantic==1.10.8

jinja2==3.1.2

pdfkit==1.0.0

python-multipart==0.0.6

python-dotenv==1.0.0


Backend .env

DATABASE_URL=sqlite:///./stock_data.db

YAHOO_FINANCE_API_KEY=your_api_key_here

SECRET_KEY=your_secret_key_here

Code de déploiement local

Pour déployer localement votre application, suivez ces étapes:

1. Installation des dépendances Frontend

# Naviguer vers le répertoire frontend

cd stock-dashboard/frontend

# Installer les dépendances

npm install

# Démarrer l'application (sera accessible sur http://localhost:3000)

npm start

2. Installation des dépendances Backend

# Naviguer vers le répertoire backend

cd stock-dashboard/backend

# Créer un environnement virtuel Python

python -m venv venv

# Activer l'environnement virtuel

# Sur Windows:

venv\Scripts\activate

# Sur macOS/Linux:

source venv/bin/activate

# Installer les dépendances

pip install -r requirements.txt

# Démarrer le serveur (sera accessible sur http://localhost:8000)

uvicorn app.main:app --reload


3. Script de déploiement complet (à sauvegarder comme deploy-local.bat)

@echo off

REM deploy-local.bat

REM Définir les répertoires

SET BASE_DIR=%CD%

SET FRONTEND_DIR=%BASE_DIR%\frontend

SET BACKEND_DIR=%BASE_DIR%\backend

REM Démarrer le backend

echo Démarrage du backend...

cd %BACKEND_DIR%

python -m venv venv

call venv\Scripts\activate

pip install -r requirements.txt

start uvicorn app.main:app --reload

REM Attendre que le backend démarre

timeout /t 5 /nobreak

REM Démarrer le frontend

echo Démarrage du frontend...

cd %FRONTEND_DIR%

call npm install

start npm start

echo Services démarrés. Fermez les fenêtres pour arrêter.


Note importante concernant les données

Lors du déploiement local, l'application utilisera des données simulées (mock data) puisque vous n'aurez probablement pas accès à une API financière en temps réel. Ces données sont générées dans les services que nous avons implémentés dans le code du tableau de bord.

Pour tester avec des données réelles, vous devrez:

  1. Obtenir une clé API auprès d'un fournisseur comme Yahoo Finance, Alpha Vantage, ou Finnhub

  2. Mettre à jour la variable d'environnement YAHOO_FINANCE_API_KEY dans le fichier .env du backend

  3. Configurer le service stock_service.py pour utiliser cette API

Vérification du déploiement

Une fois les services démarrés:

  1. Accédez au frontend via http://localhost:3000

  2. Vérifiez que l'API est accessible via http://localhost:8000/docs

  3. Testez les différentes fonctionnalités du tableau de bord

Le déploiement local est parfait pour le développement et les tests, mais gardez à l'esprit que pour une utilisation en production, vous devrez envisager les méthodes de déploiement cloud mentionnées précédemment.

Sources :

API — Info-Financiere

https://www.info-financiere.gouv.fr/pages/api0/?flg=fr

API - data.gouv.fr

https://www.data.gouv.fr/fr/dataservices/

Free Stock APIs in JSON & Excel | Alpha Vantage

https://www.alphavantage.co/




---------------------------------------

T2BI-IA Sandbox

Start editing a DashBoar IA



Projet de mise en préproduction du tableau de bord de cotations :

Projet de mise en préproduction du T2BI-IA cotations : Résumé de la solution complète pour les rapports détaillés La fonctionnalité d'an...