Skip to content

fix(qc,#20910): ETF-Pairs seuil de demie-vie 50 -> 90 j (option 2) + re-execution LEAN - #21713

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/20910-etf-pairs-half-life
Oct 24, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/20910-etf-pairs-half-life

Conversation

@jsboige

@jsboige jsboige commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Grain: DEEP/qc — lane myia-po-2023:CoursIA-2 — prev: DEEP/genai #21675

Part of #20355

Quoi

L'issue #20910 constatait que la sélection de cointégration du quantbook ETF-Pairs ne retenait aucune paire sur l'univers à 10 tickers (seule candidate : AAPL-SPY, p-value ≈ 0.04, demi-vie ≈ 82 j, écartée par le filtre « demi-vie < 50 jours »). L'issue portait trois options à arbitrer ; cette PR retient l'option 2 : assouplir le filtre de demi-vie de 50 à 90 jours et le documenter — le seuil de 50 jours est une convention de rapidité de mean-reversion, pas une contrainte du modèle. Le test d'Engle-Granger lui-même n'est pas touché.

Changements

Re-exécution réelle (pas de sortie fabriquée)

Kernel LEAN Research local — lean research en conteneur Docker quantconnect/research via l'organe scripts/notebook_tools/qc_quantbook_execute.py (pré-vol fraîcheur #8734 OK). Données daily au format LEAN régénérées par scripts/quantconnect/yfinance_to_lean_daily.py pour les 10 titres (1960 bars 2019 → 2026-10-19 chacun) ; fenêtre du carnet 2020-01-02 → 2025-12-31 (1508 jours). 10/10 cellules code exécutées, 0 erreur, execution_count 1–10 réels.

Mesures (fenêtre 2020 → 2025, 1508 jours)

Avant (main) Après (cette PR)
Paires retenues 0 1 — AAPL-SPY (p-value 0.0427, hr 0.369, HL 82.8 j, corr 0.94)
Trades 0 40
Sharpe (défaut z 1.5 / lb 50) 0.000 −3.952
CAGR / MaxDD / Vol (défaut) 0.0% / 0.0% / 0.0% −0.1% / −2.2% / 0.8%
Meilleur lookback — 100 j (Sharpe −3.557)
SPY B&H (réf. §7) CAGR 15.9%, Sharpe 0.747 CAGR 15.6%, Sharpe 0.727, MaxDD −25.4%

Verdict déclaré : la sélection est non vide et la stratégie est mesurée — et elle ne bat pas la référence SPY (edge négatif, volatilité 0.8 % : capital à peine engagé, sizing 5 %/position). Le verdict est donc un résultat de marché négatif, pas un état de sélection vide. La prose du carnet le dit explicitement (section 9), y compris que l'univers hétérogène reste la cause structurelle et que l'option 1 (univers homogène) reste la piste prometteuse — l'option 2 documente le plafond atteignable.

Acceptance #20910

  • Une des trois options est choisie et écrite dans le carnet (option 2, cellules 7–8 + 9).
  • Le carnet est re-exécute et ses sorties committent correspondent à la prose (C.2 / C.4) — re-execution LEAN réelle ci-dessus, prose alignée cellule par cellule.
  • (option 3 non retenue — non applicable)

Closes #20910 (les trois critères d'acceptance sont couverts).

🤖 Generated with Claude Code

…re-execution LEAN

La selection de cointegration ne retenait aucune paire sur l'univers a 10
tickers (seule candidate: AAPL-SPY, p-value ~0.04, demie-vie ~82 j). Le seuil
de 50 jours est une convention, pas une contrainte du modele: le relâcher a
90 jours (option 2 arbitree dans l'issue) rend la selection non vide sans
toucher au test d'Engle-Granger.

Re-execution reelle en kernel LEAN Research local (conteneur
quantconnect/research, donnees daily LEAN fraiches 2019 -> 2026-10-19 via
yfinance_to_lean_daily.py, fenetre 2020-01-02 -> 2025-12-31, 1508 jours):
1 paire retenue (AAPL-SPY, p-value 0.0427, hr 0.369, HL 82.8 j), 40 trades,
Sharpe -3.952 / CAGR -0.1% / MaxDD -2.2% par defaut — meilleur lookback 100j
(Sharpe -3.557). Face a SPY B&H (CAGR 15.6%, Sharpe 0.727) la strategie ne
demontrE aucun avantage: le verdict est maintenant mesure (resultat de
marche negatif), plus un etat de selection vide. Prose des sections 2, 3 et
9 alignee sur les mesures fraiches; PNG regeneres.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Prose/output review needed in the notebooks this PR changed: a numeric value is not anchored, an explicit relation is contradicted, or its evidence is missing. These cases remain distinct in the JSON report; the signal is advisory, NOT a merge gate.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Stale-claim review needed: a markdown cell claims a measurement value that appears in NO committed output of the notebook. Advisory, NOT a merge gate — triage against the JSON artifact.

Scope = notebooks CHANGED in this PR, not the whole corpus. The stale-claim-report run artifact holds the structured JSON.
Rationale: the sibling detector above only compares a claim to the outputs of the cells that PRECEDE it; a claim written in a cell that precedes its code (App-5-Timetabling c.2/c.4) is invisible to it, and a value imported from a twin notebook is never produced locally. See python scripts/check_stale_claims.py --help.

@github-actions

Copy link
Copy Markdown
Contributor

✅ 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 factual-mislabel-report run artifact holds the structured JSON.
Rationale: pure ABSENCE of a claimed value is the sibling stale-claim detector's job; this one only reports CONTRADICTIONS between an adjacent code cell's stream and the markdown that describes it. See python scripts/check_factual_mislabel.py --help.

@github-actions

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@github-actions

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 9/9 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 10.8s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 7.0s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 6.9s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 6.3s
Search-01-StateSpace.ipynb ✅ SUCCESS 5.6s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 3.4s
RL-04-Bandits-Manchots-Python.ipynb ✅ SUCCESS 29.5s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 4.5s
GameTheory-13d-Optimistic-CFR-Python.ipynb ✅ SUCCESS 19.3s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 10
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@github-actions

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] review — APPROVE

Option 2 de #20910 livrée et intégralement re-dérivée depuis les sorties committées.

  • Changement exact : cellule 7 hl < 50 → hl < 90 avec commentaire citant l'arbitrage ; test d'Engle-Granger intact. Base : 0 paire retenue (sortie base vérifiée). Head : 1 paire AAPL-SPY (p 0.0427, hr 0.369, HL 82.8 j, corr 0.94) imprimée dans la sortie committée de la cellule 7.
  • Re-exécution réelle : 10/10 cellules code, execution_count 1–10 réels, sorties fraîches sur les 8 cellules non-touchées côté source (5→20) — cohérent avec un vrai run LEAN, pas une greffe. PNG : 2 images régénérées (md5 différents base↔head ; 1 image nouvelle en cell 16), PNG latéraux livrés dans la PR.
  • Chaque chiffre de la prose re-ancré dans le concat des outputs : 0.0427/0.369/82.8/0.94 (cell 7) ✓ ; Sharpe −3.952, CAGR −0.1 %, MaxDD −2.2 %, Vol 0.8 %, 40 trades (cell 10) ✓ ; sweep z-entry 1.5σ meilleur (cell 12) ✓ ; sweep lookback 100j → Sharpe −3.557 (cell 14) ✓ ; comparaison SPY B&H 15.6 %/0.727/−25.4 % (cell 18) ✓. La ligne « CAGR +0.2 % » de la table « Meilleure config » (cell 21) est le CAGR du lookback 100j — ancré dans la sortie du sweep (cell 14), composition correcte des deux sweep : la table croise honnêtement les deux meilleurs configs, chacune mesurée.
  • Verdict honnête : « mesuré, pas vide » + résultat de marché négatif documenté (« ne pas déployer en l'état »), limites de méthode explicitées (in-sample, pas de coûts de transaction), l'option 1 (univers homogène) citée comme piste restante. La prose ne maquille pas le plafond de l'option 2.
  • Cellules 8/9/21 : prose alignée sur le rendu réel (l'ancienne « note de lecture » à sélection vide est remplacée). Cellules 1–6 inchangées.
  • CI au head au moment de la review : PR gate seul cancellé (famine CI Linux #21558, classe infra).

Acceptance #20910 couverte : option choisie et écrite au carnet, re-exécution réelle, prose alignée. Closes #20910 légitime.

@myia-ai-01 myia-ai-01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revue du coordinateur a la tete exacte, sans dossier [ADJOINT PREFLIGHT] a cette tete.

Verifie a f7ab9a4fb4 :

  • B.0 (check_unaddressed_nits.py 21713) : rc=0, aucune remarque non levee ;
  • checks : latest-wins-green (lecture commits/<head>/check-runs, dernier started_at par nom) ;
  • mergeStateStatus: CLEAN ;
  • diff conforme au titre : 3 fichiers, +175/-103.

Approbation du coordinateur en lieu et place du dossier manquant ; le bot avait deja approuve a cette meme tete.

@myia-ai-01 myia-ai-01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE coordinateur (myia-ai-01) a f7ab9a4, sur dossier de lecture delegue (procedure 9 points : perimetre, preuves, hygiene notebook, chiffres ancres, prose, references, reserves) puis controle par sondage.

Objet : Relache le filtre de demi-vie du quantbook ETF-Pairs de 50 a 90 jours (option 2 de #20910), re-execute sous LEAN Research, et reecrit les sections 2/3/9 sur les mesures fraiches (1 paire AAPL-SPY, 40 trades, Sharpe -3.952).

Tete, B.0 rc=0 et absence de fichier de harnais reverifies au moment de l'approbation.

@myia-ai-01
myia-ai-01 merged commit 98d41b0 into main Oct 24, 2026
93 of 94 checks passed
myia-ai-01 pushed a commit that referenced this pull request Oct 24, 2026
…e (critere 4) (#22345)

* Fix(qc,#20355): ETF-Pairs -- les deux balayages recoivent leur lecture (critere 4)

Les criteres 1, 2, 3 et 5 de l'issue ont ete livres par #20447 (comptabilite
cash normalisee) puis #21713 (seuil de demi-vie 90 j + re-execution LEAN) :
le cash est debite a l'entree, les sorties commitees sont plausibles
(Sharpe -3.952, CAGR -0.1 %, vol 0.8 %), et les deux « meilleur » ne
reposent plus sur un max() de valeurs egales.

Le critere 4 restait ouvert : aucune cellule d'interpretation ne suivait les
deux tableaux de balayage. Ajout de deux cellules markdown, apres le tableau
Z-Entry et apres le tableau Lookback, qui lisent les valeurs reellement
imprimees par les cellules de balayage : les trois seuils sont indiscernables
(0,26 de Sharpe d'ecart, et le seul signal monotone est le drawdown), et le
lookback ne degage aucun optimum (forme en V, sans tendance).

Aucun code touche : 46 lignes ajoutees, 0 supprimee. Le changement est
markdown seul, donc la re-execution C.2 acquise a #21713 reste valable.

See #20355

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(qc,#20355): review Hermes -- lecture lookback deplacee apres sa table, CAGR reformules

(A) La lecture du balayage lookback etait inseree AVANT la cellule du
tableau qu'elle lit (gate #17040) -- deplacee apres (c15 -> c16).
(B) « les trois configurations perdent » etait faux au sens monetaire :
la sortie committee porte CAGR +0,1 % (20j) / -0,1 % (50j) / +0,2 % (100j).
Reformule : « aucune ne batte les 3 % du taux sans risque (deux CAGR
sont meme legerement positifs) ».
(obs) « perte reelle de 0,1 % du capital » precise « par an (CAGR) ».

Markdown-only, 0 cellule code touchee (verifie cellule par cellule vs
HEAD), aucune re-execution due (C.2 exception markdown).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Quantbook ETF-Pairs : la selection de cointegration ne retient aucune paire sur l'univers a 10 tickers

3 participants