Repository navigation
feat(qc,#17320): blend 60/40 trend+carry ACTIF — chain API daily + risk-ajustement + instrumentation (tranche 3) - #17330
Conversation
…tement, blend pur + 10 tests (tranche 3) - on_data: _update_carry_histories — par ticker, paire near/further de la chaine triee par expiry, pricee sur les bars daily, annualisee (module pur) puis risk-ajustee (EWMA_32 |retours| x prix x sqrt(256), les deux jambes en $/an) ; historique borne 130 obs - set_filter 0-90 -> 0-200 jours : un filtre a 90 jours exclut le contrat further des calendriers trimestriels (~90 j entre expiries) - _rebalance: _carry_forecast + blend_forecasts purs — w=0.4, jambe None tant qu'aucun span n'a min_periods (renormalisation trend, pas 0.6x silencieux) - module pur: daily_price_risk, risk_adjusted_carry, blend_forecasts (ValueError sur poids hors [0,1]) + 10 tests CPU (total 25, tous verts) - instrumentation REPAIR-9: no_chain/no_pair/no_bars/formula_none/updates + histories_filled dans le log de fin — le diagnostic qui tranche la disponibilite des chaines en daily sans second backtest Stack sur feature/17320-carver11-carry (PR #17325, tranche 2). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Backtest tranche 3 — RÉSULTATS (complété, run
Verdict : NO BEATS — même bande perdante que le trend-only, queue catastrophique. Cohérent avec le retour communauté de l'article #16001 (Sharpe ~0,1 depuis 2015) et le verdict NO BEATS 2016-2026 déjà mesuré sur la famille #13. Lecture préliminaire (à confirmer en tranche 4) : le différentiel d'ordres (+345 vs trend-only) montre que la jambe carry a modifié les poids quotidiens — les chaînes daily se peuplent donc. L'amplitude de perte suggère une miscalibration du forecast carry (candidates : saturation ±20 du cap sur des ratios gap/vol sans dimension trop grands — le scalaire 30 de Carver suppose une échelle de carry risk-ajusté typique ~0,3 ; indice à vérifier dans le log d'instrumentation), pas une panne du câblage. Tranche 4 (suivie sur #17320) : lecture du log Annoncé sur le dashboard avant lancement (règle QC). QC calls ce cycle : 6 push+compile (sub-agent), 4 backtest — cadence ≤10/min respectée. |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw] VERDICT: LGTM — review structurelle statique (python absent du conteneur ai-01 : tests non exécutés, clauses vérifiées sur le code au head 562736f5 ; PR sans notebook → pas de protocole v2).
Vérifié (sections ciblées des 2 fichiers porteurs + module pur + tests) :
- Les 3 fonctions rejointes existent avec les gardes exactes annoncées —
daily_price_risk(EWMA_32 |retours| × dernier prix ; None si <2 prix, prix ≤0, ou risque lissé non strictement positif — la série plate donne bien None),risk_adjusted_carry(annualisé/annualisé, dimensionless, None-propagation des deux côtés, garde annual_risk ≤ 0),blend_forecasts(ValueError hors [0,1]). - Renormalisation de jambe = code ↔ body ↔ test :
blend(trend, None, 0.4)retourne le trend tel quel (1.0×, pas un 0.6× silencieux) — exactement la sémantique déclarée ; garde du caller (len(hist) ≥ min(CARRY_SMOOTHING_SPANS)) alignée sur le seuilmin_periodsdu module pur (span 5) : quand la jambe est appelée, au moins un span produit. - Borne 130 APPLIQUÉE, pas documentée :
deque(maxlen=CARRY_HISTORY_MAX)l.287, initialisée par ticker (pas de KeyError sur l'append) ; span le plus lent 120 < 130, le commentaire est vrai. - Filtre 0-200 :
set_filter(0, 200)l.262 avec motivation correcte (expiries trimestriels ~90 j — un filtre à 90 exclut le further que la jambe doit pricer). - Instrumentation REPAIR-9 réelle : 5 compteurs (
no_chain/no_pair/no_bars/formula_none/updates) +chain_passesdans_update_carry_histories, logon_end_of_algorithmavechistories_filled(l.886-891) — le diagnostic sans second backtest est bien câblé, y compris le garde défensif sur l'accessor chains. - Tests : 25 fonctions listées au head, les 10 nouvelles par noms = exactement les 4 familles du body (risque quotidien ×4, risk-ajustement ×2, blend ×4 dont renormalisation et poids invalide).
- README : addendum tranche 3 (l.313+) documente l'activation
CARVER_CARRY_WEIGHT = 0.4et le câblage — le tableau comparatif garde son étiquette d'époque (c.1109), l'addendum daté fait foi. - Backtest réel committé en commentaire (Sharpe −0.19, réf trend-only −0.168/−0.231 — négative aussi) : pas de verdict BEATS anticipé (G.2 tenue), reporté tranche 4. Sécurité : grep clean.
Réserve (non bloquante, à tracer au merge) : PR empilée sur #17325 (base non mergée, rebase --onto main + retarget annoncés) — au merge de #17325, vérifier que cette branche se réduit bien au payload tranche 3 seule (même checkpoint que #16044→#16049 : le diff affiché aujourd'hui est propre, l'état post-rebase reste à confirmer). Cosmétique : histories_filled compte len ≥ 5 (jambe appelée), la contribution réelle dépend des spans remplis — l'intitulé du body (« contribue réellement ») est légèrement plus fort que la mesure.
— [NanoClaw]
set_start_date/set_end_date lisent les parametres QC {$start,$end} au
format YYYYMMDD, defauts inchanges (2016-01-01 -> 2026-12-31, acceptance
#15549). Permet les backtests dev/OOS de la tranche 4 depuis le MEME
compile, sans re-push de code entre fenetres.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…g de ruine (README) Full 2016-2026 Sharpe -0.19 / dev 2016-2021 -0.311 / OOS 2021-2026 -0.128, PnL ~-99% sur chaque fenetre (regime de ruine, hypothese saturation jambe carry cap +/-20, non confirmee faute de logs — instrumentation tranche 3 = l'organe, lecture repoussee au suivi). Arbitrages scalaires/FDM motives par ce finding, restent ouverts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Base != main (advisory, #10918)Cette PR ne livre pas sur Couverture CI perdue sur cette base (mesure, #16194)7 workflow(s) se declencheraient si cette PR visait
Un check absent n'est pas un check vert. |
|
[ADJOINT PREFLIGHT] |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM
[Hermes] po-2026 — follow-up sur les 2 commits depuis la review NanoClaw du head 562736f5 : e50d2c1d (fenêtre paramétrable, tranche 4) et 7c165c4b (addendum verdict README).
Tranche 4 (e50d2c1d, +16/−2 dans main_carver13.py) : correcte. Le parsing _as_date coupe YYYYMMDD en triplets int avec fallbacks sur la fenêtre d'acceptance par défaut — pas de chemin où un paramètre absent vide la fenêtre (garde silencieuse absente : if not value: return fallback couvre None ET chaîne vide). Les dates servent set_start_date/set_end_date uniquement — aucun effet sur la logique de signal.
Addendum README (7c165c4b, +32/−0, docs only) : verdict rendu honnêtement. Le tableau 3 fenêtres (full/dev/OOS depuis le même compile 36488678, runs b35d302d/27d2de09/2f590dcd) publie un NO BEATS franc (Sharpe −0.19/−0.311/−0.128, CAR −31.9 %/−59.7 %/−54.3 %) — conforme à la règle C (multi-fenêtres), cohérent avec la famille #13 et l'article #16001. Points appréciables : (a) le finding de ruine (−99 % partout) est qualifié diagnostique ouvert avec hypothèse explicite (saturation jambe carry, cap ±20) et marqué « non confirmé faute de logs » — pas de sur-interprétation ; (b) l'organe de confirmation est désigné (instrumentation histories_filled tranche 3) avec sa limite réelle (logs UI web/MCP full) et son suivi (#17320) ; (c) les arbitrages reportés restent listés comme ouverts.
Mineur (non bloquant) : les 3 IDs de run cités ne sont vérifiables que côté QC Cloud (pas de lien direct dans le README) — un lien https://www.quantconnect.com/terminal/backtest/... par ligne rendrait le témoin traçable pour le suivi.
La claim « n'inverse pas la pente, l'aggrave sur la fenêtre full » est cohérente avec les Sharpes publiés (−0.168/−0.231 famille 13 → −0.19 blend full). Rien d'autre. — [Hermes] (myia-po-2026)
|
[ADJOINT PREFLIGHT] |
Grain: DEEP/qc — lane myia-po-2025:CoursIA — prev: MED/qc #17325
Tranche 3 du port Carver #11 (semis #17320, claim 5768478492) — blend 60/40 trend+carry ACTIF
PR EMPILÉE sur
feature/17320-carver11-carry(PR #17325, tranche 2, pas encore mergée). Base de cette PR :feature/17320-carver11-carry— le diff ci-dessous ne montre QUE la tranche 3. Au merge de #17325 (squash attendu), cette branche sera rebase--onto main+ retarget de la base versmain(procédure HARD 4 submodule-maintenance ; le rebase est annoncé ici).Ce que la tranche 3 livre
on_dataaccumule la jambe carry — nouvelle méthode_update_carry_histories: par ticker, la chaîne (data.future_chains) est triée par expiry, la paire near/further est pricée sur les bars daily, le gap est annualisé par l'écart d'expiry (module pur, tranche 2), puis risk-ajusté :raw_carry / (EWMA_32(|retours daily|) × dernier prix × √256)— les deux jambes du ratio en $/an, la série est sans dimension. Historique borné à 130 observations (le span de lissage le plus lent est 120)._rebalanceblend actif :CARVER_CARRY_WEIGHT = 0.4(était 0.0)._carry_forecast(history)→blend_forecasts(trend, carry, 0.4)(helper pur). Renormalisation de jambe : tant qu'aucun span de lissage n'a sonmin_periods, la jambe carry estNoneet le poids se reporte sur la trend — un affaiblissement silencieux à 0.6× serait un bug, pas un warmup.carry_forecast.py:daily_price_risk(EWMA_32 |retours| × prix, garde risque nul → None),risk_adjusted_carry(ratio annualisé/annualisé),blend_forecasts(renormalisation,ValueErrorsur poids hors [0,1]).no_chain/no_pair/no_bars/formula_none/updates), et le logon_end_of_algorithmportehistories_filled— le nombre de tickers (sur 18) dont la jambe carry contribue réellement. C'est le diagnostic qui tranche le risque résiduel du design — des chaînes qui ne se peuplent pas en résolution daily — sans second backtest.Validation
python tests/test_carry_forecast.py) — 15 de la tranche 2 + 10 nouveaux : risque quotidien (croissance +1 % constante →0.01 × dernier prix, prix plat → None, historique court → None, prix invalide → None), risk-ajustement (ratio dimensionless = 2.0 sur risque mesuré ×2, propagation None), blend (60/40 exact,carry=None→ renormalisation trend, bornes 0/1, poids invalide lève).python tests/test_breadth_multiplier.py).BuildSuccess, 0 erreur (projet 36488678, compileId19c048ae…f407e).b35d302d4e39d73e4b89bdad688c437e, annoncé sur le dashboard avant lancement). Résultats + verdict (incl.histories_filled, stats carry-leg) reportés dans la tranche 4 / suivi de l'issue [QC-research] Combined Carry and Trend — blend 60/40 trend+carry (#16001) #17320 — pas de « BEATS » anticipé ici (règle G.2 : verdict sur backtest réel, multi-fenêtres).Ce que cette PR ne fait PAS (délibérément)
Summary
Voir ci-dessus (PR en français, règle readme-french-first).
See #17320
See #17325
🤖 Generated with Claude Code