Repository navigation
Fix(qc,#22496): le DM de research_turn_of_month porte des moments bruts et la condition de signe - #23557
Conversation
…ts et la condition de signe Le test de Diebold-Mariano de la cellule 6 estimait la variance sur la serie **centree** (la dispersion instantanee du differentiel) tout en plaquant le numérateur sur l'ecart **moyen**. Deux consequences mesurees : - la variance estimee est celle des *fluctuations*, pas la variance de long-run du differentiel -- qui est persistant (la strategie est a plat les deux tiers du temps, elle perd donc a chaque journee de marche) ; - la significativite obtenue est donc **anti-conservatrice** : l'ecart type du differentiel centre est mecaniquement plus petit que celui du marche. Correction portee de l'organe de la serie (`research_st_reversal.ipynb`, `dm_test_hac`) : variance HAC Newey-West a noyau Bartlett (maxlag 5) sur les **moments bruts**, numerateur `dbar` non re-centre, teste sur le differentiel de **rendement** (strategie - B&H). Le verdict exige en outre le **signe** (`stat > 0` = la strategie est significativement meilleure) : une significativite negative est une defaite significative, pas une victoire. **Mesures fraichees** (re-execution complete : 10 cellules code, 0 erreur, `execution_count` 1->10, donnees au 2026-10-29) : | actif | DM stat | DM p | lecture | |---|---|---|---| | SPY | -1.029 | 0.3036 | non significatif | | QQQ | -1.197 | 0.2313 | non significatif | | EFA | -0.643 | 0.5202 | non significatif | La previous lecture « significativement negative (SPY p=0.012, QQQ p=0.004) » etait un artefact de l'estimateur : le DM **ne conclut rien** sur l'echantillon complet. Le verdict NO BEATS reste, mais il repose desormais sur la **rentabilite nette** (Sharpe TOM negatif contre B&H positif) et sur l'instabilite out-of-sample -- pas sur une significativite que l'instrument ne sait pas produire ici. Prose realignee sur les sorties fraiches : tableau recapitulatif (cellule 15), sensibilite k sur EFA (cellule 13), et premisse de l'Exercice 2 (cellule 19), qui décrivait un test « à un seul lag » -- le test porte maintenant un noyau Bartlett a 5 lags, l'exercice demande de choisir h par la regle de Newey-West. Cellules source modifiees : 12 (code), 13, 15, 19 -- les 19 autres sont identiques a main. Re-execution complete, aucune sortie de cellule editee a la main (C.2). Voir #22496, #22700. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Sur `main`, `research_turn_of_month` et `research_st_reversal` sont deux `orphan_entry` au sens de `check_notebook_nav_chain.py` : aucun carnet ne pointe vers eux. `research_vrp_putwrite` est le dernier maillon de la chaine de la serie -- sa ligne de Navigation le relie a `research_rl_tactical_overlay` en amont, et rien en aval. Cette PR touche `research_turn_of_month`, donc l'organe lui imputait le finding : la ligne de Navigation de `research_vrp_putwrite` porte desormais les deux liens sortants qui donnent enfin a ces deux carnets un lien entrant. **Un seul lien change** (+1 / -1, markdown seul, aucune re-execution due) : les deux cibles existent deja sur `main`, donc aucun lien 404 n'est introduit. `research_month_of_year` -- qui n'existe que sur #22579 -- reste hors de cette ligne : la resolution avec #22579 est une **union** des deux lignes (les trois liens), quelle que soit l'ordre de merge. Preuve : `check_notebook_nav_chain.py --check --diff-base origin/main` -> rc=0. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
Preuves d'exécution et de chaîne de navigation, rejouées sur la tête 1. Chaîne de navigation —
2. Exécution réelle (H.1 / H.3 / C.1) — {
"notebooks": [
{
"path": "MyIA.AI.Notebooks/QuantConnect/research/research_turn_of_month.ipynb",
"kernel": "python3",
"total_code": 10,
"passed": true,
"errors": [],
"forensic_verdict": "EXEC_PROVED"
},
{
"path": "MyIA.AI.Notebooks/QuantConnect/research/research_vrp_putwrite.ipynb",
"kernel": "python3",
"total_code": 6,
"passed": true,
"errors": [],
"forensic_verdict": "EXEC_PROVED"
}
],
"total_notebooks": 2,
"total_code_cells": 16,
"passed": true,
"failed_count": 0
}3. Prose et activité — 4. Périmètre — |
|
Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit |
|
Scope = notebooks CHANGED in this PR, not the whole corpus. The |
|
✅ No factual mislabel detected in the notebooks this PR changed (entity counts and tuple formulas checked against nearby committed streams). Scope = notebooks CHANGED in this PR, not the whole corpus. The |
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
Notebook outputs-required (H.4 schema): PASS (every code cell carries an
|
Notebook PR Validation: PASS
Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns) |
Le lien sortant vers `research_st_reversal` reste porte par `research_risk_parity` -- sa soeur declaree -- conformement au geste du coordinateur (DM du 30/10 17:10Z). La ligne de Navigation de `research_vrp_putwrite` ne porte donc plus que le lien vers `research_turn_of_month` (+1 / -1, markdown seul). Chaque carnet de la chaine garde ainsi un predecesseur unique et reciproque : `vrp_putwrite -> turn_of_month` d'un cote, `risk_parity -> st_reversal` de l'autre. Organe rejoue sur cette tete : `check_notebook_nav_chain.py --check --diff-base origin/main` -> **rc=0** (`OK: 0 NEW finding vs baseline`). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Golden-Set Execution (H.7 P3)✅ 9/9 notebooks passed (certified reproducible)
Pinned lockfile: |
…search_vrp_putwrite Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
Conflit avec Merge de Re-contrôle local |
Path-collision (organ #13359/#13615)Cette PR #23557 (
Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur |
Grain: MED/qc — lane myia-po-2024:CoursIA-2 — prev: DEEP/qc #22579
Correction du test de Diebold-Mariano de
research_turn_of_month.ipynb(carnet mergé par #22496), demandée par le coordinateur dans son DM du 30/10 15:50Z (point 1). Cette PR ne crée aucun carnet : elle corrige un carnet existant, et ferme #22700 (doublon de #22496).Le défaut mesuré
La cellule 6 (
dm_test) estimait la variance sur la série centrée tout en plaçant le numérateur sur l'écart moyen :Deux conséquences, mesurées :
h = 1ne corrigeait rien — la bouclerange(1, 1)est vide.p < 0.05était atteint par construction.Le test comparait bien le différentiel de rendement (et non des pertes quadratiques) — mais l'estimateur de variance en faisait un instrument qui ne pouvait pas ne pas sonner.
Le correctif
Portage de l'organe de la série (
research_st_reversal.ipynb,dm_test_hac) : variance HAC Newey-West, noyau Bartlett (maxlag = 5) sur les moments bruts, numérateurdbarnon re-centré, test toujours posé sur le différentiel de rendement (stratégie − B&H).Ajout de la condition de signe :
stat > 0= la stratégie est significativement meilleure ;stat < 0= elle est significativement pire. Une significativité négative n'est plus lue comme une victoire — l'ancien affichage annonçaitSIGNIFICATIF (p<0.05)quel que soit le signe.Mesures fraîches (re-exécution complète : 10 cellules code, 0 erreur,
execution_count1→10, données au 2026-10-29) :Ce qui change dans la conclusion : le DM ne conclut plus rien sur l'échantillon complet. Le verdict
NO BEATStient — il repose désormais sur la rentabilité nette (Sharpe TOM négatif : −0.03 à −0.07, contre 0.17 à 0.43 pour le B&H) et sur l'instabilité out-of-sample (l'écart change de signe d'un fold à l'autre), et non plus sur une « défaite significative » que l'instrument ne savait pas produire.Diagnostic dérive
Cause : (c) moteur upstream — l'instrument du test lui-même, pas les données ni l'environnement. Le carnet mergé par #22496 portait une valeur de p produite par un estimateur qui sous-estimait la variance de long-run d'un différentiel persistant : la valeur était fausse, et la prose alignée dessus l'était aussi.
Verdict :
CAUSE_FIXED— la cause est dans la source (cellule 6), elle est corrigée, et le carnet est re-exécuté : aucune sortie de cellule n'a été éditée à la main (C.2). La prose (tableau récapitulatif, sensibilitéksur EFA, conclusion) est réalignée sur les sorties fraîches. La fenêtre de données a également glissé d'un jour de bourse (2026-10-29), ce qui explique les écarts de Sharpe minimes (QQQ −0.020 → −0.027).Organe invoqué (règle organ-first)
research/research_st_reversal.ipynb(dm_test_hac, même dossier)ML-Training-Pipeline/scripts/dm_test.pyattend des erreurs de prévision et reproduirait le défaut sur des rendements (loss_fn="mse") → copie déclaréedm_test_hacvers un module commun de la série — hors périmètre ici, signalép < 0.05par construction sur un différentiel persistant ; le corriger rendp = 0.30 / 0.23 / 0.52— il peut ne pas sonnerdm_test.pyet sa suitePortée
research_turn_of_month.ipynb: 4 cellules source modifiées (12 code, 13, 15, 19), les 19 autres identiques àmain; ré-exécution complète, sorties réécrites.research_vrp_putwrite.ipynb: 1 ligne de Navigation (+1 / −1), markdown seul, aucune ré-exécution due (C.3).Le lien de navigation et #22579
research_turn_of_monthest unorphan_entrysurmain(rien ne pointe vers lui). Comme cette PR touche le carnet, l'organe lui imputait le finding. La ligne de Navigation deresearch_vrp_putwriteporte donc le lien>> research_turn_of_month— vers un carnet qui existe déjà surmain, donc sans lien 404.Le lien vers
research_st_reversaln'est pas porté ici : il reste porté parresearch_risk_parity, sa sœur déclarée, conformément au geste du coordinateur (DM du 30/10 17:10Z) — il est livré par #22579. Chaque carnet de la chaîne garde ainsi un prédécesseur unique et réciproque :vrp_putwrite → turn_of_monthd'un côté,risk_parity → st_reversalde l'autre.research_month_of_yearn'existe que sur #22579 : il reste hors de cette ligne. Si #22579 et cette PR se fusionnent, dans un ordre ou dans l'autre, la résolution du conflit sur cette ligne est une union (>> research_turn_of_month+>> research_month_of_year) — déterminée, sans ambiguïté.Preuve :
python scripts/notebook_tools/check_notebook_nav_chain.py --check --diff-base origin/main→ rc=0 (OK: 0 NEW finding vs baseline), tête4290d3f573.Voir #22700, #22496.
🤖 Generated with Claude Code