# Méthodologie : régression pénalisée des révisions de CA

## Objectif

Estimer, à partir des ventilations REVERE et des révisions du consensus de chiffre
d'affaires des entreprises sélectionnées, un tableau :

| Secteur TRBC2 | Révision implicite et IC à 90 % | Contribution à la révision de l'univers |
|---|---|---|
| Technology Equipment | Beta estimé et intervalle bootstrap | Points de pourcentage |

Le but principal est d'identifier une composante commune par secteur et de
décomposer la révision agrégée de l'échantillon. Ce n'est pas de prédire avec
précision la révision d'une entreprise extérieure à l'échantillon.

Une erreur individuelle importante n'invalide donc pas automatiquement le tableau.
En revanche, des betas qui changent fortement lorsqu'on retire quelques sociétés
ou qu'on modifie les pénalités sont fragiles.

## 1. Données et population

### Choix du niveau sectoriel

Le volet permet de choisir le niveau de l'étude. TRBC2 reste la valeur par défaut.
Les équations et exemples détaillés ci-dessous illustrent ce cas ; la même méthode
s'applique aux autres niveaux avec les poids et le parent correspondants :

| Niveau étudié | Poids Solr | Rapprochement pénalisé vers |
|---|---|---|
| TRBC1 | `consolidation_json.level1` | Moyenne globale |
| TRBC2 | `consolidation_json.level2` | Parent TRBC1 |
| TRBC3 | `consolidation_json.level3` | Parent TRBC2 |
| Segments REVERE, niveau 4 interne | `consolidation_json.segment` | Parent TRBC3 |

Au niveau 1, il n'existe pas de parent sectoriel supérieur : le modèle écrit
\(\beta_s=\mu+\delta_s\) et choisit une seule pénalité sur les \(\delta_s\).
Aux niveaux 2, 3 et 4, les deux pénalités portent sur le parent et sur l'écart
propre au secteur étudié. Le niveau 4 est la bibliothèque interne REVERE, pas
un niveau TRBC officiel.

Les parents des segments internes sont lus dans `segment_to_trbc.csv`.
Les libellés du tableau, les exclusions et l'export CSV indiquent le niveau retenu.
Les anciens calculs sans paramètre de niveau restent des études TRBC2.

Plus le niveau est fin, plus le nombre de secteurs augmente, avec moins de pure
players par secteur et davantage de risques de non-identification. La pénalisation
stabilise le calcul, mais ne crée pas l'information absente. Le dashboard signale
notamment une matrice de rang incomplet ou un faible nombre d'entreprises par rapport
au nombre de secteurs. L'échantillon retenu peut varier avec le niveau si certaines
ventilations sont incomplètes.

Le volet **Régression**, situé après **Portefeuille** dans le screener de production,
utilise exclusivement les titres sélectionnés dans le screener au moment du
lancement. Les filtres seuls ne suffisent pas : il faut sélectionner les résultats.
Le calcul ne force pas le pays du siège à US ; appliquer ce filtre dans le screener
pour retrouver l'univers américain.

Pour chaque société :

- les poids TRBC2 proviennent de `consolidation_json.level2` dans Solr ;
- les secteurs ne différant que par la casse sont regroupés ;
- leur parent TRBC1 provient de `trbc_level_3_to_level_1_mapping.csv` ;
- le consensus provient de
  `GET /internal/instrument/{codezb}/consensus/revision?fiscalYearBefore=0&fiscalYearAfter=1&from=YYYY-MM-DD&to=YYYY-MM-DD&fields=revenue`.

La révision sur la période est :

$$
r_i = \frac{CA^{consensus}_{i,\mathrm{fin}}}
           {CA^{consensus}_{i,\mathrm{début}}} - 1.
$$

Il s'agit d'une **révision des estimations pour un même exercice**, pas du taux de
croissance du CA de cet exercice par rapport au précédent.

### Exercice cible

Le choix FY1 utilise le premier exercice de l'horizon renvoyé par Zonebourse
(`horizon.from`). FY2 utilise cet exercice + 1.

| Horizon renvoyé par l'API | FY1 | FY2 |
|---|---|---|
| 2026–2027 | 2026 | 2027 |
| 2027–2028 | 2027 | 2028 |

Ce n'est pas une année civile commune, ni une garantie que les entreprises ont le
même nombre de mois prospectifs. Le résultat affiche le nombre de sociétés par
exercice cible. Le décalage des calendriers n'est pas corrigé.

### Règles d'exclusion en production

- Consensus absent, bornes de période absentes ou moins de deux points.
- CA non positif, invalide, ou devise/unité incohérente dans la série.
- Nombre d'analystes absent/invalide, ou **moyenne inférieure à 5** sur les points
  journaliers disponibles de la période. Les zéros ne sont pas ignorés.
- CA non exprimé en **millions**, devise sans paire USD configurée, ou cours
  historique de conversion absent/invalide. Les montants initiaux sont convertis
  en millions USD au taux figé décrit ci-dessous.
- Ventilation TRBC2 incomplète (somme hors de 99,5–100,5 %) ou parent inconnu.
  Les petits écarts d'arrondi acceptés sont rebasés à 100 %.
- Par défaut, révision supérieure à ±25 % en valeur absolue. Ce seuil est visible
  et modifiable ; laisser le champ vide désactive cette exclusion.

La liste des exclusions avec les raisons est affichée et exportée. Une révision
extrême n'est pas une preuve de changement de périmètre : le seuil est une
précaution exploratoire, pas une détection des acquisitions/cessions.

Au moins cinq sociétés exploitables sont nécessaires. Ce minimum ne garantit pas
la qualité statistique : un petit échantillon peut être insuffisant pour identifier
les secteurs présents.

### Conversion USD au taux de début figé

Pour intégrer les sociétés dont le consensus est exprimé dans une autre devise,
le serveur appelle `POST /internal/instrument/quotes` avec les instruments FX
nécessaires, `interval=3600` et `dividend_adjustment=false`.

| Paire (USD pour une unité de devise) | CodeZB |
|---|---:|
| EUR/USD | 4591 |
| GBP/USD | 89717 |
| CHF/USD | 2389514 |
| SEK/USD | 45567137 |
| NOK/USD | 2373617 |
| DKK/USD | 2373603 |
| TWD/USD | 2373648 |
| JPY/USD | 46178029 |
| SGD/USD | 2373636 |
| KRW/USD | 2373579 |
| AUD/USD | 2373531 |

La conversion utilise le champ `close` à la date de début de l'étude. Si aucun
cours positif et fini n'est disponible ce jour-là, on retient le dernier cours
valide antérieur, au maximum sept jours avant la date de début. Aucun cours d'une
date ultérieure n'est utilisé. La devise de cotation du fournisseur doit être USD.
Pour les montants déjà en USD, le multiplicateur vaut 1.

$$
CA^{USD}_{i,0}=CA^{natif}_{i,0}\times FX_{c_i/USD}(t_0).
$$

Ce taux reste **constant sur toute la période**. La révision individuelle et sa
courbe continuent d'être calculées dans la devise native :

$$
r_i(t)=\frac{CA^{natif}_i(t)}{CA^{natif}_i(t_0)}-1.
$$

Ainsi, une hausse de l'euro après le début de l'étude n'ajoute pas artificiellement
une révision au consensus. Les taux servent à rendre comparables les montants de
pondération, les parts de CA sectoriel et les contributions agrégées.
Les effets de change déjà intégrés par les analystes dans leurs prévisions ne sont
pas isolés pour autant.

Les taux, dates effectivement utilisées, codes FX et nombres d'entreprises sont
affichés dans les résultats, exportés en CSV et sauvegardés avec les séries.
Une paire non configurée (par exemple CNY/USD) ou un cours manquant entraîne une
exclusion motivée ; il n'y a pas de substitution silencieuse par un taux de 1.
Une indisponibilité de l'API de change fait échouer le calcul explicitement.

Les anciens résultats calculés uniquement sur des consensus USD restent inchangés.
Relancer l'étude applique la conversion aux nouvelles données retenues.

## 2. Modèle transversal

$$
r_i = \sum_s w_{is}\beta_s + \varepsilon_i.
$$

- \(r_i\) : révision observée de la société \(i\).
- \(w_{is}\) : part de son CA attribuée au secteur TRBC2 \(s\), entre 0 et 1.
- \(\beta_s\) : révision implicite commune au secteur.
- \(\varepsilon_i\) : résidu individuel non expliqué.

L'hypothèse centrale est qu'un secteur possède une composante de révision commune
aux différentes entreprises. Le modèle ne suppose pas que leurs révisions
totales sont identiques : leurs poids et leurs résidus peuvent différer.

Les poids sont ceux de REVERE et restent fixes pendant le calcul. Ils ne sont pas
nécessairement les vrais poids de CA prospectifs de l'exercice du consensus.

## 3. Sans pénalité : le meilleur compromis entre les équations

Exemple fictif, avec deux secteurs :

| Société | Equipment | Software | Révision observée |
|---|---:|---:|---:|
| A | 100 % | 0 % | +6 % |
| B | 0 % | 100 % | +2 % |
| C | 50 % | 50 % | +5 % |

