Skip to content

fhermet/stockscanner

Repository files navigation

StockScanner

Application web de stock screener oriente strategies d'investissement.

"Choisis une strategie d'investissement, on te montre les actions qui y correspondent le mieux."

Quick start

npm install
npm run dev          # http://localhost:3000
npm test             # 112 tests

Pour activer les donnees Yahoo Finance (gratuites, temps reel) :

cp .env.example .env
# Editer .env β†’ YAHOO_ENABLED=true
npm run dev

Strategies

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

Navigation par indice

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

Architecture data

  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   β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Politique de cache (stale-while-revalidate)

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

Politique de fallback

  1. Yahoo Finance est le provider principal (gratuit, sans cle API)
  2. Si Yahoo echoue (rate limit, timeout, API change), le composite bascule automatiquement sur le dataset local
  3. Le fallback est transparent pour l'utilisateur β€” un badge ambre indique "Source de secours"
  4. Chaque fallback est logge (structured JSON) pour observabilite

Metadata de transparence

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.

Univers d'actions

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.

Performance

Premier chargement (~340 tickers) : ~15-20 secondes (3 batches de 20 en parallele). Ensuite : instantane grace au cache SWR (1h fresh, 4h stale tolerance).

Architecture projet

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
        └── ...

Tests

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

Limites connues

  • 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.ts ou tickers/europe.ts. La recherche libre permet d'analyser n'importe quel ticker hors univers.
  • Pas d'historique EPS depuis Yahoo (quoteSummary ne 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.

Historique des versions

V2.9.1 (actuelle) β€” Polish comparateur

  • 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)

V2.9 β€” Comparateur d'actions

  • 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)

V2.8 β€” Historique et explications des variations

  • 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)

V2.7 β€” Navigation par indices

  • 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)

V2.6 β€” Personnalisation et alertes intelligentes

  • 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)

V2.5 β€” Engagement et retour quotidien

  • 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

V2.4 β€” Performance percue et engagement

  • 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

V2.3 β€” Couverture et recherche

  • 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

V2.2 β€” Production readiness

  • 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

V2.1 β€” Solidification

  • Yahoo Finance provider, composite fallback, data completeness, sector benchmarks, 47 tests

V2.0 β€” Architecture

  • Data provider pattern, scoring engine, normalisation, explications, watchlist, dark mode

V1.0 β€” MVP

  • Scoring simple, donnees mockees, 3 pages

V3 β€” Prochaines etapes

Priorite Idee Complexite
P1 Assistant IA contextuel (chat sur les actions) Elevee
P1 Portefeuille virtuel (simulation) Moyenne
P1 Insights automatiques (deltas de scores) Fait en V2.4
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.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages