Contenu éducatif uniquement — pas un conseil financier. Le trading comporte un risque substantiel de perte.
Référence avancée · Bibliothèques et modèles ML/IA · Trading algorithmique
Guide avancé de trading par IA : La référence complète des bibliothèques, modèles et frameworks de ML pour quants
Une carte de niveau praticien de l'écosystème open source et Hugging Face pour le trading systématique — gradient boosting, architectures profondes de séries temporelles, modèles de fondation zero-shot, TALN financier, apprentissage par renforcement, la boîte à outils de validation de López de Prado, moteurs de backtesting et MLOps — avec des notes d'architecture, des licences, des benchmarks et du code pour chacun.
Essai gratuit de 5 jours
Sans carte bancaire
Transactions illimitées
Exécution instantanée
👋
Nouveau dans le trading par IA/ML ? Cette page suppose une aisance en ML et Python et fait l'impasse sur les fondamentaux. Si vous préférez commencer par la version en langage clair — ce qu'est le méta-étiquetage, comment le pipeline s'assemble, comment automatiser l'exécution avec PickMyTrade — lisez d'abord le Guide de trading par IA pour débutants puis revenez ici.
01
ML classique / tabulaire — les chevaux de bataille
Les arbres de décision à gradient boosting (GBDT) — et non les réseaux profonds — sont la famille de modèles par défaut pour chaque tâche tabulaire de classification/régression de ce pipeline : méta-étiquetage, caractéristiques de régime, scoring de facteurs. Une comparaison de 2024 largement citée, portant sur plus de 100 à 300 benchmarks tabulaires, a constaté que les GBDT égalent ou surpassent le deep learning sur données tabulaires avec bien moins de réglages (arXiv:2402.03970). Les données financières tabulaires sont exactement le régime où cela tient le plus fort : faible rapport signal/bruit, caractéristiques mixtes continues/catégorielles/creuses, forte non-stationnarité et petites tailles d'échantillon effectives — des conditions où la flexibilité des réseaux profonds achète surtout de la variance, pas du signal.
Pourquoi les GBDT dominent les données financières tabulaires
Compromis biais-variance. Avec quelques milliers de lignes effectives (pondérées par l'unicité) et un signal faible et bruité, le faible biais d'un réseau à haute capacité se paie d'un coût en variance que vous ne pouvez pas vous permettre. Des arbres peu profonds à forte régularisation (nombre de feuilles, min-data-in-leaf, bagging) se situent bien mieux sur ce compromis.
Caractéristiques mixtes et creuses nativement. Les arbres découpent sur les valeurs brutes des caractéristiques — pas de mise à l'échelle, pas de stratégie d'imputation, pas de table d'embeddings pour les catégorielles rarement renseignées (secteur, place, indicateur de proximité d'échéance). L'effort d'ingénierie des caractéristiques va au signal, pas à la tuyauterie de prétraitement.
Les contraintes monotones encodent directement des a priori financiers. LightGBM/XGBoost/CatBoost prennent tous en charge monotone_constraints : p. ex. forcer P(gain) à être non décroissante en force de tendance et non croissante en volatilité réalisée. Cela régularise vers des modèles sensés au regard du domaine et est indisponible, ou bien plus laborieux, dans un MLP standard.
Valeurs manquantes et non-stationnarité. Les arbres acheminent nativement les valeurs manquantes (pas d'imputation sujette aux fuites ajustée sur l'ensemble du jeu de données), et des arbres peu profonds fréquemment réentraînés s'adaptent plus vite aux changements de régime qu'un grand réseau qui a besoin de nombreuses époques pour désapprendre des schémas obsolètes.
Library
License
Maturity / stars*
Categorical handling
Speed
Best fit here
LightGBM
MIT
Mature · moved microsoft/LightGBM → lightgbm-org/LightGBM Mar 2026, still MIT
Native (histogram-based, leaf-wise growth)
Fastest of the three on CPU, large-N
Default meta-label / primary classifier
XGBoost
Apache-2.0
Mature, dmlc-maintained, huge ecosystem
Needs one-hot or target-encoding (or enable_categorical)
Slightly slower than LightGBM on CPU histogram mode
When you have many high-cardinality categoricals (symbol, sector, exchange)
scikit-learn
BSD-3-Clause
Foundational, ~19+ years
Via ColumnTransformer/OneHotEncoder
N/A — utility layer
CV splitters, metrics, pipelines, calibration, GMM — the glue, not the model
*Les nombres d'étoiles sont indicatifs, vérifiés mi-2026 — à traiter comme un « ordre de grandeur », pas comme des chiffres exacts.
LightGBM
MIT
Mécanisme : gradient boosting basé sur histogrammes avec croissance de l'arbre par feuille (best-first) plutôt que par niveau — converge plus vite et généralement vers une perte plus faible que la croissance par niveau pour un budget de feuilles donné, au prix d'une plus grande propension au surapprentissage sur petites données (à contrôler via num_leaves/min_data_in_leaf).
Quand l'utiliser : choix par défaut pour le filtre de méta-étiquette et toute classification/régression tabulaire de cette stack — entraînement CPU le plus rapide, acheminement natif des valeurs manquantes, contraintes monotones natives. Quand ne pas : échantillons très petits (< ~500 lignes) où la croissance par feuille surapprend vite ; préférez alors XGBoost par niveau ou une simple régression logistique.
Python · Entraînement de méta-étiquette LightGBM sur des étiquettes de triple barrière
import lightgbm as lgb
from sklearn.model_selection import train_test_split
# X: one row per primary-strategy signal date. Columns e.g.
# log_ret_5d, log_ret_20d, realized_vol_20d, atr_14, frac_diff_price,
# ema_slope, rsi_14, bb_pctb, obv_z, dist_200ma
# y: triple-barrier label from mlfinpy -> 1 = profit barrier hit first, 0 = stop/time first
# w: sample weight from mlfinpy uniqueness/time-decay (NEVER plain 1s -- labels overlap)
X, y, w = features_df[feature_cols], labels_df["tb_label"], labels_df["sample_weight"]
X_train, X_val, y_train, y_val, w_train, w_val = train_test_split(
X, y, w, test_size=0.2, shuffle=False # never shuffle time series
)
params = {
"objective": "binary", "metric": "auc",
"num_leaves": 31, "learning_rate": 0.03,
"feature_fraction": 0.7, "bagging_fraction": 0.7, "bagging_freq": 5,
"min_data_in_leaf": 50,
# financial priors: e.g. [trend, vol, ...] -> win-prob non-decreasing in trend,
# non-increasing in realized vol, unconstrained (0) elsewhere
"monotone_constraints": [1, 0, -1, 0, 0, 1, 0, 0, 0, -1],
"verbosity": -1,
}
train_set = lgb.Dataset(X_train, label=y_train, weight=w_train)
val_set = lgb.Dataset(X_val, label=y_val, weight=w_val, reference=train_set)
model = lgb.train(params, train_set, num_boost_round=2000,
valid_sets=[val_set], callbacks=[lgb.early_stopping(100)])
meta_label_proba = model.predict(X_new) # P(this signal hits the profit barrier first)
XGBoost
Apache-2.0
Mécanisme : arbres boostés par niveau (depth-wise) avec un objectif régularisé (L1/L2 sur les poids des feuilles) intégré au critère même de recherche de découpe, plus un algorithme de découpe par histogramme/quantile-sketch bien optimisé pour les grandes données.
Quand l'utiliser : comme second modèle au biais différent pour l'ensembling avec LightGBM (la croissance par niveau vs par feuille décorrèle utilement les erreurs) ; entraînement GPU si vous dépassez le CPU. Quand ne pas : si vous avez besoin d'une gestion native de premier ordre des catégorielles sans prétraitement — CatBoost est meilleur là-dessus.
Mécanisme : ordered boosting (un schéma piloté par permutation qui évite la fuite de cible dont souffre le target-encoding glouton classique) plus des statistiques de cible ordonnées natives pour les caractéristiques catégorielles — pas d'étape d'encodage manuel, et moins sujet au décalage de prédiction que le target encoding naïf.
Quand l'utiliser : modèles transversaux de paniers d'actions avec de nombreuses caractéristiques catégorielles (secteur, industrie, place, indicateurs d'appartenance à un indice) où vous devriez sinon bricoler un target encoding à la main. Quand ne pas : budgets serrés de temps d'entraînement CPU — CatBoost est généralement le plus lent des trois à ajuster, quoique rapide à scorer.
Son rôle ici : non pas une famille de modèles concurrente mais le tissu conjonctif — Pipeline pour un prétraitement intra-fold sans fuite, GroupKFold/séparateurs purgés personnalisés, GaussianMixture pour une base de régime légère, CalibratedClassifierCV pour transformer les scores GBDT en probabilités honnêtes avant de dimensionner les positions à partir d'eux (les sorties brutes des GBDT sont bien classées mais mal calibrées).
Calibrez avant de dimensionner
La sortie de predict_proba d'un GBDT est un bon signal de classement mais généralement pas une probabilité bien calibrée telle quelle — les GBDT ont tendance à pousser les prédictions vers 0/1. Si votre dimensionneur de position consomme la « confiance » directement (Kelly fractionnaire, taille pondérée par méta-étiquette), enveloppez le modèle dans sklearn.calibration.CalibratedClassifierCV (isotonique ou Platt) ajusté à l'intérieur du fold de CV, sinon votre dimensionnement sera systématiquement trop confiant.
02
Architectures de séries temporelles en deep learning
Ce sont les architectures neuronales à entraîner soi-même de zéro (généralement via neuralforecast, Apache-2.0, qui les implémente toutes), par opposition aux modèles de fondation préentraînés du §3. Chacune d'elles a été benchmarkée jusqu'à son existence sur M4/M3/electricity/traffic/ETT — aucune n'a été conçue face à des séries de rendements financiers, et le verdict honnête par architecture le reflète.
Architecture
Year / venue
Core idea
Problem vs. plain LSTM
Financial-data verdict
LSTM / GRU
1997 / 2014
Gated recurrent units carry a cell state across time steps to fight vanishing gradients.
— (baseline)
Still a reasonable baseline for sequence classification (e.g. regime state); rarely beats GBDT on tabular-framed return prediction and is slower to train/tune.
TCN
Bai et al. 2018
Stacked causal, dilated 1-D convolutions (WaveNet-style) give an exponentially growing receptive field with fully parallel training.
Parallelizable (no sequential recurrence) and avoids vanishing/exploding gradients over long lookbacks.
Solid, fast baseline in neuralforecast; no documented financial edge over GBDT, but useful when you specifically need a long causal receptive field cheaply.
N-BEATS
Oreshkin et al. 2020 (ICLR)
Pure fully-connected stacks with backward/forward residual "basis expansion" blocks; interpretable trend/seasonality decomposition, no recurrence or attention.
Much simpler and more parallel than RNN/attention stacks; beat the M4-competition winner by ~3% and a statistical benchmark by ~11%.
Benchmarks are M3/M4/tourism — non-financial. Useful as a fast, interpretable univariate baseline; not evidence of edge on returns.
N-HiTS
Challu et al. 2023 (AAAI)
Extends N-BEATS with hierarchical interpolation and multi-rate input sampling so different blocks specialize in different frequency bands.
Cuts long-horizon compute and reportedly beats Transformer baselines by >25% on long-horizon benchmarks.
Same caveat as N-BEATS — a strong long-horizon forecaster on benchmark data, unproven on financial returns specifically.
Temporal Fusion Transformer (TFT)
Lim et al. 2021 (Int. J. Forecasting)
LSTM encoder for local processing + interpretable multi-head self-attention for long-range dependencies + a variable-selection gating network that also yields feature-importance-like interpretability.
Natively handles static covariates, known-future inputs (e.g. expiry date), and produces quantile forecasts with built-in interpretability — none of which vanilla LSTM offers.
The most finance-plausible of the deep architectures because of native covariate support; still no peer-reviewed evidence of consistent OOS financial-return edge over GBDT meta-labeling.
Informer
Zhou et al. 2021 (AAAI, best paper)
ProbSparse self-attention selects only the top-scoring queries, cutting attention cost from O(L²) to O(L log L) for very long sequences.
Makes long-sequence (thousands of steps) transformer forecasting computationally tractable.
Designed for long-horizon benchmark forecasting, not noisy short-memory financial returns; see the DLinear caveat below.
Autoformer
Wu et al. 2021 (NeurIPS)
Replaces standard attention with an auto-correlation mechanism plus built-in series decomposition (trend/seasonal) between blocks.
Captures periodicity more directly than dot-product attention; more robust on strongly seasonal series.
Financial returns have weak/no reliable seasonality at daily/swing frequency — decomposition assumption is a weaker fit than on electricity/traffic data.
FEDformer
Zhou et al. 2022 (ICML)
Performs attention in the frequency domain (via Fourier/wavelet transforms) with a mixture-of-experts decomposition for trend.
Frequency-domain attention scales sub-quadratically and captures global periodic structure.
Same seasonality-dependence caveat as Autoformer; frequency-domain priors are a mismatch for near-random-walk return series.
PatchTST
Nie et al. 2023 (ICLR)
Splits each series into subseries "patches" as transformer tokens (like ViT for time series) and treats each channel independently, sharing one transformer backbone across all channels.
Patch tokenization retains local semantics and cuts attention cost quadratically vs. point-wise tokens; channel-independence avoids spurious cross-channel overfitting. Reported ~21% MSE reduction over prior transformer SOTA on long-horizon benchmarks.
The architectural basis for several foundation models below (see §3); channel-independence is a genuinely useful inductive bias, but the MSE gains are on ETT/weather/traffic, not equities.
iTransformer
Liu et al. 2024 (ICLR spotlight)
"Inverts" the standard transformer: each variate's whole time series becomes one token, and attention runs across variates instead of across time steps, with a per-series FFN handling temporal encoding.
Captures multivariate correlations directly via attention without modifying core transformer components; generalizes to unseen variate counts.
Notably, in a 2026 financial-return benchmark (arXiv:2606.27100, see §3), iTransformer beat the pretrained foundation models on META — a rare case of a from-scratch architecture outperforming zero-shot foundation models on a specific liquid single-name equity.
La mise en garde DLinear — à lire avant de dégainer un quelconque transformer
Zeng et al., « Are Transformers Effective for Time Series Forecasting? » (AAAI-23 Oral ; code : cure-lab/LTSF-Linear) ont montré qu'une simple couche linéaire avec décomposition tendance/saisonnalité (DLinear) a battu Informer, Autoformer et FEDformer sur presque tous les benchmarks standard à long horizon, avançant que leurs gains rapportés provenaient surtout de la stratégie d'entraînement direct multi-étapes non autorégressive, et non de l'attention elle-même. L'analyse de suivi de Hugging Face a quelque peu nuancé (les transformers à paramètres équivalents font mieux), mais la leçon pratique tient : benchmarkez toujours toute architecture profonde face à une base linéaire/ARIMA (Nixtla statsforecast, §11) avant de faire confiance à un gain de précision dû à la complexité. C'est doublement vrai sur des données financières, où le bruit domine le signal bien plus que sur des données d'électricité ou de trafic.
03
Modèles de fondation de séries temporelles sur Hugging Face
Les prévisionnistes de séries temporelles préentraînés et zero-shot sont réels et utiles — pour la volatilité, pas la direction du prix. Une étude de juin 2026 construite spécifiquement pour tester cela, « Pretrained Time-Series Foundation Models for Financial Return Forecasting » (Noguer i Alonso et Pereira Franklin, AI Finance Institute), a benchmarké TimeGPT, TimesFM-2.5, Moirai-2.0, Chronos et Chronos-2 face à NBEATS/NHITS/PatchTST/iTransformer/KAN entraînés de zéro sur cinq actions américaines liquides (AAPL, AMZN, GOOG, JPM, META) avec un protocole à origine glissante face à une base de marche aléatoire. Le résultat : sur dix combinaisons actif/tâche, seules deux ont montré une surperformance statistiquement significative de la marche aléatoire — Chronos sur AMZN et Moirai-2.0 sur GOOG — et les auteurs affirment sans détour que « les gains sur la base de marche aléatoire sont faibles et rares », concluant que les TSFM sont « des a priori pratiques utiles qui réduisent les coûts de développement de modèles », mais explicitement « pas des moteurs universels pour une génération d'alpha statistiquement fiable ». Traitez chaque modèle ci-dessous en conséquence : d'excellents moteurs, exécutables sur CPU, pour des entrées de volatilité/prévision de vol vers une couche de dimensionnement ; faibles à égaux à la marche aléatoire pour la direction du prix.
Model
Org
Architecture family
Params
Context
License
Chronos / Chronos-Bolt
Amazon Science
T5-style encoder-decoder over quantized/tokenized values (Chronos) or direct patch-based multi-step regression heads (Bolt)
Masked-encoder transformer with "any-variate" attention (flattens multiple series into one token sequence so it natively handles arbitrary channel counts and covariates)
Small/Base/Large (14M–311M)
Flexible, any positive length
CC BY-NC-4.0
Lag-Llama
ServiceNow / Morgan Stanley / Mila et al.
LLaMA-style decoder-only transformer fed engineered lag features (not raw tokenized values) as its "vocabulary"
~2.45M (deliberately tiny)
Recommended 32–1024 pts, tunable
Apache-2.0
MOMENT
Auton Lab, CMU
Transformer trained multi-task (forecast + classify + detect anomalies + impute) on the "Time-series Pile" corpus
Small/Base/Large (~40M–341M)
Task-dependent
MIT
IBM Granite-TimeSeries (PatchTSMixer / PatchTST / TTM)
IBM Research
PatchTSMixer = all-MLP mixer over patches (no attention); PatchTST variant = patch-transformer; TTM = "Tiny Time Mixer," a very small pretrained mixer
PatchTSMixer ~1M (task head), TTM sub-5M
512-in / 96-out typical configs
Apache-2.0
Amazon Chronos / Chronos-Bolt
Apache-2.0 · 205M
Fiche du modèle :huggingface.co/amazon/chronos-bolt-base (la famille inclut aussi chronos-t5-{tiny,mini,small,base,large} et le plus récent amazon/chronos-2).
Architecture : le Chronos d'origine tokenise des valeurs de séries temporelles mises à l'échelle et quantifiées en un vocabulaire fixe et les passe dans un encodeur-décodeur T5 standard — c.-à-d. qu'il traite la prévision comme du modélisation de langage sur un alphabet numérique discrétisé. Chronos-Bolt remplace le décodage autorégressif token par token par une régression directe multi-étapes par patchs, rapportée comme jusqu'à ~250× plus rapide et ~20× plus efficace en mémoire pour une précision comparable ou meilleure (mesurée via WQL/MASE sur 27 jeux de données de benchmark), entraînée sur de l'ordre de ~100 milliards d'observations de séries temporelles.
Verdict : le meilleur choix polyvalent pour une entrée de prévision de volatilité en CPU seul — Apache-2.0, rapide, zero-shot, et le seul modèle du benchmark 2606.27100 à avoir atteint la significativité (sur AMZN). Néanmoins : un résultat significatif sur dix essais n'est pas la preuve d'un avantage directionnel reproductible.
Python · prévision de volatilité zero-shot avec Chronos-Bolt
pip install chronos-forecasting torch
import torch
from chronos import BaseChronosPipeline
pipeline = BaseChronosPipeline.from_pretrained(
"amazon/chronos-bolt-base", # T5-style encoder-decoder, 205M params, Apache-2.0
device_map="cpu", # CPU is fine for daily-bar, small-batch inference
torch_dtype=torch.bfloat16,
)
# Feed REALIZED VOLATILITY, not raw price -- this is a vol forecaster, not an oracle
context = torch.tensor(realized_vol_20d.values[-512:])
quantiles, mean = pipeline.predict_quantiles(
context=context,
prediction_length=10, # 10-day-ahead vol forecast
quantile_levels=[0.1, 0.5, 0.9],
)
vol_forecast_median = quantiles[0, :, 1] # feed straight into GARCH/vol-target sizing (see §10)
Google TimesFM
Apache-2.0 · 200M/500M
Fiche du modèle :huggingface.co/google/timesfm-2.0-500m-pytorch (ICML 2024). Architecture : transformer décodeur seul entraîné à consommer des patchs d'entrée de longueur fixe (32 points) et à émettre directement des patchs de sortie plus longs (128 points) — plus proche de l'objectif de token suivant d'un modèle de langage que de l'approche par valeurs tokenisées de Chronos, mais opérant sur des embeddings de patchs continus plutôt que sur un vocabulaire discrétisé.
Verdict : avec Moirai-2.0, il a eu le meilleur rang moyen sur le benchmark à cinq actions (en tête sur AAPL/JPM/GOOG/AMZN) — mais selon le cadrage même de l'article, un rang fort ≠ un avantage significatif ; aucune des victoires de TimesFM n'a franchi la barre de significativité de la marche aléatoire. Bon, bien maintenu, Apache-2.0, adapté à la volatilité ; pas un feu vert pour la direction du prix.
Fiche du modèle :huggingface.co/Salesforce/moirai-1.0-R-large. Architecture : transformer à encodeur masqué avec « any-variate attention » — au lieu d'un embedding fixe par canal, il aplatit un nombre arbitraire de variables (cibles + covariables dynamiques/statiques) en une seule séquence de tokens, de sorte qu'un unique modèle préentraîné gère nativement toute tâche de prévision multivariée sans réentraînement par jeu de données. Moirai-MoE remplace la FFN dense par une couche de mélange d'experts pour une meilleure spécialisation à coût d'inférence similaire.
Bloqueur de licence — à lire avant de toucher à ceci dans un système en direct
Les poids de Moirai et Moirai-MoE sont publiés sous CC BY-NC 4.0 — usage non commercial uniquement. Les utiliser (même juste pour l'inférence) dans un système qui gère votre propre capital de trading constitue sans doute un usage commercial et n'est pas couvert par cette licence sans un accord distinct de Salesforce. Chronos, TimesFM, Lag-Llama et MOMENT sont sous Apache-2.0/MIT et ne portent aucune telle restriction — préférez-les pour tout ce qui touche du capital réel. Moirai convient uniquement pour de la recherche/du backtesting personnels.
Verdict : Moirai-2.0 a produit l'autre résultat significatif du benchmark (GOOG) et a égalé TimesFM pour le meilleur rang moyen — techniquement intéressant, mais les règles de licence l'excluent d'un pipeline en direct quoi qu'il en soit.
Lag-Llama
Apache-2.0 · ~2.45M
Fiche du modèle :huggingface.co/time-series-foundation-models/Lag-Llama. Architecture : un transformer décodeur seul de style LLaMA, mais au lieu de lui fournir des valeurs brutes ou des patchs, chaque token d'entrée est un vecteur de lag features classiques (valeurs en t-1, t-2, t-7, t-30, ...) plus des covariables de date/heure — c.-à-d. qu'il place un transformer au-dessus d'une représentation à caractéristiques ingénierées rappelant la modélisation autorégressive classique, délibérément gardée minuscule (~2,45 M de paramètres) face aux autres entrées ici.
Verdict : ne fait pas directement partie du benchmark 2606.27100, mais architecturalement le plus proche d'une base autorégressive « transparente » du groupe — un second avis raisonnable pour la prévision de volatilité quand vous voulez quelque chose de plus petit/rapide que Chronos-Bolt/TimesFM, tout en restant Apache-2.0 sans souci.
MOMENT
MIT · ~341M
Fiche du modèle :huggingface.co/AutonLab/MOMENT-1-large (ICML 2024 ; Auton Lab, Carnegie Mellon). Architecture : un unique backbone transformer préentraîné en multitâche sur la prévision, la classification, la détection d'anomalies et l'imputation sur le « Time-series Pile » curé, ce qui en fait le plus polyvalent de ce groupe plutôt qu'un spécialiste de la prévision.
Quand l'utiliser : ses têtes de détection d'anomalies et d'imputation sont sans doute plus différenciées pour un pipeline de trading que sa tête de prévision — p. ex. signaler des bougies intraday anormales dans un garde-fou de qualité des données, ou imputer des trous dans un flux de données alternatives — plutôt que comme le prévisionniste de volatilité lui-même. Licence : MIT, aucune restriction.
IBM Granite-TimeSeries
Apache-2.0
Fiche du modèle :huggingface.co/ibm-granite/granite-timeseries-patchtsmixer (voir aussi ibm-granite/granite-timeseries-patchtst et la lignée « Tiny Time Mixer » TTM). Architecture : PatchTSMixer remplace entièrement l'attention par un MLP-Mixer sur les patchs — aucun coût d'attention quadratique — rapportant une mémoire/un temps d'exécution 2 à 3× inférieurs aux patch-transformers pour une précision comparable ou meilleure sur des benchmarks publics à long horizon (p. ex. 0,37 de MSE sur la prévision à 96 pas d'ETTh1).
Quand l'utiliser : l'option la moins coûteuse à exécuter ici de loin (des variantes TTM de moins de 5 M de paramètres existent) — un bon choix si vous voulez un composant de prévision de vol léger, trivial en CPU, et n'avez pas besoin de la généralité zero-shot de Chronos/TimesFM. Licence : Apache-2.0.
La politique en une phrase pour toute cette section
Utilisez tout modèle Apache-2.0/MIT d'ici comme entrée de volatilité/covariable vers la couche de dimensionnement déterministe du §10 ; n'utilisez aucun d'eux, y compris les résultats significatifs de Chronos/Moirai, comme signal d'entrée autonome — les auteurs mêmes du benchmark 2606.27100 qualifient l'effet de « faible et rare », et iTransformer (une architecture entraînée de zéro, §2) a battu tous les modèles de fondation sur META, soulignant que le préentraînement n'est pas un avantage universel sur les séries financières.
04
TALN financier et LLM
Le sentiment/TALN financier appartient à la couche de risque (une caractéristique de veto/régime) et non à la couche d'alpha — selon la recherche source du §0, l'avantage du sentiment d'actualités isolé est en grande partie un artefact d'anticipation qui meurt hors échantillon. Voici les trois modèles qui valent vraiment la peine d'être connus.
FinBERT (ProsusAI)
Apache-2.0 · ~110M
Fiche du modèle :huggingface.co/ProsusAI/finbert (~7,5 M de téléchargements/mois au moment de la recherche). Architecture : BERT-base (12 couches, 768 dimensions cachées, 110 M de paramètres) préentraîné davantage sur un grand corpus financier (Reuters TRC2), puis affiné pour un sentiment à 3 classes sur le Financial PhraseBank. Benchmark : 86 % de précision sur l'ensemble du Financial PhraseBank (97 % sur le sous-ensemble à forte concordance des annotateurs), soit environ 8 points au-dessus du BERT vanilla (arXiv:1908.10063).
Quand l'utiliser : scoring des gros titres en fin de journée comme caractéristique de veto de blackout de résultats / régime baissier. Quand ne pas : comme signal d'alpha autonome, ou sur des gros titres scrapés à horizon 1 jour où les flux institutionnels ont déjà fait bouger le prix.
Python · inférence de sentiment FinBERT
pip install transformers torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
tok = AutoTokenizer.from_pretrained("ProsusAI/finbert")
model = AutoModelForSequenceClassification.from_pretrained("ProsusAI/finbert")
model.eval()
headlines = ["Company X beats earnings estimates, raises guidance",
"Regulators open investigation into Company X"]
with torch.no_grad():
inputs = tok(headlines, return_tensors="pt", padding=True, truncation=True)
probs = torch.softmax(model(**inputs).logits, dim=-1)
# label order per config.id2label: 0=positive, 1=negative, 2=neutral
labels = ["positive", "negative", "neutral"]
scores = [dict(zip(labels, p.tolist())) for p in probs]
# aggregate to a daily sentiment score; use ONLY as a veto/regime feature, not alpha
FinGPT
MIT (code)
Dépôt :github.com/AI4Finance-Foundation/FinGPT. Architecture : pas un modèle entraîné de zéro — une recette d'affinage LoRA (Low-Rank Adaptation) appliquée à des LLM de base ouverts (LLaMA2-7B/13B pour FinGPT v3.2/v3.3, ChatGLM2-6B pour v3.1). LoRA gèle les poids de base et entraîne à la place de petites matrices adaptatrices de faible rang, réduisant les paramètres entraînables de ~6,17 Md à ~3,67 M — pratique à affiner sur un seul GPU grand public.
Cas d'usage : analyse de sentiment financier, Q&R de type robo-advisor, et expériences de prévision utilisant des signaux ingénierés par LLM (aussi la base de la piste « signaux ingénierés par LLM » du FinRL Contest). Nuance de licence : le code d'entraînement/inférence de FinGPT est sous MIT, mais les poids de base LLaMA sous-jacents portent les propres termes de licence communautaire de Meta — vérifiez-les indépendamment avant tout déploiement commercial d'un checkpoint affiné.
FinBERT-tone
Apache-2.0 · ~110M
Fiche du modèle :huggingface.co/yiyanghkust/finbert-tone (Huang, Wang et Yang, Contemporary Accounting Research 2022). Architecture : également BERT-base (12 couches / 768 cachées / 12 têtes), mais entraîné sur une lignée de corpus différente — préentraîné sur du texte de 10-K/10-Q/earnings calls, puis affiné sur 10 000 phrases de rapports d'analystes annotées manuellement, lui donnant un comportement de classification de ton un peu différent de celui du FinBERT de ProsusAI malgré le nom similaire.
Quand l'utiliser : un second avis de sentiment entraîné différemment pour l'ensembling avec FinBERT spécifiquement sur du texte de rapports d'analystes ou d'earnings calls (plutôt que des gros titres d'actualités générales).
05
Apprentissage par renforcement pour le trading
Le RL est l'élément le plus survendu et le moins fiable de toute cette page pour un moteur de trading central. L'outillage est réellement bon ; le verdict honnête, étayé par le propre concours de benchmark de la communauté RL, est de le cantonner à des sous-problèmes étroits et strictement validés (p. ex. le timing d'exécution) plutôt qu'à un moteur principal ou au niveau du portefeuille.
Dynamic market-environment and dataset layer for FinRL (hundreds of market simulators)
Active, smaller community (~1–2k★)
Stable-Baselines3
MIT
Reliable, well-tested implementations of the underlying RL algorithms (PPO, SAC, DQN, A2C, TD3, DDPG, HER) that FinRL wraps
Actively maintained, the de facto standard PyTorch RL library
TensorTrade
Apache-2.0
RL trading-environment framework (Gym-style)
Maintenance stalled — a community fork, TensorTrade-NG, was created explicitly because the original "needed a lot of refactoring, was outdated, and looked not really maintained." Treat as unmaintained for planning purposes.
Les quatre familles d'algorithmes (une ligne chacune)
PPO (Proximal Policy Optimization) — on-policy, actions discrètes ou continues ; borne l'étape de mise à jour de la politique pour rester proche de l'ancienne, échangeant un peu d'efficacité d'échantillon contre de la stabilité d'entraînement. Le premier choix par défaut dans la plupart des exemples FinRL.
SAC (Soft Actor-Critic) — off-policy, actions continues seulement ; objectif à entropie maximale (récompense explicitement l'exploration) avec un tampon de rejeu, généralement plus efficace en échantillon que PPO mais plus sensible aux hyperparamètres.
DQN (Deep Q-Network) — off-policy, actions discrètes seulement ; apprend une fonction valeur-action via un tampon de rejeu et un réseau cible. Nécessite un espace d'action discrétisé (p. ex. acheter/conserver/vendre), ce qui convient mal au dimensionnement continu de position.
A2C (Advantage Actor-Critic) — on-policy, discret ou continu ; un cousin plus simple et synchrone d'A3C, généralement le plus faible des quatre sur les tâches financières dans les propres benchmarks de FinRL.
Pourquoi le RL est concrètement fragile pour le trading — pas seulement « difficile »
Paysage de récompense non stationnaire : la fonction de valeur d'un agent RL est apprise face à un régime historique spécifique ; quand le régime change (comme le font constamment les marchés financiers), la politique apprise optimise pour une surface de récompense qui n'existe plus — contrairement à un méta-étiqueteur GBDT réentraîné, il n'y a pas de simple « réajuster sur la dernière fenêtre » pour un réseau de politique sans risquer un oubli catastrophique. Inefficacité d'échantillon : le RL profond a typiquement besoin de millions d'interactions avec l'environnement pour converger ; vous n'avez exactement qu'une seule histoire non rejouable du marché, si bien que « plus de données » signifie soit de la simulation (qui encode vos propres hypothèses comme vérité de terrain) soit des années d'attente supplémentaire en temps réel. Reward-hacking sur les backtests : un agent optimisant le PnL simulé cumulé apprendra volontiers à exploiter les bizarreries du simulateur (hypothèses d'exécution irréalistes, impact de marché nul, arrondi exact du moteur de backtest) plutôt qu'un véritable avantage de marché — précisément le mode d'échec que documente l'article FinRL Contests (arXiv:2504.02281) : les agents soumis présentant une forte probabilité de surapprentissage au backtest sont explicitement rejetés à un seuil de significativité de 10 % par les propres organisateurs du concours — les gens qui construisent l'écosystème de trading par RL considèrent que la plupart des agents de trading RL soumis sont par défaut statistiquement indiscernables d'un bruit surappris.
Portée pratique, si vous utilisez le RL malgré tout : un sous-problème étroit à récompense naturellement en forme de MDP (p. ex. le timing d'exécution d'ordres au sein d'un ordre parent fixe, le suivi VWAP), évalué avec la même discipline PBO/DSR que tout le reste au §14 — jamais comme moteur principal d'entrée/sortie/dimensionnement.
06
Pipelines complets de ML quant — Microsoft Qlib
Qlib est ce qui se rapproche le plus d'une plateforme de recherche IA-quant clé en main en open source — une couche de données, un DSL d'ingénierie de caractéristiques, un zoo de modèles et un harnais de backtest walk-forward/analyse de portefeuille, reliés entre eux via des configurations de workflow YAML. Sous licence MIT (microsoft/qlib), des dizaines de milliers d'étoiles GitHub, MIT depuis son ouverture en septembre 2020, activement mis à jour (v0.9.7, août 2025) et désormais couplé au RD-Agent de Microsoft pour une expérimentation automatisée de boucle de recherche.
Alpha158 vs. Alpha360 — les deux jeux de caractéristiques intégrés
Raw normalized OHLCV history flattened over a 60-day lookback (6 fields × 60 days = 360 columns), essentially no feature engineering
Feature relationships
Low spatial/temporal structure between columns — a classic tabular feature matrix
Strong spatial-temporal structure — designed for models that learn their own representation from raw sequences
Best-paired models
LightGBM, XGBoost, CatBoost, linear/MLP models
GRU, LSTM, Transformer-family, ALSTM, GATs — sequence models that benefit from raw structure
Système de workflow/configuration et zoo de modèles intégré
Les expériences Qlib sont typiquement pilotées par un unique fichier YAML consommé par la CLI qrun, déclarant le gestionnaire de données (Alpha158/360 ou personnalisé), le modèle, le découpage du jeu de données, la stratégie de portefeuille et les paramètres de backtest — cela fait du remplacement de LightGBM par un GRU ou un wrapper TFT un changement de config d'une ligne, pas une réécriture. Le zoo de modèles intégré couvre des approches classiques et profondes : LGBModel (LightGBM), XGBModel, CatBoostModel, MLP, GRU/LSTM/ALSTM (récurrents), Transformer, wrapper TFT, TabNet, HIST, IGMTF, et plusieurs modèles de recherche à graphes/attention (GATs, KRNN, Localformer) — tous entraînés et évalués via le même harnais de workflow avec un rapport partagé de backtest walk-forward/analyse d'IC.
YAML · configuration de workflow Qlib minimale (LightGBM sur Alpha158)
qlib_init:
provider_uri: "~/.qlib/qlib_data/custom_nse" # see note below on pointing Qlib at NSE data
region: in # generic region tag; India isn't a stock Qlib region out of the box
market: &market custom_nse_500
benchmark: &benchmark NIFTY500
data_handler_config: &data_handler_config
start_time: 2010-01-01
end_time: 2025-12-31
fit_start_time: 2010-01-01
fit_end_time: 2019-12-31
instruments: *market
task:
model:
class: LGBModel
module_path: qlib.contrib.model.gbdt
kwargs:
loss: binary
num_leaves: 31
learning_rate: 0.03
monotone_constraints: [1, 0, -1, 0]
dataset:
class: DatasetH
module_path: qlib.data.dataset
kwargs:
handler:
class: Alpha158
module_path: qlib.contrib.data.handler
kwargs: *data_handler_config
segments:
train: [2010-01-01, 2019-12-31]
valid: [2020-01-01, 2021-12-31]
test: [2022-01-01, 2025-12-31]
# run with: qrun this_config.yaml
Pointer Qlib vers des données personnalisées (p. ex. NSE)
Qlib est livré avec des fournisseurs de données US et Chine prêts à l'emploi ; NSE/BSE exige que vous construisiez votre propre magasin de données binaire avec scripts/dump_bin.py, en l'alimentant de fichiers Parquet/CSV OHLCV point-in-time que vous avez déjà assemblés (selon la discipline d'un plan de données sans biais de survie). Vous aurez aussi besoin d'un calendrier de trading personnalisé (les jours fériés NSE diffèrent de ceux de NYSE/Chine) et d'enregistrer votre fichier d'univers d'instruments — la couche de données de Qlib est agnostique au format une fois convertie, si bien qu'Alpha158/360 et tout le zoo de modèles fonctionnent tels quels sur des données NSE une fois l'étape de dump effectuée.
07
Méthodes de ML financier de López de Prado — mlfinpy et skfolio
La boîte à outils d'Advances in Financial Machine Learning de López de Prado signifiait autrefois une licence payante mlfinlab — ce n'est plus le cas. Deux paquets gratuits et sous licence permissive couvrent désormais l'étiquetage de triple barrière, le méta-étiquetage, la différenciation fractionnaire, la pondération d'unicité d'échantillon, la CPCV et la HRP.
Package
License
Covers
mlfinpy
MIT
Triple-barrier labeling, meta-labeling, fractional differentiation, sample-weight/uniqueness utilities — a modern Pythonic re-implementation of the AFML code snippets
skfolio
BSD-3-Clause
scikit-learn-compatible portfolio optimization and model selection: CombinatorialPurgedCV out of the box, plus HRP, HERC, risk-budgeting, CVaR/CDaR optimization
mlfinlab (paid)
Commercial
The original, packaged, paid version — only worth it if you specifically want Hudson & Thames' maintained extras beyond what the two free packages cover
Python · étiquetage de triple barrière avec mlfinpy
pip install mlfinpy
from mlfinpy.labeling import get_events, add_vertical_barrier, get_bins
from mlfinpy.util import get_daily_vol
# causal, EWMA-based daily volatility -- uses data strictly up to t, no leakage
daily_vol = get_daily_vol(close=prices, lookback=50)
vertical_barriers = add_vertical_barrier(
t_events=signal_dates, close=prices, num_days=10 # time-limit barrier
)
triple_barrier_events = get_events(
close=prices,
t_events=signal_dates, # your primary (Pine) strategy's signal dates
pt_sl=[2.0, 1.5], # profit-take / stop-loss as multiples of daily_vol
target=daily_vol,
min_ret=0.0005,
num_threads=4,
vertical_barrier_times=vertical_barriers,
)
labels = get_bins(triple_barrier_events, prices)
# labels['bin'] -> 1 = profit barrier hit first, 0 = stop/time barrier hit first
# labels['ret'] -> realized return at the barrier that was hit
# labels['t1'] -> the barrier-touch timestamp (needed for purging downstream)
Python · CombinatorialPurgedCV de skfolio pour le modèle de méta-étiquette
pip install skfolio
from skfolio.model_selection import CombinatorialPurgedCV, cross_val_predict
from sklearn.pipeline import Pipeline
import lightgbm as lgb
meta_label_pipeline = Pipeline([
("model", lgb.LGBMClassifier(num_leaves=31, learning_rate=0.03,
min_child_samples=50)),
])
# n_folds=10, n_test_folds=2 -> C(10,2) = 45 combinatorial train/test paths
# purged_size / embargo_size sized to the max holding horizon (t1 - t0), NOT a flat 1%
cv = CombinatorialPurgedCV(n_folds=10, n_test_folds=2,
purged_size=10, embargo_size=10)
# returns an empirical DISTRIBUTION of out-of-sample paths, not one score --
# use it to compute PBO and the Deflated Sharpe Ratio, not a single train/test split
oos_paths = cross_val_predict(estimator=meta_label_pipeline, X=X, y=y,
cv=cv, sample_weight=w)
Ce que chaque technique vous apporte
Différenciation fractionnaire (mlfinpy.features.frac_diff / variante FFD à largeur fixe) — trouve l'ordre de différenciation minimal d (souvent 0,2-0,5) qui passe un test de stationnarité ADF tout en conservant une corrélation >0,9 avec la série de niveaux, donnant une entrée stationnaire qui garde de la mémoire — strictement meilleur pour les modèles à arbres/linéaires que les rendements bruts (mémoire nulle) ou le prix brut (non stationnaire).
Pondération d'unicité d'échantillon — les étiquettes de triple barrière se chevauchent dans le temps (une période de détention de 10 jours signifie que des signaux adjacents partagent des fenêtres d'étiquette), violant l'hypothèse IID sur laquelle repose l'essentiel de la théorie du ML. Pondérez chaque échantillon par son unicité moyenne (inverse du nombre d'étiquettes concurrentes) plus une décroissance temporelle, sinon votre taille d'échantillon effective est une fraction de votre nombre de lignes et chaque test de significativité en aval est surestimé.
Validation croisée purgée combinatoire (CPCV) — génère de nombreuses combinaisons de chemins train/test (et non un seul chemin walk-forward), purge les lignes d'entraînement dont la fenêtre d'étiquette chevauche le fold de test, et applique un embargo tampon après chaque fold de test. Produit une distribution complète de ratios de Sharpe hors échantillon (alimentant le PBO et le DSR) au lieu d'une estimation ponctuelle — c'est pourquoi elle est structurellement plus fiable que le walk-forward simple.
HRP (Hierarchical Risk Parity) (skfolio.optimization.HierarchicalRiskParity) — alloue via un clustering hiérarchique de la matrice de corrélation au lieu d'inverser une matrice de covariance bruitée (ce que fait l'optimisation moyenne-variance), la rendant bien plus robuste à l'erreur d'estimation sur un panier d'actions corrélées.
08
Détection de régimes — hmmlearn et ruptures
C'est la section où réside le bug de fuite silencieuse le plus courant du gating de régime chez les particuliers — et où montrer le mauvais schéma à côté du bon est plus utile que de le décrire en prose.
Library
License
Maturity
Role
hmmlearn
BSD
Mature, scikit-learn-style API, ~3k★
Gaussian/GMM/Categorical HMMs for a discrete calm/stormy regime state
ruptures
BSD-2-Clause
Mature, academic (ENS Paris-Saclay/CNRS)
Offline changepoint detection — PELT (exact, linear-cost, unknown number of changes), binary segmentation (BinSeg, greedy/approximate), and sliding-window methods
Le bug d'anticipation silencieux nº 1 : décodage HMM lissé sur échantillon complet
La manière par défaut, la plus facile, d'appeler hmmlearn — ajuster GaussianHMM sur tout votre historique, puis appeler .predict() pour les étiquettes de régime — utilise sous le capot un décodage Viterbi/lissé. L'étiquette de régime à l'instant t est choisie en utilisant la séquence entière, y compris tout ce qui suit t. Le garde-fou « sait » de fait qu'une crise arrive avant qu'elle ne survienne. Chaque chiffre publié bluffant de réduction de drawdown par HMM (56 %→24 % de DD max, etc.) qui ne contrôle pas explicitement cela est très probablement construit ainsi. Ci-dessous : le schéma qui fuit, et le schéma causal, walk-forward, à posterior filtrée qui est réellement déployable.
Python · FAUX — décodage lissé sur échantillon complet qui fuit (ne pas déployer)
from hmmlearn.hmm import GaussianHMM
model = GaussianHMM(n_components=2, covariance_type="diag", n_iter=1000)
model.fit(X_full) # fit on the ENTIRE history -- future leaks into the fit
regimes = model.predict(X_full) # Viterbi = globally-smoothed decode over the whole path
# regimes[t] used information from t+1 ... T. This is look-ahead bias.
# Any backtest of a regime gate built this way is invalid and will not reproduce live.
Python · CORRECT — garde-fou de régime causal, walk-forward, à posterior filtrée
from hmmlearn.hmm import GaussianHMM
import numpy as np
regime_at_t = np.full(len(X), np.nan)
model, refit_every, min_train = None, 63, 500 # e.g. refit quarterly
for t in range(min_train, len(X)):
if model is None or t % refit_every == 0:
model = GaussianHMM(n_components=2, covariance_type="diag", n_iter=200)
model.fit(X[:t]) # ONLY data strictly before t
# forward-algorithm FILTERED posterior using data up to and including t --
# no smoothing, no future information, no re-fit on data that includes t's label use
posteriors = model.predict_proba(X[:t + 1])
regime_at_t[t] = posteriors[-1].argmax() # today's regime, knowable today
# regime_at_t is safe to merge into the feature frame for both backtest and live use.
# Expect a MUCH smaller, laggier drawdown benefit than the full-sample-smoothed version --
# that gap IS the size of the leakage bug you just closed.
ruptures est l'outil complémentaire quand vous voulez des points de rupture plutôt qu'un état de régime persistant — p. ex. signaler une rupture de régime de volatilité dans une série EWMA pour déclencher un réajustement du HMM, ou comme détecteur alternatif de frontières de régime pour recouper les transitions du HMM. Pelt (recherche exacte à coût linéaire, nombre inconnu de points de rupture, nécessite un paramètre de pénalité) est le choix par défaut ; Binseg échange l'exactitude contre la vitesse sur des séries plus longues ; les méthodes à fenêtre sont les moins coûteuses mais les moins précises sur les ruptures subtiles. Comme le HMM, exécutez-le en fenêtre expansive/glissante pour un usage en direct — l'API standard de ruptures est elle aussi une méthode hors ligne sur série complète par défaut.
09
Moteurs de backtesting et d'exécution
Aucun moteur unique n'est adapté à chaque étape. Utilisez un moteur vectorisé pour trier des milliers de combinaisons de paramètres, puis revalidez chaque survivant sur un moteur événementiel avec des exécutions réalistes avant de risquer du capital — confondre les deux étapes (faire confiance à un backtest de moteur vectorisé comme réponse finale) est une erreur courante et coûteuse.
Engine
Speed
Fill realism
License
Maintenance
Best-fit use case
vectorbt (community)
Extremely fast (Numba-vectorized, thousands of configs at once)
Weak — vectorized fills, easy to fool yourself
Apache-2.0 + Commons Clause
Community edition maintenance-frozen; active dev moved to paid vectorbtPRO
Fast first-pass parameter sweep / triage only
backtrader
Moderate (pure Python, event-driven)
Moderate (configurable slippage/commission, but manual)
GPL-3.0
Stalled ~2021 — open PRs/issues unmerged for years
Legacy strategies only; don't start new work here
Zipline-reloaded
Moderate
Good (Quantopian-derived fill/slippage models)
Apache-2.0
Community-maintained fork (stefan-jansen), modest but real activity
Research backtests wanting the original Zipline/Quantopian API and pipeline model
NautilusTrader
Fast (Rust core)
High — same strategy code path for backtest and live
LGPL-3.0-or-later
Very active, ~24k★, production-grade
Final realistic-fill re-validation and the bridge to live — the one tool built for research-to-live parity
QuantConnect LEAN
Fast (C#/.NET core, Python API)
High — institutional-grade fill/slippage/margin models
Apache-2.0
Very active, ~19k★, backs a commercial cloud platform
Full-featured alternative to NautilusTrader, especially with QuantConnect's hosted data/cloud/live options
bt
Moderate
Moderate (higher-level "Algo" abstraction over vectorized fills)
MIT
Actively maintained (releases into 2026)
Fast, readable portfolio-level (multi-asset allocation) backtests, less suited to per-trade microstructure realism
backtesting.py
Fast (single-asset, vectorized-ish)
Basic (simple slippage/commission model)
AGPL-3.0
Active, small footprint, ~2.4k★
Quick single-asset prototyping only — AGPL is a real constraint if you build a hosted/SaaS product on it
Pourquoi l'architecture de NautilusTrader compte vraiment
La plupart des échecs « excellent backtest, réel décevant » ne sont pas des échecs de modèle — ce sont des bugs d'écart recherche/production : votre moteur de backtest et votre code d'exécution en direct sont deux bases de code distinctes qui dérivent silencieusement l'une de l'autre (une hypothèse de prix d'exécution ici, un bug de timing de bougie décalé d'une unité là), et rien ne les force à rester cohérentes. La conception événementielle à cœur Rust de NautilusTrader exécute le même code de stratégie — les mêmes classes, les mêmes gestionnaires d'événements — en mode backtest, paper et live ; seuls les adaptateurs de données/exécution changent. Ce choix architectural élimine toute une classe de bugs par construction plutôt que par discipline, ce qui en fait le bon outil pour le rôle de « revalidation finale à exécutions réalistes et pont vers la production » plutôt qu'un simple plus.
Note de licence — LGPL-3.0, pas GPL
NautilusTrader est en LGPL-3.0-or-later, pas la plus stricte GPL-3.0 qui régit backtrader et freqtrade. La LGPL permet de lier/utiliser la bibliothèque depuis du code propriétaire sans open-sourcer votre code de stratégie, à condition que les modifications à NautilusTrader lui-même (le cas échéant) soient reversées — matériellement moins restrictif qu'une dépendance GPL pure pour un système de trading à code fermé. Confirmez tout de même les termes de licence actuels sur le dépôt avant un déploiement commercial.
10
Construction de portefeuille et risque
C'est ici que le « contrôle du drawdown » est réellement implémenté — comme des mathématiques déterministes consommant des prévisions de volatilité et la confiance de méta-étiquette, pas comme une nouvelle tâche de prédiction.
Library
License
Role
PyPortfolioOpt
MIT
Classical mean-variance / efficient frontier, Black-Litterman, shrinkage covariance estimators, and HRP — the most approachable API of the three
Riskfolio-Lib
BSD-3-Clause
Deeper risk-based allocation: HRP/HERC, ~24 risk measures including CVaR/CDaR/EVaR, risk-parity/risk-budgeting, built on CVXPY convex optimization
arch
NCSA
GARCH/EGARCH/GJR-GARCH/TARCH volatility-family models — the standard econometric volatility forecaster feeding vol-targeted sizing
Python · prévision de volatilité GJR-GARCH → taille de position ciblée en vol (arch)
pip install arch
from arch import arch_model
import numpy as np
returns_pct = 100 * log_returns.dropna() # arch expects % returns for numerical stability
# GJR-GARCH(1,1,1) with Student-t errors -- captures the leverage effect (vol reacts more to
# negative returns than positive ones), which plain GARCH(1,1) misses
am = arch_model(returns_pct, vol="GARCH", p=1, o=1, q=1, dist="t")
res = am.fit(disp="off", last_obs=train_end_date) # fit only on data up to the current date
fcast = res.forecast(horizon=10, reindex=False)
vol_forecast_daily = np.sqrt(fcast.variance.values[-1]) / 100 # back to decimal daily vol
target_vol_daily = 0.10 / (252 ** 0.5) # ~10% annualized portfolio vol target
position_scale = target_vol_daily / vol_forecast_daily[0]
position_size = base_size * min(position_scale, max_leverage_cap) # always cap leverage
PyPortfolioOpt
MIT
Quand l'utiliser : une allocation rapide HRP ou à covariance shrinkée sur un panier sans tirer toute une pile de dépendances d'optimisation convexe. Quand ne pas : si vous avez besoin d'objectifs CVaR/CDaR ou de mesures de risque plus exotiques — c'est le travail de Riskfolio-Lib.
Python · allocation HRP
from pypfopt import HRPOpt
hrp = HRPOpt(returns=daily_returns_df) # NOT prices -- pass returns
weights = hrp.optimize() # hierarchical-clustering-based, no covariance inversion
Riskfolio-Lib
BSD-3
Quand l'utiliser : chaque fois que l'objectif est explicitement conscient du risque de queue (CVaR/CDaR) plutôt que de la variance — un meilleur choix pour un mandat de « moindre drawdown » que la moyenne-variance.
Python · portefeuille optimal CVaR
import riskfolio as rp
port = rp.Portfolio(returns=daily_returns_df)
port.assets_stats(method_mu="hist", method_cov="hist")
weights = port.optimization(model="Classic", rm="CVaR", obj="MinRisk", rf=0, l=0)
11
Ingénierie de caractéristiques et utilitaires de prévision
Avant de faire confiance à tout résultat de GBDT ou de modèle de fondation, benchmarkez-le face à la base ennuyeuse. Ces deux bibliothèques couvrent l'extraction automatisée de caractéristiques et les bases de prévision classiques que vous ne devriez jamais sauter.
Library
License
Role
tsfresh
MIT
Automated extraction of hundreds of statistical/signal-processing time-series features, with a built-in hypothesis-testing-based relevance filter (the "FRESH" algorithm) to control false-discovery rate on the feature explosion
Nixtla statsforecast
Apache-2.0
Fast classical/econometric baselines — AutoARIMA, AutoETS, AutoCES, Theta — the mandatory benchmark before believing any ML "edge"
Nixtla mlforecast
Apache-2.0
Machine-learning forecasting at scale (pandas/polars/Spark/Dask/Ray backends) with the same lag-feature-engineering plumbing regardless of backend
Nixtla neuralforecast
Apache-2.0
30+ neural architectures under one API — every model in §2 (NBEATS, NHITS, TFT, Informer, Autoformer, FEDformer, PatchTST, iTransformer, TimeLLM, ...) available without hand-rolling each paper's code
Python · extraction de caractéristiques automatisée + filtrée avec tsfresh
pip install tsfresh
from tsfresh import extract_relevant_features
# long-format df: columns [id, time, value]; y indexed by id (e.g. triple-barrier label)
features = extract_relevant_features(
long_format_df, y=labels_by_id, column_id="id", column_sort="time",
fdr_level=0.01, # false-discovery-rate control -- do NOT skip this on financial data
)
# re-run the relevance filter INSIDE each CV fold in production, never on the full dataset
Python · base obligatoire avant de faire confiance à l'« avantage » de tout modèle
pip install statsforecast
from statsforecast import StatsForecast
from statsforecast.models import AutoARIMA, AutoETS
sf = StatsForecast(models=[AutoARIMA(), AutoETS()], freq="D", n_jobs=-1)
sf.fit(train_df)
baseline_forecast = sf.predict(h=10)
# your GBDT / foundation-model forecast must beat THIS, net of cost, or there is no edge
12
MLOps pour un système de trading en direct
L'outillage MLOps ici ne concerne pas l'échelle — il concerne l'honnêteté. La fonction MLOps la plus déterminante de toute cette stack est la discipline du décompte d'essais pour le Deflated Sharpe Ratio : chaque configuration de backtest que vous avez essayée, suivie, pour toujours, afin que la correction pour tests multiples soit calculée face à votre décompte d'essais réel, pas au sous-ensemble flatteur dont vous vous souvenez.
Tool
License
Role
When to adopt
MLflow
Apache-2.0
Experiment tracking (params/metrics/artifacts) + model registry with stage transitions
Early — every single backtest run, from day one, feeds the DSR trial count
Once a strategy is running on a schedule against live data
NannyML
Apache-2.0
Label-free live performance estimation — CBPE for classifiers, DLE for regressors — estimates real-world accuracy before ground-truth labels are even available
Once paper/live trading is running and labels arrive with a lag (exactly the triple-barrier situation)
Prefect
Apache-2.0
Pythonic pipeline orchestration: scheduling, retries, caching, event-driven triggers for the nightly ingest→feature→predict→size→alert DAG
Once a plain cron script becomes unwieldy — not needed for an MVP
Dagster
Apache-2.0
Alternative orchestrator with stronger data-asset lineage/typing — heavier but better observability at scale
If you outgrow Prefect's simplicity and want asset-level lineage across many pipelines
Python · journalisation MLflow qui impose réellement la discipline du décompte d'essais du DSR
pip install mlflow
import mlflow
with mlflow.start_run(run_name="lgbm_meta_label_v37"):
mlflow.log_params(params) # every hyperparameter tried
mlflow.log_param("cv_scheme", "CombinatorialPurgedCV(10,2)")
mlflow.log_param("feature_set_hash", feature_set_hash) # so re-used feature sets don't double count
mlflow.log_metric("oos_sharpe_median", oos_sharpe_median) # across the CPCV path distribution
mlflow.log_metric("pbo", pbo_value)
mlflow.log_metric("trial_number_in_family", trial_counter) # THIS feeds the Deflated Sharpe N
mlflow.lightgbm.log_model(model, "model")
# Query the full run history to compute N for the Deflated Sharpe Ratio -- include prior
# Pine-Script optimization trials too (see §14), not just the ML runs.
Pourquoi c'est non négociable, pas un simple plus
Le Deflated Sharpe Ratio a besoin d'un décompte honnête de chaque configuration que vous avez jamais essayée face à ces données — pas seulement le modèle final. Sans système de référence, le décompte d'essais est reconstruit de mémoire à l'instant précis où vous êtes le plus motivé à le sous-estimer. MLflow (ou un équivalent) transforme « combien de choses ai-je réellement essayées » d'une estimation autodéclarée en un fait interrogeable.
13
Données et jeux de données alternatifs sur Hugging Face
Au-delà des hubs de modèles, le Datasets Hub de Hugging Face abrite un ensemble croissant de jeux de données pertinents pour la finance, qui valent la peine d'être connus pour le prototypage et le travail sur le sentiment — traitez-les tous comme des sources de prototypage/de secours, pas comme des données de production sans biais de survie (voir la discipline du Plan de Données dans le rapport de recherche source).
Labeled Twitter/X financial and crypto sentiment — useful for fine-tuning or validating a FinBERT-style veto filter
huggingface.co/datasets?search=finance
Hub search
The Hub's finance-tagged dataset list changes frequently — always re-search rather than trusting a static list; verify licensing per-dataset before any commercial use
Numerai — un autre jeu, pas une source de données pour votre propre système
Numerai se comprend mieux comme un marché de compétences en modélisation, et non comme un jeu de données à brancher sur votre propre pipeline. Le tournoi principal fournit gratuitement des caractéristiques pré-ingénierées et obfusquées — passées en PCA, z-scorées et découpées dans le temps — pour que vous puissiez modéliser des données financières de classe mondiale sans jamais savoir quelles actions ou quelles dates vous regardez (chaque « ère » hebdomadaire a des ID qui ne se correspondent pas d'une ère à l'autre, par conception). Numerai Signals est le produit complémentaire : vous soumettez des prédictions sur votre propre univers/caractéristiques, en visant des signaux orthogonaux à ce que la pile de modèles existante de Numerai capture déjà. Tous les modèles soumis alimentent un méta-modèle pondéré par le stake qui pilote à son tour le propre hedge fund de Numerai. Cadrez-le comme une optionnalité pour monétiser une compétence de modélisation — évaluée sur une performance pluriannuelle incluant le drawdown, pas comme une voie rapide vers un revenu — et comme un écosystème adjacent intéressant plutôt qu'un composant du pipeline du §14.
14
Architecture de référence — pipeline complet
Comment un utilisateur avancé raccorde chaque bibliothèque ci-dessus en un seul pipeline, de bout en bout. Ingestion des données → caractéristiques Qlib/tsfresh → différenciation fractionnaire (mlfinpy) → modèle de méta-étiquette LightGBM validé par validation croisée purgée combinatoire imbriquée (skfolio) → garde-fou de régime causal hmmlearn → dimensionnement ciblé en vol basé sur GARCH (arch) → backtest NautilusTrader → journalisation MLflow → webhook PickMyTrade pour l'exécution.
Chaque flèche est un passage de données entre des bibliothèques interchangeables indépendamment — aucune étape ne dépend d'un choix spécifique dans une autre.
Python · squelette du pipeline de référence de bout en bout
"""
Reference pipeline skeleton: data ingestion -> PickMyTrade execution.
Every preprocessing step is fit INSIDE the CPCV training fold only -- never on
the full dataset. Illustrative structure; wire in your own data store / config.
"""
import numpy as np
import pandas as pd
import lightgbm as lgb
import mlflow
import requests
from hmmlearn.hmm import GaussianHMM
from arch import arch_model
from mlfinpy.labeling import get_events, add_vertical_barrier, get_bins
from mlfinpy.util import get_daily_vol
from mlfinpy.features import frac_diff_ffd
from skfolio.model_selection import CombinatorialPurgedCV, cross_val_predict
from sklearn.pipeline import Pipeline
from qlib.contrib.data.handler import Alpha158
from tsfresh import extract_relevant_features
from nautilus_trader.backtest.engine import BacktestEngine
from nautilus_trader.trading.strategy import Strategy
# 1. DATA INGESTION -- point-in-time, survivorship-bias-free universe only
def load_point_in_time_universe(as_of_date, min_adv_usd=2_500_000):
"""Never filter by TODAY's liquidity -- that imports survivorship bias."""
raw = data_store.query_asof(as_of_date=as_of_date) # Parquet/DuckDB store
return raw[raw["adv_20d_asof"] > min_adv_usd]
# 2. FEATURES -- Qlib Alpha158 for technicals, tsfresh + mlfinpy for the rest
def build_features(prices: pd.DataFrame) -> pd.DataFrame:
alpha158 = Alpha158(instruments=prices["symbol"].unique().tolist(),
start_time=prices.index.min(), end_time=prices.index.max())
tech_features = alpha158.fetch()
tsfresh_features = extract_relevant_features(
prices.reset_index(), y=None, column_id="symbol", column_sort="date", fdr_level=0.01,
)
d = find_min_ffd_order(prices["close"], adf_pvalue=0.05, min_corr=0.9) # search d in [0.1, 1.0]
frac_diff_price = frac_diff_ffd(prices["close"], d=d, threshold=1e-4) # stationary, RETAINS memory
return tech_features.join(tsfresh_features, how="inner").assign(frac_diff_price=frac_diff_price)
# 3. LABELS -- causal EWMA vol -> ATR-scaled triple barrier (mlfinpy)
def label_events(prices: pd.Series, signal_dates: pd.DatetimeIndex) -> pd.DataFrame:
daily_vol = get_daily_vol(close=prices, lookback=50)
vertical_barriers = add_vertical_barrier(t_events=signal_dates, close=prices, num_days=10)
events = get_events(close=prices, t_events=signal_dates, pt_sl=[2.0, 1.5], target=daily_vol,
min_ret=0.0005, num_threads=4, vertical_barrier_times=vertical_barriers)
return get_bins(events, prices) # -> bin (0/1), ret, t1 (needed for purging)
# 4. META-LABEL MODEL -- LightGBM inside nested Combinatorial Purged CV
def train_meta_label_model(X: pd.DataFrame, y: pd.Series, w: pd.Series, trial_counter: int):
pipeline = Pipeline([("model", lgb.LGBMClassifier(
num_leaves=31, learning_rate=0.03, min_child_samples=50,
monotone_constraints=MONO_CONSTRAINTS))])
cv = CombinatorialPurgedCV(n_folds=10, n_test_folds=2, purged_size=10, embargo_size=10)
oos_paths = cross_val_predict(estimator=pipeline, X=X, y=y, cv=cv, sample_weight=w)
pbo = compute_pbo(oos_paths)
dsr = compute_deflated_sharpe(oos_paths, n_trials=get_trial_count_from_mlflow() + trial_counter)
if pbo > 0.50 or dsr.p_value > 0.05:
raise ValueError(f"Model rejected: PBO={pbo:.2f}, DSR p={dsr.p_value:.3f}")
final_model = pipeline.fit(X, y, model__sample_weight=w)
return final_model, pbo, dsr
# 5. REGIME GATE -- causal, walk-forward, FILTERED (never smoothed) HMM posterior
def causal_regime_state(vol_return_features: np.ndarray, t: int, model_cache: dict,
refit_every: int = 63, min_train: int = 500) -> int:
if t < min_train:
return 1 # default "calm" until enough history exists
if t % refit_every == 0 or "model" not in model_cache:
hmm = GaussianHMM(n_components=2, covariance_type="diag", n_iter=200)
hmm.fit(vol_return_features[:t]) # only data strictly before t
model_cache["model"] = hmm
posteriors = model_cache["model"].predict_proba(vol_return_features[: t + 1])
return int(posteriors[-1].argmax()) # filtered state at t, no look-ahead
# 6. VOL-TARGETED SIZING -- GJR-GARCH forecast -> fractional-Kelly-scaled size
def size_position(returns_pct: pd.Series, meta_label_confidence: float, regime_state: int,
target_vol_annual: float = 0.10, kelly_fraction: float = 0.5,
max_leverage: float = 1.5) -> float:
if regime_state == 0: # 0 = "stormy" -- stand aside
return 0.0
res = arch_model(returns_pct, vol="GARCH", p=1, o=1, q=1, dist="t").fit(disp="off")
vol_fc = np.sqrt(res.forecast(horizon=1, reindex=False).variance.values[-1, 0]) / 100
vol_scale = (target_vol_annual / (252 ** 0.5)) / vol_fc
kelly_scale = kelly_fraction * max(2 * meta_label_confidence - 1, 0) # confidence -> edge proxy
return float(np.clip(vol_scale * kelly_scale, 0, max_leverage))
# 7. BACKTEST -- NautilusTrader (same strategy class runs backtest AND live)
class MetaLabelStrategy(Strategy):
def __init__(self, model, hmm_cache, config):
super().__init__(config)
self.model, self.hmm_cache = model, hmm_cache
def on_bar(self, bar):
feats = self.build_live_features(bar) # same code path as build_features()
confidence = self.model.predict_proba(feats)[:, 1][0]
regime = causal_regime_state(self.vol_history, self.clock.timestamp_ns, self.hmm_cache)
size = size_position(self.returns_pct_history, confidence, regime)
if confidence > 0.55 and size > 0:
self.submit_bracket_order(side="BUY", size=size, sl_atr_mult=1.5, tp_atr_mult=2.0)
def run_backtest(historical_bars, final_model, strat_config):
engine = BacktestEngine()
engine.add_data(historical_bars)
engine.add_strategy(MetaLabelStrategy(model=final_model, hmm_cache={}, config=strat_config))
return engine.run() # the SAME strategy object later promotes to paper/live -- adapters swap only
# 8. MLFLOW LOGGING -- every trial, forever (feeds the Deflated Sharpe trial count)
def log_run(params, pbo, dsr, backtest_results, final_model, trial_counter):
with mlflow.start_run(run_name=f"pipeline_v{trial_counter}"):
mlflow.log_params(params)
mlflow.log_metric("pbo", pbo)
mlflow.log_metric("dsr_p_value", dsr.p_value)
mlflow.log_metric("backtest_sharpe", backtest_results.sharpe_ratio)
mlflow.log_metric("backtest_max_dd", backtest_results.max_drawdown)
mlflow.log_metric("trial_number_in_family", trial_counter)
mlflow.lightgbm.log_model(final_model, "meta_label_model")
# 9. EXECUTION -- PickMyTrade webhook JSON (paper first, then tiny live)
def send_to_pickmytrade(symbol, side, qty, sl_price, tp_price, webhook_url, secret):
payload = {
"secret": secret, "symbol": symbol, "action": side, # "buy" / "sell"
"quantity": qty, "stopLoss": sl_price, "takeProfit": tp_price, "orderType": "market",
}
resp = requests.post(webhook_url, json=payload, timeout=5)
resp.raise_for_status()
return resp.json()
Chaque flèche est un point de substitution, par conception
Remarquez qu'aucune étape n'est câblée en dur à un choix spécifique des sections antérieures : remplacez LightGBM par CatBoost, l'Alpha158 de Qlib par un jeu de caractéristiques fait main, NautilusTrader par QuantConnect LEAN, ou PickMyTrade par un autre pont d'exécution, et rien d'autre dans le pipeline n'a besoin de changer. Ce découplage est ce qui rend la matrice de décision du §15 exploitable plutôt que prescriptive.
14.5
Claude Fable comme co-ingénieur pour cette stack
Claude Fable est le modèle de pointe d'Anthropic (id de modèle claude-fable-5), disponible via l'app Claude et Claude Code. Sur une stack aussi profonde, sa valeur n'est pas « écris-moi un bot de trading » — c'est le milieu ingrat et sujet aux erreurs : réussir l'arithmétique des folds de CPCV, écrire une boucle de décodage HMM causale (pas fuyante) du premier coup, câbler un gestionnaire de données Qlib pour un marché non livré en standard, et lire un pipeline multi-étapes de bout en bout pour trouver l'unique fuite qui, sinon, ne referait surface que comme un écart réel/backtest des mois plus tard.
Là où il gagne sa place sur la stack spécifique de cette page :
Logique des folds de CPCV — dériver les tailles de purge/embargo à partir de l'horizon de votre étiquette et du lookback de caractéristique le plus lent (§7), au lieu de les deviner et de le découvrir via un Sharpe de backtest gonflé.
Inférence de régime causale — écrire la boucle walk-forward à posterior filtrée au lieu de l'appel fuyant à decode()/Viterbi sur échantillon complet montré comme exemple « faux » au §8.
Configuration Qlib — générer et adapter le YAML de workflow Alpha158/Alpha360 à un gestionnaire de données personnalisé pour une région que Qlib ne livre pas, comme l'exemple NSE au §6.
Revue de fuites sur tout le pipeline — lire le squelette du §14 étape par étape pour un bug d'ajustement hors du fold avant qu'il ne touche du capital.
Conversion Pine Script → Python — porter la logique d'entrée d'une stratégie TradingView dans la fonction de signal primaire qui alimente le modèle de méta-étiquetage.
Colle d'exécution — rédiger le code du payload de webhook/de la clé d'idempotence couvert au §14.6, et la journalisation MLflow qui garde honnête votre décompte d'essais du Deflated Sharpe (§12).
Des prompts prêts à adapter pour chacun de ces cas — spécifiques à la stack de cette page, pas des demandes génériques de « construis-moi un bot » :
Prompt 1 · Revue de purge/embargo de CPCV
Review this skfolio CombinatorialPurgedCV setup [paste code]: 10 folds, 2 test folds, on triple-barrier-labeled
signals where barriers can resolve up to 10 trading days after the signal (get_events num_days=10). Check whether
purged_size and embargo_size are large enough to cover that full label-resolution window plus my slowest feature's
lookback. Flag any fold where a training sample's resolution window overlaps a test sample's, explain the leak, and
give me corrected purge/embargo values with the reasoning shown.
Prompt 2 · Garde-fou de régime HMM causal, pas fuyant
Here is my hmmlearn regime-detection code [paste code]. Confirm it only calls predict_proba on data up to and
including index t when producing the label used AT time t, and that it never calls hmm.decode() or reads a Viterbi
path computed over the full series. If it's using the full-sample smoothed posterior, rewrite it as a walk-forward
loop that refits every N bars on strictly past data and returns the filtered (not smoothed) posterior at each step,
matching the causal pattern, not the leaky one.
Prompt 3 · Qlib Alpha158 sur un marché non par défaut
I want Microsoft Qlib's Alpha158 handler running on NSE (India) equities, not one of Qlib's built-in regions.
Here's my current workflow YAML [paste config]. Write a custom data handler/provider that points Alpha158's feature
computation at my own point-in-time OHLCV store instead of Qlib's default region data, keeping the Alpha158 feature
set intact. Explain specifically what breaks -- calendar, instrument universe, trading-day alignment -- if I just
change the region tag without supplying compatible replacements.
Prompt 4 · Audit de fuites sur tout le pipeline
Here is my end-to-end pipeline: data ingestion, feature engineering, triple-barrier labeling, LightGBM meta-label
training inside CombinatorialPurgedCV, HMM regime gate, GARCH-based sizing, and NautilusTrader backtest [paste code].
Walk it stage by stage and flag every point where a transform -- scaler, feature selector, frac-diff order search, HMM
fit -- is fit on data outside the current CV training fold, or a feature could see information unavailable at signal
time. Rank findings by how much each would inflate the backtest Sharpe if left uncorrected.
Prompt 5 · Pine Script → fonction de signal primaire
Here is my TradingView Pine Script strategy [paste script]. Convert its entry logic into a Python function that
takes a pandas DataFrame of OHLCV bars and returns a boolean signal series, matching the Pine version bar-for-bar on
identical historical data. This becomes the primary-model signal feeding my meta-labeling filter, so flag anything --
security() calls with lookahead, use of the current bar's close before it closes -- that would make the two versions
diverge.
Prompt 6 · Payload de webhook + clé d'idempotence
Write a Python function that takes a meta-label confidence score, ATR-based stop/target multiples, and a
position size from my vol-targeted sizing calc, and builds the JSON payload for a PickMyTrade webhook POST -- symbol,
side, quantity, stopLoss, takeProfit. Add a deterministic idempotency key (hash of symbol + signal timestamp + bar
index) as a payload field, and wrap the POST in retry-with-backoff logic that treats a timeout as "unknown, reconcile
before retrying" rather than blindly resubmitting.
Fable rédige, vous fusionnez
Aucun des prompts ci-dessus ne remplace la lecture du diff par vous-même. Claude Fable est rapide sur les parties mécaniques — arithmétique des folds de CV, logique de réessai standard, conversion de Pine vers pandas — mais les tailles de purge/embargo, les seuils de rejet PBO/DSR et la décision d'acheminer du capital via un webhook donné restent les vôtres à valider, à chaque fois, avant que quoi que ce soit ne touche un compte paper ou réel.
14.6
Pont d'exécution — construire vs. acheter pour le dernier saut
La même décision construire vs. acheter que prend toute équipe systèmes, appliquée au dernier saut du pipeline du §14 : vos rares heures d'ingénierie vont-elles à la tuyauterie de routage d'ordres, ou aux couches de modèle qui sont réellement les vôtres ? Cette section plaide pour traiter l'exécution en direct comme une dépendance achetée à interface étroite — et montre à quoi ressemble l'interface côté pipeline.
1 · La tuyauterie de routage d'ordres a un large rayon d'impact pour les bugs silencieux
Logique de réessai, ré-authentification de session courtier, réconciliation d'exécutions partielles, machines à états de brackets OCO, déduplication de webhooks — chacun est un problème bien compris isolément, et chacun est exactement le genre de code où un bug ne lève pas d'exception. Il duplique silencieusement un ordre, laisse tomber un stop, ou laisse une machine à états sur le mauvais nœud. Un écouteur planté détenant une position à terme ouverte du jour au lendemain n'est pas une trace d'appel ; c'est un appel au desk de votre courtier.
2 · Un bug d'exécution silencieux est un événement de P&L, pas une exception capturée
Les erreurs de votre modèle se manifestent par un Sharpe plus faible sur des milliers de trades — bruyantes mais bornées et diagnosticables. Une erreur de la couche d'exécution se manifeste par un stop manquant précis ou une exécution en double, réalisée en dollars, généralement l'unique fois où la volatilité s'envole et où vous ne regardez pas le terminal. Les tests unitaires attrapent les bugs pour lesquels vous avez pensé à écrire un test ; ils attrapent rarement un token de session expirant en milieu de journée ou un webhook livré deux fois lors d'un couac réseau.
3 · Les heures qui valent la peine d'être dépensées sont celles que vous seul pouvez dépenser
Réessai/backoff, machines à états OCO et traduction d'ordres spécifique au courtier sont le même problème pour chaque trader qui achemine vers Rithmic ou IB — c'est précisément pourquoi ils sont banalisés. Votre modèle de méta-étiquetage, votre garde-fou de régime et votre validation CPCV ne sont résolus nulle part ailleurs ; ce sont la seule couche où une heure de plus peut réellement faire bouger votre Sharpe. Une heure à durcir un routeur d'ordres maison contre des cas limites contre lesquels quelqu'un s'est déjà durci est une heure non dépensée là.
4 · La séparation des responsabilités est un motif de fiabilité, pas une coquetterie
Une interface HTTP étroite et bête — un POST, une forme de payload — entre stratégie et courtier signifie que votre code de recherche peut être aussi expérimental que vous le souhaitez sans jamais détenir un token de session en direct. Si l'infrastructure du fournisseur d'exécution a un incident, c'est sa rotation d'astreinte, pas une alerte à 2 h du matin pour vous ni un bug dans votre modèle. C'est la même raison pour laquelle les équipes plateforme ne laissent pas le code applicatif ouvrir des sockets bruts vers une base de données.
Où cela se situe dans le pipeline du §14
Le pipeline de référence se termine à « journalisation MLflow → webhook PickMyTrade pour l'exécution » parce que c'est la frontière de confiance naturelle. Votre modèle émet un signal → une alerte TradingView se déclenche, ou — puisqu'une configuration avancée peut contourner TradingView entièrement — votre propre service Python construit et POST le JSON directement vers le endpoint webhook de PickMyTrade → PickMyTrade prend en charge le placement des brackets OCO, la traduction d'ordres spécifique au courtier, le fan-out multi-comptes et la boucle de reconnexion/réessai face à la place vers laquelle vous acheminez. Cette division du travail signifie que votre service n'a qu'à être fiable jusqu'à « envoyer un seul POST HTTP idempotent » — il n'a jamais à maintenir une connexion à état, sur plusieurs semaines, à l'API de session d'un courtier, à rafraîchir des tokens d'authentification selon un planning, ni à réconcilier l'état des ordres après une partition réseau. Toute cette catégorie de problème quitte votre assiette.
JSON · forme illustrative du payload d'un webhook (générique — vérifiez les noms des champs dans la documentation actuelle du fournisseur)
Délibérément générique — ce n'est pas un schéma PickMyTrade vérifié (voir l'appel fonctionnel send_to_pickmytrade() au §14 pour les noms de champs déjà utilisés dans le pipeline de référence de cette page). quantity provient directement du calcul de dimensionnement ciblé sur la volatilité des §11/§14 ; stopLoss/takeProfit correspondent à l'entrée ± ATR × les multiples de barrière déjà validés dans le labeling en triple barrière (§7) ; idempotencyKey — absent de l'exemple minimal du §14 — est ce qui transforme une livraison de webhook « au moins une fois » en un ordre « effectivement une seule fois ».
Les modes de défaillance qu'il vaut la peine d'anticiper dès le départ
La livraison des webhooks se fait « au moins une fois », pas « exactement une fois » — sans quoi un POST relancé après un délai d'attente peut dupliquer un ordre ; une clé d'idempotence est ce qui rend les relances sûres. Les limites de débit des API des courtiers et les cycles de rafraîchissement des jetons d'authentification sont des détails propres à chaque courtier (jetons de session Rithmic, reconnexions d'IB Gateway, rafraîchissement OAuth de Tradovate) qu'une couche d'exécution partagée a déjà rencontrés des milliers de fois sur les comptes d'autres utilisateurs. La réconciliation de l'état des ordres après une partition réseau — cet ordre bracket a-t-il vraiment été placé, ou la connexion a-t-elle coupé avant l'accusé de réception ? — impose d'interroger l'état des ordres chez le courtier et de le comparer à ce que vous croyez avoir envoyé, à chaque reconnexion. Sous tout cela : votre code de recherche n'a aucune exigence de SLA — un noyau planté vous coûte une réexécution — tandis que votre code d'exécution a besoin d'une fiabilité proche des cinq neuf, car « le listener est resté hors service quatre minutes » est indiscernable, dans ses conséquences, de « le stop-loss n'existait pas ».
Maintenez à zéro le rayon d'impact de l'environnement de recherche
Votre code de backtest, de réentraînement et d'expériences suivies avec MLflow (§12) ne devrait comporter aucun chemin de code capable de passer un ordre réel — ni feature flag, ni valeur par défaut dry_run=False attendant d'être basculée par erreur. Faire transiter chaque ordre réel par une unique frontière HTTP externe et étroite impose cette séparation de manière structurelle : la seule façon pour le code de recherche de passer une transaction réelle serait de construire délibérément exactement le même POST de webhook que celui de votre stratégie en production. C'est la même raison pour laquelle les runners CI n'obtiennent pas les identifiants de la base de données de production — ici, cela coûte un abonnement plutôt qu'une seconde rotation d'astreinte.
Une infrastructure banalisée, consommée via API
Traitez l'exécution comme vous traitez déjà le calcul : vous n'installez pas vos propres serveurs pour obtenir un GPU, et il n'y a pas non plus d'alpha à installer votre propre routeur d'ordres. PickMyTrade est une infrastructure que vous appelez, pas un composant de votre avantage — le modèle, le filtre de régime et la validation sont les parties de cette pile qui méritent d'être défendues.
15
Matrice de décision — quel outil pour quelle tâche
Une table de correspondance unique pour « j'ai besoin de… → utilisez ceci → parce que… ».
I need to…
Use
Why
Filter trade quality (meta-label)
LightGBM + mlfinpy triple-barrier
Highest-ROI, lowest-risk ML addition; GBDT dominates tabular financial data
Statistical drift tests (KS, PSI, Wasserstein) across features and predictions
Estimate live performance before labels arrive
NannyML (CBPE/DLE)
Label-free — critical since triple-barrier outcomes only resolve after the barrier is hit
Use financial sentiment as a risk veto
FinBERT (ProsusAI)
Apache-2.0, CPU, sub-second — defensive filter, not an alpha engine
Cheaply fine-tune an LLM on financial text
FinGPT (LoRA on LLaMA)
~3.67M trainable params vs. 6.17B full fine-tune — fits on one consumer GPU
Orchestrate the nightly pipeline
Prefect (Dagster at scale)
Scheduling/retries/caching once a cron script becomes unwieldy — not needed pre-MVP
Avoid a non-commercial license trap
Prefer Chronos / TimesFM / Lag-Llama / MOMENT over Moirai
Moirai is CC BY-NC-4.0 — not usable in a system that manages your own capital
Find structural breaks / changepoints
ruptures (PELT)
Linear-cost exact search, no assumed number of breakpoints
Use RL without it blowing up your backtest
Stable-Baselines3 (PPO) on a narrow sub-problem, PBO-tested
FinRL's own contests reject overfit agents at 10% significance — confine RL accordingly
Execute live orders
PickMyTrade webhook
Execution is a solved, hardened problem — your edge lives in the model layers, not order plumbing
Draft / review pipeline code quickly
Claude Fable (claude-fable-5)
Pair-engineer for CPCV fold math, causal HMM decoding, and leakage review — see §14.5; every merge is still a human decision
Bridge a model signal to a live broker order
PickMyTrade (webhook execution bridge)
One idempotent POST replaces weeks of broker auth, retry, and OCO state-machine engineering — see §14.6
16
Annexe sur les licences
Chaque outil et modèle abordé sur cette page, avec sa licence et un indicateur clair. Sûr = permissif, sans restriction notable pour un usage commercial ou de trading en réel. Prudence = utilisable, mais lisez les conditions (obligations de copyleft, clauses de code disponible mais restreint, ou préoccupation liée à l'état de maintenance plutôt qu'à la licence). Restreint = un véritable obstacle pour un système commercial ou en réel sans restriction, en l'absence d'un accord distinct.
Covers §2's from-scratch DL architectures via one API
Nixtla TimeGPT
Proprietary / paid API
Caution
Closed, vendor lock-in; prefer open Chronos/TimesFM instead
Amazon Chronos / Chronos-Bolt
Apache-2.0
Safe
—
Google TimesFM
Apache-2.0
Safe
—
Salesforce Moirai / Moirai-MoE
CC BY-NC-4.0
Restricted
Non-commercial only — do not use in a system managing your own capital without a separate license
Lag-Llama
Apache-2.0
Safe
—
MOMENT
MIT
Safe
—
IBM Granite-TimeSeries (PatchTSMixer/PatchTST/TTM)
Apache-2.0
Safe
—
FinBERT (ProsusAI)
Apache-2.0
Safe
—
FinBERT-tone
Apache-2.0
Safe
—
FinGPT (code)
MIT
Caution
Code is MIT, but fine-tuned checkpoints inherit the base LLaMA weights' separate Meta community license — check that independently
FinRL / FinRL-Meta
MIT
Safe
—
Stable-Baselines3
MIT
Safe
—
TensorTrade
Apache-2.0
Caution
License is permissive, but maintenance has stalled enough that a community fork (TensorTrade-NG) exists specifically to address it — plan accordingly
Microsoft Qlib
MIT
Safe
—
mlfinpy
MIT
Safe
—
skfolio
BSD-3-Clause
Safe
—
mlfinlab (paid)
Commercial
Caution
Paid license required — the two free packages above already cover the essentials
hmmlearn
BSD
Safe
—
ruptures
BSD-2-Clause
Safe
—
vectorbt (community)
Apache-2.0 + Commons Clause
Caution
Commons Clause blocks selling a product/service whose value derives primarily from the software itself; fine for internal use, and maintenance-frozen
backtrader
GPL-3.0
Restricted
Strong copyleft; also stalled since ~2021 — avoid for new work on both grounds
Zipline-reloaded
Apache-2.0
Safe
—
NautilusTrader
LGPL-3.0-or-later
Caution
Permits linking from closed-source strategy code; modifications to NautilusTrader itself must be shared back — verify current terms before commercial deployment
QuantConnect LEAN
Apache-2.0
Safe
—
bt
MIT
Safe
—
backtesting.py
AGPL-3.0
Restricted
Network-use copyleft — a real constraint if you build a hosted/SaaS product on it; fine for private, non-distributed use
freqtrade
GPL-3.0
Restricted
Crypto-only bot; strong copyleft restricts closed-source commercial derivatives — flagged since it's a common trap
PyPortfolioOpt
MIT
Safe
—
Riskfolio-Lib
BSD-3-Clause
Safe
—
arch
NCSA
Safe
Permissive, commercial-OK
tsfresh
MIT
Safe
—
MLflow
Apache-2.0
Safe
—
Evidently AI
Apache-2.0
Safe
—
NannyML
Apache-2.0
Safe
—
Prefect
Apache-2.0
Safe
—
Dagster
Apache-2.0
Safe
—
PickMyTrade
Proprietary / paid SaaS
Caution
Execution API, not an installable library — no open-source or self-hosted option; a subscription gates access (see §14.6), a vendor-dependency call rather than an OSS-license one
Ceci n'est pas un avis juridique
Les licences et leur interprétation peuvent évoluer, et les limites de l'« usage commercial » (en particulier pour CC BY-NC et AGPL) sont réellement propres à chaque cas. Considérez ce tableau comme une carte de départ pour votre diligence raisonnable, et non comme un substitut à la lecture par vous-même du texte actuel de la licence — ou à l'avis d'un avocat — avant tout déploiement engageant du capital réel ou distribué à des tiers.
Avertissement financier important
À des fins éducatives uniquement. Tout le contenu de cette page est fourni à des fins éducatives et informatives générales et ne constitue ni un conseil en investissement, financier, juridique ou fiscal, ni une recommandation ou sollicitation d'achat ou de vente d'un quelconque titre, contrat à terme ou autre instrument financier.
Risque substantiel de perte. Le trading de contrats à terme, de produits dérivés et d'autres produits à effet de levier comporte un risque substantiel de perte et ne convient pas à tous les investisseurs. Vous pouvez perdre plus que votre investissement initial. Seul du capital à risque — de l'argent que vous pouvez vous permettre de perdre sans que cela affecte votre mode de vie — doit être utilisé pour le trading.
Les performances passées ne préjugent pas des résultats futurs. Les résultats de performance hypothétiques et issus de backtests présentent des limites inhérentes : ils sont établis avec le recul, n'impliquent aucun risque financier et ne peuvent tenir compte de tous les facteurs — dont la capacité à supporter des pertes — qui affectent le trading réel. Chaque chiffre de benchmark et chaque nombre d'étoiles ou de téléchargements cité sur cette page reflète un instantané à un moment donné, pris lors de recherches menées à la mi-2026, et peut avoir changé au moment où vous le lisez — vérifiez les chiffres actuels auprès de la source primaire (dépôt GitHub, fiche de modèle Hugging Face ou article cité) avant de vous y fier.
Aucune garantie. Rien sur cette page ne garantit un profit ni une protection contre les pertes. Les modèles d'apprentissage automatique — y compris les modèles de fondation pour séries temporelles évoqués au §3 — peuvent se tromper, les conditions de marché évoluent et les systèmes automatisés peuvent connaître des dysfonctionnements.
Pas un conseiller enregistré. L'auteur et l'éditeur de cette page ne sont ni un conseiller en investissement enregistré, ni un courtier-négociant, ni un conseiller en trading de matières premières (CTA), ni un planificateur financier. Avant de prendre toute décision financière, consultez un conseiller financier agréé en mesure d'évaluer votre situation personnelle.
Pas un avis juridique sur les licences. L'annexe sur les licences du §16 est fournie par commodité et reflète une lecture de bonne foi des fichiers de licence publiquement disponibles au moment de la recherche ; il ne s'agit pas d'un avis juridique. Confirmez les conditions de licence actuelles directement auprès de chaque projet avant tout usage commercial ou en production.
À propos des outils mentionnés. PickMyTrade est un outil tiers d'automatisation de l'exécution qui achemine des alertes vers les courtiers ; il ne fournit ni conseil, ni signal, ni stratégie de trading. Toutes les bibliothèques, tous les modèles et frameworks nommés (Hugging Face, Amazon, Google, Salesforce, IBM, Microsoft, Meta/LLaMA, AI4Finance Foundation et tout projet open source référencé) sont la propriété de leurs détenteurs respectifs ; cette page est un contenu éducatif indépendant, ni approuvé par ni affilié à aucun d'entre eux. Les détails factuels (licences, nombres d'étoiles, chiffres de benchmark) ont été extraits des dépôts officiels, des fiches de modèles et des articles cités au moment de la recherche et peuvent changer — vérifiez toujours auprès de la source primaire.
Votre avantage réside dans les couches du modèle, du filtre de régime et de la validation. Laissez PickMyTrade prendre en charge la plomberie de l'exécution — un unique webhook idempotent vers plus de 60 courtiers et prop firms, avec ordres bracket attachés.