Notes sur la construction de systèmes qui marchent et d'autres choses... peut-être ?

M'apprendre le quant tout seul

· 7 min

J'avais sauvegardé un thread sur X il y a un moment. Une de ces roadmaps d'auto-formation en quant qui passent tous les quelques mois : voilà les maths dont tu as vraiment besoin, dans l'ordre, sans raccourcis. J'en avais peut-être mis cinq en favoris au fil des années, et lu aucune correctement. Celle-là, je l'ai copiée dans un repo, réorganisée en dossiers, et j'ai commencé à vraiment la faire.

Donc ce n'est pas mon programme. Je tiens à être clair là-dessus dès le départ, parce qu'il existe une version de ce billet où je fais semblant d'avoir conçu un parcours en cinq niveaux qui va des probabilités au calcul stochastique et où tu es censé être impressionné. Ce n'est pas le cas. Quelqu'un sur X a tracé le chemin, je l'ai adapté, et j'en suis à quelques semaines. Ce qui suit, c'est l'impression que ça donne quand tu es tout en bas de l'échelle.

La forme est simple. Cinq niveaux, et l'idée c'est que tu ne peux en sauter aucun :

  1. Probabilités. Raisonnement conditionnel, Bayes, espérance, variance.
  2. Statistiques. Tests d'hypothèses, p-values, le piège des comparaisons multiples.
  3. Algèbre linéaire. Matrices de covariance, décomposition en valeurs propres, PCA, Markowitz.
  4. Calcul différentiel et optimisation. Descente de gradient, optimisation convexe.
  5. Calcul stochastique. Mouvement brownien, Ito, Black-Scholes.

J'en suis au niveau deux. Je n'ai pas touché au quatre ni au cinq, à part lire la table des matières et avoir un léger haut-le-cœur. Si tu es venu apprendre le calcul stochastique avec quelqu'un qui le maîtrise, mauvais billet.

Le premier niveau était plus accueillant que prévu. Les probabilités, c'est le seul morceau du truc auquel j'avais déjà été vraiment exposé, donc l'essentiel était de la répétition. Probabilité conditionnelle, P(A | B), le truc où une action monte 60 % des jours mais 75 % des jours à fort volume, et où le 75 % est le chiffre intéressant parce qu'il est conditionné par quelque chose que tu peux observer. Bayes comme outil de mise à jour des croyances plutôt que comme formule à mémoriser. L'espérance comme ta conviction, la variance comme ton risque, et le point discret en dessous des deux : un pari qui gagne un dollar 51 % du temps et un pari qui gagne cent dollars 51 % du temps ont le même avantage mais des probabilités complètement différentes de te ruiner avant que l'avantage ne se manifeste. Je savais tout ça, vaguement. Écrire les simulations a rendu ça moins vague.

Puis le niveau deux m'a mis un coup.

Le chapitre s'ouvre sur une phrase dont je n'arrive pas à me débarrasser. La plupart de ce qui ressemble à un avantage n'est en fait que du bruit. Et la façon dont il le démontre est tellement simple et tellement dévastatrice que je veux la détailler, parce qu'elle a changé ma façon de lire tous les résultats de backtest que j'ai pu croiser sur internet.

Voici le principe. Tu construis une stratégie de trading. Tu la backtestes. Elle rapporte 15 % par an. Bien, non ? Tu as trouvé quelque chose. La vraie question, c'est : est-ce qu'une stratégie sans aucun avantage réel aurait pu produire un résultat aussi bon par chance ? C'est un test d'hypothèse. Hypothèse nulle : la stratégie n'a pas de rendement espéré. La p-value, c'est la probabilité de voir des résultats aussi bons si l'hypothèse nulle est vraie. p en dessous de 0,05, tu rejettes l'hypothèse nulle, tu cries victoire.

Le piège, c'est ce qui arrive quand tu fais ça plus d'une fois. Si tu testes mille stratégies aléatoires, des stratégies qui sont littéralement du bruit pur, environ cinquante d'entre elles passent sous p < 0,05 par hasard. C'est ce que veut dire 0,05. Une sur vingt.

Le notebook te fait regarder ça se produire. À peu près ceci, simplifié par rapport à ce qu'il y a vraiment dans la leçon :

