⚠ Le trading comporte un risque important de perte. Tout le contenu de ce site est fourni à des fins éducatives uniquement et ne constitue pas un conseil financier.
Leçon 12 sur 13 · Gratuit

Automatiser une watchlist quotidienne : un script planifié qui récupère les données, calcule les signaux et rédige un rapport, et les pièges des clés d'API et des limites de requêtes

Transformez le code d'un notebook en un script robuste en ligne de commande, avec configuration, journalisation, nouvelles tentatives avec temporisation croissante, gestion sûre des clés d'API et planificateur, et produisez un fichier de rapport quotidien.

Auteur: Moustafa HijaziContenu relu le: 2026-10-307 min de lectureCours en autoformation

Ce que vous allez apprendre

  • Comment restructurer des cellules de notebook en un script doté de fonctions, d'un point d'entrée main() et d'un fichier de configuration.
  • Comment garder les clés d'API hors du code et gérer les limites de requêtes par l'attente et une temporisation exponentielle (exponential back-off).
  • Comment rédiger un rapport utile à 07:30 du matin : un tableau classé, quelques alertes et un horodatage.
  • Comment planifier le script avec cron ou le Planificateur de tâches de Windows, et quoi journaliser pour que les échecs silencieux ne passent pas inaperçus.

Explication

Un notebook sert à explorer ; un script répète la même tâche chaque jour sans que vous ayez à le surveiller. Les indicateurs (leçon 6) et la logique des signaux (leçons 7 et 8) restent les mêmes ; tout ce qui les entoure change.

Structure du script

Découpez le travail en fonctions ayant chacune une seule tâche : load_config(), fetch(ticker), compute_signals(df), build_report(rows) et main(). La garde if __name__ == '__main__': main() vous permet d'exécuter le fichier tout en important ses fonctions dans des tests. Conservez la watchlist, les paramètres et le dossier de sortie dans config.yaml ou config.json, afin de pouvoir les modifier sans toucher au code.

Clés d'API et secrets

N'écrivez jamais une clé dans le code source ou dans un notebook que vous pourriez partager ou versionner dans Git. Lisez-la depuis une variable d'environnement ou un fichier .env avec os.environ['DATA_API_KEY'] (le paquet python-dotenv charge le fichier .env), et inscrivez .env dans .gitignore. Traitez la clé comme un mot de passe et renouvelez-la si elle fuite.

Limites de requêtes, nouvelles tentatives et temporisation

Une limite de requêtes (rate limit) est le nombre maximal de requêtes qu'un fournisseur autorise par minute ou par jour ; la dépasser renvoie une erreur HTTP 429 ou, pire, des données vides sans erreur. Cadencez la boucle avec time.sleep(60 / max_per_minute). En cas d'échec temporaire (429, 500, délais dépassés), réessayez avec une temporisation exponentielle : attendez 1 s, 2 s, 4 s, 8 s, puis abandonnez et journalisez le ticker comme manquant. Ne réessayez jamais dans une boucle serrée ; c'est ainsi que des clés se font bannir.

  • def fetch_with_retry(ticker, tries=4, base=1.0):
  • for n in range(tries):
  • try:
  • return fetch(ticker)
  • except TransientError as e:
  • wait = base * 2 ** n
  • log.warning('%s : %s, nouvel essai dans %.0f s', ticker, e, wait)
  • time.sleep(wait)
  • log.error('%s : abandon', ticker)
  • return None

Mettez en cache les téléchargements bruts (data/raw/TICKER_YYYY-MM-DD.parquet) : une seconde exécution le même jour lit le fichier au lieu de consommer du quota, et vous conservez une trace de ce que le script a vu.

Validation avant les signaux

Les données arrivent défectueuses plus souvent que vous ne le pensez : une dernière barre manquante, une date périmée, une clôture à 0, un split non ajusté. Vérifiez que la dernière date correspond à la date de bourse attendue, que les 20 dernières lignes ne contiennent aucun NaN et que le rendement absolu du jour reste sous un seuil de vraisemblance, par exemple 50 %. Les échecs sont consignés dans une section « problèmes de données » du rapport au lieu de produire un signal d'achat sur une cotation erronée.

Le rapport

