QuantConnect (QC) - Configuration et règles

Document de reference pour la coordination QC (MCP, orgs, patterns, anti-patterns). Pour les details pédagogiques et le mapping livre Jared, voir la navigation des docs QC ci-dessous.

Backtests obligatoires

Toute modification d’une stratégie QC (main.py, paramètres, périodes) DOIT être validée par un backtest :

  1. create_compile pour vérifier la compilation
  2. create_backtest pour lancer le backtest
  3. read_backtest pour récupérer les métriques (Sharpe, CAGR, MaxDD)
  4. Reporter les résultats dans le message de commit ET sur RooSync

Changer une date ou un paramètre sans backtest = travail invalide.

Mesures post-backtest : gates minimaux (read_backtest post-completion, #14142)

read_backtest appelé pendant qu’un backtest tourne encore rend totalOrders: 0 et des statistics à "-" / "0%" / "$0.00" — un état indiscernable d’un run terminé sans aucun ordre. Incident fondateur (PR #14012, 2026-09-01) : la conclusion « la condition OR n’a JAMAIS été vraie sur 1 461 jours BTC/ETH minute » a été publiée sur un totalOrders=0 lu en cours d’exécution ; la relecture post-completion (commit 71849ef20) a trouvé 487 172 ordres — la conclusion inverse.

Garde obligatoire avant de citer totalOrders ou statistics (invariant cross-lane, tout read_backtest cité dans une PR/issue/JSON la porte) :

result = read_backtest(project_id=..., backtest_id=...)

# GARDE : tant que le backtest n'a pas termine, totalOrders=0 et statistics="-"
# sont des artefacts d'etat, pas des mesures.
assert result["status"] == "Completed.", \
    f"backtest pas termine : status={result['status']!r}"
assert result["progress"] == 1, \
    f"progress != 1 : progress={result['progress']!r}"

# Ici seulement, totalOrders / statistics sont fiables.

Seconde cause de « remplissage nul » à écarter avant toute conclusion stratégique : la devise de compte (#14215). Sur AccountType.CASH, LEAN exige le solde de la devise de cotation ; un compte financé en USD qui négocie des paires USDT (BTCUSDT/ETHUSDT) voit chaque achat rejeté — 0 fill, quelle que soit la condition d’entrée. Le backtest de contrôle B3 (une seule variable changée : set_account_currency("USDT") avant set_cash) est passé de 0 ordre à 917 199 ordres (net −99,88 %) — preuve que le « signal absent » était un compte dans la mauvaise devise. Un verdict « aucun remplissement » sur paires crypto DOIT donc vérifier devise de cotation ↔︎ devise de compte avant d’inférer quoi que ce soit sur la stratégie.

Ces deux gates se vérifient en session via le MCP (snippet ci-dessus à coller dans l’appel) — pas via un script REST direct, interdit par la règle d’accès ci-dessous.

Convention SetEndDate — fenêtre figée vs flottante (mécanisme D2, #9768)

L’absence d’un appel SetEndDate (Python : self.set_end_date(...)) n’est pas toujours un défaut : elle ouvre la fenêtre de backtest à la date courante, ce qui est un comportement légitime selon le type de notebook. La classification (audit #9772 Phase 0) distingue deux régimes :

Régime Environnement SetEndDate attendu Raison
Déploiement (class X(QCAlgorithm), dossier projects/) QC Cloud / Live / Paper Requis (fenêtre figée) Reproductibilité du backtest de production — sans date fixée, le résultat dérive à chaque exécution
Recherche (QuantBook(), dossier ML-Training-Pipeline/) Research env Flottant par design (légitime) Notebooks exploratoires : la fenêtre flottante est une feature, le notebook n’est pas un livrable reproductible

Avant de « corriger » un notebook QC sans SetEndDate : vérifier son régime. Un notebook de recherche QuantBook sans date figée n’est pas un defect D2. Un notebook de déploiement QCAlgorithm (surtout dans projects/) sans SetStartDate/SetEndDate est un defect à figer (exception : Paper Trading explicite, où l’absence de dates = live par construction, ex. QC-Py-27). Le détecteur canonique est scripts/notebook_tools/scan_window_drift.py (#10230/#10627, qui remplace le grep -L set_end_date brut — ce dernier sur-compte d’un ordre de grandeur en mélangeant les deux régimes).

QC Cloud API - Accès via MCP Docker (OBLIGATOIRE)

Méthode d’accès : Utiliser le MCP Docker quantconnect/mcp-server configure dans .mcp.json a la racine du projet.

  • NE PAS utiliser de scripts Python avec l’API REST directe (provoque du rate-limiting et des erreurs d’auth)
  • Le MCP gère l’authentification et le rate-limiting automatiquement
  • Fichier de config : .mcp.json (déjà dans .gitignore, JAMAIS committer)

Configuration .mcp.json

{
  "mcpServers": {
    "qc-mcp": {
      "command": "docker",
      "args": ["run", "-i", "--rm",
        "-e", "QUANTCONNECT_USER_ID",
        "-e", "QUANTCONNECT_API_TOKEN",
        "-e", "QUANTCONNECT_ORGANIZATION_ID",
        "-e", "AGENT_NAME",
        "quantconnect/mcp-server"],
      "env": {
        "QUANTCONNECT_USER_ID": "<voir dashboard RooSync>",
        "QUANTCONNECT_API_TOKEN": "<voir dashboard RooSync>",
        "QUANTCONNECT_ORGANIZATION_ID": "<voir dashboard RooSync>",
        "AGENT_NAME": "claude-code"
      }
    }
  }
}

Alternative légère : qc-mcp-lite (~5k tokens vs ~40k)

Le MCP Docker officiel charge un schema d’outils volumineux (~40k tokens). Pour les workflows de backtest standard, le dépôt fournit un wrapper Python léger scripts/qc-mcp-lite/server.py (~10 outils, schema <5k tokens) qui re-expose l’API QC v2 sans conteneur Docker.

Outils exposes : create_compile, read_compile, create_backtest, read_backtest (Sharpe/CAGR/MaxDD), read_backtest_chart (graphique écrit sur disque : equity, exposition, rotation, graphique personnalisé), list_backtests, list_projects, read_project, read_file, create_file, update_file_contents. Auth = pattern QC v2 (SHA256(token:timestamp) + header Basic userId:hash). Rate limiting 10 appels/min applique in-process (même limite fleet-wide).

Config .mcp.json (remplace l’entrée Docker qc-mcp ; secrets dans .env gitignore, JAMAIS inline) :

{
  "mcpServers": {
    "qc-mcp-lite": {
      "command": "python",
      "args": ["scripts/qc-mcp-lite/server.py"],
      "env": {
        "QC_API_USER_ID": "<voir dashboard RooSync>",
        "QC_API_ACCESS_TOKEN": "<voir dashboard RooSync>"
      }
    }
  }
}

Verification rapide : python -c "from server import list_projects; print(list_projects())" depuis scripts/qc-mcp-lite/. Procédure complete (setup .env, retour au MCP Docker complet) : scripts/qc-mcp-lite/README.md.

Rate limiting strict

MAX 10 appels/minute entre TOUS les agents. Avant de lancer un backtest, poster sur le dashboard. Un seul agent a la fois sur l’API QC.

Pour retrouver les tokens

  • Dashboard workspace CoursIA : section status
  • Messages RooSync : tag quantconnect ou TOKEN
  • En cas de token invalide : demander au coordinateur (ai-01) via RooSync

Troubleshooting hash mismatch (incident 2026-04-05)

~/.claude.json (config globale Claude Code) contient parfois une section mcpServers par workspace qui surcharge .mcp.json local. Un ancien token cache la peut causer Hash doesn't match malgré le bon token dans .mcp.json projet.

Vérifier dans cet ordre :

  1. ~/.claude.json section du workspace (config globale qui peut surcharger)
  2. .mcp.json racine projet (config projet standard)
  3. Token valide sur QC (tester via API directe Python)

Fix recurrent : supprimer l’entrée mcpServers.qc-mcp de ~/.claude.json pour que .mcp.json soit la seule source de vérité.

Organisations QC

QC est multi-tenant via les “organizations”. Le cluster CoursIA utilise plusieurs orgs en parallèle selon le contexte :

Org Tier Usage Backtest API
Research tier dedicated (default user) Research (payant) Deploiements de reference, Binance crypto data subscription, projets de développement Inclus
Partner school Free/sponsored Cours partenaire, masterclass Quant League NON inclus
ECE Free Matériel pédagogique ECE NON inclus

Règle d’or : pour create_backtest programmatique via API, il faut une org avec backtest API incluse (research tier). Les orgs gratuites/éducatives (partenaire, ECE) n’ont PAS l’API backtest — erreur récurrente : tenter create_backtest sur une org partenaire échoue silencieusement ou avec rate-limit. Vérifier l’org cible avant de dispatcher.

Switcher d’org

L’orga par défaut du MCP est définie par QUANTCONNECT_ORGANIZATION_ID dans .mcp.json. Deux options pour changer ponctuellement :

  1. Éditer .mcp.json env var et rebuild le MCP Docker container
  2. Spécifier organizationId explicitement par appel quand le tool MCP l’accepte

Note : read_account retourne TOUJOURS l’orga par défaut du USER_ID (la research tier quand non force par env var).

Énumération des orgs

Il n’existe pas d’endpoint list_organizations. La seule façon : mcp__qc-mcp__list_projects retourne les projets de toutes les orgs dont l’user est membre+ — agréger les organizationId distincts.

Structure QC dans le dépôt

MyIA.AI.Notebooks/QuantConnect/
  Python/           # 27+ notebooks progressifs (QC-Py-01 a QC-Py-Cloud-XX)
  projects/          # ~50 strategies avec main.py + research.ipynb
  shared/            # Librairie utilitaire (backtestlib, indicators, plotting)
  partner-course-quant-trading/  # Cours partenaire : exercices, templates, lean-workspace
  docs/              # Documentation technique (pas de coordination)

Provisionnement reproductible des data LEAN locales

Les data equity/forex locales (<lean-workspace>/data/) sont gitignorées (binaires volumineuses, régénérables — .gitignore ligne 581). L’incident #8734 (leçon C942-L ★★★, découvert c.942) a montré que des zips tronqués (fin 2021-03-31) forward-fillés silencieusement par fillDataForward=True (défaut Lean) invalident les métriques sans aucun signal d’erreur : le notebook affiche une période « 2015 → 2025 » normale mais les ~4-5 dernières années sont une ligne plate. Trois outils forment la chaîne reproductible qui ferme ce défaut :

Outil Rôle Issue
scripts/quantconnect/yfinance_to_lean_daily.py Convertisseur yfinance → zips LEAN daily (OHLC x10000, 00:00, lowercase) #8627
scripts/quantconnect/check_data_freshness.py Détecteur STALE, exit 1 gatable pre-exec #8737
scripts/quantconnect/provision_lean_data.py Provisionneur : regen idempotente one-command d’un univers + gate fraîcheur cablée #8742

Le manifeste versionné lean_universes.manifest.json (committé, texte) pin la spec de chaque univers (tickers + plage + regen_date + issue) — c’est le « quelle data a produit ce Sharpe » vérifiable au merge-gate. Les zips restent gitignorés (machine-local), mais reproductibles en une commande :

python scripts/quantconnect/provision_lean_data.py --universe turn_of_month
# → download yfinance + convert + gate fraîcheur (exit 1 si STALE)

Avant toute re-exec equity/forex quantbook : provisionner l’univers (ou lancer check_data_freshness.py) pour ne pas reposer sur une ligne plate forward-fillée. Le provisionneur est idempotent (un ticker déjà FRESH est skipé sauf --force) et la gate est cablée post-provision (pas un outil optionnel à penser à lancer). Voir #8734, #8737, #8627.

QC Cloud Assistants — méthode privilégiée Quantbook execution

QuantConnect expose 8 assistants intégrés (Conductor, Ideas, Research, Research Validation, Backtest, Paper Testing, Live Monitoring, Mia) accessibles via :

https://www.quantconnect.com/organization/<org_id>/assistants

Le Research Assistant résout le problème “Quantbook execution Windows local impossible” : il execute les cells du notebook sur QC Cloud, itère automatiquement (edit, execute, fix, re-execute) jusqu’au succès, et les tokens consommes sont ceux de QC (pas Anthropic).

Workflow Research Assistant (via Playwright)

  1. Naviguer https://www.quantconnect.com/organization/<org_id>/assistants
  2. Cliquer “New Task” sur Research Assistant
  3. Créer tâche avec prompt + project_id QC Cloud cible
  4. Deployer : l’agent execute les cells du notebook
  5. Lire les résultats dans Tasks > Deployments > Completed

Limites et précautions

  • Validation cluster obligatoire post-deployment : même si Research Assistant claim “Sharpe 3.50”, refaire en local par walk-forward 5-fold + multi-seed >=4 + transaction costs avant tout claim BEATS. Cf .claude/rules/pr-review-discipline.md section C.
  • Coût QC tokens : ne pas lancer 50 deployments en parallèle sans vérifier le burn rate
  • Éviter chevauchement agents sur même deployment (tokens dupliqués) : coordination via dashboard avant lancement
  • Notebook output download : Playwright snapshot ou API download artifact (workflow exact a documenter par usage)

Cas d’usage privilégiés

  • Re-execution Quantbooks audit (cf section validation H.7 de CLAUDE.md)
  • Validation algos QC Cloud avant import dans projects/
  • Debugging multi-aller-retour des strategies en iteration

Architecture composites (AlphaModel + MultiStrategyPCM)

Pattern standardise pour combiner plusieurs strategies dans un même algo QC :

Structure de fichiers (3 fichiers obligatoires)

  • main.py : QCAlgorithm avec set_alpha(CompositeAlphaModel(...)) + set_portfolio_construction(MultiStrategyPCM(...))
  • alpha_models.py : une classe par alpha, chaque avec self.name et source_model=self.name
  • portfolio_construction.py : MultiStrategyPCM avec determine_target_percent (PAS create_targets)

MultiStrategyPCM — design

  • Groupe les insights par source_model
  • Alloue une slice de capital par stratégie via dict alpha_allocations
  • Supporte branches weight-hint ET equal-weight
  • Utilise set_rebalancing_func pour le rebalance timing

AlphaModel — règles

  • DOIT avoir self.name = "StrategyName" dans __init__
  • DOIT passer source_model=self.name a tous les Insight.price()
  • DOIT filtrer par liste explicite de tickers (PAS algorithm.securities.values())
  • DOIT enregistrer les indicateurs dans on_securities_changed uniquement pour les tickers connus
  • NE JAMAIS ajouter SPY comme equity benchmark dans l’univers (cause un leak si on itère securities)

Composites realises — leçons (consolidation, pas snapshot)

Composite Allocation optimum Sharpe Leçon
TrendWeather (TrendStocks + AllWeather) T75 / AW25 1.15+ Sweep monotone : plus de TrendStocks = meilleur Sharpe. ROC63 momentum weighting = gain majeur (0.79 -> 1.13)
FamaFrenchAllWeather FF20 / AW80 ~0.59 Sweep monotone vers AllWeather : FamaFrench n’ajoute pas de diversification
MomentumRegime (SectorMomentum + RegimeSwitching) ABANDONNE max 0.24 Problème “double-defense” : les deux alphas défensifs sur les mêmes périodes
EMATrend (EMA-Cross + TrendStocks) en cours a venir Overlap 5 tech stocks entre strategies (intentionnel)

Règle générale : si le sweep d’allocation montre un comportement monotone (90/10 ou 10/90 gagne), le second alpha n’apporte pas de diversification — vérifier qu’il occupe un quadrant de marche distinct du premier. Confirmation par la “décennie 2015+” : risk-off via TLT détruit la valeur, equity défensifs (XLP/IEF) > bonds long.

Patterns universels (consolidation 30+ iterations strategies)

Patterns confirmés (a ré-utiliser)

  1. Risk-adjusted momentum (return/vol) > raw momentum
  2. Skip-month (Jegadeesh 1990) : exclure le dernier mois — single-asset only
  3. TLT risk-off détruit la valeur sur la décennie 2015+ : XLP/IEF > TLT
  4. Stop-loss -8% a -12% : réduit MaxDD sans tronquer les reversions
  5. ATR sizing contre-productif pour Donchian trend following
  6. Profit target 50% pour options (TastyTrade) + VIX band 15-35
  7. Drift rebalancing 3% > SMA overlay pour portfolios statiques
  8. Vol window 60d > 20d pour covariance min-var
  9. Monthly + regime-change rebal > daily : réduit trades 80%
  10. Trail breakeven 3% > 4% pour BTC daily
  11. SMA50 >> SMA100 pour crypto : SMA100 filtre les bonnes entrées bull
  12. SL 6% minimum sur BTC daily : 5% trop serré
  13. OLS hedge ratio ne sauve pas pairs trading : le problème est les paires elles-mêmes
  14. Fix structural bugs >> academic improvements : leverage/risk mgmt > signal refinement
  15. Diversifier instruments > relaxer seuils : ajouter SPY+QQQ+IWM > baisser RSI threshold
  16. Composite via Algorithm Framework = clean separation (AlphaModel + PCM + source_model)
  17. Biweekly rebalance est l’optimum pour ML (weekly = trop de turnover, monthly = trop lent)
  18. Anti-overfitting (max_depth 5, min_samples 10) critique pour tree models
  19. MLPClassifier/MLPRegressor de sklearn marche bien sur QC Cloud
  20. Selective liquidation réduit le turnover vs full portfolio wipe

Anti-patterns critiques

  • SPY Parking : investir en SPY quand inactif = beta loading déguisé, le Sharpe monte mais l’alpha est nul
  • Backtests courts = overfitting : Trend-Following Sharpe 2.157 (3 mois) -> 0.06 (7 ans)
  • ChatGPT/academic suggestions : 3/4 dégradent sur QC cloud. Ne garder que les fixes structurels
  • yfinance != QC cloud : 6/12 research suggestions dégradent en pratique
  • Crypto strategies pre-2018 unreliable : 2017 bubble distortion
  • MaximumDrawdownPercentPortfolio = JAMAIS sur multi-stock (liquidation simultanée)
  • 1 param a la fois : changer tout ensemble -> regression non-diagnostiquable
  • Raw momentum + min-var : ne pas combiner (double penalisation)
  • Fake ML implementations (hardcoded weights) : pires que real sklearn models
  • SMA100 filter trop restrictif pour mean reversion
  • USD trend filter degrade FX momentum

Leçons techniques QC

  • read_file AVANT update_file_contents : collaboration lock (expire vite)
  • Options : Resolution.MINUTE sinon chain vide
  • 1 seul backtest a la fois sur le node QC
  • algo.rsi(symbol, 14, Resolution.Hour) ne marche pas dans OnSecuritiesChanged -> utiliser register_indicator
  • class X(QCAlgorithm, Mixin) interdit (Python/CLR multiple inheritance)
  • Binance CASH : set_account_currency("USDT") + set_cash(10000)
  • Binance fees : preleve en BTC -> utiliser portfolio[sym].quantity pas order qty
  • QC API auth : SHA256(token:timestamp) as hash, header Timestamp, Basic auth
  • Chart API : data seulement pour backtests récents (~quelques heures)

Historique training & checkpoints (preservation)

Toute l’historique des trainings ML/QC est préservée dans le dépôt et accessible a tous les agents, PAS dans des memos chronologiques :

Source Contenu
MyIA.AI.Notebooks/QuantConnect/ML-Training-Pipeline/REGISTRY.md Registry 70+ checkpoints, BEATS/FAIL/MIXED par symbole, stages -1/0/1/2, Anti-Bias audit
MyIA.AI.Notebooks/QuantConnect/ML-Training-Pipeline/CURRICULUM.md Plan global ML curriculum
MyIA.AI.Notebooks/QuantConnect/ML-Training-Pipeline/docs/M1..M17 + Stage2 + Stage7 + RECAP_KEEPERS_V2 35 fichiers de notes méthodologiques par iteration
MyIA.AI.Notebooks/QuantConnect/ML-Training-Pipeline/docs/Curriculum_V2_Meta_Analysis.md Meta-analyse curriculum V2
MyIA.AI.Notebooks/QuantConnect/ML-Training-Pipeline/scripts/results/*/checkpoint.jsonl + train.log 27 runs avec état par combo et logs unbuffered (local, gitignored)
QC Cloud (MCP list_projects + list_backtests + read_backtest) Sharpe/CAGR/MaxDD live de chaque iteration
docs/archive/ml-trading-state.md Leçons consolidées (vol vs direction, parcimonie, transaction costs, recommandations datasets)

Règle : pas de duplication. Si tu veux ajouter une note sur une iteration training, vise ML-Training-Pipeline/docs/M<N>_*.md ou QC Cloud notes, pas un memo coordinateur. Pour une leçon trans-iteration : docs/archive/ml-trading-state.md.

Livre de reference

Hands-On AI Trading de Jared Broad — https://www.hands-on-ai-trading.com/

  • Repo exemples : https://github.com/QuantConnect/HandsOnAITradingBook
  • 22 exemples : Ch06 (19 strategies ML), Ch07 (1 RL hedging options), Ch08 (2 portfolio)
  • Issues associées : #107 (mapping), #143 (implementation ML)

Le livre couvre les patterns ML actuels (RF, XGBoost, LSTM, CNN temporel, Chronos foundation models, RL hedging) avec exemples QC Cloud directement importables. Cf MyIA.AI.Notebooks/QuantConnect/projects/ pour les imports realises.

Reference QC partnership

QuantConnect (Jared Broad, CEO) sponsorise l’usage éducatif via le code promo education2025 (annule 100% du coût des seats Trading Firm). Architecture éducative recommandée :

  • Org sponsorisée = espace commun (algos d’exemple, evaluation collective, masterclass), avec coupon
  • Comptes perso FREE pour les étudiants = suffisants pour term projects sur leur poste
  • Coût minimum par org éducative avec coupon : 14$/mois (1 noeud B2-8 backtest)

Mécanique du coupon : cart vide non accepte pour checkout, minimum 1 noeud compute requis. Rate limit API : 15 min de cooldown si on clique trop vite sur +/-. Le coupon couvre les seats Trading Firm (unlimited members), pas le compute.

Hands-On AI Trading book : recommandation officielle de Jared pour le cursus (cf section “Livre de reference”).

Retour au sommet