Repository navigation
[QC][livre] Comparer les résultats annoncés par le livre et nos reproductions, ch. 06 à 08 #18900
Description
Activity
- addedquantconnectQuantConnect strategy developmentQuantConnect strategy developmentquantconnect-researchMoissonnage QC research — distillation intelligenteMoissonnage QC research — distillation intelligente
on Oct 2, 2026 [CLAIMED] lane myia-po-2024:CoursIA-3 -- tranche 1 (exemples 06-01 a 06-07) : chiffres annonces par le livre face a nos reproductions, tableau dans BOOK_MAPPING.md -- paths: MyIA.AI.Notebooks/QuantConnect/BOOK_MAPPING.md
(check_lane_claim #9774 -- server-stamped UTC; body timestamps are NOT authoritative. Release with
[RELEASED]when your PR lands.)Pré-enregistrement, tranche 1 (exemples 06-01 à 06-07) : tolérance d'écart fixée avant tout calcul, comme le demande la méthode de l'issue. À cette heure, aucun chiffre du livre n'a encore été confronté aux nôtres.
Métrique principale. Le ratio de Sharpe tel que QuantConnect le calcule, des deux côtés : les chiffres du livre et les nôtres sont des statistiques de backtest QC, donc ils ont la même définition, taux sans risque compris. Le CAGR et la pire baisse ne sont comparés que si le livre les donne.
Tolérance, appliquée seulement à un rejeu dans les conditions du livre (même fenêtre, même modèle de frais, même univers) :
Mesure Écart toléré Sharpe ≤ 0,25 en valeur absolue, et même signe CAGR ≤ max(2 points, 25 % de la valeur du livre) Pire baisse ≤ 5 points Verdicts
REPRODUIT: toutes les mesures disponibles sont sous la tolérance. Un écart au-delà ne compte comme « expliqué » que si sa cause est mesurée, c'est-à-dire qu'un second rejeu sans cette cause ramène l'écart sous la tolérance. Une cause seulement plausible ne suffit pas.ÉCART: au-delà de la tolérance, sans cause mesurée. Une issue fille porte le diagnostic.NON COMPARABLE: le texte du livre n'annonce aucun chiffre pour l'exemple.
Conditions différentes. Quand notre dernier backtest ne tourne pas dans les conditions du livre (autre fenêtre, grille de frais de nos campagnes comparatives, autre univers), il n'y a pas de verdict avant le rejeu. Le tableau garde deux colonnes séparées : notre chiffre dans nos conditions, et le rejeu dans les conditions du livre.
Rejeux. Un backtest à la fois, annoncé sur le dashboard avant lancement, sous la limite de 10 appels/min partagée. Les résultats ne sont lus qu'une fois le backtest terminé.
Complément au pré-enregistrement de la tranche 1, posté avant tout rejeu. La lecture du livre a fait apparaître trois cas que le texte du 10:41Z ne prévoyait pas. Je les tranche ici, avant de lancer le moindre backtest.
1. Exemples 01 à 03 : le livre ne publie aucun backtest. Ce sont des carnets de recherche. Leurs seuls chiffres sont des exactitudes de classification :
- 01 : 51,2 % ;
- 02 : 0,6101 / 0,5849 / 0,5882 / 0,5962 ;
- 03 : 0,5548 en échantillon, 0,5277 hors échantillon.
Le pré-enregistrement supposait des statistiques de backtest des deux côtés. Or nos projets 01 et 03 sont des stratégies backtestées qui ne mesurent pas d'exactitude, et 02 n'a pas de reproduction. 01 et 03 sont donc
NON COMPARABLEpour la métrique retenue, puisque le livre n'annonce ni Sharpe, ni CAGR, ni pire baisse. La décision est prise après lecture du livre. Elle ne dépend pas de nos chiffres, qui sont d'une autre nature.2. Exemples 04 et 05 : le texte n'annonce aucun chiffre agrégé. Il ne donne que des constats de sensibilité qualitatifs (« A lookback period of 1 year leads to a negative Sharpe ratio »). Les planches du dépôt du livre ne montrent que des courbes, sans statistique imprimée (vérifié sur celle de 05). Ces deux exemples sont
NON COMPARABLE, selon la définition déjà posée.3. Exemples 06 et 07 : le livre donne un intervalle ou une borne, pas une valeur. Ces bornes portent sur la grille de sensibilité, qui contient les paramètres du backtest publié :
- 06 : « The Sharpe ratio only ranges from 0.476 to 0.617 » ;
- 07 : « All the Sharpe ratios are >= 0.7 ».
Règle fixée avant le rejeu. L'écart se mesure à l'intervalle : il est nul à l'intérieur, et vaut sinon la distance à la borne la plus proche. La tolérance de 0,25 et la règle de même signe s'appliquent à cet écart. Concrètement, 07 est sous la tolérance si le rejeu donne un Sharpe ≥ 0,45, et 06 si le rejeu tombe dans [0,226 ; 0,867]. Le livre ne donne ni CAGR ni pire baisse : seul le Sharpe est comparé.
Rejeux. 07 d'abord, puis 06 si le temps le permet, un backtest à la fois. Les conditions sont celles du livre : du 2019-01-01 au 2024-04-01, capital du livre, modèle de courtier par défaut (ligne
set_brokerage_modelretirée), paramètres publiés. Notre code reste inchangé par ailleurs. Pour 07,hold_durationvaut 3, comme dans le texte (« hold_duration: 3 ») et comme dans le code du livre. Les notes du dépôt du livre (footnotes.txt) indiquent 2 : l'écart est relevé ci-dessous, il ne change pas le rejeu.Écarts internes au livre (texte face au code de son dépôt), relevés en passant :
- 01 : BTCUSD dans le texte, BTCUSDT sur Binance dans le code ;
- 03 : le texte donne 0,5548 / 0,5277 / [592 1559], les sorties enregistrées du carnet donnent 0,5561 / 0,5309 / [609 1542] ;
- 07 :
hold_duration3 dans le texte, 2 dans les notes.
Tranche 1 (chapitre 06, exemples 01 à 07) : résultats des rejeux, sous la règle publiée plus haut (base, complément chapitre 06).
Verdicts
Exemple Verdict Motif 06-01, 06-03 NON COMPARABLEle livre publie une précision de classification tirée d'un notebook de recherche, pas un backtest 06-02, 06-04/02, 06-04/03 sans objet aucune reproduction dans le dépôt 06-04/01, 06-05 NON COMPARABLEaucun chiffre dans le texte ; le tearsheet ne montre que des courbes 06-06 REPRODUITrejeu dans les conditions du livre : Sharpe 0,638 ; le livre annonce 0,476 à 0,617. L'écart à la borne haute, 0,021, est dans la tolérance de 0,25 06-07 REPRODUITrejeu dans les conditions du livre : Sharpe 1,343. Le livre annonce ≥ 0,7 sur tout son balayage, donc l'écart est nul Rejeux (QC Cloud)
Exemple Projet Backtest Sharpe CAGR Pire baisse PSR Ordres 06-07 37295024 a7dd583491a45d77ab4a74a3655734601,343 65,87 % 37,6 % 62,0 % 235 06-06 37295108 009ff61bd41bc25832870bd613cbc65f0,638 17,87 % 31,5 % 13,0 % 1301 Fichiers rejoués (sha256) :
- 07
main.py:c3a30bb1769a3e448241e463683bac96e5f6b11bb8be0ecee4dc46e78e3f99eb. Diff par rapport àprojects/Positive-Negative-Splits-ML/main.py: date de début 2015-01-01 → 2019-01-01, ligneset_brokerage_modelretirée. - 06
main.py:d78a3acdda03c1d5399c9e8a094e6ef17bade4d09cbad6aa9d57ea0cd33caec0. Diff par rapport àprojects/Dividend-Harvesting-ML/main.py: fenêtre 2015-01-01 → 2026-03-01 remplacée par 2019-01-01 → 2024-04-01, ligneset_brokerage_modelretirée. - 06
symboldata.py:2bdab3aa9661d7f71b6c44d5e500cc7e8724ea142b345ae9bb70f7e23c40ac40, identique au fichier du dépôt.
Le rejeu 06 a été comparé au code du livre au niveau de l'arbre syntaxique. Il n'en diffère que par une garde ajoutée chez nous (
if prediction_sum <= 0: return) et par des renommages de variables.Ce que
REPRODUITveut dire06. Le rejeu tombe juste au-dessus du balayage du livre, aux paramètres publiés : l'ordre de grandeur est reproduit, la position exacte dans le balayage ne l'est pas. Notre mesure de 2015-2026 (0,468, avec le modèle de frais de nos campagnes) est plus basse. Le rejeu changeant à la fois la fenêtre et les frais, il ne dit pas lequel des deux explique l'écart.
07. Le livre publie un plancher, pas un chiffre précis. Notre mesure sur 2015-2024 reste à 1,066 (PSR 34,9 %), et l'effet est concentré sur 2018-2024, comme le README du projet le dit déjà.
Livraison
- Le tableau est dans
BOOK_MAPPING.md, section « Résultats du livre face à nos reproductions » : PR docs(qc,#18900): chiffres du livre face à nos reproductions, chapitre 06 exemples 01 à 07 #18985, empilée sur docs(qc,#18899): one book inventory, every row a checked path #18965. - Quatre README du chapitre 06 contredisent leur propre code : docs(qc): quatre README du chapitre 06 contredisent leur code (chiffres, paires, rythme, description) #18982.
- Tranche suivante : chapitre 06, exemples 08 à 13.
- 07
- added a commit that references this issue
on Oct 3, 2026 [CLAIMED] lane myia-po-2024:CoursIA-3 -- tranche 2 (chapitre 06, exemples 08 a 13) : relevé du livre, pré-enregistrement complémentaire avant tout rejeu, rejeux QC dans les conditions du livre, tableau de résultats -- paths: MyIA.AI.Notebooks/QuantConnect/BOOK_MAPPING.md
Complément au pré-enregistrement, tranche 2 (chapitre 06, exemples 08 à 13), posté avant tout rejeu. La règle de base et le complément du chapitre 06 s'appliquent. Le relevé ci-dessous vient du texte du livre et des
footnotes.txtde son dépôt (commite025f21). Aucun de nos chiffres n'a été regardé pour l'écrire.Ce que le livre annonce, et le traitement retenu
Exemple Ce que le livre annonce Traitement 08/01 17 des 20 seuils de stop battent le buy-and-hold de KO (Sharpe 0,263) ; paramètre publié : 0,95 sans objet : aucune reproduction ( GAP)08/02 les 30 combinaisons du balayage ont un Sharpe positif, 28 dépassent 0,263 ; paramètres publiés : 3 mois d'historique, écart de stop 0,01, alpha_exponent4rejeu ; borne : Sharpe > 0 08/03 aucun chiffre sans objet : aucune reproduction ( GAP)09 notebook de recherche : 1357 paires testées, 30 retenues ; aucun backtest NON COMPARABLE: un décompte de paires n'est pas un backtest10 tous les Sharpe du balayage sont ≥ 0 ; paramètres publiés : univers liquide 100, univers final 10, 365 jours d'historique, 5 composantes sans objet, pas de rejeu : notre projet ne met pas en œuvre le modèle du livre (voir plus bas) 11 toutes les combinaisons du balayage sont profitables ; paramètres publiés : 3 mois, 3 mois, 365 jours rejeu ; borne : profit net > 0 12 démonstration des coûts : 774 ordres moins chers (42,36 %), 28 inchangés, 13 plus chers ; aucune statistique de backtest NON COMPARABLE13 toutes les combinaisons du balayage sont profitables ; Sharpe maximal à 3 composantes et 126 jours ; paramètres publiés : 3 composantes, 63 jours, seuil de z-score 1,5, univers de 100 rejeu ; borne : profit net > 0 Les paramètres publiés de 08/02, 11 et 13 sont tous dans le balayage auquel la borne se rapporte.
Bornes à zéro : le test se réduit au signe
Pour 08/02, 11 et 13, le livre ne publie qu'un signe. Appliquer la tolérance de 0,25 contredirait alors la règle « même signe ». Le test porte donc sur le signe seul :
REPRODUITsi le rejeu a un Sharpe > 0 (08/02) ou un profit net > 0 (11, 13) ;ÉCARTsinon.
Pour 11 et 13, la mesure est le
Net Profitde QuantConnect ; le CAGR a toujours le même signe. C'est un test faible : il dit que notre reproduction ne contredit pas le livre, pas qu'elle en reproduit un chiffre.Exemple 10 : pas de rejeu
Le docstring de
projects/Clustering-Fundamentals-ML/main.pyle dit : notre version (v4) classe les actions par z-scores de 8 facteurs fondamentaux, sans PCA niLGBMRanker. Elle a remplacé deux versions plus fidèles, abandonnées pour leur lenteur et desNaN. Un rejeu mesurerait donc une autre stratégie que celle du livre, et sa borne (Sharpe ≥ 0) ne dirait rien de la reproduction. Dans le tableau de correspondance, la ligne 10 passe deCOVEREDàPARTIAL.Conditions des rejeux
La fenêtre et le capital sont repris de
set_start_date,set_end_dateetset_cashdans le code du livre :- 08/02 : 2018-12-31 → 2024-04-01, capital 100 000 ;
- 13 : 2019-01-01 → 2024-04-01, capital 1 000 000 ;
- 11 : 2018-12-31 → 2024-04-01, capital 100 000 000.
Pour chacun : courtage par défaut (la ligne
set_brokerage_modelest retirée) et paramètres publiés. Notre code reste inchangé par ailleurs.Chaque rejeu tourne dans un projet QC séparé, un backtest à la fois, annoncé sur le dashboard. Il n'est lu qu'à
completed: true. Ordre : 08/02, 13, puis 11.Différences de notre code avec celui du livre, gardées au rejeu
Le rejeu juge notre reproduction, pas le code du livre.
- 08/02 : la volatilité réalisée de SPY remplace le VIX (docstring du projet).
- 11 : trois surcouches de risque propres à notre projet (
weight_multiplier,max_position_pct,stop_loss_pct). Le modèle reste le mêmeRidge. - 13 :
LinearRegressionde scikit-learn à la place desm.OLSavec constante. Les deux ajustent une constante, donc les résidus sont les mêmes. Nous avons aussi ajouté des gardes (univers trop petit, historique vide).
Écarts internes au livre
- 08/01 : le texte et les notes publient 0,95 ; la valeur par défaut du code est 0,99, dans la zone où le livre dit que le Sharpe s'effondre (≥ 0,985).
- 08/02 : le texte et les notes publient 3 mois d'historique ; le code vaut 1 par défaut. Le rejeu suit le texte : 3.
- 13 : le texte et les notes publient 63 jours ; le code vaut 60 par défaut, une valeur hors du balayage, dont le pas est de 21. Le rejeu suit le texte : 63.
Tranche 2 (chapitre 06, exemples 08 à 13) : résultats des rejeux, sous la règle publiée plus haut (base, complément chapitre 06, complément tranche 2, posté à 18:57:08Z ; premier backtest créé à 18:58:14Z).
Verdicts
Exemple Verdict Motif 06-08/01, 06-08/03 sans objet aucune reproduction dans le dépôt 06-08/02 REPRODUIT(borne à zéro)rejeu dans les conditions du livre : Sharpe 0,24 > 0. Le livre annonce un Sharpe positif pour les 30 combinaisons de son balayage 06-09 NON COMPARABLEle livre publie un décompte de paires tiré d'un notebook de recherche, pas un backtest 06-10 sans objet, pas de rejeu notre projet ne met pas en œuvre le modèle du livre (PCA puis LGBMRanker) : ces noms n'apparaissent que dans son docstring. La ligne d'inventaire passe deCOVEREDàPARTIAL06-11 REPRODUIT(borne à zéro)rejeu dans les conditions du livre : profit net de 23,7 % > 0. Le livre annonce que toutes les combinaisons de son balayage sont profitables 06-12 NON COMPARABLEdémonstration d'un modèle de coûts, sans statistique de backtest 06-13 REPRODUIT(borne à zéro)rejeu dans les conditions du livre : profit net de 38,1 % > 0. Le livre annonce que toutes les combinaisons de son balayage sont profitables Rejeux (QC Cloud, projets séparés, un backtest à la fois)
Exemple Projet Backtest Sharpe CAGR Pire baisse Profit net PSR Ordres 06-08/02 37309010 3e0d8c17982c9acc9d544fccf9260a090,24 6,87 % 20,5 % 41,8 % 1,7 % 746 06-13 37309113 a0205f4b3e052a526d3fc25de8acdc700,211 6,34 % 34,7 % 38,1 % 1,4 % 1658 06-11 37309271 a30271d032a6f4e54c2f2ed3bbb903810,124 4,13 % 41,0 % 23,7 % 0,8 % 532 Fichiers rejoués (sha256) :
- 08/02
main.py:e25e0f7a42a108b616e1fa90595a4787c73caff9318342265d9614e24d0547e5. Diff par rapport àprojects/Stoploss-Volatility-ML/main.py: fenêtre 2015-01-01 → 2026-03-01 remplacée par 2018-12-31 → 2024-04-01, ligneset_brokerage_modelretirée,indicator_lookback_months1 → 3 (valeur du texte du livre). - 13
main.py:dc0fcd27072d856a2facfdb2eb012700a03bb1fe1f39b2ce35562d10ee6f77da. Diff par rapport àprojects/PCA-StatArbitrage/main.py: fenêtre 2015-01-01 → 2024-01-01 remplacée par 2019-01-01 → 2024-04-01, ligneset_brokerage_modelretirée,lookback_days60 → 63 (valeur du texte du livre). - 11
main.py:a151a0ef01ae50d2f0d102468d8004aad4ed71c9122d0378c3c47c9424fabb95. Diff par rapport àprojects/InverseVolatility-Rank/main.py: date de début 2015-01-01 → 2018-12-31, ligneset_brokerage_modelretirée ; la date de fin et le capital étaient déjà ceux du livre.
Ce que
REPRODUITveut dire iciPour ces exemples, le livre ne publie qu'un signe sur tout un balayage. Le rejeu confirme ce signe aux paramètres publiés. Il ne dit rien de la place du rejeu dans le balayage, ni de la qualité de la stratégie : les PSR des rejeux (1,7 % pour 08/02, 1,4 % pour 13, 0,8 % pour 11) rappellent qu'un Sharpe positif sur cinq ans n'est pas un avantage établi.
11. Le fichier rejoué est identique, à l'octet près, au
main.pydu projet QC Cloud 29463533, sur lequel a été mesuré notre chiffre de la page de statut. Le rejeu redonne donc exactement Sharpe 0,124, CAGR 4,13 % et pire baisse 41,0 % ; seul le PSR change (1,9 % sur la page, 0,8 % au rejeu). Lemain.pydu dépôt, lui, commence au 2015-01-01 et fixe un modèle de courtage : les chiffres publiés ne décrivent pas le code publié. Suivi dans #19018.Livraison
- Le tableau est dans
BOOK_MAPPING.md, section « Résultats du livre face à nos reproductions » : PR docs(qc,#18900): chiffres du livre face à nos reproductions, chapitre 06 exemples 08 à 13 #19019, empilée sur docs(qc,#18900): chiffres du livre face à nos reproductions, chapitre 06 exemples 01 à 07 #18985. - Le livre se contredit sur trois paramètres (texte contre code de son dépôt : 08/01, 08/02, 13) ; la section les liste.
- Tranche suivante : chapitre 06, exemples 14 à 19.
- 08/02
[CLAIMED] lane myia-po-2024:CoursIA-3 -- tranche 3 de la comparaison (chapitre 06, exemples 14 à 19), même règle de verdict, sur une branche empilée sur #19019 -- paths: MyIA.AI.Notebooks/QuantConnect/BOOK_MAPPING.md
Recouvrement de fichier avec #19041 (ligne 09 de l'inventaire) : lignes disjointes,
git merge-treesans conflit ; coordination postée sur #19041 (c.5975869567).Complément au pré-enregistrement, tranche 3 (chapitre 06, exemples 14 à 19), posté avant tout rejeu. La règle de base, le complément du chapitre 06 et le complément « borne à zéro » s'appliquent. Le relevé vient du texte du livre, des
footnotes.txtet destearsheet2.pngde son dépôt (commite025f21). Aucun de nos chiffres n'a été regardé pour l'écrire.Une source nouvelle : l'échelle de couleur du balayage
Pour 14 et 15, le livre ne publie pas de Sharpe dans le texte, mais le balayage de paramètres de
tearsheet2.png(« Sensitivity Test: Sharpe Ratio ») porte une échelle de couleur. Nous la lisons comme l'intervalle des Sharpe du balayage, en supposant la normalisation par défaut de matplotlib : les deux bornes de l'échelle sont alors le minimum et le maximum observés. La lecture est précise à 0,03 environ. Un rejeu qui tombe à moins de 0,05 d'une borne de tolérance sera rapporté comme fragile, quel que soit son verdict.Les paramètres publiés de 14 ne sont pas dans le balayage (voir « Écarts internes »). L'intervalle sert donc de fourchette pour la stratégie, pas de chiffre pour le paramètre publié.
Ce que le livre annonce, et le traitement retenu
Exemple Ce que le livre annonce Traitement 14 « la plupart des combinaisons ne sont pas profitables » ; échelle du balayage : Sharpe de −0,55 à 0,20 ; paramètres publiés : 500 échantillons, univers de 3 rejeu ; REPRODUITsi le Sharpe est dans [−0,80 ; 0,45]. L'intervalle contient zéro : la condition de signe ne contraint rien ici15 « toutes les combinaisons sont profitables » ; échelle du balayage : Sharpe de 0,42 à 1,02 ; paramètres publiés : 4 jours par échantillon, 100 échantillons, univers de 10 rejeu ; REPRODUITsi le Sharpe est dans [0,17 ; 1,27] et > 016 Sharpe 1,695 (TSLA, 2023-11-01 → 2024-03-01, résumés d'articles par un LLM) pas de rejeu, pas de verdict (voir plus bas) 17 « toutes les combinaisons sont profitables » ; paramètres publiés : max_size100,step_size10, seuil de confiance 0,5, détention 10 joursrejeu ; borne à zéro : REPRODUITsi le profit net > 018/01 courbes de prévision et table de rendements mensuels ; aucun chiffre de backtest dans le texte NON COMPARABLE18/02 — sans objet : aucune reproduction ( GAP, #18962)19/01 idem 18/01 NON COMPARABLE19/02 — sans objet : aucune reproduction ( GAP, #18962)Exemple 16 : pas de rejeu
Notre projet
ML-LLM-Summarizationne joue pas la stratégie du livre par défaut :- sans paramètre de projet portant une clé d'API, il classe les articles par mots-clés, sans LLM ;
- le mode LLM exige de déposer cette clé comme paramètre du projet QC, ce que nous ne faisons pas ;
- l'actif est SPY, pas TSLA.
Un rejeu mesurerait donc une autre stratégie que celle du livre, comme pour l'exemple 10. Dans le tableau de correspondance, la ligne 16 passe de
COVEREDàPARTIAL.Conditions des rejeux
La fenêtre et le capital sont repris de
set_start_date,set_end_dateetset_cashdans le code du livre :- 15 : 2019-01-01 → 2024-04-01, capital 1 000 000 ;
- 17 : 2019-01-01 → 2024-04-01, capital 100 000 ;
- 14 : 2018-12-31 → 2024-04-01, capital 100 000.
Pour chacun : courtage par défaut (la ligne
set_brokerage_modelest retirée) et paramètres publiés, qui sont déjà nos valeurs par défaut. Notre code reste inchangé par ailleurs.Chaque rejeu tourne dans un projet QC séparé, un backtest à la fois, annoncé sur le dashboard. Il n'est lu qu'à
completed: true. Ordre : 15, 17, puis 14. Nous relevons le Sharpe, le PSR, le nombre d'ordres et le profit net.Différences de notre code avec celui du livre, gardées au rejeu
Le rejeu juge notre reproduction, pas le code du livre. Comparaison faite à l'arbre syntaxique (docstrings retirés), pas au texte.
- 14 : dans
main.py, seules la fenêtre et la ligne de courtage diffèrent. Danstemporalcnn.py, des renommages,verbose=0et des conversions de type ; le modèle est le même. - 15 : des gardes (moins de 20 observations,
try/exceptautour de l'ajustement et de la prédiction). Et une différence de comportement : quand aucune action n'est prédite en hausse, notre code liquide tout, alors que celui du livre garde ses positions. - 17 : une garde (
symbol not in data) et des conversions de type. Surtout, le livre charge un modèle entraîné depuis l'Object Store ; notre code fait de même si la clé existe, et sinon entraîne sur place un CNN sur des motifs synthétiques (graine fixe). Le journal du rejeu dit lequel des deux a tourné, et le résultat le rapportera.
Écarts internes au livre
- 14 : l'univers publié (3) n'est pas dans le balayage, dont les valeurs sont 2, 4, …, 10.
- 17 : le texte et les notes disent « toutes les combinaisons sont profitables », mais l'échelle du balayage va d'environ −135 à −20 en Sharpe. Les deux ne se contredisent pas forcément : le Sharpe de QuantConnect retranche le taux sans risque, et une stratégie presque toujours hors du marché a une volatilité proche de zéro, ce qui rend son Sharpe très négatif même avec de petits gains. C'est pourquoi la borne de 17 porte sur le profit net et non sur le Sharpe.
Tranche 3 (chapitre 06, exemples 14 à 19) : résultats des rejeux, sous la règle publiée plus haut (base, complément chapitre 06, complément « borne à zéro », complément tranche 3, posté à 02:51:41Z ; premier backtest créé à 02:52:47Z).
Verdicts
Exemple Verdict Motif 06-14 REPRODUITrejeu dans les conditions du livre : Sharpe 0,202, dans [−0,80 ; 0,45], à la borne haute de l'échelle du balayage (0,20) 06-15 REPRODUITrejeu dans les conditions du livre : Sharpe 0,582, positif et dans l'échelle du balayage (0,42 à 1,02) 06-16 sans objet, pas de rejeu sans clé d'API en paramètre du projet, notre projet classe les articles par mots-clés, sans LLM, et l'actif est SPY. La ligne d'inventaire passe de COVEREDàPARTIAL06-17 ÉCART(borne à zéro)rejeu dans les conditions du livre : profit net de −0,062 %. Le modèle du livre manquait à notre Object Store : c'est le CNN de repli, entraîné sur des motifs synthétiques, qui a tourné (journal du backtest). Issue fille #19053 06-18/01, 06-19/01 NON COMPARABLEcourbes de prévision et rendements mensuels, sans statistique de backtest dans le texte 06-18/02, 06-19/02 sans objet aucune reproduction dans le dépôt ( GAP, #18962)Rejeux (QC Cloud, projets séparés, un backtest à la fois)
Exemple Projet Backtest Sharpe CAGR Pire baisse Profit net PSR Ordres 06-15 37323229 8df461e5fffd0f0df859d0bd412961300,582 18,69 % 41,8 % 146,0 % 10,1 % 1813 06-17 37323273 87648032844af2f195239271140bcb1f−24,1 −0,012 % 0,2 % −0,062 % 0 % 8 06-14 37323339 672faa80ccb73bdaa629b4137f3885900,202 6,11 % 44,7 % 36,6 % 1,3 % 624 Fichiers rejoués (sha256) :
- 15
main.py:0836d6897129deeacd97b026287d971e58b6f9b2393df79b66b13998a26e9a56. Diff par rapport àprojects/ML-Gaussian-Classifier/main.py: fenêtre 2015-01-01 → 2026-01-01 remplacée par 2019-01-01 → 2024-04-01, capital porté à 1 M, ligneset_brokerage_modelretirée. - 17
main.py:83c956a4ca3c57842aed5e2737c8e969d8a3d206068c4aa4e003a28c17503bf2. Diff par rapport àprojects/ML-HeadShoulders-CNN/main.py: fenêtre 2015-01-01 → 2024-01-01 remplacée par 2019-01-01 → 2024-04-01, ligneset_brokerage_modelretirée. - 14
main.py:3ad8305adaa3a25778aac3ec866630f0caf354159a5b65d8ee9c1d6f936c7093. Diff par rapport àprojects/ML-Temporal-CNN/main.py: fenêtre 2015-01-01 → 2024-01-01 remplacée par 2018-12-31 → 2024-04-01, ligneset_brokerage_modelretirée.temporalcnn.pyenvoyé tel quel (sha25634390ca45d939df6a1469d73995dba251cc5fad4b4334339d4d61491fdcd0d36).
Chaque fichier a été relu sur QC après envoi (même sha256), et chaque backtest lu seulement à
completed: true.Ce que ces verdicts disent
L'échelle de couleur d'un balayage est une source plus faible qu'un chiffre du texte : elle borne la stratégie sur tout le balayage, pas le paramètre publié.
- 15 : le rejeu tombe dans la fourchette ; sa PSR (10,1 %) rappelle qu'un Sharpe de 0,58 sur cinq ans n'est pas un avantage établi.
- 14 : le rejeu tombe à la borne haute de l'échelle, avec un profit net positif (36,6 %), alors que le livre dit que la plupart des combinaisons ne sont pas profitables. L'univers publié (3) n'est pas dans le balayage : les deux ne se contredisent pas, et la PSR du rejeu (1,3 %) ne dit pas plus.
- 17 : l'
ÉCARTporte sur le modèle. La première ligne du journal du backtest estObject Store model missing, training synthetic CNN: le rejeu a joué le CNN de repli, et non le modèle entraîné du livre, absent de notre Object Store. Il dit que le projet, tel qu'il tourne aujourd'hui sur QC Cloud, ne retrouve pas le signe annoncé ; il ne dit encore rien de la stratégie du livre. Le Sharpe (−24,1) tombe dans l'échelle du balayage du livre (de −135 à −20 environ), ce qui ne change pas le verdict, la règle portant sur le profit net. Suite : [QC][livre] Head & Shoulders CNN (06/17) : notre rejeu tourne sans le modèle entraîné du livre #19053 (exécuter leresearch.ipynbdu projet sur QC Cloud pour déposer le modèle, puis rejouer).
Livraison
- Le tableau est dans
BOOK_MAPPING.md, section « Résultats du livre face à nos reproductions » : PR docs(qc,#18900): tranche 3 du livre face à nos reproductions (chapitre 06, ex. 14-19) #19056, empilée sur docs(qc,#18900): chiffres du livre face à nos reproductions, chapitre 06 exemples 08 à 13 #19019. - Deux écarts internes au livre (14, 17) y sont listés.
- La ligne 16 de l'inventaire passe de
COVEREDàPARTIAL. - Tranche suivante : chapitre 07.
- 15
- added a commit that references this issue
on Oct 4, 2026 [CLAIMED] lane myia-po-2024:CoursIA-3 -- tranche 4 de la comparaison (chapitres 07 et 08), dernière tranche de l'issue, même règle de verdict, sur une branche empilée sur #19056 -- paths: MyIA.AI.Notebooks/QuantConnect/BOOK_MAPPING.md
Recouvrement de fichier avec #19071 (lignes 06-02) et #19052 (ligne d'inventaire 08-02) : la tranche n'ajoute que des lignes dans la section « Résultats du livre face à nos reproductions » et ne touche pas ces lignes-là. Coordination avec la lane de #19052 postée sur #18901.
Complément au pré-enregistrement, tranche 4 (chapitres 07 et 08), posté avant tout rejeu. J'ai lu les chapitres 7 et 8 du livre et le dépôt du livre au commit
e025f21. À cette heure, aucun backtest de la tranche n'est lancé.07-01, couverture d'options par apprentissage par renforcement. Le livre ne publie que des courbes : prix, convergence des pertes, décision face au delta, richesse des portefeuilles de couverture (figures 7.3 à 7.8). Il ne donne ni Sharpe, ni CAGR, ni pire baisse. Verdict :
NON COMPARABLE. Le dépôt n'a de toute façon pas de reproduction (STUB, portage suivi par #18902).08-01, CPO appliquée. L'exemple appliqué du livre ne publie aucune statistique de backtest. Il porte sur 16 ETF, de 2020-02 à 2024-04, avec des poids mensuels lus dans l'Object Store après un appel au service PredictNow. Les tables 8.4 à 8.9 portent sur d'autres portefeuilles, et leurs chiffres viennent du service, pas d'un backtest du livre. Notre
Portfolio-Optimization-MLest une autre stratégie : 15 actions, covariance Ledoit-Wolf, maximum de Sharpe. Verdict :NON COMPARABLE.Relevé en passant : la table 8.9 publie aussi des allocations conventionnelles, qu'on pourrait rejouer sans le service. Elle porte sur un portefeuille de 5 ETF, de 2019-01 à 2022-12, rééquilibré toutes les deux semaines :
- poids égaux : 0,62 / 6,61 % ;
- parité de risque : 0,22 / 1,16 % ;
- Markowitz : −0,13 / −2,09 % ;
- variance minimale : −0,05 / 0,39 %.
Ce rejeu sort du périmètre de cette issue, qui compare le livre à nos reproductions.
08-02, Corrective AI sur la saisonnalité EUR/USD. Le livre publie ces chiffres, hors échantillon du 2021-10-01 au 2023-01-15, sans frais de transaction :
Sharpe rendement annuel moyen pire baisse primaire 0,88 3,5 % −3,5 % après Corrective AI 1,29 4,1 % −1,9 % Ses données (EBS) ne sont pas partagées.
La reproduction est celle de #19052 (lane myia-po-2025:CoursIA, ouverte), figée à sa tête
1940f6c6d4: la règle primaire de Breedon et Ranaldo sur EUR/USD, données OANDA à la minute. Le correctif y est remplacé par un méta-étiquetage, pas par le modèle du service.- Ligne « après Corrective AI » :
NON COMPARABLE. Le modèle correctif n'est pas celui du livre. - Ligne « primaire » : verdict par la règle de base. Le Sharpe est la mesure principale. La tolérance du CAGR s'applique au rendement annuel moyen publié, celle de la pire baisse à 3,5 %.
- R1 : le
main.pyde feat(qc,#18901): Corrective-AI ch. 08-02 — primaire Breedon-Ranaldo + méta-étiquetage (20 backtests, NO BEATS) #19052 tel quel, avecuse_meta=false, la convention par défaut et la fenêtre du 2021-10-01 au 2023-01-15. - R2 : le même rejeu, avec un seul changement : les ordres sont remplis au milieu de la fourchette. C'est un rejeu sans écart achat-vente, la condition « sans frais » du livre ; les frais du moteur sont déjà nuls.
- Verdict. Si R1 est sous la tolérance :
REPRODUIT. Sinon, si R2 l'est :REPRODUIT, avec un écart expliqué par l'écart achat-vente (cause mesurée). Sinon :ÉCART. - Diagnostic d'un
ÉCART. Il va à [QC][livre] Corrective-AI (08-02) : porter la saisonnalité EUR/USD et sa correction par méta-étiquetage #18901, l'issue du portage, encore ouverte, plutôt qu'à une nouvelle issue qui la doublerait. À ce stade, les causes candidates sont la source de données (EBS ou OANDA) et le sens des fenêtres. - Convention rejouée. Seule la convention par défaut est rejouée : c'est celle que feat(qc,#18901): Corrective-AI ch. 08-02 — primaire Breedon-Ranaldo + méta-étiquetage (20 backtests, NO BEATS) #19052 retient. La convention du papier y est déjà mesurée dans la fenêtre du livre, avec l'écart achat-vente.
- R1 : le
Les deux rejeux tournent dans un projet QC séparé, un à la fois, annoncés sur le dashboard. Je ne touche ni aux fichiers ni au projet QC de #19052.
Résultat, tranche 4 (chapitres 07 et 08)
Règle appliquée sans changement : complément pré-enregistré #18900 (comment).
Exemple Verdict 07/01 couverture d'options NON COMPARABLE: le livre ne publie que des courbes. Le dépôt n'a pas de reproduction (#18902).08/01 CPO appliquée NON COMPARABLE: aucune statistique de backtest dans l'exemple appliqué.08/02 après Corrective AI NON COMPARABLE: le modèle correctif n'est pas celui du livre.08/02 stratégie primaire ÉCART08/02, stratégie primaire : rejeux
Code de #19052 figé à sa tête
1940f6c6d4, stratégie primaire seule, convention par défaut, EUR/USD OANDA à la minute, capital 100 k, frais du moteur nuls, du 2021-10-01 au 2023-01-15. Les deux rejeux ont tourné l'un après l'autre dans un projet QuantConnect séparé (37336051). Le projet de #19052 n'a pas été touché.Sharpe CAGR Pire baisse Profit net Ordres PSR Livre (sans frais, données EBS) 0,88 3,5 % (rendement annuel moyen) 3,5 % — — — Tolérance [0,63 ; 1,13] [1,5 % ; 5,5 %] ≤ 8,5 % R1 tel quel ( 38c7614524d8fa7d3bfeeabfbe968dca)−0,976 −6,20 % 10,6 % −7,94 % 1336 0,3 % R2 au milieu de la fourchette ( 935c5f7588034b0054cb9457fc8565b1)−0,143 0,77 % 5,7 % 1,00 % 1336 5,9 % R1 est hors tolérance sur les trois mesures. R2 est hors tolérance sur le Sharpe, de signe opposé, et sur le CAGR, à 2,7 points du livre. Seule sa pire baisse entre dans la tolérance. Aucun des deux ne satisfait la règle :
ÉCART. Le diagnostic va à #18901, comme annoncé.Journaux. Les deux rejeux comptent 668 fenêtres, toutes prises, sans ré-entraînement : le méta-étiquetage est bien inactif. R2 montre le remplissage au milieu de la fourchette, par exemple le 2021-10-01 à 03:00 : cours acheteur 1,15872, cours vendeur 1,15887, ordre rempli à 1,158795 au lieu de 1,15872.
Diffs (empreintes SHA-256) :
main.pyde feat(qc,#18901): Corrective-AI ch. 08-02 — primaire Breedon-Ranaldo + méta-étiquetage (20 backtests, NO BEATS) #19052 à1940f6c6d4:2b9c359c92522455754d675d2edd57cf8391f118796b8f09eb2fca7e660cddff- R1 :
3449c8f0d4c4739a5c43768ad2125d36b67edc27fc01581e5773601662d2f810 - R2 :
d2a9e98c5809ae23afd0f0c952afa55977fd7a4b707ff63afe285ad2853819e7
# R1 face à 1940f6c6d4 : fin de fenêtre du livre, primaire seule - end = self._param_date("end", date(2023, 1, 31)) + end = self._param_date("end", date(2023, 1, 15)) - self._use_meta = self.get_parameter("use_meta", "true") == "true" + self._use_meta = self.get_parameter("use_meta", "false") == "true"
# R2 face à R1 : un seul changement, le modèle de remplissage +class MidPriceFillModel(ImmediateFillModel): + """Rejeu #18900 tranche 4 (R2) : ordres au marche remplis au milieu de la fourchette.""" + + def __init__(self, algorithm): + super().__init__() + self._algo = algorithm + self._n = 0 + + def market_fill(self, asset, order): + fill = super().market_fill(asset, order) + bid, ask = asset.bid_price, asset.ask_price + if fill.status == OrderStatus.FILLED and bid > 0 and ask > 0: + mid = (bid + ask) / 2 + if self._n < 3 or self._n % 500 == 0: + self._algo.log(f"mid-fill n={self._n} bid={bid} ask={ask} brut={fill.fill_price} mid={mid}") + fill.fill_price = mid + self._n += 1 + return fill ... self._eurusd = self.add_forex("EURUSD", Resolution.MINUTE, Market.OANDA) + self._eurusd.set_fill_model(MidPriceFillModel(self))
Lecture
- Écart achat-vente. Le retirer remonte le CAGR de 7,0 points (de −6,20 % à 0,77 %) et le Sharpe de 0,83. C'est le coût principal de la stratégie telle qu'elle est codée, avec deux ordres par fenêtre sur 668 fenêtres. Il ne suffit pas à retrouver le livre : la part qu'il explique est mesurée, l'écart restant ne l'est pas.
- Convention de Sharpe. Le Sharpe de QuantConnect retranche le taux sans risque, ce qui permet qu'un CAGR positif donne un Sharpe négatif sur une fenêtre où les taux montent, comme 2022. Celui du livre ne vient pas de QuantConnect. Le CAGR, lui, ne dépend pas du taux sans risque, et il est aussi hors tolérance : l'
ÉCARTne tient pas à la convention de Sharpe. - Causes encore candidates : la source de données (EBS ou OANDA) et l'horodatage exact des fenêtres. Le sens des fenêtres n'en est probablement pas une. Au milieu de la fourchette, inverser les sens rend opposé le résultat de chaque fenêtre, ce qui donnerait un CAGR proche de −0,8 %. C'est une déduction, pas une mesure.
- Pour feat(qc,#18901): Corrective-AI ch. 08-02 — primaire Breedon-Ranaldo + méta-étiquetage (20 backtests, NO BEATS) #19052 : sa conclusion ne change pas. Ce rejeu ajoute seulement que, même sans écart achat-vente, la règle primaire ne retrouve pas le chiffre du livre sur les données OANDA de la fenêtre du livre.
Avec cette tranche, les chapitres 06, 07 et 08 sont tous comparés. La PR suit, empilée sur #19056.
- added a commit that references this issue
on Oct 4, 2026
Part of #18898
Pourquoi
Nos campagnes mesurent nos portages sous la grille de frais IBKR (
docs/qc/qc-comparative-backtests.md: « only 6 of 24 verified strategies hold »), sans jamais les mettre en regard de ce que le livre annonce. Un portage faible peut l'être pour trois raisons très différentes : l'idée ne tient pas, le livre la présente dans des conditions plus favorables (fenêtre, frais, univers), ou notre portage s'en écarte. Sans la comparaison, on ne sait pas laquelle, et on ne sait pas quoi corriger.Méthode, par exemple
G:\Mon Drive\MyIA\IA\Bibliographie IA\Trading\2025 - Hands_On_AI_Trading_with_Python_QuantCon.md) et relever : période, univers, frais, paramètres, chiffres annoncés, analyses de sensibilité. Le livre en donne souvent (« The Sharpe ratio is maximized with a period of 8 months, but results are volatile »...).REPRODUIT(écart sous la tolérance, ou expliqué) /ÉCART(issue fille avec diagnostic : bug de portage, donnée manquante, dépendance externe) /NON COMPARABLE(le livre ne donne pas de chiffre).Backtests QC : annoncés sur le dashboard avant lancement, limite de 10 appels/min partagée par la flotte.
Livrable
Un tableau par chapitre dans l'inventaire retenu par le grain de réconciliation (colonnes : exemple, chiffre du livre, conditions du livre, notre chiffre, nos conditions, verdict). Pas de fichier de rapport séparé.
Tranches (une PR par tranche)
06-01 à 06-07 · 06-08 à 06-13 · 06-14 à 06-19 · 07 et 08.