A et B suggèrent +6 % et +2 %. Ces valeurs prédiraient +4 % pour C, et non
+5 %. Les équations ne sont donc pas parfaitement compatibles.

La régression classique minimise la somme des erreurs au carré :

$$
\min_\beta \sum_i \left(r_i-\sum_s w_{is}\beta_s\right)^2.
$$

Elle donne ici environ +6,33 % pour Equipment et +2,33 % pour Software,
soit +4,33 % pour C. Elle répartit le désaccord au lieu de satisfaire
exactement deux entreprises et de reporter toute l'erreur sur la troisième.

## 4. Pourquoi pénaliser ?

Si toutes les entreprises sont exposées à 50 % Equipment et 50 % Software, on peut
identifier la moyenne des deux betas, mais pas leurs valeurs séparées.

| Beta Equipment | Beta Software | Prédiction pour une société 50/50 |
|---:|---:|---:|
| +4 % | +4 % | +4 % |
| +8 % | 0 % | +4 % |
| +20 % | −12 % | +4 % |

Une régression non pénalisée peut alors devenir instable : quelques différences de
poids ou observations atypiques suffisent à produire des valeurs extrêmes.

La pénalité préfère des ajustements moins extrêmes, sauf si les données justifient
les écarts. Elle introduit donc un **biais de rapprochement** en échange d'une
réduction de la variance. Ce n'est ni un filtre qui supprime les entreprises, ni
une preuve que les secteurs ont réellement la même révision.

Les pure players sont utiles : ils permettent de distinguer les secteurs sans
dépendre uniquement des entreprises diversifiées. Un pure player REVERE désigne
ici une entreprise dont au moins 80 % du CA est attribué à un même TRBC2.

## 5. Décomposition hiérarchique des betas

Le modèle utilisé écrit :

$$
\beta_s = \mu + a_{\mathrm{parent}(s)} + \delta_s.
$$

- \(\mu\) : révision moyenne globale, calculée sur l'échantillon.
- \(a_g\) : ajustement commun au parent TRBC1 \(g\).
- \(\delta_s\) : ajustement propre au TRBC2 \(s\).

Exemple fictif :

$$
\beta_{\mathrm{Equipment}} = 1\% + 2\% + 2\% = 5\%.
$$

$$
\beta_{\mathrm{Software}} = 1\% + 2\% - 1\% = 2\%.
$$

Equipment et Software partagent ici l'ajustement du parent Technology, mais
conservent leurs différences propres. Le parent est estimé conjointement ; ce
n'est pas une révision officielle obtenue séparément.

### Fonction minimisée

$$
\min_{a,\delta}
\sum_i q_i
\left[r_i-\sum_s w_{is}
(\mu+a_{\mathrm{parent}(s)}+\delta_s)\right]^2
+\lambda_1\sum_g a_g^2
+\lambda_2\sum_s\delta_s^2.
$$

Dans le dashboard, \(q_i=1\) : **les entreprises sont équipondérées lors de
l'estimation**. Les poids personnalisés ou par capitalisation du volet Exposition
ne sont pas utilisés par la régression.

- \(\lambda_1\) freine les écarts TRBC1 à la moyenne globale.
- \(\lambda_2\) freine les écarts TRBC2 à leur parent.
- Une forte pénalité TRBC2 rapproche les secteurs d'un même parent.
- Une faible pénalité laisse davantage les observations déterminer leurs écarts.

La moyenne \(\mu\) est calculée avant l'estimation des ajustements, et recalculée
pour les sous-échantillons de validation et de bootstrap.

## 6. Exemple chiffré du rapprochement

Supposons, pour simplifier, un niveau du parent fixé à +3 %, et des pure players
dont la révision moyenne est +7 %.

Avec une pénalité \(\lambda=5\), on minimise :

$$
n(\beta-7\%)^2+5(\beta-3\%)^2.
$$

La solution est :

$$
\beta=\frac{n\times7\%+5\times3\%}{n+5}.
$$

| Nombre de pure players | Beta sans pénalité | Beta pénalisé |
|---:|---:|---:|
| 2 | +7 % | +4,14 % |
| 20 | +7 % | +6,20 % |
| 100 | +7 % | +6,81 % |

Un secteur peu documenté reste proche du parent. Un secteur bien documenté peut
s'en éloigner. Dans le vrai calcul, les entreprises sont souvent diversifiées et
les parents sont eux-mêmes estimés : la formule est plus complexe.

## 7. Choix des pénalités : ce n'est pas le choix d'epsilon

Le calcul essaie 12 valeurs logarithmiquement espacées de \(10^{-4}\) à
\(10^{1,5}\) pour chacune des deux pénalités, soit 144 couples.