Écrivez un fichier Markdown ou HTML contenant l'horodatage de l'exécution et la date des données, un tableau trié selon votre classement (par exemple la distance à la SMA sur 50 jours en unités d'ATR), les nouveaux signaux depuis la veille (comparés au fichier de signaux enregistré la veille) et les problèmes de données. Enregistrez-le sous reports/watchlist_2026-10-30.md pour conserver l'historique ; des graphiques par ticker signalé (leçon 10) sont facultatifs.

Planification et journalisation

Sous Linux et macOS, cron exécute des commandes selon un horaire : 30 6 * * 1-5 /path/venv/bin/python /path/watchlist.py >> /path/logs/cron.log 2>&1 s'exécute à 06:30 les jours ouvrés ; sous Windows, le Planificateur de tâches fait la même chose via une boîte de dialogue. Utilisez le chemin complet du Python de l'environnement virtuel (leçon 1), car les planificateurs n'activent pas les environnements. Journalisez dans un fichier avec le module logging : démarrage, tickers récupérés, signaux trouvés, fin. L'absence d'entrée pour aujourd'hui signifie que le planificateur a échoué. Les ordinateurs se mettent en veille, les réseaux tombent, les points d'accès changent ; un script que vous ne vérifiez pas n'est pas de l'automatisation.

Exemple commenté

Exemple hypothétique : une watchlist de 40 actions européennes et américaines, une offre de données gratuite limitée à 5 requêtes par minute et 500 par jour (chiffres inventés ; vérifiez les conditions actuelles de votre fournisseur).

  1. Cadence. 40 tickers à 5 par minute = 40 / 5 = 8 minutes au minimum. Le script attend 12 secondes entre les appels. Une planification à 06:30 signifie que les données sont prêtes vers 06:40.
  2. Quota. Une exécution consomme 40 des 500 appels quotidiens (880 par mois sur 22 jours de bourse). Un bug qui relancerait le script toutes les 10 minutes brûlerait 240 appels par heure et atteindrait le plafond en deux heures environ ; un cache sur disque élimine ce risque.
  3. Temporisation. Deux tickers renvoient une erreur HTTP 429 au premier essai. Les nouvelles tentatives après 1, 2 et 4 secondes réussissent au deuxième essai ; dans le pire des cas, le temps supplémentaire est de 1 + 2 + 4 + 8 = 15 secondes par ticker, l'exécution se termine donc toujours dans le budget de 10 minutes.
  4. Rapport. Règle : « la clôture croise à la hausse la SMA sur 50 jours avec un RSI(14) inférieur à 60 ». Le fichier de la veille comptait 3 signaux actifs ; l'exécution du jour en trouve 5, dont 2 nouveaux. Le rapport liste d'abord les 2 nouvelles valeurs, puis les 3 qui se poursuivent, et 1 ticker sous « problèmes de données » parce que sa dernière barre date de deux jours.

Exclu : rien de tout cela ne dit si le signal est rentable ; cela rend seulement la préparation quotidienne fiable et reproductible.

Erreur fréquente

Se fier à une exécution qui n'a produit aucune erreurDe nombreux fournisseurs renvoient un DataFrame vide ou les données de la veille lorsque le quota est épuisé, et pandas calculera volontiers des indicateurs dessus. Un script qui se contente d'intercepter les exceptions affichera « 0 nouveau signal » et paraîtra en bonne santé. Validez la date des données et le nombre de lignes à chaque exécution, et faites figurer la date des données dès la première ligne du rapport.

Exercice pratique

Sur papier : votre fournisseur autorise 30 requêtes par minute et 2,000 par jour. Vous voulez exécuter une watchlist de 150 tickers une fois à 06:00 et actualiser 20 tickers prioritaires toutes les 30 minutes entre 09:00 et 17:30 (CET). (a) Quel délai minimal entre les appels respecte la limite par minute ? (b) Combien d'appels une journée complète consomme-t-elle ? Est-ce dans le quota quotidien ? (c) L'exécution de 06:00 indique 150 tickers récupérés, mais tous les signaux sont identiques à ceux de la veille. Citez deux vérifications qui vous diraient si les données sont fraîches.

Afficher la solution

(a) 60 / 30 = 2 secondes entre les appels (prenez 2.1 s par sécurité).

(b) Exécution du matin : 150 appels. En journée : de 09:00 à 17:30, il y a 8.5 heures = 17 créneaux d'une demi-heure, plus le créneau de 09:00 lui-même = 18 actualisations × 20 tickers = 360 appels. Total de 510 appels, bien en deçà de 2,000. Même avec une nouvelle tentative complète pour chaque appel (1,020), le quota tient.

(c) Vérifiez que la dernière date d'index de chaque DataFrame correspond au jour de bourse précédent attendu (en tenant compte des jours fériés boursiers), et comparez une empreinte (hash) ou la dernière clôture du téléchargement du jour avec le fichier mis en cache la veille ; si les 150 dernières clôtures sont identiques à celles de la veille, le fournisseur a servi des données périmées.

Limites : les quotas, les points d'accès et les règles des offres gratuites changent ; les chiffres donnés ici sont illustratifs et vous devez lire la documentation actuelle de votre fournisseur.

Points clés à retenir

  • Les scripts ont besoin de fonctions, d'un fichier de configuration, d'une garde main() et d'une journalisation ; les notebooks, non.
  • Conservez les clés dans des variables d'environnement ou dans .env ; cadencez les requêtes selon la limite et réessayez avec une temporisation exponentielle, puis abandonnez et journalisez.
  • Validez les dates et le nombre de lignes avant de calculer les signaux ; mettez en cache les téléchargements bruts.
  • Planifiez avec cron ou le Planificateur de tâches en utilisant le chemin complet du Python de l'environnement virtuel, et consultez le journal chaque jour.

Étape suivante

La leçon 13 assemble le tout en un projet complet de notebook de recherche, des données au rapport, et le passe en revue avec une liste de contrôle contre le biais d'anticipation et le surapprentissage.

Auto-évaluation

Répondez aux questions, puis vérifiez vos réponses. Vous pouvez recommencer autant de fois que vous le souhaitez.

1. Un fournisseur autorise 10 requêtes par minute. Votre watchlist compte 75 tickers et vous voulez aussi une marge de temps de 20 %. Combien de temps faut-il prévoir pour la boucle de récupération ?

2. Quelle organisation protège le mieux une clé d'API tout en permettant de partager le script dans un dépôt Git ?

3. Votre script planifié a échoué trois jours de suite et vous ne l'avez remarqué que le quatrième jour. Quel changement unique aurait le plus directement réduit ce délai ?

Auto-évaluation automatique pour vos propres révisions. Vos réponses sont vérifiées dans votre navigateur ; nous ne les voyons pas et ne les évaluons pas. Ce n'est ni un examen ni une qualification.

Votre progression

« Terminée » signifie seulement que vous avez marqué la leçon comme lue. Ce n'est pas un test de votre compréhension. La progression et les notes sont enregistrées uniquement dans ce navigateur, sur cet appareil — pas dans un compte.