# illustrative: test 100 strategies that are all pure noise
import numpy as np
from scipy import stats

p_values = []
for _ in range(100):
    returns = np.random.normal(0, 0.02, 252)   # zero mean by construction
    _, p = stats.ttest_1samp(returns, 0)
    p_values.append(p)

p_values = np.array(p_values)
print((p_values < 0.05).sum(), "of 100 'strategies' look significant")

Chaque stratégie dans cette boucle est du bruit. Il n'y a de signal nulle part. La moyenne est nulle parce que je l'ai fixée à zéro. Et environ cinq d'entre elles reviennent en ayant l'air significatives, sans broncher, avec une p-value que tu aurais publiée.

La solution qu'enseigne le chapitre est Bonferroni, presque insultante de simplicité : si tu as lancé cent tests, divise ton seuil par cent. Exige p < 0,0005 au lieu de p < 0,05. Lance ça sur le même tableau et les faux positifs disparaissent presque tous. Il y a des corrections plus malines, mais l'important n'est pas l'arithmétique précise. L'important, c'est que le nombre de choses que tu as essayées fait partie de la preuve, et que si tu ne notes pas ce nombre, tu te mens à toi-même gratuitement.

Ce qui m'a marqué, c'est que ce n'est pas un mode de défaillance exotique. C'est le comportement par défaut de n'importe qui d'enthousiaste avec un backtester. Tu essaies des idées jusqu'à ce qu'une marche. C'est tout le problème. Le fait d'essayer, c'est la comparaison multiple, et personne ne la compte. J'ai absolument fait une version de ça en software classique, à fixer un dashboard jusqu'à trouver la découpe des données qui confirme ce que je croyais déjà. Je n'avais juste jamais eu le mot pour expliquer pourquoi c'était mal.

Le reste du niveau deux s'appuie sur la même méfiance. La régression pour se demander si tes rendements ne sont pas juste le marché déguisé, en décomposant une stratégie en bêta fois l'indice plus ce qu'il reste. Le maximum de vraisemblance comme le vrai sens du mot « calibrer », que tout le monde dit et que peu définissent. Un test de normalité sur de vrais rendements qui revient en hurlant NON, parce que les rendements ont des queues épaisses et que la jolie courbe en cloche que tout le monde dessine est une fiction commode. Le chapitre va chercher de vraies données pour ça, les rendements d'actions via yfinance, les facteurs Fama-French depuis le site de Kenneth French, pour que tu ne testes pas ton détecteur de bruit contre encore plus de ton propre bruit synthétique.

Je garde quand même le synthétique sous la main, parce que les expériences synthétiques sont là où la leçon est la plus nette. Quand tu génères toi-même les données, tu connais la vérité terrain. Tu sais qu'il n'y a aucun avantage dans cette boucle. Donc quand le test te dit qu'il y en a un, tu ne peux pas le contester ni le rationaliser. Les maths t'ont attrapé, et tu les as regardées t'attraper.

Il y a une phrase dans le matériel de la roadmap qui dit que le vrai ennemi est l'erreur d'estimation, que des maths parfaites avec des paramètres imparfaits échouent quand même. Je n'ai pas encore les bases pour ressentir tout le poids de ça. Repose-moi la question au niveau trois, quand j'inverserai une matrice de covariance estimée à partir de pas assez de données et que je la regarderai produire un portefeuille qui mise tout sur l'actif qui a eu l'échantillon le plus chanceux. Je vois la forme de là où ça va. Je ne peux pas encore le sentir dans mes mains.

Voilà à peu près le statut honnête. Un niveau qui était de la révision, un niveau qui a réorganisé ma façon de regarder n'importe quelle prétention d'avantage, et trois niveaux que je ne vais pas faire semblant d'avoir ouverts. Je ne sais pas si je finirai. La roadmap dit qu'il faut près de deux ans pour passer de rien à quelque chose, et c'est la partie à laquelle je crois plus qu'à toute autre.

Ce à quoi je ne m'attendais pas, c'est que l'idée la plus utile jusqu'ici n'a rien à voir avec la finance. Compte tes comparaisons. La plupart de ce qui ressemble à un signal est le résidu du nombre de fois où tu as regardé.