Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

Quand l’équipondération bat l’optimisation

L’équipondération bat le dimensionnement optimisé si l’échantillon est court. Une simulation Python avec graine montre le croisement, puis sa disparition avec plus de données.

La pondération équipondérée est plus performante qu’un dimensionnement optimisé des positions lorsque l’échantillon est trop court pour estimer précisément les rendements attendus. Or, les échantillons courts sont la norme, et non l’exception.

Un optimiseur applique une arithmétique rigoureuse à une donnée que personne ne mesure correctement. Le portefeuille 1/N, à pondération égale, n’estime absolument rien. C’est pourquoi il reste robuste lorsque les estimations sont mauvaises.

L’équipondération surperforme-t-elle réellement l’optimisation ?

Sous une condition précise, oui. Examinons les termes un par un. L’équipondération, notée 1/N, répartit le capital à parts égales entre N positions et ne nécessite aucune prévision. L’optimisation moyenne-variance détermine les pondérations offrant le meilleur rendement attendu par unité de variance estimée. Le critère de Kelly détermine les pondérations qui maximisent la croissance composée à long terme ; pour des actifs non corrélés, il revient à attribuer à chaque actif une pondération proportionnelle à son rendement excédentaire attendu, divisé par sa variance. Notre guide dimensionnement des positions avec le critère de Kelly présente cette formule en détail.

Les deux méthodes d’optimisation utilisent la même donnée d’entrée : un rendement attendu par actif. C’est cette donnée qu’un échantillon estime le moins bien. La volatilité peut être estimée avec une précision exploitable sur une fenêtre courte. Ce n’est pas le cas de la moyenne, et l’écart entre les deux est suffisamment important pour être visible dans n’importe quel historique de cours. Le graphique ci-dessous porte sur six valeurs largement détenues. Il mesure séparément chaque année civile de 2015 à 2024 et indique l’écart entre l’estimation annuelle la plus élevée et la plus basse. Le calcul est effectué deux fois par valeur : une fois pour le rendement quotidien moyen annualisé, et une fois pour la volatilité annualisée.

