Aller au contenu
Table des matières

BatchBacktesting

BatchBacktesting transforme un backtest en traitement reproductible : choisir les instruments, obtenir et nettoyer les prix, exécuter une stratégie, puis conserver des résultats comparables. C’est un dépôt AlgoÉTS ; les faits ci-dessous viennent de ses fichiers source et de son README, lus pour l’article associé.

  • Mis à jour

1. Aperçu

Pourquoi il existe. Un backtest par lots est un petit pipeline de données, et le projet garde chaque étape visible en Python plutôt que derrière un tableau de bord.

Cas d’usage. Comparer une stratégie sur plusieurs instruments avec les mêmes hypothèses enregistrées, puis lire côte à côte les CSV par instrument et agrégés.

2. Cas d’utilisation

Carnets d'AlgoÉTS qui testent en parallèle des stratégies d'indicateurs sur le S&P 500 et des cryptos, avec CSV et graphiques.

Diagramme de cas d’utilisation de BatchBacktesting : Constituer l'univers de titres; Télécharger les cours; Tester une stratégie en lot; Toutes stratégies, un titre; Comparer au buy & hold; Ouvrir les graphiques HTMLBatchBacktestingConstituer l'univers de titresTélécharger les coursTester une stratégie en lotToutes stratégies, un titreComparer au buy & holdOuvrir les graphiques HTMLChercheur en stratégie«système»API de cours FMP«système»Liste S&P 500 (Wiki)
Acteurs à gauche (personnes) et à droite (systèmes externes) ; chaque ovale est un cas d’utilisation appuyé par les fichiers cités ci-dessous.
Constituer l'univers de titres
Chercheur en stratégieListe S&P 500 (Wiki)

get_SP500() lit la table des symboles du S&P 500 sur Wikipédia avec pandas.read_html, et get_all_crypto() renvoie une liste fixe de paires crypto comme BTCUSD et ETHUSD.

Télécharger les cours
Chercheur en stratégieAPI de cours FMP

process_instrument appelle le point historical-price-full de FMP pour les actions, ou sa variante crypto, avec la clé FMP_API_KEY lue dans l'environnement par src/config.py.

Tester une stratégie en lot
Chercheur en stratégieAPI de cours FMP

run_backtests(tickers, strategy=EMA, num_threads=12, generate_plots=True) lance backtesting.py sur chaque titre dans un pool de fils et écrit output/raw/<Stratégie>/<titre>-<début>-<fin>.csv.

Toutes stratégies, un titre
Chercheur en stratégie

run_backtests_strategies(["BMO"], STRATEGIES_STR) soumet chaque stratégie définie dans src/strategies.py (EMA, RSI, MACD, bandes de Bollinger, ADX, TRIX…) pour les instruments donnés.

Comparer au buy & hold
Chercheur en stratégie

analyse.ipynb charge output/raw/<Stratégie>/*.csv, classe les instruments selon Return [%] et trace les cinq meilleurs face au Buy & Hold Return [%] avec matplotlib.

Ouvrir les graphiques HTML
Chercheur en stratégie

Avec generate_plots=True, plot_results enregistre chaque graphique backtesting.py dans output/charts/<Stratégie>/<titre>-<début>-<fin>.html ; le dépôt contient déjà ceux de 23 stratégies.

2.1. Scénario : Tester l'EMA sur le S&P 500

  1. Installer les dépendances avec pip install -r requirements.txt et définir FMP_API_KEY dans l'environnement (voir .env.exemple).
  2. Lancer jupyter notebook et ouvrir batch.ipynb.
  3. Exécuter la cellule tickers = get_SP500() puis run_backtests(tickers, strategy=EMA, num_threads=12, generate_plots=True).
  4. Consulter output/EMA-<début>-<fin>.csv pour les résultats combinés et output/charts/EMA/ pour un graphique HTML par titre.
  5. Ouvrir analyse.ipynb et exécuter la section EMA pour voir les meilleurs rendements et les comparer au buy and hold.

Fichiers consultésREADME.mdbatch.ipynbanalyse.ipynbsrc/BatchBacktesting.pysrc/data.pysrc/config.pysrc/strategies.pyrequirements.txt.env.exemple

3. Démarrage

Le README pointe vers un exemple publié plutôt qu’une installation en une commande ; le point d’entrée est le runner.

4. Fonctions et composants

ComposantRôle
Runner par instrumentChoisit l’adaptateur de prix, nettoie les observations, exécute un Backtest, étiquette le résultat avec l’instrument et la stratégie
Pool de workersThreadPoolExecutor, quatre workers par défaut pour une stratégie ; l’aide multi-stratégies imbrique un pool externe autour des pools internes
Paramètres par défaut100 000 de capital initial, commission de 0,002 (0,2 %), ordres exclusifs
Stratégie EMAEMA de 20, 80 et 150 périodes calculées ; les entrées comparent les courbes 20 et 80 ; côté long, fermeture de la position précédente puis achat avec stop à 90 % et cible à 125 %
SortiesCSV par instrument, CSV agrégé par stratégie, graphique HTML optionnel

5. Comment les stratégies décident

Croisement de moyennes mobiles exponentielles. La stratégie par défaut calcule des moyennes mobiles exponentielles de la clôture, EMAₜ = α · Pₜ + (1 − α) · EMAₜ₋₁ avec α = 2 / (n + 1) : 0,095 pour la moyenne sur 20 périodes et 0,025 pour celle sur 80, si bien que la courte réagit environ quatre fois plus vite. À chaque barre :

  • quand l’EMA 20 passe au-dessus de l’EMA 80, la stratégie ferme toute position et achète, avec un stop à 90 % et un objectif à 125 % de la clôture ;
  • quand l’EMA 80 passe au-dessus de l’EMA 20, elle ferme et vend à découvert, avec un stop à 110 % et un objectif à 75 %.

La moyenne sur 150 périodes est calculée mais jamais utilisée.

Ce qu’impliquent les sorties. Avec un stop à 10 % et un objectif à 25 %, un achat risque 10 pour gagner 25. Hors frais, il est à l’équilibre si plus de 10 / (10 + 25) ≈ 28,6 % des transactions atteignent l’objectif avant le stop. Chaque aller-retour paie aussi deux fois la commission de 0,2 %, ce qui relève un peu ce seuil. Comme le croisement suivant ferme d’abord la position, beaucoup de transactions se terminent sur un croisement plutôt que sur le stop ou l’objectif.

flowchart TD
  B["Nouvelle barre"] --> C1{"EMA20 passe au-dessus de l’EMA80 ?"}
  C1 -->|oui| L["Ferme la position, achète : SL 0,90 × clôture, TP 1,25 × clôture"]
  C1 -->|non| C2{"EMA80 passe au-dessus de l’EMA20 ?"}
  C2 -->|oui| S["Ferme la position, vend à découvert : SL 1,10 × clôture, TP 0,75 × clôture"]
  C2 -->|non| H["Conserve ; le courtier vérifie SL et TP"]

Les autres stratégies. src/strategies.py définit vingt-trois stratégies d’indicateurs (RSI, bandes de Bollinger, MACD, régression linéaire, ADX, OBV, Aroon, DEMA, ALMA, SMA …). La plupart suivent le même modèle, et quatorze d’entre elles utilisent les mêmes sorties 90/125 % et 110/75 %. Deux d’entre elles ne testent pas ce que leur nom suggère. Dans RSI, rsi30 et rsi70 sont des RSI calculés sur 30 et 70 barres, pas les niveaux 30 et 70 : la stratégie négocie les croisements entre trois courbes de RSI. BollingerBands n’utilise que la première colonne de pandas_ta.bbands, la bande inférieure.

Agrégation. process_instrument marque chaque résultat de Backtest.run() avec l’instrument et la stratégie, l’exécuteur les concatène en un CSV par stratégie, et analyse.py classe les instruments. get_max_return regroupe par instrument et prend max() colonne par colonne : la « meilleure » ligne mélange le meilleur rendement et la meilleure valeur de chacune des autres colonnes.

6. Architecture

flowchart TD
  I["Liste d'instruments et stratégie"] --> P["ThreadPoolExecutor"]
  P --> D["Télécharger et nettoyer l'historique"]
  D --> B["Backtest par instrument"]
  B --> R["Résultat avec instrument et stratégie"]
  R --> C["CSV par instrument"]
  R --> A["CSV agrégé par stratégie"]
  B --> H["Graphique HTML optionnel"]

7. Limites et points à vérifier

  • Un instrument en échec renvoie None ; si tous échouent, la concaténation finale n’a aucun tableau.
  • groupby("Instrument").max() dans analyse.py prend le maximum de chaque colonne séparément : une ligne de synthèse peut mélanger des métriques de runs différents. Choisissez une vraie ligne par rendement avant de citer son drawdown.
  • Les paramètres par défaut n’incluent ni le slippage, ni la disponibilité des ventes à découvert, ni les titres radiés, ni les opérations sur titres.
  • Les nombres de workers et les dates ci-dessus sont des valeurs par défaut du code et des dates d’exemple, pas un débit mesuré ni une plage fixe.

8. Liens

9. Pipeline CI/CD

Aucun pipeline CI/CD dans le dépôt. Le code se construit et se lance à la main, comme décrit plus haut.

Généré à partir du code au commit 6aae4af.

10. Schéma de déploiement

Mermaid Schéma de déploiement
flowchart LR
  repo[("Dépôt GitHub")]
  local["Poste local<br/>Python"]
  repo -->|"cloner et lancer"| local

11. Dépendances externes

5 paquets déclarés (5 à l’exécution, 0 pour le développement) dans requirements.txt.

Tableau des paquets 5
Dépendances externes
PaquetVersionUsageRôleRegistre
backtesting==0.3.3exécutionTestspypi.org
concurrent-futures==1.3.0exécution—pypi.org
numpy==1.26.0exécutionAnalyse de donnéespypi.org
pandas==1.3.5exécutionAnalyse de donnéespypi.org
pandas-ta==0.3.15exécutionAnalyse de donnéespypi.org

12. Glossaire

Dépôt

Les fichiers source, la configuration et l’historique versionné d’un projet.

README

Le document d’entrée du dépôt, qui présente généralement son rôle et son installation.

Dépendance

Une bibliothèque, un outil ou un service nécessaire à la compilation ou à l’exécution d’un composant.

HTTP

Un protocole de requête et réponse utilisé par les navigateurs et services web. Une requête comprend une méthode, un chemin, des en-têtes et parfois un corps.

Interface en ligne de commande

Une interface textuelle où les commandes et arguments choisissent les opérations. Les codes de retour permettent aux scripts de détecter un succès ou un échec.

Intégration continue

Des vérifications automatiques lors des changements de source, comme la compilation, les tests et l’analyse statique. Elles ne couvrent que ce qu’elles vérifient.

Mermaid

Un langage de diagrammes textuel. Les nœuds et liens décrivent un modèle ; le diagramme n’exécute pas le projet.

13. Références

  1. AlgoÉTS. (2026, 5 novembre). [Web page] github.com.
  2. AlgoETS. (2026, 5 novembre). src/BatchBacktesting.py. [Source file or documentation] github.com.
  3. AlgoETS. (2026, 5 novembre). src/strategies.py. [Source file or documentation] github.com.
  4. AlgoETS. (2026, 5 novembre). src/analyse.py. [Source file or documentation] github.com.
  5. output/charts/EMA. (2026, 5 novembre). [Web page] algoets.github.io.
  6. AlgoETS. (2026, 5 novembre). BatchBacktesting. [Software repository] github.com.
  7. Exemple publié. (2026, 5 novembre). [Web page] algoets.github.io.

Les sources sans date de publication indiquent la date de leur dernière vérification, le 5 novembre 2026. Les liens des fichiers conservent la révision inspectée lorsqu’elle est disponible.