Pour chaque couple, une validation croisée leave-one-out (LOO) estime l'erreur
obtenue lorsqu'une société est retirée de l'estimation et prédite par les autres.
Le couple qui minimise l'erreur quadratique moyenne est retenu.

Les résidus LOO sont calculés par une formule algébrique, incluant le recalcul de
la moyenne globale de l'échantillon privé du titre.

Ce critère sert à limiter le surajustement des betas, même si la prédiction
individuelle n'est pas l'objectif principal.

Le R² LOO compare cette erreur à celle d'une simple moyenne estimée sans la société
retirée :

$$
R^2_{\mathrm{LOO}}=1-\frac{MSE_{\mathrm{modèle}}}{MSE_{\mathrm{moyenne}}}.
$$

Un R² positif indique un gain par rapport à cette référence. Il ne garantit ni une
bonne précision individuelle ni une attribution correcte. Comme la même validation
sert à sélectionner les pénalités, ce score reste exploratoire ; une validation
indépendante demanderait une procédure imbriquée ou un échantillon séparé.

## 8. Résidus, epsilon et révisions extrêmes

Le résidu est la différence entre la révision réelle et modélisée. Les erreurs
s'expriment en **points de pourcentage** :

> Révision réelle +5 %, prédiction +2,5 % : erreur +2,5 points, et non 2,5 % de +5 %.

Un 80e percentile de 2,54 points signifie que 80 % des erreurs absolues sont
inférieures ou égales à 2,54 points. C'est important si la révision médiane est
proche de +0,6 %.

Le prototype de recherche contient aussi un diagnostic minimax :

$$
\min_{\beta,\epsilon}\epsilon
\quad\text{sous}\quad
|r_i-\sum_s w_{is}\beta_s|\leq\epsilon.
$$

Dans ce prototype, les betas du programme linéaire sont bornés à ±50 %. L'epsilon
minimal est donc conditionnel à ces bornes.

Le calcul qui retire les 10 % de plus grands résidus LOO sert uniquement à mesurer
la sensibilité de ce diagnostic minimax. **Ces 10 % ne sont pas retirés pour estimer
les betas du tableau.** Le volet de production n'effectue pas cette suppression
et ne calcule pas le minimax ; il affiche les résidus et leur 80e percentile LOO.

## 9. Intervalle bootstrap à 90 %

Le dashboard effectue 500 rééchantillonnages des entreprises avec remise.
Pour chacun, il recalcule la moyenne et les betas, à pénalités sélectionnées fixes.
Les percentiles 5 et 95 donnent l'intervalle affiché.

Cet intervalle représente la sensibilité à la composition de l'échantillon,
conditionnellement aux choix du modèle.

Il ne couvre pas complètement :

- l'incertitude sur les poids REVERE ;
- le choix et le réglage du modèle ;
- les différences de calendriers, périmètres ou devises ;
- la dépendance des erreurs entre sociétés ;
- le biais introduit par la pénalisation.

Un intervalle étroit ne prouve donc pas une attribution causale. Lorsque le secteur
est mal représenté, le rapprochement vers le parent peut donner une fausse
impression de précision.

## 10. Calcul des contributions

Les contributions utilisent une pondération différente de l'estimation : le CA
consensus de début de période des entreprises retenues, **converti en USD au taux
de début figé**. Dans les formules suivantes, \(CA_{i,0}\) désigne ce montant USD.

$$
W_s=\frac{\sum_i CA_{i,0}w_{is}}{\sum_i CA_{i,0}},
\qquad C_s=W_s\beta_s.
$$

Si Equipment représente 5,3 % du CA et son beta vaut +5,13 % :

$$
C_{\mathrm{Equipment}}=0,053\times0,0513
\simeq0,00272=+0,272\text{ point}.
$$

La révision implicite mesure l'intensité sectorielle. La contribution dépend aussi
de la taille du secteur dans **l'échantillon retenu**, pas dans le marché entier.

L'identité comptable est :

$$
R_{\mathrm{univers}}
=\sum_s C_s+
\frac{\sum_i CA_{i,0}\varepsilon_i}{\sum_i CA_{i,0}}.
$$

Un grand résidu agrégé indique qu'une part importante de la révision pondérée de
l'univers n'est pas attribuée aux facteurs sectoriels par ce modèle.

## 11. Exemple historique après le filtre de cinq analystes

Première estimation exploratoire, fenêtre 06/07/2026–06/10/2026, FY1,
356 sociétés américaines retenues :