RequêteDix ans d’estimations annuelles : la moyenne évolue bien plus que la volatilité
Le SQL exact derrière chaque chiffre
WITH prices AS
(
    SELECT
        ticker,
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO', 'JNJ')
      AND date >= '2015-01-01'
      AND date <  '2025-01-01'
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
yearly AS
(
    SELECT
        ticker,
        toYear(date)                     AS yr,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM rets
    WHERE isFinite(ret)
    GROUP BY ticker, yr
    HAVING count() >= 200
)
SELECT
    ticker,
    round(max(mean_pct) - min(mean_pct), 1) AS mean_estimate_range_pct,
    round(max(vol_pct) - min(vol_pct), 1)   AS vol_estimate_range_pct
FROM yearly
GROUP BY ticker
ORDER BY mean_estimate_range_pct DESC
Run this yourself

Pour NVDA, l’estimation annuelle de la moyenne couvre une amplitude de 184.7 points de pourcentage sur ces dix années, contre 28.6 points pour l’amplitude de l’estimation de la volatilité de cette même valeur sur les mêmes années. La valeur la plus stable du panel, KO, a tout de même vu son estimation annuelle de la moyenne varier de 23.9 points. Toute méthode qui fournit à un optimiseur la moyenne du rendement de l’an dernier comme rendement attendu pour l’année en cours lui transmet donc une donnée susceptible de varier dans de telles proportions.

De quelle longueur d’échantillon avez-vous besoin pour estimer un rendement attendu ?

L’erreur standard d’un rendement moyen estimé correspond à la volatilité de l’actif divisée par la racine carrée de la longueur de l’échantillon en années. En années, et non en nombre d’observations : échantillonner les mêmes douze mois toutes les heures au lieu d’une fois par jour n’apporte rien. En appliquant cette formule à un actif dont la volatilité est de 20 %, une année d’historique donne une erreur standard de 20 points de pourcentage par an. Quatre ans la ramènent à 10. Pour l’abaisser à un point, précision souhaitable avant de classer deux actifs dont les moyennes réelles diffèrent de deux points, il faut quatre siècles de données.

La volatilité constitue un cas différent. Sa précision s’améliore avec le nombre d’observations, plutôt qu’avec la durée calendaire. Quelques mois de données quotidiennes suffisent donc déjà à l’estimer à quelques points près. Le graphique ci-dessous découpe vingt ans de rendements quotidiens d’un fonds indiciel en blocs non chevauchants de longueur fixe. Il calcule les deux estimations dans chaque bloc et indique dans quelle mesure elles varient d’un bloc à l’autre.

RequêteDispersion des estimations de moyenne et de volatilité selon la longueur de l’échantillon
Le SQL exact derrière chaque chiffre
WITH prices AS
(
    SELECT
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2005-01-01'
      AND date <  '2025-01-01'
    GROUP BY date
),
rets AS
(
    SELECT
        date,
        c / lagInFrame(c, 1) OVER (ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
numbered AS
(
    SELECT
        ret,
        row_number() OVER (ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
),
sweep AS
(
    SELECT
        arrayJoin([21, 63, 126, 252, 504]) AS n,
        i,
        ret
    FROM numbered
),
blocks AS
(
    SELECT
        n,
        intDiv(i - 1, n)                 AS blk,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM sweep
    GROUP BY n, blk
    HAVING count() = n
)
SELECT
    concat(toString(n), ' sessions') AS sample_length,
    round(stddevPop(mean_pct), 1)    AS mean_estimate_spread_pct,
    round(stddevPop(vol_pct), 1)     AS vol_estimate_spread_pct,
    count()                          AS window_count
FROM blocks
GROUP BY n
ORDER BY n ASC
Run this yourself

Pour des blocs de 21 sessions, l’estimation de la moyenne varie sur 53.7 points de pourcentage, contre 10.9 points pour l’estimation de la volatilité calculée sur les mêmes blocs. En allongeant le bloc à 504 sessions, la dispersion de la moyenne se réduit à 10.6 points. Elle diminue selon une racine carrée : chaque division par deux de l’erreur exige quatre fois plus de données.

Une simulation avec seed que vous pouvez exécuter vous-même

Rien de tout cela ne prouve que l’erreur d’estimation est suffisamment importante pour donner l’avantage à 1/N. Cette simulation le démontre. Elle nécessite uniquement une installation Python : aucun fichier de données, aucun téléchargement et aucun package tiers. Elle génère elle-même les rendements à partir des paramètres que vous choisissez. La véritable réponse est donc connue, et les deux allocations peuvent être évaluées par rapport à celle-ci.

  1. Importez deux modules, import random et import statistics, ainsi que from math import log. Définissez la seed à la ligne suivante avec random.seed(20260816).
  2. Définissez cinq actifs dont les rendements annuels attendus vrais sont de 5, 6, 7, 8 et 9 %, chacun avec une volatilité annuelle vraie de 20 %, sans corrélation entre eux. Convertissez ces paramètres en fréquence quotidienne avec mu_d = mu_a / 252 et sd_d = sd_a / (252 ** 0.5).
  3. Choisissez une longueur d’échantillon T dans la grille [60, 125, 250, 500, 1000, 2500, 5000].
  4. Générez T rendements quotidiens pour chaque actif avec random.gauss(mu_d, sd_d). Cette série constitue l’intégralité de l’historique auquel le gérant a accès.
  5. Estimez la moyenne de chaque actif avec statistics.mean et sa volatilité avec statistics.stdev. Ce sont les seules estimations connues de l’optimiseur.
  6. Construisez le portefeuille équipondéré en attribuant une pondération de 0,2 à chacun des cinq actifs. Il n’utilise aucune des estimations.
  7. Construisez le portefeuille optimisé en fixant chaque pondération brute à mu_hat / (sd_hat ** 2), puis en divisant chaque pondération par la somme des valeurs absolues des pondérations brutes. Les deux portefeuilles ont ainsi la même exposition brute.
  8. Générez un nouvel échantillon hors échantillon de 2520 rendements quotidiens par actif à partir des vrais paramètres. Aucune des deux allocations n’a été exposée à cet échantillon.
  9. Évaluez les deux portefeuilles sur cet échantillon à l’aide de la moyenne de log(1 + r), où r représente la somme pondérée des rendements des cinq actifs sur la journée.
  10. Répétez les étapes 4 à 9 pour 2000 essais indépendants à chaque valeur de T, puis enregistrez la proportion d’essais où le portefeuille équipondéré surperforme le portefeuille optimisé.

Lisez la grille de la valeur de T la plus courte à la plus longue. Pour les échantillons courts, le portefeuille équipondéré gagne dans une nette majorité des essais. Cette proportion diminue régulièrement à mesure que T augmente. Pour les échantillons longs, le portefeuille optimisé gagne dans la plupart des essais. Les deux approches se croisent quelque part entre les deux. Le point de croisement varie selon la seed et selon l’écart entre les moyennes vraies. La direction du résultat ne change pas : davantage de données favorisent l’optimiseur, tandis que moins de données favorisent 1/N. Pour reproduire la simulation, modifiez l’entier situé à l’intérieur de random.seed(20260816), puis relancez la grille.

Pourquoi l’optimiseur amplifie une mauvaise estimation de la moyenne

Examinez comment les estimations interviennent dans le poids. La moyenne estimée figure au numérateur et la variance estimée au dénominateur. Si vous doublez l’estimation de la moyenne, le poids double. Si vous réduisez d’un quart l’estimation de la variance, le poids augmente d’un tiers. Dans un échantillon favorable, les deux erreurs vont dans le même sens : une série de tirages positifs fait progresser la moyenne mesurée et réduit souvent la variance mesurée sur la même période. L’optimiseur considère alors ce titre comme le meilleur du groupe et lui attribue un poids en conséquence. Hors échantillon, il redevient un titre ordinaire du groupe. L’équipondération n’a jamais tenu compte de cet échantillon favorable.

La simulation présente la version la plus modérée du problème. Cinq actifs non corrélés produisent une matrice de covariance diagonale, qui ne nécessite aucune inversion complexe. Les portefeuilles réels sont corrélés, et une matrice de covariance calculée sur à peine plus d’observations que d’actifs est proche d’être singulière. Son inversion transforme de petites erreurs de saisie en poids très élevés. C’est ainsi qu’un optimiseur peut aboutir à une position représentant plusieurs fois le capital sur un titre, compensée par une position short sur son substitut le plus proche. Notre note sur le risque de concentration dans un portefeuille décrit l’effet d’un tel poids sur un drawdown.

Les données d’entrée ne restent pas stables non plus. Le graphique ci-dessous suit la moyenne mobile sur un an des rendements journaliers, annualisée et calculée chaque mois, pour un fonds indiciel large et une grande valeur du secteur des biens de consommation de base.

RequêteRendement moyen glissant sur un an, la donnée fournie à un optimiseur
Le SQL exact derrière chaque chiffre
WITH prices AS
(
    SELECT
        ticker,
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('SPY', 'KO')
      AND date >= '2015-10-01'
      AND date <  '2025-01-01'
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
trailing AS
(
    SELECT
        ticker,
        date,
        avg(ret) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) * 252 * 100 AS trailing_mean_pct,
        row_number() OVER (PARTITION BY ticker ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
)
SELECT
    toString(toStartOfMonth(date))                     AS month,
    round(avgIf(trailing_mean_pct, ticker = 'SPY'), 1) AS spy_trailing_mean_pct,
    round(avgIf(trailing_mean_pct, ticker = 'KO'), 1)  AS ko_trailing_mean_pct
FROM trailing
WHERE i >= 252
  AND date >= '2017-01-01'
GROUP BY month
ORDER BY month ASC
Run this yourself

Chaque point de ces deux courbes correspond à un chiffre qu’un optimiseur aurait pu retenir comme rendement attendu à cette date. La première mesure mensuelle de SPY est de 17.7% et la dernière de 25.8%, avec 96 mesures intermédiaires. KO ouvre la même période à -0.4%. Une méthode de pondération qui intègre cette série mois après mois hérite de chacune de ses fluctuations.

Le demi-Kelly et le shrinkage corrigent-ils le problème ?

Ils l’atténuent. En pratique, quatre correctifs sont utilisés. Chacun renonce à une partie de l’optimum théorique pour réduire la sensibilité aux estimations.

  • Le demi-Kelly divise chaque poids par deux. La courbe de croissance de Kelly est plate près de son sommet et devient fortement descendante en dessous. Une mise réduite de moitié abandonne donc une faible part du taux de croissance théorique, tout en diminuant beaucoup plus fortement les pertes liées à un avantage surestimé. Le ciblage de la volatilité applique la même logique au dénominateur : le dimensionnement repose sur la seule donnée qu’un échantillon court peut fournir.
  • Le shrinkage rapproche chaque moyenne estimée de la moyenne transversale des estimations. L’ampleur du rapprochement augmente lorsque l’échantillon se réduit. Poussé à l’extrême, il attribue à chaque actif le même rendement attendu. Avec des volatilités identiques, l’optimiseur produit alors de lui-même des poids égaux. Un portefeuille équipondéré est le portefeuille entièrement soumis au shrinkage.
  • Les contraintes, c’est-à-dire l’interdiction des positions short et un plafond par position, limitent l’influence qu’une estimation favorable isolée peut exercer sur un poids. Elles servent à limiter les dommages, et non à améliorer l’estimation.
  • Supprimer entièrement les rendements attendus laisse la variance minimale et la parité de risque, qui n’utilisent que la covariance. C’est la donnée que l’échantillon peut réellement fournir.

Aucun de ces quatre correctifs ne crée une information absente de l’échantillon. Ils modifient seulement la part du portefeuille qui dépend d’informations dont vous ne disposez peut-être pas.

Quand l’optimisation devient rentable

Le croisement se produit dans les deux sens. Lorsque T devient grand par rapport à l’écart entre les moyennes réelles, l’allocation optimisée prend l’avantage et le conserve. Plus cet écart est important, plus ce moment survient tôt. L’optimisation est également l’outil adapté lorsque la donnée d’entrée est fournie par les données elles-mêmes : la covariance et les hedge ratios sont estimés avec bien plus de précision que les rendements attendus.

L’équipondération a aussi un coût. Elle ignore des informations dont vous disposez réellement et, dans un univers réduit, elle se concentre autant qu’un optimiseur pourrait le faire. Considérez-la comme le point de référence que toute pondération candidate doit dépasser sur des données que les pondérations n’ont jamais vues. Ajuster les pondérations et les évaluer sur le même échantillon relève du biais de regard vers l’avenir dans le backtesting sous une autre forme, et cela favorise systématiquement l’optimiseur. Pour obtenir un intervalle crédible autour d’un avantage mesuré plutôt qu’une estimation ponctuelle, les intervalles de confiance bootstrap constituent l’outil de référence.

FAQ

L’égal-pondération surpasse-t-elle vraiment l’optimisation moyenne-variance ?

Sur les échantillons courts, c’est souvent le cas. Un optimiseur a besoin d’une estimation du rendement attendu de chaque actif. Cette estimation présente une erreur standard d’environ la volatilité de l’actif divisée par la racine carrée de la longueur de l’échantillon en années. Tant que cette erreur reste supérieure aux véritables écarts entre les actifs, l’optimiseur trie du bruit. L’égal-pondération ne repose sur aucune estimation susceptible d’être erronée.

Combien d’observations faut-il pour estimer un rendement attendu ?

Davantage que presque tout le monde n’en dispose. Pour un actif affichant une volatilité de 20 %, une année de données quotidiennes laisse une erreur standard proche de 20 points de pourcentage par an. Pour réduire cette erreur de moitié, il faut multiplier par quatre la période couverte. Ajouter des observations intraday au cours de la même année n’aide pas. En revanche, la volatilité peut être estimée de manière exploitable avec quelques mois de données.

Le demi-Kelly est-il simplement une mise plus faible ?

C’est une mise plus faible, avec un profil de risque plus favorable. La courbe de croissance de Kelly est plate près de son point culminant. Réduire la mise de moitié ne coûte donc qu’une faible part du taux de croissance théorique, tout en réduisant approximativement de moitié la volatilité de la trajectoire et le coût d’un avantage surestimé.

Qu’est-ce que le portefeuille 1/N ?

C’est un portefeuille qui investit une fraction égale du capital dans chacune des N positions et se rééquilibre selon un calendrier défini. Il ne nécessite ni prévision de rendement ni estimation de covariance. C’est ce qui en fait le benchmark standard de toutes les méthodes de pondération qui en ont besoin.

Construction des panneaux

Les trois panneaux utilisent les cours de clôture quotidiens et calculent les rendements simples de clôture à clôture. Les lignes en double sont regroupées pour ne conserver qu’un cours par ticker et par date. Les moyennes sont annualisées en multipliant le rendement quotidien moyen par 252 séances. Les volatilités sont annualisées en multipliant l’écart-type quotidien par la racine carrée de 252. Le panneau annuel ne conserve une année civile que lorsqu’elle compte au moins 200 séances. Le panneau par blocs utilise des blocs non chevauchants et écarte le dernier bloc partiel pour chaque longueur. Sa colonne indiquant le nombre de fenêtres montre combien de blocs ont été produits pour chaque longueur. Aucun dividende n’est inclus. Il s’agit donc de rendements de cours, et le niveau de toute moyenne est sous-estimé pour les actions versant des dividendes. L’objectif des panneaux est de montrer la dispersion des estimations, et non leur niveau.


Chaque panneau présente ici la requête SQL exacte sous le graphique, et la simulation indique sa seed. Pour exécuter le même test de stabilité des estimations sur votre propre liste de valeurs, demandez-le en langage courant sur le terminal Strasmore.

#quant#position sizing#portfolio construction#estimation error#kelly