Pour faire de l’analyse de données financières et du trading algorithmique, l’accès à un historique de prix fiable et complet est la première étape indispensable. Que ce soit pour tester la performance d’une stratégie (backtesting), entraîner un modèle de machine learning ou simplement pour mener des études de marché, disposer de ces données en local est un atout considérable. Nous allons voir ensemble comment construire un outil puissant et résilient en Python pour télécharger l’historique des prix du Bitcoin, ou de toute autre cryptomonnaie, en utilisant la célèbre bibliothèque CCXT.
Avant de plonger dans le code, il est essentiel de présenter l’outil principal que nous allons utiliser : CCXT (CryptoCurrency eXchange Trading Library). Il s’agit d’une bibliothèque Python qui fournit une interface unifiée pour interagir avec plus d’une centaine d’échanges de cryptomonnaies. Son avantage majeur est de vous affranchir de la nécessité d’apprendre l’API spécifique de chaque plateforme. Que vous souhaitiez vous connecter à Binance, Kraken, Coinbase ou une autre plateforme, la syntaxe pour récupérer des données ou passer des ordres restera largement la même.
Un autre point fort, particulièrement pertinent pour notre objectif, est que pour accéder aux données publiques comme l’historique des prix, il n’est généralement pas nécessaire de fournir une clé API. Cela abaisse considérablement la barrière à l’entrée. n’importe qui peut commencer à collecter des données sans même avoir de compte sur l’exchange ciblé, tant que celui-ci n’impose pas de restrictions trop sévères sur les appels non authentifiés.
Configurer la collecte de données selon vos besoins
L’un des principaux intérêts de créer son propre script est la flexibilité. Tandis que l’exemple que nous allons détailler se concentre sur la paire la plus populaire, le Bitcoin contre le Tether (BTC/USDT), le code est conçu pour être facilement adaptable. Vous pourriez tout aussi bien l’utiliser pour récupérer l’historique de l’Ethereum (ETH/USD), du Solana (SOL/USDT) ou de n’importe quelle autre paire disponible sur l’exchange de votre choix.
La flexibilité s’étend également à la granularité des données. Les données de marché sont généralement fournies sous forme de bougies (ou candles) sachant que le vrai nom étant les chandeliers japonais dans notre bon vieux français. Elles résument l’activité sur une période donnée avec quatre informations cruciales : le prix d’ouverture (Open), le plus haut (High), le plus bas (Low) et le prix de clôture (Close), ainsi que le volume des échanges (Volume). C’est ce qu’on appelle l’OHLCV. Notre script vous permettra de définir l’échelle de temps, ou timeframe, de ces bougies. Vous pouvez opter pour une granularité très fine, comme une minute (‘1m’), ce qui générera un très grand nombre de lignes de données, idéale pour des analyses détaillées. Inversement, vous pouvez choisir une vue plus large avec des bougies de quatre heures (‘4h’) ou d’une journée (‘1d’), plus adaptées à une analyse des tendances à long terme.
Enfin, il est possible de spécifier une date de début pour le téléchargement. L’historique complet de certaines paires peut être colossal et représenter des millions de lignes. En définissant une date de départ, par exemple le 1er janvier 2020, vous pouvez cibler précisément la période qui vous intéresse, économisant ainsi du temps et de l’espace de stockage.
Un script robuste et optimisé pour une collecte fiable de l’historique des prix
Le véritable défi lors du téléchargement de grandes quantités de données n’est pas seulement de faire la requête initiale, mais de gérer les imprévus. Une connexion internet peut être instable, un serveur peut être momentanément indisponible, ou le processus peut simplement être très long. Un script naïf qui s’interrompt au milieu d’un téléchargement de plusieurs heures vous forcerait à tout recommencer.
C’est là que notre script se distingue par sa robustesse. Il intègre une logique de reprise intelligente. Au lancement, il vérifie si un fichier de données existe déjà. Si c’est le cas, au lieu de l’écraser, il l’ouvre et lit de manière très efficace uniquement la toute dernière ligne enregistrée. De cette dernière ligne, il extrait le timestamp (l’horodatage précis) de la dernière bougie sauvegardée. Le téléchargement reprend alors exactement à partir de ce point, garantissant qu’aucune donnée ne soit manquante ou téléchargée en double. Cette approche est non seulement fiable mais aussi extrêmement performante, car elle évite de charger en mémoire des fichiers qui peuvent peser plusieurs gigaoctets.
De plus, le script est doté d’une gestion des erreurs réseau. En cas d’échec de connexion à l’API de l’exchange, il ne s’arrête pas brusquement. Il se met en pause pendant quelques secondes avant de réessayer, surmontant ainsi les micro-coupures et les instabilités passagères. Pour le confort de l’utilisateur, une barre de progression est affichée, indiquant en temps réel le nombre de bougies téléchargées et la date atteinte, offrant une visibilité claire sur l’avancement du processus.
Le script pour télécharger l’historique des prix d’une cryptomonnaie en Python
Avant de faire quoi que ce soit, je vous conseille de créer un environnement virtuel avec venv, uv ou encore l’outil de votre choix pour ne pas impacter votre système d’exploitation. Surtout si vous êtes sur une distribution Linux ou encore macOS. Une fois que c’est fait, il est vraiment temps de passer aux choses sérieuses.
Pour pouvoir utiliser le script, il est nécessaire de s’assurer que votre environnement Python dispose des bibliothèques requises. Celles-ci ne sont pas toutes incluses par défaut dans Python et doivent être installées manuellement. Notre script s’appuie sur trois bibliothèques externes principales :
- ccxt : Le cœur de notre application, pour communiquer avec les API des exchanges.
- pandas : Une bibliothèque incontournable pour la manipulation de données en Python. Nous l’utilisons pour structurer les données OHLCV dans un format tabulaire (DataFrame) facile à exporter en fichier CSV.
- tqdm : Un outil très pratique pour créer des barres de progression intelligentes et esthétiques, offrant une meilleure expérience utilisateur lors de longs téléchargements.
Pour installer ces trois bibliothèques en une seule commande, ouvrez votre terminal (ou invite de commandes) et exécutez la ligne suivante :
pip install ccxt pandas tqdm
Sans plus attendre, voici le code source complet commenté qui met en œuvre tous ces principes pour extraire l’historique complet du Bitcoin sur un timeframe et une durée en particulier :
import ccxt import pandas as pd from datetime import datetime, timezone import os import time from tqdm import tqdm def get_last_timestamp_from_csv(filename): """ Lit très efficacement la dernière ligne d'un CSV pour en extraire le timestamp. Retourne le timestamp en millisecondes ou None si le fichier est vide/invalide. """ try: # Ouvre le fichier en binaire pour se positionner à la fin with open(filename, 'rb') as f: # Va à la fin du fichier, puis recule de 2 octets (pour éviter le dernier \n) f.seek(-2, os.SEEK_END) # Lit en arrière jusqu'à trouver un saut de ligne while f.read(1) != b'\n': f.seek(-2, os.SEEK_CUR) # Lit la dernière ligne complète et la décode en texte last_line = f.readline().decode() # Extrait la date (la première colonne) last_date_str = last_line.split(',')[0] # Convertit la date en objet datetime, puis en timestamp millisecondes last_datetime = pd.to_datetime(last_date_str) # Assurez-vous que le datetime est conscient du fuseau horaire UTC pour une conversion correcte last_datetime_utc = last_datetime.tz_localize('UTC') return int(last_datetime_utc.timestamp() * 1000) except Exception: # Si une erreur se produit (fichier très court, corrompu, etc.), on retourne None return None def telecharger_et_mettre_a_jour(symbole, timeframe, nom_fichier, depuis_date=None): """ Télécharge l'historique OHLCV, avec sauvegarde incrémentielle et reprise automatique et optimisée. """ exchange = ccxt.binance({'enableRateLimit': True}) since = None mode_ecriture = 'w' entete = True # --- Logique de reprise optimisée --- if os.path.exists(nom_fichier) and os.path.getsize(nom_fichier) > 0: dernier_timestamp = get_last_timestamp_from_csv(nom_fichier) if dernier_timestamp: since = dernier_timestamp + 1 # On demande les données juste après la dernière enregistrée mode_ecriture = 'a' entete = False date_reprise = datetime.fromtimestamp(dernier_timestamp / 1000, tz=timezone.utc) print(f"Fichier '{nom_fichier}' existant. Reprise du téléchargement après {date_reprise.strftime('%Y-%m-%d %H:%M:%S')}.") else: print(f"Fichier '{nom_fichier}' trouvé mais impossible de lire la dernière date. Le fichier sera écrasé pour garantir l'intégrité.") if not since: if depuis_date: since = exchange.parse8601(depuis_date) print(f"Démarrage d'un nouveau téléchargement à partir de : {depuis_date}") else: print("Démarrage du téléchargement pour l'historique complet.") # --- Boucle de téléchargement --- with tqdm(desc=f"Données pour {symbole} {timeframe}", unit=" bougies") as pbar: while True: try: ohlcv = exchange.fetch_ohlcv(symbole, timeframe, since, limit=1000) if not ohlcv: print("\nFin de l'historique ou données les plus récentes atteintes.") break # Le premier lot téléchargé est celui qui contient la date de 'since' # Le dernier lot est celui de la bougie la plus récente df_lot = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) df_lot['datetime'] = pd.to_datetime(df_lot['timestamp'], unit='ms') df_lot.set_index('datetime', inplace=True) df_lot.drop('timestamp', axis=1, inplace=True) # Sauvegarde du lot df_lot.to_csv(nom_fichier, mode=mode_ecriture, header=entete) mode_ecriture = 'a' entete = False since = ohlcv[-1][0] + 1 pbar.update(len(ohlcv)) pbar.set_postfix(date=f"{df_lot.index[-1].strftime('%Y-%m-%d')}") except ccxt.NetworkError as e: print(f"\nErreur réseau : {e}. Pause de 15 secondes...") time.sleep(15) except Exception as e: print(f"\nUne erreur inattendue est survenue : {e}") break # --- Configuration et Lancement --- paire_btc_usdt = 'BTC/USDT' intervalles = ['1m', '5m', '30m'] date_de_debut = "2020-01-01 00:00:00" for intervalle in intervalles: nom_fichier_csv = f"historique_{paire_btc_usdt.replace('/', '_')}_{intervalle}.csv" print("-" * 60) print(f"Lancement du processus pour l'intervalle : {intervalle}") telecharger_et_mettre_a_jour( symbole=paire_btc_usdt, timeframe=intervalle, nom_fichier=nom_fichier_csv, depuis_date=date_de_debut ) print(f"Processus pour {intervalle} terminé.")
Une fois que vous allez votre script, vous devriez normalement avoir un résultat qui ressemble à quelque chose ça :
------------------------------------------------------------
Lancement du processus pour l'intervalle : 1m
Fichier 'historique_BTC_USDT_1m.csv' existant. Reprise du téléchargement après 2025-10-17 18:29:00.
Données pour BTC/USDT 1m: 1000 bougies [00:02, 358.63 bougies/s, date=2025-10-23]
Fin de l'historique ou données les plus récentes atteintes.
Données pour BTC/USDT 1m: 8262 bougies [00:05, 1509.27 bougies/s, date=2025-10-23]
Processus pour 1m terminé.
------------------------------------------------------------
Lancement du processus pour l'intervalle : 5m
Fichier 'historique_BTC_USDT_5m.csv' existant. Reprise du téléchargement après 2025-10-17 18:25:00.
Données pour BTC/USDT 5m: 1653 bougies [00:02, 619.10 bougies/s, date=2025-10-23]
Fin de l'historique ou données les plus récentes atteintes.
Données pour BTC/USDT 5m: 1653 bougies [00:03, 514.31 bougies/s, date=2025-10-23]
Processus pour 5m terminé.
------------------------------------------------------------
Lancement du processus pour l'intervalle : 30m
Fichier 'historique_BTC_USDT_30m.csv' existant. Reprise du téléchargement après 2025-10-17 18:00:00.
Données pour BTC/USDT 30m: 276 bougies [00:02, 106.02 bougies/s, date=2025-10-23]
Fin de l'historique ou données les plus récentes atteintes.
Données pour BTC/USDT 30m: 276 bougies [00:02, 95.67 bougies/s, date=2025-10-23]
Processus pour 30m terminé.
Vous pouvez maintenant utiliser ces fichiers de données pour d’autres taches en lien avec les cryptomonnaie tel que le Bitcoin.