PE25 — Projet d’études · École Centrale de Lyon
Application web de gestion et simulation de portefeuille : sélection d’actifs (actions des grands indices US, cryptomonnaies), historiques de prix, actualités, modèles d’optimisation type Markowitz (classique, multi-facteurs, pipeline LLM, crypto Fama-French) et suivi des simulations.
- Accueil — présentation du projet, liens vers les modules principaux, indicateurs (nombre d’actions / cryptos chargées depuis l’API).
- Mode actifs — bascule actions / crypto (navbar) : adapte le portefeuille sauvegardé, les modèles disponibles en simulation et les libellés côté interface.
- Mon portefeuille (
/portfolio) — composition du portefeuille à partir du catalogue d’actions (S&P 500, NASDAQ-100, Dow Jones) ou des cryptos listées par le backend ; graphiques de performance et métriques de risque sur données historiques (yfinance côté API). - Simulation (
/simulation) — choix du modèle d’optimisation et de la méthode numérique (Monte-Carlo, gradient à pas fixe / optimal, mode comparaison) ; pour Markowitz LLM, progression en Server-Sent Events (backtest mois par mois) ; mode crypto : modèle Fama-French à 3 facteurs sur séries locales. - Historique (
/history) — enregistrement des dernières simulations (fichier JSON côté serveur), édition de description, suppression d’entrées. - Architecture (
/architecture) — page de documentation / schéma du système pour le rapport de projet. - Actualités — flux d’articles liés à un symbole (Yahoo Finance), avec cache côté API pour limiter les appels répétés.
- Expérience desktop — sur petit écran, un écran MobileBlock invite à utiliser un affichage plus large (l’UI cible le bureau).
- Interface — composants shadcn/ui (Radix), graphiques Recharts, animations Framer Motion, notifications Sonner, formulaires compatibles React Hook Form + Zod où pertinent.
Note : le dépôt contient aussi des notebooks / scripts de recherche sous
gestion/(méthodologies Markowitz, Fama-French, module VIX en Python, etc.). Tout n’est pas forcément exposé par l’API FastAPI : les routes listées plus bas reflètent ce que le front consomme aujourd’hui.
| Couche | Technologie |
|---|---|
| Build & dev (front) | Vite 5 |
| UI | React 18 |
| Langage (front) | TypeScript 5 |
| Routage | React Router 6 |
| Style | Tailwind CSS 3 + thème applicatif |
| Composants | Radix UI, shadcn/ui, Lucide React |
| Données client | TanStack Query |
| Validation | Zod, React Hook Form |
| Graphiques | Recharts |
| API | FastAPI + Uvicorn |
| Données marché | yfinance, pandas |
| Stats / facteurs | statsmodels, pandas-datareader |
| LLM (sélection de facteurs, etc.) | SDK Mistral, OpenAI, Anthropic, Google GenAI (selon configuration) |
| Tests (front) | Vitest, Testing Library |
- Node.js ≥ 18 (LTS recommandé)
- Python ≥ 3.10 avec pip
- Connexion Internet pour yfinance (téléchargement des cours) et, si vous utilisez le modèle LLM ou les actualités, pour les appels réseau correspondants
- Pour le pipeline Markowitz LLM : clé API du fournisseur choisi (
SELECTOR_PROVIDERdans.env, voir ci-dessous)
git clone https://github.com/<org>/PE25.git
cd PE25Frontend
npm installBackend
pip install -r server/requirements.txtÀ la racine du projet, créer un fichier .env (le chargeur Python lit ce fichier pour le module gestion.dynamic.llm_config). Un exemple minimal est fourni dans .env.example.
cp .env.example .envExemple de contenu (adapter selon les besoins) :
# LLM — pipeline « choix dynamique des facteurs » (Markowitz LLM)
MISTRAL_API_KEY=
MISTRAL_MODEL=mistral-medium-latest
SELECTOR_PROVIDER=mistral
# Optionnel — autres fournisseurs si SELECTOR_PROVIDER change
# OPENAI_API_KEY=
# OPENAI_MODEL=gpt-4o
# ANTHROPIC_API_KEY=
# ANTHROPIC_MODEL=claude-sonnet-4-5
# GOOGLE_API_KEY=
# GEMINI_MODEL=gemini-2.0-flashFrontend : si l’API n’est pas sur http://localhost:8000, définir par exemple :
VITE_API_URL=http://127.0.0.1:8000La liste des tickers est lue depuis server/stocks_data.json si présent, sinon server/stocks_data.default.json. Pour régénérer le fichier à jour :
cd server && python update_stocks_data.pyLes séries historiques crypto attendues par l’API sont des CSV sous gestion/crypto/données/ (format attendu : colonnes dont snapped_at, price). Sans ces fichiers, la liste ou l’historique crypto peut être vide ou renvoyer une erreur « fichier absent ».
Le script npm run start lance en parallèle Uvicorn (port 8000) et Vite (port 8080).
npm run start- Interface : http://localhost:8080
- API seule :
npm run api→ http://127.0.0.1:8000 - Front seul :
npm run dev(sans backend, les appels/api/...échoueront sauf proxy ouVITE_API_URLvers une API déjà démarrée)
npm run buildLe résultat est dans dist/. En local, l’API et le front peuvent rester sur deux ports (voir VITE_API_URL et CORS dans server/main.py). Pour une mise en ligne sur une seule URL (recommandé), utiliser le Dockerfile à la racine : build Vite + Uvicorn qui sert l’UI et /api/* (même origine, pas de CORS à configurer).
8. Déploiement sur Render
Le fichier render.yaml décrit un Web Service Docker (plan Free par défaut). L’application répond sur une URL du type https://pe25-portfolio.onrender.com : page d’accueil, routes React (/portfolio, etc.) et API sous /api/....
Étapes
- Créer un compte Render et connecter le dépôt GitHub (ou GitLab) contenant ce projet.
- Dashboard → New → Blueprint → sélectionner le dépôt → Render détecte
render.yamlet propose de créer le service. Confirmer le déploiement.
Alternative : New → Web Service → même dépôt → Runtime : Docker → répertoire racine du repo, Dockerfile path :Dockerfile. - Dans Environment du service, renseigner au besoin les secrets (voir
.env.example) :MISTRAL_API_KEYsi vous utilisez Markowitz LLM ; laisserALLOW_ORIGINSvide pour l’image monolithique. Les variablesSELECTOR_PROVIDER/MISTRAL_MODELsont préremplies dans le blueprint ; adaptez-les si vous changez de fournisseur. - Attendre la fin du premier build (plusieurs minutes :
npm ci,npm run build,pip install). Le health check utiliseGET /api/health. - Ouvrir l’URL HTTPS affichée par Render : c’est l’unique origine à utiliser pour la démo.
Comportement du plan gratuit
Le service se met en veille après une période sans trafic ; la première requête après veille peut prendre une minute ou plus (cold start + build image si redéploiement). Pour une démo sans veille, passer à un plan payant Render (Starter ou supérieur) sur ce même Web Service.
Fichiers utiles
| Fichier | Rôle |
|---|---|
Dockerfile |
Image : Node (build dist/) + Python 3.12 + uvicorn sur le port PORT (injecté par Render). |
render.yaml |
Blueprint : nom du service, healthCheckPath, variables d’environnement. |
.dockerignore |
Réduit le contexte Docker ; l’historique server/simulation_history.json n’est pas copié (fichier recréé à l’usage sur l’instance). |
| Commande | Description |
|---|---|
npm run start |
Uvicorn (reload) sur le port 8000 + Vite sur le port 8080 (recommandé en local) |
npm run dev |
Vite seul (port 8080) |
npm run api |
API FastAPI seule (uvicorn server.main:app --reload --host 0.0.0.0 --port 8000) |
npm run build |
Build de production dans dist/ |
npm run build:dev |
Build en mode development |
npm run preview |
Prévisualisation du build Vite |
npm run lint |
ESLint |
npm test |
Vitest (une fois) |
npm run test:watch |
Vitest en mode watch |
├── gestion/ # Logique métier Python (optimisation, facteurs, crypto, LLM…)
│ ├── Methodes_de_descente/ # Descentes de gradient (pas fixe / optimal)
│ ├── multifactor/ # Markowitz 1, 3 et 5 facteurs
│ ├── dynamic/ # Pipeline LLM, config, cache, loaders FRED, etc.
│ ├── crypto/ # Markowitz crypto + CSV « données » + helpers FF
│ ├── vix/ # Travaux autour du VIX (recherche / extension)
│ ├── methodology/ # Notes méthodologiques (.md)
│ ├── config.py # Méthode d’optimisation par défaut (ex. gradient_optimal)
│ └── markowitz_simple.py # Markowitz classique
├── server/
│ ├── main.py # Application FastAPI : routes /api/*
│ ├── tickers_data.py # Chargement de la liste d’actions depuis JSON
│ ├── stocks_data.json # Liste d’actions (optionnel, sinon .default.json)
│ ├── stocks_data.default.json
│ ├── simulation_history.json # Historique des simulations (créé à l’usage)
│ ├── update_stocks_data.py # Script de régénération des tickers
│ └── requirements.txt
├── src/
│ ├── App.tsx # Routes, providers, garde mobile
│ ├── main.tsx
│ ├── context/ # Mode actifs actions / crypto
│ ├── components/ # Navbar, Footer, résultats de simulation, ui/ (shadcn)
│ ├── hooks/
│ ├── lib/ # Client API, historique, stockage local portefeuille
│ ├── pages/ # Home, Portfolio, Simulation, History, Architecture, NotFound
│ └── index.css
├── index.html
├── vite.config.ts # Port 8080, alias `@` → `./src`
├── Dockerfile # Build front + API pour prod (ex. Render)
├── render.yaml # Blueprint Render (Web Service Docker)
├── structure.md # Guide pédagogique détaillé du front
├── .env.example
└── package.json
Base URL côté front : en dev, VITE_API_URL ou http://localhost:8000 ; en build prod sans VITE_API_URL, requêtes relatives vers la même origine (Docker / Render monolithique).
| Méthode | Chemin | Rôle |
|---|---|---|
GET |
/api/stocks |
Liste des actions (symbole, nom, indice) |
GET |
/api/crypto/list |
Liste des cryptos disponibles (données locales) |
GET |
/api/crypto/history |
Historique de prix (symbol, start, end optionnels) |
GET |
/api/crypto/news-symbol |
Symbole Yahoo pour les news à partir du code crypto |
GET |
/api/history |
Historique de cours pour un ou plusieurs tickers (symbols, dates, interval) |
GET |
/api/news |
Actualités pour un symbole Yahoo (symbol, limit) |
POST |
/api/simulate |
Lance une optimisation (model, symbols, method optionnel) |
POST |
/api/simulate-llm-stream |
SSE : progression + résultat Markowitz LLM |
GET |
/api/history/list |
Liste l’historique des simulations enregistrées |
POST |
/api/history/save |
Enregistre une entrée d’historique |
PATCH |
/api/history/{id}/description |
Met à jour la description d’une entrée |
DELETE |
/api/history/{id} |
Supprime une entrée |
Modèles attendus par POST /api/simulate (champ model) : markowitz-classic, markowitz-1factor, markowitz-3factors, markowitz-5factors, markowitz-llm, markowitz-crypto-ff3.
Projet d’études (PE25) — École Centrale de Lyon : application de recherche et de démonstration autour de l’optimisation de portefeuille et des modèles factoriels, sans conseil en investissement.
Pour une présentation pas à pas du code React / Vite du dépôt, voir aussi structure.md.