| Secteur TRBC2 | Beta et IC bootstrap à 90 % | Contribution |
|---|---:|---:|
| Technology Equipment | +5,13 % [3,60 ; 7,09] | +0,27 pt |
| Energy – Fossil Fuels | +2,76 % [1,05 ; 4,49] | +0,27 pt |
| Transportation | +3,96 % [2,18 ; 5,81] | +0,14 pt |
| Banking & Investment Services | +1,43 % [0,43 ; 2,39] | +0,10 pt |
| Retailers | +1,09 % [0,49 ; 1,70] | +0,09 pt |
| Software & IT Services | +1,38 % [0,68 ; 2,15] | +0,07 pt |

La révision agrégée était +1,70 %, contre +1,34 point de contributions de tous les
secteurs et +0,36 point de résidu. Ces valeurs documentent le premier prototype ;
elles ne sont pas des constantes et peuvent changer avec les données et la
sélection. La version de production applique notamment des exclusions plus
explicites et corrige le recalcul de la moyenne dans la validation LOO.

## 12. Utilisation et limites opérationnelles

1. Filtrer les sociétés dans le screener et sélectionner les titres souhaités.
2. Ouvrir Régression, choisir le niveau sectoriel, les dates, FY1/FY2 et le seuil éventuel des extrêmes.
3. Lancer le calcul ; suivre la progression et consulter les exclusions.
4. Lire les betas, les IC et les contributions, puis exporter le CSV.

### Détail d'un secteur et courbes de révision

Cliquer sur le nom d'un secteur ouvre une fenêtre avec deux graphiques :
l'agrégat observé des entreprises exposées et les courbes de CA total des principales
entreprises. Les dix premières entreprises sont classées par
\(CA^{USD}_{i,0}\times w_{is}\), le CA consensus initial exposé au secteur converti
au taux de début figé. Les cinq
premières courbes sont affichées par défaut ; les cases à cocher permettent de
choisir jusqu'à cinq entreprises parmi les dix.

Chaque courbe est une révision cumulée depuis la date de début :

$$
r_i(t)=CA_i^{consensus}(t)/CA_i^{consensus}(t_0)-1.
$$

La courbe agrégée utilise **toutes** les entreprises retenues ayant une exposition
strictement positive au secteur, avec des poids initiaux fixes en USD et des
révisions individuelles en devise native :

$$
\widetilde r_s(t)=
\frac{\sum_i CA_{i,0}w_{is}r_i(t)}
     {\sum_i CA_{i,0}w_{is}}.
$$

Le tableau indique l'exposition de chaque société au secteur, sa part du CA exposé,
sa révision de CA total et sa contribution en points à ce proxy observé.
Les parts ne sont pas rebasées sur les dix premières entreprises.

**Ce proxy n'est ni le beta de régression ni une série de révisions directement
observées du CA du segment.** Il utilise le consensus de CA total de chaque
entreprise et peut donc refléter d'autres activités, en particulier chez les groupes
diversifiés. Les deux valeurs sont présentées séparément.

Les graphiques utilisent l'intersection des dates disponibles pour toutes les
entreprises exposées ; aucun point manquant n'est remplacé par zéro ou par un
report de la valeur précédente. Le survol du graphique donne les valeurs à la date
la plus proche. Les exercices fiscaux cibles sont indiqués par entreprise.

Les poids, séries et montants initiaux sont sauvegardés avec les nouveaux calculs
dans `data/regression/inputs`. Ouvrir un secteur ne refait pas d'appel à Zonebourse
et ne relit pas les poids actuels de Solr : les données restent celles de l'étude.
Pour les anciens calculs sans cette sauvegarde, un message demande de relancer
l'étude plutôt que d'inventer un historique.

Un seul calcul tourne à la fois sur le serveur ; les autres lancements sont refusés
explicitement. Les révisions API sont mises en cache une heure, sauf actualisation
forcée. Les résultats et paramètres sont conservés dans `data/regression` sur le
serveur et le navigateur mémorise l'identifiant de son dernier calcul. Un calcul
interrompu par un redémarrage est signalé comme tel et doit être relancé.

Le calcul utilise Solr en lecture seule. Il ne lance pas le pipeline REVERE et
n'effectue aucun appel LLM. Il nécessite le tunnel Solr opérationnel et les
identifiants Zonebourse déjà utilisés par le volet Portefeuille.

**Interprétation finale :** le tableau constitue une décomposition statistique de
la révision agrégée sous les hypothèses du modèle. Sa robustesse doit être étudiée
par secteur, notamment face à la sélection des entreprises, aux pénalités, aux
exercices cibles et aux changements de périmètre. Ce n'est pas une preuve causale
de la contribution économique réelle de chaque secteur.
