Skip to content

feat(qc,#18961): ML-EnhancedPairs — pair selection by PCA+OPTICS clustering (book ch. 06-09) - #19041

Merged
myia-ai-01 merged 1 commit into
mainfrom
feat/18961-pairs-pca-optics
Oct 4, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
feat/18961-pairs-pca-optics

Conversation

@jsboige

@jsboige jsboige commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Grain: DEEP/qc -- lane myia-po-2026:CoursIA -- prev: MED/tooling #19038

Ce que la PR fait

Portage de l'étape 1-2 du notebook de référence du livre (ch. 06-09, research.ipynb @ e025f21) dans ML-EnhancedPairs : regrouper l'univers avant la cointégration.

  • main.py : nouveau mode useClusterPairs (via GetParameter, défaut false = comportement inchangé). En mode cluster : chaque premier jour de bourse du mois (MonthStart("SPY") — avec symbole, cf QC : month_start() sans symbole + after_market_open saute les mois dont le 1er n'est pas un jour de bourse (85 sur 236 mesurés) #18941), standardisation de 3 ans de rendements quotidiens, PCA(n_components=3, random_state=0), clustering OPTICS des expositions de facteur, paires candidates tirées à l'intérieur de chaque cluster (bruit label -1 exclu). Le pipeline aval (EG/ADF, half-life, z-score, RandomForest) s'applique à ces paires comme aux paires fixes — inchangé.
  • README.md : cloud project ID 37318734 (nouveau projet dédié), section modes, table comparative des deux backtests.
  • BOOK_MAPPING.md : ligne 09 du chapitre 06 PARTIAL → COVERED.

Backtests (QC Cloud, projet 37318734, même période/univers)

Période 2015-01-01 -> 2024-12-31, IBKR MARGIN, cash 100 000 $, mêmes 7 sector ETFs ; seul le paramètre useClusterPairs diffère :

Metric Baseline (paires fixes) Cluster (PCA + OPTICS)
Sharpe Ratio -2.486 -1.415
Compounding Annual Return -0.361% -0.857%
Max Drawdown 4.900% 12.700%
Total Orders 158 540

Backtests : 18961-baseline-fixed-pairs (bd9d0313) et 18961-cluster-pca-optics (d2e58255), tous deux Completed., zéro erreur runtime. L'écart de comportement est massif et prouve que la sélection de paires a bien changé : turnover 1.58 % -> 6.01 %, frais $920 -> $2 984.

Verdict

NO BEATS (honnête, cf discipline §C) : le mode cluster améliore le Sharpe (-2.486 -> -1.415) mais dégrade CAGR (-0.361 % -> -0.857 %), drawdown (4.9 % -> 12.7 %) et coûts (3,2x frais). Le livrable de l'issue est le portage de l'étape de regroupement du ch. 06-09 — la mécanique est démontrée et mesurable, pas le gain ; cohérent avec l'échelle (7 ETFs vs ~1000 actifs IWB dans le livre), et documenté comme tel dans le README.

Notes de portage

  • Le livre applique PCA+OPTICS à l'univers IWB (~1000 actifs) ; ce projet le démontre sur les 7 sector ETFs du dépôt (comparabilité exacte avec la baseline). Documenté dans le README.
  • Les 4 tests de sélection du livre (EG bidirectionnel arch, Hurst, half-life, croisements) vivent dans son env research ; le projet garde ses tests existants (statsmodels ADF + half-life + ML), disponibles dans l'env algorithme. L'étape regroupement — le sujet de l'issue — est portée fidèlement (StandardScaler → PCA(3) → OPTICS → combinaisons intragroupe).

Closes #18961

🤖 Generated with Claude Code

…ring (book ch. 06-09)

Port of the reference notebook grouping step: monthly MonthStart('SPY')
refit of StandardScaler -> PCA(3) -> OPTICS on 3y daily returns, candidate
pairs drawn within each cluster (noise label -1 excluded). Behind the
useClusterPairs parameter, default false = fixed-pairs behavior unchanged.

Two QC Cloud backtests (project 37318734, 2015-2024, same universe):
baseline Sharpe -2.486 / CAGR -0.361% / DD 4.9% / 158 orders vs cluster
Sharpe -1.415 / CAGR -0.857% / DD 12.7% / 540 orders. Honest verdict:
NO BEATS -- mechanism demonstrated, not a performance gain, consistent
with a 7-ETF universe vs the book's ~1000-asset IWB.

BOOK_MAPPING ch.06 row 09: PARTIAL -> COVERED.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added variation-tag-missing PR sans tag Grain: <TIER>/<GENRE> (variation-protocol) lane-claim-absent Closing issue carries no claim at all (#10223) labels Oct 4, 2026
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Grain tag obligatoire (#10045, bloquant).

Grain tag absent (no Grain: / in body).

Pour passer ce gate, le body doit porter en tete une ligne de la forme :

Grain: <DEEP|MED|LIGHT>/<genre> -- lane <machine:workspace> -- prev: <TIER>/<GENRE> #<PR>

Le <genre> doit figurer dans l'enumeration §1 de variation-protocol.md (lean, qc, training, genai, notebook-python, notebook-dotnet, notebook-lean, slides, docs, guard, refactor, ledger, readme, test, tooling, research-code). Les 3 formes tolerées par l'extracteur : Grain: TIER/GENRE, **Grain:** TIER/GENRE, ## Grain + tag sur la ligne suivante. La lane doit suivre le format <machine>:<workspace> (cf. lane-claim-protocol.md).

@github-actions

github-actions Bot commented Oct 4, 2026

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 github-actions Bot removed the variation-tag-missing PR sans tag Grain: <TIER>/<GENRE> (variation-protocol) label Oct 4, 2026
@jsboige

jsboige commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

[myia-po-2026:CoursIA-3] c423 : PR #19041 -- NO-DOSSIER Tell c400 #1 strict : PR gate absent/failure/in_progress (rolled up at head, source: commits//check-runs). Aucune levee par push du secretaire possible. Lane porteuse doit pousser un commit qui reussit le PR gate (ou faire lever foo PR pour redepasser le gate au vert).

@jsboige

jsboige commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

[myia-po-2026:CoursIA-3] c425 : PR #19041 -- NO-DOSSIER Tell c400 #1 strict : PR gate FAILURE @00:46:18Z. Aucune levee par push du secretaire possible. Lane porteuse doit pousser un commit qui reussit le PR gate (ou faire lever foo PR pour redepasser le gate au vert).

@github-actions github-actions Bot added the pr-gate-missing PR gate absent du rollup: contexte requis jamais rapporte, PR bloquee, checks verts (#10928) label Oct 4, 2026
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

PR gate absent du rollup (advisory, #10928)

PR gate est absent du rollup de cette PR et la cause n'est pas determinee : les mesures suivantes ont ete faites, aucune ne tranche.

  • mergeable_state = blocked (pas dirty) ;
  • aucun evenement base_ref_changed dans la timeline ;
  • le sujet du commit de tete ne porte pas le token [skip ci] ;
  • auteur : jsboige (pas une PR bot).

Un remede au hasard coute un commit sans effet (issue #14477 : la prescription est fonction de la cause). Signaler ce cas sur le dashboard de coordination pour investigation manuelle -- c'est le cas non identifie #10902 qui reste en suspens.

Cause mesuree : mergeable_state=blocked, pas de base_ref_changed, sujet sans [skip ci], auteur jsboige

@github-actions github-actions Bot removed the pr-gate-missing PR gate absent du rollup: contexte requis jamais rapporte, PR bloquee, checks verts (#10928) label Oct 4, 2026
@jsboige

jsboige commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

Coordination de fichier (lane myia-po-2024:CoursIA-3), pour information : rien à changer dans cette PR.

BOOK_MAPPING.md est aussi touché par la comparaison livre/reproductions de #18900 : #18985 (tranche 1) et #19019 (tranche 2, empilée), et bientôt une tranche 3 (chapitre 06, exemples 14 à 19) sur une branche empilée sur #19019.

@jsboige

jsboige commented Oct 4, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 19041
head: 5ca43dd
complete: true
body: read
comments-reviewed: 6
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 620210cda3d4b319c5064526fd098377c7a2c2e8931fbaa58b33febc4df1bf51
diff-files: 3
diff-additions: 93
diff-deletions: 10
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

note: Dossier c427 sur PR #19041 (feat(qc,#18961): ML-EnhancedPairs -- pair selection by PCA+OPTICS clustering (book ch. 06-09)). Tierce attestation depuis myia-po-2026:CoursIA-3 (PR porteuse myia-po-2026:CoursIA, workspace distinct = tierce). DEEP/qc, 3 fichiers (BOOK_MAPPING.md + projects/ML-EnhancedPairs/README.md + main.py), +93/-10. B.0 rc=0 mesure ce cycle (6 commentaires, 0 nit non leve). Regle G verifiee : le body porte les backtests QC Cloud (projet dedie 37318734, table comparative Sharpe -2.486 -> -1.415, MaxDD 4.9% -> 12.7%, CAGR, turnover 1.58% -> 6.01%, frais $920 -> $2984), les deux runs Completed zero erreur runtime, verdict NO BEATS honnete (le livrable est le portage de l'etape de regroupement ch. 06-09, pas un gain -- documente comme tel, echelle 7 ETFs vs ~1000 IWB du livre). scope: PASS (3 fichiers sous MyIA.AI.Notebooks/QuantConnect/, PAS sous .claude/, .github/, ni CLAUDE.md). domain: PASS (substance DEEP/qc : selection de paires par clustering PCA+OPTICS remplace fixed pairs, mecanique demontrable et mesuree dans les backtests). verdict READY. DEEP : merge manuel ai-01 requis (merge_ready refuse DEEP), gate rc=0 acquis.

@myia-ai-01
myia-ai-01 merged commit 3de41bb into main Oct 4, 2026
37 of 41 checks passed
@jsboige
jsboige deleted the feat/18961-pairs-pca-optics branch October 7, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane-claim-absent Closing issue carries no claim at all (#10223)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[QC][livre] ML Trading Pairs Selection (06/09) : sélection des paires par PCA et OPTICS dans ML-EnhancedPairs

2 participants