Documentation Technique et FonctionnelleTechnical and Functional Documentation
1. Vue d'ensemble1. Overview
Portfolio Manager est une application web monopage de gestion de portefeuille boursier. Elle est entièrement autonome : le serveur est écrit en Python pur (aucune dépendance externe) et le front-end est un fichier HTML unique avec JavaScript vanilla (Bootstrap 5, Chart.js chargés via CDN).
Portfolio Manager is a single-page web application for stock portfolio management. It is fully self-contained: the server is written in pure Python (no external dependencies) and the front-end is a single HTML file with vanilla JavaScript (Bootstrap 5, Chart.js loaded via CDN).
Ce que fait l'applicationWhat the application does
| DomaineDomain | FonctionnalitésFeatures |
|---|---|
| Suivi de portefeuillePortfolio tracking | Table de positions avec cotations temps réel, P&L, KPIs agrégés, graphique d'allocationPosition table with live quotes, P&L, aggregated KPIs, allocation chart |
| Gestion des positionsPosition management | CRUD, import CSV, saisie en masse, édition inlineCRUD, CSV import, bulk paste, inline editing |
| Analyse quantitativeQuantitative analysis | Contribution à la performance, VaR Monte Carlo (100 000 scénarios), CVaR, attribution BHBPerformance contribution, Monte Carlo VaR (100,000 scenarios), CVaR, BHB attribution |
| Modèle IAAI model | Score composite 4 critères (potentiel analyste, alpha secteur/pays, point d'entrée), optionnellement DCFComposite score 4 criteria (analyst target, sector/country alpha, entry point), optionally DCF |
| Valorisation DCFDCF valuation | Mode simplifié (données Yahoo Finance) et mode complet (projections FCF manuelles). Onglet Scores DCF dédié.Simple mode (Yahoo Finance data) and complete mode (manual FCF projections). Dedicated DCF Scores tab. |
| Arbitrage | Simulation avec 7 modèles prédéfinis ou portefeuilles cibles personnalisésSimulation with 7 predefined models or custom target portfolios |
| Gestion clientsClient management | CRUD clients, association portefeuilles, rapport valorisé en EURClient CRUD, portfolio association, EUR-valued report |
| ComparaisonComparison | Analyse What If, comparaison de benchmarks sur 5 périodesWhat If analysis, benchmark comparison over 5 periods |
| ESG | Score ESG/E/S/G issu d'un fichier Excel externeESG/E/S/G score from an external Excel file |
Stack techniqueTechnical stack
| ComposantComponent | TechnologieTechnology |
|---|---|
| Serveur HTTPHTTP server | Python 3 stdlib — http.server.HTTPServer / BaseHTTPRequestHandler |
| PersistencePersistence | Fichiers JSON locauxLocal JSON files |
| Données marchéMarket data | Yahoo Finance API (spark, chart, quoteSummary, search) via urllib.request |
| IdentificationIdentification | OpenFIGI API v3 (mapping TICKER → ISIN) |
| ESG | Fichier Excel .xlsx lu via zipfile + xml.etree.ElementTreeExcel .xlsx file read via zipfile + xml.etree.ElementTree |
| Front-end | HTML5 + CSS3 + JavaScript ES2020 vanilla |
| UI framework | Bootstrap 5.3.2 (CDN) + Bootstrap Icons 1.11.3 (CDN) |
| GraphiquesCharts | Chart.js 4.4.0 (CDN) |
Architecture
Navigateur Serveur Python (port 5000) Sources externes ────────── ────────────────────────── ──────────────── index.html ←── GET / ── Handler.do_GET Yahoo Finance API JavaScript ←──REST API── Handler.do_POST/PUT/DELETE OpenFIGI API fetch() ─────────────► Calculs : VaR, BHB, DCF, arbitrage ESG Excel (local) Chart.js Cache mémoire (_cache dict) Bootstrap Fichiers JSON (portfolio, arb, dcf, clients)Browser Python server (port 5000) External sources ────────── ────────────────────────── ──────────────── index.html ←── GET / ── Handler.do_GET Yahoo Finance API JavaScript ←──REST API── Handler.do_POST/PUT/DELETE OpenFIGI API fetch() ─────────────► Calcs: VaR, BHB, DCF, arbitrage ESG Excel (local) Chart.js In-memory cache (_cache dict) Bootstrap JSON files (portfolio, arb, dcf, clients)
Le serveur est single-threaded (pas de ThreadingMixIn) ; les calculs longs (VaR Monte Carlo) bloquent donc le serveur le temps du calcul. Un verrou threading.Lock protège le cache partagé contre les accès concurrents potentiels.
The server is single-threaded (no ThreadingMixIn); long calculations (Monte Carlo VaR) therefore block the server during computation. A threading.Lock protects the shared cache against potential concurrent access.
2. Installation et démarrage2. Installation and startup
PrérequisPrerequisites
- Python 3.8+ (aucune librairie externe requise)
- Python 3.8+ (no external libraries required)
- Accès internet (direct ou via proxy) pour Yahoo Finance
- Internet access (direct or via proxy) for Yahoo Finance
- Fichier ESG optionnel :
H:\test\etf_constituants_popular_investments_etf_strict_isinfirst.xlsx - Optional ESG file:
H:\test\etf_constituants_popular_investments_etf_strict_isinfirst.xlsx
Fichiers nécessairesRequired files
portfolio_app/ ├── server.py # Serveur + toute la logique backendServer + all backend logic ├── start.bat # Lanceur Windows (détection Python automatique)Windows launcher (auto Python detection) ├── templates/ │ ├── index.html # Application front-end SPASPA front-end application │ ├── documentation.html # Cette documentationThis documentation │ └── data_model.html # Modèle de donnéesData model ├── portfolio.json # Créé automatiquement au premier ajoutAuto-created on first add ├── arb_portfolios.json # Créé automatiquementAuto-created ├── dcf_params.json # Créé automatiquementAuto-created └── clients.json # Créé automatiquementAuto-created
DémarrageStartup
# Option 1 : double-clic sur start.bat (Windows) # Option 2 : ligne de commande# Option 1: double-click start.bat (Windows) # Option 2: command line cd H:\portfolio_app python server.py
Au démarrage, le programme :
On startup, the program:
- Charge les données ESG depuis le fichier Excel (si présent)
- Loads ESG data from the Excel file (if present)
- Demande interactivement la configuration du proxy :
- Entrée vide → proxy par défaut
-→ pas de proxy (connexion directe)host:port→ proxy personnalisé
- Interactively asks for proxy configuration:
- Empty enter → default proxy
-→ no proxy (direct connection)host:port→ custom proxy
- Demande optionnellement un login/mot de passe proxy
- Optionally asks for proxy login/password
- Démarre le serveur sur
http://127.0.0.1:5000 - Starts the server on
http://127.0.0.1:5000
Ctrl+CCtrl+C3. Structure des fichiers3. File structure
| FichierFile | RôleRole | |
|---|---|---|
server.py | Point d'entrée unique. Contient : serveur HTTP, toutes les routes REST, les calculs quantitatifs (VaR, BHB, DCF, contribution, arbitrage, what-if), les référentiels de données, le chargement ESG, la gestion du cache et du proxy. | Single entry point. Contains: HTTP server, all REST routes, quantitative calculations (VaR, BHB, DCF, contribution, arbitrage, what-if), data references, ESG loading, cache and proxy management. |
templates/index.html | Application front-end SPA. Contient : le HTML des 8 onglets, tous les styles CSS inline, et ~4 000 lignes de JavaScript vanilla gérant l'état, les appels REST, le rendu des tableaux, les graphiques Chart.js, la logique DCF Scores et la gestion clients. | SPA front-end. Contains: HTML for 8 tabs, all inline CSS, ~4,000 lines of vanilla JavaScript managing state, REST calls, table rendering, Chart.js graphs, DCF Scores logic and client management. |
portfolio.json | Portefeuille principal — liste des positions de l'utilisateur. | Main portfolio — list of user positions. |
arb_portfolios.json | Portefeuilles secondaires (arbitrage, stratégie, simulation, watchlist). | Secondary portfolios (arbitrage, strategy, simulation, watchlist). |
dcf_params.json | Paramètres DCF complets sauvegardés par ticker. | Full DCF parameters saved per ticker. |
clients.json | Données clients (CRUD, associations portefeuilles). | Client data (CRUD, portfolio associations). |
etf_constituants_…xlsx | Source ESG externe (lecture seule). Chemin codé en dur. | External ESG source (read-only). Hard-coded path. |
4. Données persistées4. Persisted data
4.1 portfolio.json
{
"positions": [
{
"isin": "FR0000131104",
"name": "BNP Paribas",
"ticker": "BNP.PA",
"quantity": 10,
"pru": 45.50,
"currency": "EUR",
"entry_date": "2024-01-15",
"category": "Stock",
"potentiel": 15.0,
"secteur": "Finance",
"pays": "FR",
"frais": 12.50
}
]
}
4.2 arb_portfolios.json
[
{
"id": "arb_1700000000000",
"name": "Tech Growth",
"created": "2024-01-15",
"type": "target",
"description": "Portefeuille cible tech",
"positions": [ ... ]
}
]
4.3 dcf_params.json
{
"AAPL": {
"current_price": 185.0,
"shares_outstanding": 15500000000,
"total_debt": 111000000000,
"total_cash": 65000000000,
"wacc": 0.09,
"terminal_growth": 0.025,
"fcf_projections": [90000000000, 95000000000, 100000000000],
"currency": "USD",
"last_updated": "2024-06-01"
}
}
4.4 clients.json
[
{
"id": "client_1700000000000",
"name": "Jean Dupont",
"email": "jean.dupont@example.com",
"phone": "+33 6 00 00 00 00",
"risk_profile": "Moderate",
"portfolio_ids": ["arb_1700000000001"],
"notes": "Client depuis 2022",
"created": "2024-01-15"
}
]
| ChampField | Type | DescriptionDescription | |
|---|---|---|---|
id | string | Identifiant unique généré (client_ + timestamp) | Generated unique ID (client_ + timestamp) |
name | string | Nom complet du client | Client full name |
email | string | Adresse email | Email address |
phone | string | Numéro de téléphone | Phone number |
risk_profile | string | Conservative, Moderate, Aggressive | |
portfolio_ids | string[] | IDs des portefeuilles arbitrage associés | IDs of associated arbitrage portfolios |
notes | string | Notes libres | Free-form notes |
created | string | YYYY-MM-DD |
5. API REST complète5. Full REST API
Portefeuille principalMain portfolio
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/portfolio | Retourne toutes les positions | Returns all positions |
POST | /api/portfolio | Ajoute une position | Adds a position |
PUT | /api/portfolio/<isin> | Met à jour une position | Updates a position |
DELETE | /api/portfolio/<isin> | Supprime une position | Deletes a position |
POST | /api/portfolio/bulk | Importe plusieurs positions (CSV ou JSON) | Imports multiple positions (CSV or JSON) |
GET | /api/portfolio/export | Exporte en CSV | Exports to CSV |
Cotations & analyseQuotes & analysis
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/quotes?tickers=A,B | Cotations temps réel Yahoo Finance | Real-time Yahoo Finance quotes |
GET | /api/performance?period=1y | Données de performance historique | Historical performance data |
GET | /api/contribution | Contribution de chaque position au P&L | Each position's P&L contribution |
GET | /api/var?simulations=100000 | VaR + CVaR Monte Carlo | Monte Carlo VaR + CVaR |
POST | /api/bhb | Attribution BHB (Brinson-Hood-Beebower) | BHB attribution (Brinson-Hood-Beebower) |
GET | /api/whatif | Simulation What If | What If simulation |
GET | /api/benchmark?period=1y | Comparaison benchmarks | Benchmark comparison |
ESG
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/esg?isin=FR… | Score ESG pour un ISIN | ESG score for an ISIN |
GET | /api/esg/portfolio | Scores ESG de tout le portefeuille | ESG scores for the whole portfolio |
DCF
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/dcf/simple?ticker=AAPL | DCF simplifié — données Yahoo Finance uniquement | Simple DCF — Yahoo Finance data only |
GET | /api/dcf/complete?ticker=AAPL | DCF complet avec projections FCF sauvegardées | Full DCF with saved FCF projections |
GET | /api/dcf/params?ticker=AAPL | Charge les paramètres DCF sauvegardés | Loads saved DCF parameters |
POST | /api/dcf/params | Sauvegarde les paramètres DCF | Saves DCF parameters |
GET | /api/dcf/portfolio?portfolio_id=… | Scores DCF pour toutes les positions d'un portefeuille | DCF scores for all positions in a portfolio |
portfolio_id est optionnel pour /api/dcf/portfolio : si absent, utilise le portefeuille principal.portfolio_id parameter is optional for /api/dcf/portfolio: if absent, uses the main portfolio.ArbitrageArbitrage
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/arbitrage/models | Liste des 7 modèles d'arbitrage | List of 7 arbitrage models |
GET | /api/arbitrage/simulate?portfolio_id=…&model=momentum&target_portfolio_id=… | Lance la simulation d'arbitrage | Runs arbitrage simulation |
GET | /api/arb-portfolios | Liste des portefeuilles secondaires | List of secondary portfolios |
POST | /api/arb-portfolios | Crée un portefeuille secondaire | Creates a secondary portfolio |
PUT | /api/arb-portfolios/<id> | Met à jour un portefeuille secondaire | Updates a secondary portfolio |
DELETE | /api/arb-portfolios/<id> | Supprime un portefeuille secondaire | Deletes a secondary portfolio |
Paramètres DCF additionnels pour model=dcf :
Additional DCF parameters for model=dcf:
| ParamètreParameter | DéfautDefault | DescriptionDescription | |
|---|---|---|---|
dcf_mrp | 5.5 | Prime de risque marché (%) | Market risk premium (%) |
dcf_terminal_g | 2.5 | Taux de croissance terminal (%) | Terminal growth rate (%) |
dcf_rf_eur | 3.5 | Taux sans risque EUR (%) | Risk-free rate EUR (%) |
dcf_rf_usd | 4.3 | Taux sans risque USD (%) | Risk-free rate USD (%) |
dcf_sell_thresh | -5.0 | Seuil vente : upside < X% → vendre | Sell threshold: upside < X% → sell |
dcf_buy_thresh | 5.0 | Seuil achat : upside > X% → acheter | Buy threshold: upside > X% → buy |
ClientsClients
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/clients | Liste de tous les clients avec détails portefeuilles | List all clients with portfolio details |
POST | /api/clients | Crée un nouveau client | Creates a new client |
PUT | /api/clients/<id> | Met à jour un client | Updates a client |
DELETE | /api/clients/<id> | Supprime un client | Deletes a client |
GET | /api/clients/<id>/report | Rapport client : valeur totale en EUR, positions par portefeuille | Client report: total EUR value, positions per portfolio |
UtilitairesUtilities
| Method | Path | DescriptionDescription | |
|---|---|---|---|
GET | /api/search?q=apple | Recherche ticker Yahoo Finance | Yahoo Finance ticker search |
GET | /api/isin-lookup?ticker=AAPL | Résolution ISIN via OpenFIGI | ISIN resolution via OpenFIGI |
GET | /api/cache/clear | Vide le cache en mémoire | Clears the in-memory cache |
6. Modules fonctionnels6. Functional modules
6.1 Onglet Portfolio principal6.1 Main Portfolio tab
L'onglet principal affiche une table de toutes les positions du portefeuille, enrichie en temps réel par des cotations Yahoo Finance. Chaque ligne montre :
The main tab displays a table of all portfolio positions, enriched in real-time by Yahoo Finance quotes. Each row shows:
- Cotation actuelle, variation jour, valeur totale de la ligne, P&L (montant + %)
- Current price, daily change, total line value, P&L (amount + %)
- Score IA composite (0–100) calculé côté client
- Composite AI score (0–100) calculated client-side
- Score ESG (si disponible dans le fichier Excel)
- ESG score (if available in the Excel file)
- Actions : édition, suppression, lien Yahoo Finance
- Actions: edit, delete, Yahoo Finance link
KPIs agrégés (en haut) : valeur totale du portefeuille, P&L global, meilleure/pire position.
Aggregated KPIs (top): total portfolio value, overall P&L, best/worst position.
Graphique d'allocation : camembert Chart.js par secteur ou par pays.
Allocation chart: Chart.js pie chart by sector or country.
6.2 Import CSV6.2 CSV import
Deux méthodes d'import en masse :
Two bulk import methods:
- Upload CSV : fichier avec entêtes
isin,name,ticker,quantity,pru,currency,category,secteur,pays - CSV upload: file with headers
isin,name,ticker,quantity,pru,currency,category,secteur,pays - Bulk paste : copier-coller d'un tableau de données (séparateurs TAB ou virgule)
- Bulk paste: copy-paste from a data table (TAB or comma separators)
6.3 Cotations temps réel6.3 Real-time quotes
Les cotations sont récupérées via l'API non-officielle Yahoo Finance. Le serveur maintient un cache en mémoire (_yf_cache) avec une durée de vie de 5 minutes. Le crumb et les cookies de session sont gérés automatiquement.
Quotes are fetched via the unofficial Yahoo Finance API. The server maintains an in-memory cache (_yf_cache) with a 5-minute TTL. The crumb and session cookies are managed automatically.
6.4 Onglet Performances6.4 Performance tab
Graphique de performance normalisée (base 100) comparant le portefeuille à ses benchmarks sur la période sélectionnée (1j, 1s, 1m, 3m, 6m, 1an, 3ans). Inclut la contribution par position et les métriques de risque (VaR, CVaR) via simulation Monte Carlo.
Normalized performance chart (base 100) comparing the portfolio to its benchmarks over the selected period (1d, 1w, 1m, 3m, 6m, 1y, 3y). Includes contribution per position and risk metrics (VaR, CVaR) via Monte Carlo simulation.
6.5 Scores ESGESG Scores
Le fichier Excel .xlsx est parsé au démarrage sans dépendance externe : le fichier est ouvert comme un ZIP, les feuilles XML extraites et parsées avec ElementTree. Les scores E, S, G et global sont affichés dans la table principale et dans l'onglet Modèle.
The .xlsx Excel file is parsed at startup without external dependencies: the file is opened as a ZIP, XML sheets extracted and parsed with ElementTree. E, S, G and global scores are displayed in the main table and the Model tab.
6.6 Valorisation DCFDCF Valuation
Deux modes de calcul :
Two calculation modes:
- DCF simplifié : utilise exclusivement les données disponibles sur Yahoo Finance (FCF TTM, beta, dettes, trésorerie, taux d'imposition). Calcul WACC automatique.
- Simple DCF: uses only Yahoo Finance data (TTM FCF, beta, debt, cash, tax rate). Automatic WACC calculation.
- DCF complet : l'utilisateur saisit des projections FCF annuelles, WACC personnalisé, taux de croissance terminal. Les paramètres sont sauvegardés dans
dcf_params.json. - Complete DCF: user enters annual FCF projections, custom WACC, terminal growth rate. Parameters are saved in
dcf_params.json.
Le résultat clé est l'upside_pct : (valeur_intrinsèque / cours_actuel - 1) × 100. Positif = sous-évalué, négatif = sur-évalué.
The key result is upside_pct: (intrinsic_value / current_price - 1) × 100. Positive = undervalued, negative = overvalued.
6.7 Onglet ArbitrageArbitrage tab
Simule un rééquilibrage de portefeuille selon 7 modèles prédéfinis :
Simulates a portfolio rebalancing according to 7 predefined models:
| # | ModèleModel | Logique de venteSell logic | Logique d'achatBuy logic | ||
|---|---|---|---|---|---|
| 1 | Momentum | Performance 6m < 0 | Meilleure perf. sectorielle 6m | Sell: 6m perf < 0 | Best sector 6m perf |
| 2 | Mean Reversion | RSI > 70 (surachat) | RSI < 30 (survente) | Sell: RSI > 70 (overbought) | Buy: RSI < 30 (oversold) |
| 3 | Sector Rotation | Secteurs sous-performants vs indice | Secteurs surperformants | Sell: underperforming sectors vs index | Buy: outperforming sectors |
| 4 | Quality Growth | Faible score IA (<40) ou fort P/E | Score IA élevé + croissance CA | Sell: low AI score (<40) or high P/E | Buy: high AI score + revenue growth |
| 5 | Risk Parity | Positions sur-pondérées vs risque | Positions sous-pondérées | Sell: over-weighted vs risk | Buy: under-weighted |
| 6 | ESG Tilt | Mauvais score ESG (<40) | Meilleur score ESG du portefeuille cible | Sell: poor ESG score (<40) | Buy: best ESG score in target |
| 7 | DCF Valuation | upside DCF < seuil (défaut -5%) | upside DCF > seuil (défaut +5%) | Sell: DCF upside < threshold (default -5%) | Buy: DCF upside > threshold (default +5%) |
Pour le modèle DCF (n°7), des paramètres additionnels sont exposés dans l'interface : MRP, taux terminal, Rf EUR, Rf USD, seuil vente, seuil achat. Ces paramètres écrasent temporairement les valeurs globales via un mécanisme try/finally.
For the DCF model (#7), additional parameters are exposed in the UI: MRP, terminal rate, Rf EUR, Rf USD, sell threshold, buy threshold. These parameters temporarily override the global values via a try/finally mechanism.
6.8 Onglet Scores DCFDCF Scores tab
Cet onglet calcule et affiche les scores DCF (upside %) pour toutes les positions d'un portefeuille sélectionné. Pour chaque ticker :
This tab calculates and displays DCF scores (upside %) for all positions of a selected portfolio. For each ticker:
- Si des paramètres FCF complets sont sauvegardés → utilise
dcf_complete - If complete FCF parameters are saved → uses
dcf_complete - Sinon → utilise
dcf_simple(données Yahoo Finance) - Otherwise → uses
dcf_simple(Yahoo Finance data)
L'onglet affiche des KPI (moyenne upside, nb sous-évalués/sur-évalués), un tableau trié par upside, et un graphique à barres de distribution.
The tab shows KPIs (average upside, nb undervalued/overvalued), a table sorted by upside, and a bar distribution chart.
6.9 Onglet ClientsClients tab
Gestion complète des clients :
Full client management:
- CRUD : créer, modifier, supprimer des fiches clients
- CRUD: create, edit, delete client records
- Association portefeuilles : un client peut être associé à un ou plusieurs portefeuilles arbitrage
- Portfolio association: a client can be linked to one or more arbitrage portfolios
- Profil de risque : Conservative / Moderate / Aggressive
- Risk profile: Conservative / Moderate / Aggressive
- Rapport client : valorisation totale en EUR (avec conversion FX en temps réel), liste des positions par portefeuille
- Client report: total EUR valuation (with real-time FX conversion), position list per portfolio
La conversion FX utilise les taux EURUSD, EURGBP, EURCHF récupérés en temps réel sur Yahoo Finance au moment de la génération du rapport.
FX conversion uses EURUSD, EURGBP, EURCHF rates fetched in real-time from Yahoo Finance at report generation time.
6.10 Onglet AnalyseAnalysis tab
Fournit l'attribution de performance BHB (Brinson-Hood-Beebower) : décomposition de l'alpha en effets allocation, sélection et interaction, par secteur et par pays.
Provides BHB (Brinson-Hood-Beebower) performance attribution: decomposition of alpha into allocation, selection and interaction effects, by sector and country.
6.11 What If
Simule l'impact sur le portefeuille de scénarios hypothétiques : changement de prix d'un actif, ajout/suppression de position, variation de taux de change. Recalcule les KPIs en temps réel sans modifier le portefeuille réel.
Simulates the portfolio impact of hypothetical scenarios: asset price change, position add/remove, FX rate variation. Recalculates KPIs in real-time without modifying the real portfolio.
6.12 Benchmark
Compare la performance du portefeuille à des indices de référence (CAC 40, S&P 500, MSCI World, etc.) sur 5 périodes prédéfinies. Les benchmarks sont construits de façon composite, pondérés par l'allocation géographique et sectorielle du portefeuille.
Compares portfolio performance against reference indices (CAC 40, S&P 500, MSCI World, etc.) over 5 predefined periods. Benchmarks are built compositionally, weighted by the portfolio's geographic and sector allocation.
7. Calculs quantitatifs7. Quantitative calculations
7.1 VaR Monte Carlo
La VaR (Value at Risk) est calculée par simulation Monte Carlo sur 100 000 scénarios :
VaR (Value at Risk) is calculated by Monte Carlo simulation with 100,000 scenarios:
- Récupération des rendements journaliers historiques sur 1 an pour chaque position (endpoint
/api/performance) - Fetch daily historical returns over 1 year for each position (endpoint
/api/performance) - Calcul de la matrice de covariance des rendements
- Calculate the return covariance matrix
- Génération de 100 000 scénarios par décomposition de Cholesky
- Generate 100,000 scenarios via Cholesky decomposition
- Calcul du P&L simulé pour chaque scénario
- Calculate simulated P&L for each scenario
- VaR 95% = 5e percentile de la distribution des P&L simulés
- VaR 95% = 5th percentile of the simulated P&L distribution
7.2 CVaR (Expected Shortfall)
La CVaR est la moyenne des pertes au-delà de la VaR :
CVaR is the average of losses beyond VaR:
CVaR_95% = E[P&L | P&L < VaR_95%]
= moyenne des scénarios sous le 5e percentile
7.3 Attribution BHBBHB Attribution
La méthode Brinson-Hood-Beebower décompose l'alpha en trois effets :
The Brinson-Hood-Beebower method decomposes alpha into three effects:
Effet allocation = (wp - wb) × rb Effet sélection = wb × (rp - rb) Effet interaction = (wp - wb) × (rp - rb) où : wp = poids portefeuille, wb = poids benchmark, rp = rendement portefeuille, rb = rendement benchmarkwhere: wp = portfolio weight, wb = benchmark weight, rp = portfolio return, rb = benchmark return
7.4 DCF — FormulesFormulas
DCF simplifié (données Yahoo Finance) :
Simple DCF (Yahoo Finance data):
FCF_0 = Free Cash Flow TTM (Yahoo Finance) FCF_t = FCF_0 × (1 + g_court_terme)^t [t = 1..5] VT = FCF_5 × (1 + g_terminal) / (WACC - g_terminal) Valeur = Σ(FCF_t / (1+WACC)^t) + VT / (1+WACC)^5 Intrinsic = (Valeur + Cash - Dette) / Actions upside_pct = (Intrinsic / Prix_actuel - 1) × 100
DCF complet (projections manuelles) :
Complete DCF (manual projections):
FCF_t = projection_t [saisie par l'utilisateur / entered by user] VT = FCF_last × (1 + g_terminal) / (WACC - g_terminal) Reste identique au mode simplifiéRest identical to simple mode
7.5 WACC
Le WACC est calculé automatiquement par le serveur :
WACC is calculated automatically by the server:
Ke = Rf + β × MRP # coût des fonds propres# cost of equity Kd = Kd_brut × (1 - taux_imposition) # coût de la dette après impôt# after-tax cost of debt E/V = Equity / (Equity + Debt) D/V = Debt / (Equity + Debt) WACC = (E/V) × Ke + (D/V) × Kd # borné [4%, 25%]# clamped [4%, 25%] Valeurs par défaut (modifiables via paramètres DCF) :Default values (overridable via DCF parameters): MRP = 5.5% g_terminal = 2.5% Rf par devise / by currency: EUR → 3.5% USD → 4.3% GBP → 4.2% CHF → 1.0% JPY → 0.5% HKD → 3.5%
7.6 Benchmark compositeComposite benchmark
Le benchmark est construit dynamiquement en fonction du portefeuille :
The benchmark is built dynamically based on the portfolio:
- Pour chaque pays représenté dans le portefeuille, récupère l'indice de référence (
PAYS_TO_BENCH) - For each country in the portfolio, fetch the reference index (
PAYS_TO_BENCH) - Pondère chaque indice par le poids du pays dans le portefeuille
- Weight each index by the country's weight in the portfolio
- Calcule la performance composite journalière
- Calculate daily composite performance
8. Référentiels de données8. Data references
Secteurs canoniquesCanonical sectors
Le serveur normalise les noms de secteurs via un dictionnaire SECTOR_CANONICAL qui mappe les variantes Yahoo Finance vers 12 secteurs normalisés :
The server normalizes sector names via a SECTOR_CANONICAL dictionary that maps Yahoo Finance variants to 12 normalized sectors:
| Secteur normaliséNormalized sector | Exemples de variantesExample variants |
|---|---|
| Technology | Information Technology, Tech, Technologie |
| Finance | Financial Services, Financials, Banks |
| Healthcare | Health Care, Pharma, Biotech |
| Industrials | Industriels, Industrial, Capital Goods |
| Consumer | Consumer Discretionary, Consumer Staples, Retail |
| Energy | Energie, Oil & Gas, Utilities |
| Materials | Matériaux, Basic Materials, Mining |
| Real Estate | Immobilier, REIT |
| Communication | Telecom, Media, Communication Services |
| Other | Tout ce qui ne correspond pasAnything not matching |
Indices par paysIndices by country
Le dictionnaire PAYS_TO_BENCH associe un code ISO 2 lettres à un ticker Yahoo Finance :
The PAYS_TO_BENCH dictionary maps a 2-letter ISO code to a Yahoo Finance ticker:
| ISO | PaysCountry | Ticker |
|---|---|---|
| FR | France | ^FCHI (CAC 40) |
| US | USA | ^GSPC (S&P 500) |
| DE | Germany / Deutschland | ^GDAXI (DAX) |
| GB | UK | ^FTSE (FTSE 100) |
| JP | Japan | ^N225 (Nikkei) |
| CH | Switzerland | ^SSMI (SMI) |
| — | Monde / GlobalWorld / Global | URTH (iShares MSCI World) |
9. Gestion des erreurs et cache9. Error handling and cache
Cache mémoireIn-memory cache
Le serveur utilise un dictionnaire _cache protégé par un threading.Lock. Les entrées sont stockées avec un timestamp et expirées automatiquement :
The server uses a _cache dictionary protected by a threading.Lock. Entries are stored with a timestamp and automatically expired:
| Type de donnéesData type | TTL | |
|---|---|---|
| Cotations Yahoo Finance | Yahoo Finance quotes | 5 min |
| Données historiques | Historical data | 15 min |
| Simulation arbitrage | Arbitrage simulation | 10 min |
| Calculs VaR | VaR calculations | 30 min |
Gestion des erreurs HTTPHTTP error handling
| Code | CauseCause | |
|---|---|---|
| 400 | Corps JSON invalide ou paramètre manquant | Invalid JSON body or missing parameter |
| 404 | Ressource introuvable (ISIN, client ID, etc.) | Resource not found (ISIN, client ID, etc.) |
| 500 | Erreur interne (exception Python non gérée) | Internal error (unhandled Python exception) |
{"error": "message"}. Le frontend affiche un toast d'alerte rouge pour les erreurs 4xx/5xx.{"error": "message"}. The frontend displays a red alert toast for 4xx/5xx errors.