Application web de stock screener oriente strategies d'investissement.
"Choisis une strategie d'investissement, on te montre les actions qui y correspondent le mieux."
npm install
npm run dev # http://localhost:3000
npm test # 112 testsPour activer les donnees Yahoo Finance (gratuites, temps reel) :
cp .env.example .env
# Editer .env β YAHOO_ENABLED=true
npm run dev| Strategie | Philosophie | Metriques cles |
|---|---|---|
| Buffett | Qualite & valeur | ROE, marge, FCF, dette, PER |
| Peter Lynch | Croissance a prix raisonnable | PEG, EPS growth, CA growth |
| Growth | Croissance agressive | CA growth, EPS growth, marges, potentiel |
| Dividende | Rendement & stabilite | Yield, payout ratio, FCF coverage, dette |
Flow: Pays β Indice β Strategie β Classement
| Pays | Indices | Tickers |
|---|---|---|
| USA | S&P 500, NASDAQ 100, Dow Jones 30 | ~200 / ~85 / 30 |
| France | CAC 40 | 30 |
| Allemagne | DAX 40 | 20 |
| Royaume-Uni | FTSE 100 | 30 |
| Suisse | SMI | 6 |
| Europe | STOXX Europe 50 | 28 |
L'indice scope le fetch Yahoo aux seuls tickers de l'indice (pas de fetch inutile). Couverture partielle affichee clairement : "30 / 40 couverts (couverture partielle)".
Lien direct : /scanner?country=fr&index=cac40&strategy=buffett
Requete utilisateur
β
βΌ
βββββββββββββββ
β Cache β ββ hit (fresh) βββ reponse instantanee
β (SWR TTL) β ββ hit (stale) βββ reponse + revalidation async
ββββββββ¬βββββββ ββ miss βββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββ
β CompositeProvider β
β βββββββββββ ββββββββββββββββ β
β β Yahoo β βββΊ β Mock (local) β β
β β Finance β β 25 actions β β
β βββββββββββ ββββββββββββββββ β
β ~340 tickers fallback auto β
βββββββββββββββββββββββββββββββββββββββ
| Etat | Condition | Comportement |
|---|---|---|
| Fresh | age < TTL (1h stocks, 15min detail) | Reponse instantanee |
| Stale | TTL < age < 4h | Reponse instantanee + revalidation en arriere-plan |
| Expire | age > 4h | Nouveau fetch bloquant |
- Yahoo Finance est le provider principal (gratuit, sans cle API)
- Si Yahoo echoue (rate limit, timeout, API change), le composite bascule automatiquement sur le dataset local
- Le fallback est transparent pour l'utilisateur β un badge ambre indique "Source de secours"
- Chaque fallback est logge (structured JSON) pour observabilite
Chaque reponse API inclut un objet meta :
{
"source": "cache:composite:[yahoo>mock]",
"fetchedAt": 1712234567890,
"isFallback": false,
"isCached": true,
"cacheAgeMs": 342000,
"isStale": false
}Affiche dans l'UI : source, fraicheur, indicateur stale/fallback.
| Region | Indices couverts | Tickers |
|---|---|---|
| US | S&P 500 top, NASDAQ 100 | ~243 |
| Europe | CAC 40, DAX 40, FTSE 100, Nordic, Swiss | ~94 |
| Total | ~340 |
L'univers est centralise dans src/lib/tickers/ :
us.tsβ tickers US (suffixe implicite)europe.tsβ tickers europeens avec suffixes Yahoo (.PA, .DE, .L, .SW, .ST)index.tsβ merge deduplique + stats
Recherche libre : l'utilisateur peut aussi saisir n'importe quel ticker manuellement via la barre de recherche. Le ticker est score a la volee via Yahoo, meme s'il n'est pas dans l'univers.
Premier chargement (~340 tickers) : ~15-20 secondes (3 batches de 20 en parallele). Ensuite : instantane grace au cache SWR (1h fresh, 4h stale tolerance).
src/
βββ app/
β βββ api/stocks/ # API avec meta + universe stats
β βββ api/stocks/search/ # Recherche libre par ticker
β βββ scanner/page.tsx # Scanner + recherche + badges
β βββ stocks/[ticker]/page.tsx # Detail via DataProvider
β
βββ lib/
β βββ tickers/ # Univers d'actions centralise
β β βββ us.ts # S&P 500 + NASDAQ 100 (~243)
β β βββ europe.ts # CAC/DAX/FTSE/Nordic/Swiss (~94)
β β βββ index.ts # Merge deduplique (337)
β β
β βββ data/ # Data Provider Pattern
β β βββ provider.ts # Interface DataProvider
β β βββ yahoo-provider.ts # Yahoo Finance (~340 tickers)
β β βββ mock-provider.ts # Dataset local (25 actions)
β β βββ composite-provider.ts # Fallback chain + logging
β β βββ cache.ts # SWR cache + stats
β β βββ metadata.ts # Source/freshness tracking
β β βββ index.ts # Factory singleton
β β
β βββ scoring/ # Moteur de scoring
β β βββ engine.ts # Registry + confidence
β β βββ normalize.ts # Normalisation lineaire
β β βββ sector-benchmarks.ts # 12 secteurs
β β βββ completeness.ts # Data completeness
β β βββ explain.ts # Explications + resume
β β βββ strategies/ # 4 strategies auto-enregistrees
β β
β βββ logger.ts # Structured JSON logger
β βββ types.ts # Stock, Score, DataMeta...
β βββ format.ts # Formatage partage
β
βββ components/
β βββ ticker-search.tsx # Recherche libre par ticker
β βββ ui/
β βββ confidence-badge.tsx # Confiance high/medium/low
β βββ data-source-badge.tsx # Source + fraicheur + warnings
β βββ ...
β
βββ hooks/
β βββ use-watchlist.ts # Watchlist localStorage
β βββ use-score-history.ts # Score snapshots + deltas
β βββ use-alerts.ts # Regles d'alertes + evaluation
β βββ use-theme.ts # Dark mode
β βββ use-stocks.ts # Fetch + error handling
β
βββ components/
βββ ticker-search.tsx # Recherche libre
βββ top-opportunities.tsx # Top 5 par strategie (home)
βββ daily-digest.tsx # Alertes du jour (home)
βββ score-movers.tsx # Mouvements notables
βββ ui/
βββ score-delta.tsx # Badge +N / -N
βββ confidence-badge.tsx
βββ data-source-badge.tsx
βββ ...
npm test # 112 tests
npm run test:watch # watch mode| Suite | Tests | Couvre |
|---|---|---|
| normalize | 12 | Normalisation lineaire, inverse, range |
| utils | 8 | Weighted average, redistribution |
| completeness | 7 | Completeness, confiance |
| strategies | 20 | Registry, output shape, donnees partielles |
| coherence | 11 | Panel de reference, coherence metier |
| alerts | 14 | Evaluation, seuils, dedup, watchlist filter, modes |
| indices | 17 | Registry, lookups, couverture, dedup tickers |
| change-explanation | 10 | SubScore diffs, explication, pipeline, edge cases |
| compare | 13 | Winner, ties, N/A handling, confidence, partial warnings |
- Yahoo Finance peut etre instable (rate limit, schema changes). Le fallback local mitigue ce risque.
- ~340 tickers predetermines : l'univers est large mais pas dynamique. Ajouter des tickers = editer
tickers/us.tsoutickers/europe.ts. La recherche libre permet d'analyser n'importe quel ticker hors univers. - Pas d'historique EPS depuis Yahoo (
quoteSummaryne le fournit pas simplement). L'historique n'est disponible que pour les donnees mockees. - Cache en memoire : perdu au redemarrage du serveur. Suffisant pour un usage mono-instance.
- Pas d'authentification : pas de watchlist persistante cross-device.
- Confiance et completude affichees par action (Elevee/Moyenne/Faible + %)
- Gestion N/A : cellules grises "N/A", pas de highlight best/worst sur donnees manquantes
- Quasi-egalites : seuil 3 pts, "Match serre" + "Ex aequo" au lieu de "domine"
- Resume nuance : mentionne confiance basse, donnees partielles
- Warnings explicites : "Comparaison partielle" quand >= 3 metriques manquent
- Responsive : scroll horizontal sur les tableaux, bouton "Retirer" par carte
- 112 tests (6 nouveaux : ties, N/A, confidence, partial warnings)
- Page /compare : comparaison de 2 a 4 actions cote a cote
- URL-driven : /compare?tickers=MSFT,AAPL,NVDA&strategy=buffett
- "Qui gagne?" : resume intelligent identifiant winner, forces, faiblesses
- Tableau sous-scores : highlights vert (meilleur) / rouge (moins bon)
- Tableau metriques cles : 8 metriques avec gestion inverse (PER, D/E)
- CompareBar : barre flottante pour selection multi-ticker dans le scanner
- Checkboxes dans table et cards du scanner
- Bouton "Comparer avec..." sur page detail
- Lien "Comparer" dans le header
- 106 tests (7 nouveaux pour le moteur de comparaison)
- Historique des scores enrichi: sous-scores stockes avec chaque snapshot, retention 30 jours, purge automatique
- Sparkline SVG (0 dependance): graphique d'evolution 7j/30j sur page detail
- Generateur d'explication: compare sous-scores prev/current, identifie top 1-2 contributeurs, genere 1 phrase ("Amelioration : qualite en hausse (+8 pts) et valorisation en baisse.")
- Alertes enrichies: changeExplanation basee sur les sous-scores ("MSFT +6 β qualite en hausse")
- Daily digest: priorite changeExplanation sur explication generique
- 99 tests (10 nouveaux pour change-explanation)
- Module indices/ avec 8 indices (S&P 500, NASDAQ 100, Dow 30, CAC 40, DAX 40, FTSE 100, SMI, STOXX 50) et 6 pays
- API: GET /api/countries, GET /api/indices, ?index= sur /api/stocks
- Scanner: flow Pays β Indice β Strategie avec IndexSelector
- Titre dynamique "Top Buffett β CAC 40"
- Transparence couverture: "30 / 40 couverts (couverture partielle)"
- Index-scoped fetch: ne charge que les tickers de l'indice selectionne
- 89 tests (17 nouveaux pour les indices)
- Preferences utilisateur (localStorage): strategie favorite, mode alerte, seuils
- 3 modes d'alerte: strict (score>85/delta>8), normal (80/5), sensitive (70/3)
- Page /settings: mode selector, toggles on/off par regle, seuils editables, switch watchlist-only, bouton reset
- Alertes enrichies avec explanation (1 phrase contextuelle par alerte)
- Daily digest ameliore: filtres (toutes/watchlist/hausse/baisse), tri (importance/variation/strategie), badge strategie, explications
- 72 tests (14 nouveaux pour le moteur d'alertes)
- Systeme d'alertes: 4 types de regles (score_above/below, delta_above/below), evaluation automatique, persistence localStorage, deduplication par jour
- Page /watchlist dediee: scores live, deltas, tri par score/variation/nom, bordures colorees pour gainers/losers, bouton retrait
- Daily digest sur la home: alertes declenchees aujourd'hui, icones colorees, liens vers detail, bouton effacer
- Header enrichi: compteur watchlist, cloche d'alertes avec badge ambre
- 4 regles par defaut actives sans configuration
- Progressive loading: mock instantane (phase 1) + Yahoo en arriere-plan (phase 2)
- Cold load percu: ~0ms au lieu de 15-20s (donnees indicatives puis live)
- Score history: snapshots localStorage, deltas entre visites (+3, -2)
- Top opportunites: section home page avec top 5 par strategie
- Score movers: detection automatique des mouvements significatifs (>=3 pts)
- Banniere "Actualisation en cours..." pendant le chargement live
- Univers elargi a ~340 actions (S&P 500, NASDAQ 100, CAC 40, DAX 40, FTSE 100)
- Module tickers/ centralise par region (us.ts, europe.ts)
- Parallel batching (3x20) pour cold load en ~15-20s
- Recherche libre : scorer n'importe quel ticker hors univers
- Transparence : "Base sur un univers de X actions" dans le scanner
- Fix: page detail utilise maintenant le DataProvider (plus le mock direct)
- Metadata de transparence: source, fraicheur, fallback, staleness
- Logger structure JSON pour observabilite
- Cache SWR: stale-while-revalidate, reponse instantanee meme cache expire
- 58 tests dont 11 tests de coherence metier (panel de reference)
- Badges source/fraicheur dans le scanner et le detail
- Yahoo Finance provider, composite fallback, data completeness, sector benchmarks, 47 tests
- Data provider pattern, scoring engine, normalisation, explications, watchlist, dark mode
- Scoring simple, donnees mockees, 3 pages
| Priorite | Idee | Complexite |
|---|---|---|
| P1 | Assistant IA contextuel (chat sur les actions) | Elevee |
| P1 | Portefeuille virtuel (simulation) | Moyenne |
| P2 | Screener dynamique (recherche par criteres, pas par liste) | Moyenne |
| P2 | Authentification + watchlist persistante | Moyenne |
| P2 | Backtesting de strategies | Elevee |
| P3 | Strategies custom (poids configurables) | Moyenne |
| P3 | API publique | Faible |
Donnees a titre educatif. Ne constitue pas un conseil en investissement.