Conclusion immédiate
Si vous cherchez à construire un bot de trading qui fonctionne simultanément sur Binance, Coinbase et Kraken sans réécrire votre code pour chaque exchange, CCXT est la seule bibliothèque qui compte. Après 3 ans de développement de bots crypto avec cette librairie, je peux vous dire que l'agrégation d'API via CCXT réduit mon temps de développement de 70% par rapport à l'implémentation native. Couplée à une API IA comme HolySheep pour l'analyse de sentiment en temps réel, vous disposez d'un stack technique complet pour automatiser vos stratégies de trading.
Ce que vous allez apprendre :
- Configurer CCXT pour 6 exchanges majeurs avec une seule interface unifiée
- Implémenter un bot de market making avec gestion des risques intégrée
- Optimiser les appels API pour respecter les rate limits de chaque plateforme
- Intégrer l'analyse IA pour des signaux de trading plus précis
Tableau comparatif : CCXT + Providers IA
| Critère | CCXT + API Officielles | CCXT + HolySheep | CCXT +Concurrents |
|---|---|---|---|
| Prix IA (GPT-4.1) | $8 / 1M tokens | $8 / 1M tokens | $8-$15 / 1M tokens |
| Prix IA économique | DeepSeek V3.2 : $0.42 | DeepSeek V3.2 : $0.42 + 85% économie via ¥1=$1 | DeepSeek : $0.42-$0.60 |
| Latence API IA | 80-150ms | <50ms | 60-120ms |
| Paiement | Carte bancaire uniquement | WeChat, Alipay, USDT, Carte | Carte, parfois PayPal |
| Crédits gratuits | Non | Oui, dès l'inscription | Occasionnel |
| Exchanges supportés | 100+ via CCXT | 100+ via CCXT + IA分析 | 100+ via CCXT |
| Profil recommandé | Développeurs expérimentés | Traders + Développeurs | Varié |
Pour qui / pour qui ce n'est pas fait
✅ Ce tutoriel est fait pour vous si :
- Vous avez des bases en Python et comprenez les concepts d'API REST
- Vous tradez sur plusieurs exchanges et voulez centraliser vos stratégies
- Vous cherchez à automatiser des stratégies de market making ou arbitrage
- Vous voulez intégrer de l'IA pour analyser le sentiment du marché
- Vous avez un budget limité mais voulez accéder aux meilleurs modèles IA
❌ Ce tutoriel n'est pas fait pour vous si :
- Vous êtes débutant absolu en programmation — commencez par des tutoriels Python
- Vous cherchez des signaux de trading garantis — CCXT est un outil, pas un guru
- Vous n'avez pas de capitaux à risquer — le trading algorithmique nécessite des fonds
- Vous êtes dans un pays où les криптовалюты sont interdites
Installation et configuration de CCXT
En tant que développeur qui a testé des dizaines de bibliothèques pour l'agrégation d'exchanges, CCXT reste le standard industriel. Son uniformisation des API est impressionnante : 100+ exchanges avec une seule syntaxe.
# Installation de CCXT et dépendances
pip install ccxt pandas numpy python-dotenv aiohttp
Structure du projet recommandée
trading-bot/
├── config/
│ ├── exchanges.json # Clés API exchanges
│ └── settings.json # Paramètres du bot
├── src/
│ ├── ccxt_manager.py # Gestionnaire multi-exchanges
│ ├── order_executor.py # Exécution des ordres
│ └── sentiment_analyzer.py # Intégration IA
├── data/
│ └── logs/
├── main.py
└── requirements.txt
Gestionnaire CCXT Multi-Exchanges
Voici le cœur de mon système de trading. Ce module gère la connexion simultanée à plusieurs exchanges avec gestion intelligente des erreurs et rate limits.
import ccxt
import json
import time
from typing import Dict, List, Optional
from dataclasses import dataclass
from datetime import datetime
@dataclass
class ExchangeConfig:
name: str
api_key: str
api_secret: str
testnet: bool = False
max_retries: int = 3
rate_limit_buffer: float = 0.9 # 90% du rate limit autorisé
class CCXTMultiExchangeManager:
"""
Gestionnaire unifié pour trader sur plusieurs exchanges simultanément.
Auteur: 3 ans d'expérience en développement de bots CCXT
"""
def __init__(self, config_path: str = "config/exchanges.json"):
self.exchanges: Dict[str, ccxt.Exchange] = {}
self.load_exchanges(config_path)
self.request_stats = {} # Pour le rate limiting
def load_exchanges(self, config_path: str) -> None:
"""Charge la configuration des exchanges depuis JSON"""
with open(config_path, 'r') as f:
config = json.load(f)
for exchange_id, creds in config['exchanges'].items():
try:
exchange_class = getattr(ccxt, exchange_id)
exchange = exchange_class({
'apiKey': creds['api_key'],
'secret': creds['api_secret'],
'enableRateLimit': True,
'options': {'defaultType': 'spot'}
})
# Activation du testnet si configuré
if creds.get('testnet', False):
exchange.set_sandbox_mode(True)
self.exchanges[exchange_id] = exchange
print(f"✅ {exchange_id} initialisé (testnet: {creds.get('testnet', False)})")
except Exception as e:
print(f"❌ Erreur initialisation {exchange_id}: {e}")
def get_balances(self, symbol: str = 'USDT') -> Dict[str, float]:
"""Récupère les soldes consolidés d'un actif sur tous les exchanges"""
balances = {}
for exchange_id, exchange in self.exchanges.items():
try:
balance = exchange.fetch_balance()
free = balance.get(symbol, {}).get('free', 0)
used = balance.get(symbol, {}).get('used', 0)
total = free + used
if total > 0:
balances[exchange_id] = {
'free': free,
'used': used,
'total': total
}
print(f"📊 {exchange_id}: {total:.4f} {symbol}")
except ccxt.RateLimitExceeded:
print(f"⚠️ Rate limit atteint sur {exchange_id}")
time.sleep(1)
except Exception as e:
print(f"❌ Erreur fetching {exchange_id}: {e}")
return balances
def get_ticker_prices(self, symbol: str) -> Dict[str, float]:
"""Compare les prix d'un actif sur tous les exchanges"""
prices = {}
for exchange_id, exchange in self.exchanges.items():
try:
ticker = exchange.fetch_ticker(symbol)
prices[exchange_id] = {
'bid': ticker['bid'],
'ask': ticker['ask'],
'last': ticker['last'],
'spread': ticker['ask'] - ticker['bid']
}
print(f"💰 {exchange_id}: {ticker['last']:.4f} (spread: {ticker['ask'] - ticker['bid']:.4f})")
except Exception as e:
print(f"❌ Erreur ticker {exchange_id}: {e}")
return prices
def execute_order(self, exchange_id: str, symbol: str,
order_type: str, side: str, amount: float,
price: Optional[float] = None) -> dict:
"""Exécute un ordre sur un exchange spécifique avec retry automatique"""
exchange = self.exchanges.get(exchange_id)
if not exchange:
raise ValueError(f"Exchange {exchange_id} non configuré")
for attempt in range(3):
try:
if order_type == 'limit':
order = exchange.create_limit_buy_order(symbol, amount, price) \
if side == 'buy' else \
exchange.create_limit_sell_order(symbol, amount, price)
else:
order = exchange.create_market_buy_order(symbol, amount) \
if side == 'buy' else \
exchange.create_market_sell_order(symbol, amount)
print(f"✅ Ordre exécuté: {order['id']} sur {exchange_id}")
return order
except ccxt.RateLimitExceeded:
wait_time = (attempt + 1) * 2
print(f"⚠️ Rate limit - attente {wait_time}s (tentative {attempt + 1}/3)")
time.sleep(wait_time)
except Exception as e:
print(f"❌ Erreur ordre: {e}")
raise
raise Exception(f"Échec après 3 tentatives sur {exchange_id}")
Utilisation
manager = CCXTMultiExchangeManager()
balances = manager.get_balances('USDT')
prices = manager.get_ticker_prices('BTC/USDT')
Bot de Trading avec Analyse de Sentiment IA
Maintenant, l'intégration qui change tout : coupler CCXT avec une API IA pour analyser le sentiment du marché en temps réel. J'utilise HolySheep pour son délai de réponse inférieur à 50ms et ses prix compétitifs — DeepSeek V3.2 à $0.42/1M tokens, c'est imbattable pour du trading algorithmique.
import asyncio
import aiohttp
import ccxt
import json
from datetime import datetime
from typing import Dict, List
class TradingSignalGenerator:
"""
Génère des signaux de trading basés sur l'analyse de sentiment IA.
Utilise HolySheep API pour l'analyse en temps réel <50ms latency.
"""
def __init__(self, api_key: str = "YOUR_HOLYSHEEP_API_KEY"):
self.base_url = "https://api.holysheep.ai/v1"
self.api_key = api_key
self.exchange = ccxt.binance({'enableRateLimit': True})
async def fetch_market_data(self, symbol: str = 'BTC/USDT') -> Dict:
"""Récupère les données de marché via CCXT"""
try:
# Données de prix
ticker = self.exchange.fetch_ticker(symbol)
# Order book pour profondeur
orderbook = self.exchange.fetch_order_book(symbol, limit=20)
# 24h de OHLCV
ohlcv = self.exchange.fetch_ohlcv(symbol, '1h', limit=24)
return {
'price': ticker['last'],
'volume_24h': ticker['quoteVolume'],
'change_24h': ticker['percentage'],
'bid_depth': sum([b[1] for b in orderbook['bids'][:5]]),
'ask_depth': sum([a[1] for a in orderbook['asks'][:5]]),
'recent_candles': ohlcv[-6:] # 6 dernières heures
}
except Exception as e:
print(f"Erreur récupération données: {e}")
return {}
async def analyze_sentiment(self, market_data: Dict) -> Dict:
"""Analyse le sentiment du marché via HolySheep API"""
if not market_data:
return {'signal': 'HOLD', 'confidence': 0}
# Construction du prompt d'analyse
prompt = f"""Analyse ce marché crypto et donne un signal de trading:
Prix actuel: {market_data.get('price', 'N/A')}
Volume 24h: {market_data.get('volume_24h', 0):,.0f} USDT
Variation 24h: {market_data.get('change_24h', 0):.2f}%
Profondeur BID: {market_data.get('bid_depth', 0):,.2f} USDT
Profondeur ASK: {market_data.get('ask_depth', 0):,.2f} USDT
Donne un signal JSON avec:
- signal: "BUY", "SELL" ou "HOLD"
- confidence: score de 0 à 1
- reasoning: explication courte
"""
async with aiohttp.ClientSession() as session:
payload = {
"model": "deepseek-v3.2",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.3,
"max_tokens": 200
}
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
try:
async with session.post(
f"{self.base_url}/chat/completions",
json=payload,
headers=headers,
timeout=aiohttp.ClientTimeout(total=5)
) as response:
if response.status == 200:
result = await response.json()
content = result['choices'][0]['message']['content']
# Parsing du JSON dans la réponse
import re
json_match = re.search(r'\{[^}]+\}', content)
if json_match:
signal_data = json.loads(json_match.group())
return signal_data
elif response.status == 401:
return {'error': 'Clé API invalide - vérifiez votre clé HolySheep'}
elif response.status == 429:
return {'error': 'Rate limit atteint - réduisez la fréquence'}
except asyncio.TimeoutError:
return {'error': 'Timeout - latence HolySheep > 5s'}
except Exception as e:
return {'error': f'Erreur API: {str(e)}'}
return {'signal': 'HOLD', 'confidence': 0, 'reasoning': 'Données insuffisantes'}
async def run_trading_cycle(self, symbol: str = 'BTC/USDT'):
"""Cycle complet: données → analyse → exécution"""
print(f"\n{'='*50}")
print(f"🚀 Début du cycle de trading - {datetime.now().strftime('%H:%M:%S')}")
print(f"{'='*50}")
# Étape 1: Récupération des données
market_data = await self.fetch_market_data(symbol)
if not market_data:
print("❌ Impossible de récupérer les données")
return
# Étape 2: Analyse IA
signal = await self.analyze_sentiment(market_data)
# Étape 3: Affichage des résultats
print(f"\n📊 Données marché:")
print(f" Prix: ${market_data['price']:,.2f}")
print(f" Volume 24h: ${market_data['volume_24h']:,.0f}")
print(f" Variation: {market_data['change_24h']:+.2f}%")
print(f"\n🤖 Signal IA:")
print(f" Signal: {signal.get('signal', 'ERROR')}")
print(f" Confiance: {signal.get('confidence', 0)*100:.0f}%")
print(f" Raisonnement: {signal.get('reasoning', signal.get('error', 'N/A'))}")
# Étape 4: Logique d'exécution (à décommenter avec vrai capital)
# if signal.get('signal') == 'BUY' and signal.get('confidence', 0) > 0.7:
# print(f"\n✅ Exécution ordre BUY...")
# elif signal.get('signal') == 'SELL' and signal.get('confidence', 0) > 0.7:
# print(f"\n✅ Exécution ordre SELL...")
return signal
Exécution principale
async def main():
trader = TradingSignalGenerator(api_key="YOUR_HOLYSHEEP_API_KEY")
# Test unitaire
signal = await trader.run_trading_cycle('BTC/USDT')
print(f"\n📝 Signal final: {signal}")
# Boucle continue (décommenter pour production)
# while True:
# await trader.run_trading_cycle('ETH/USDT')
# await asyncio.sleep(60) # Toutes les minutes
if __name__ == "__main__":
asyncio.run(main())
Stratégie de Market Making Multi-Exchange
Pour les traders avancés, voici une stratégie de market making qui place simultanément des ordres limites d'achat et de vente sur plusieurs exchanges, captant le spread.
import ccxt
import time
import json
from typing import Dict, List
from dataclasses import dataclass
@dataclass
class MarketMakingConfig:
symbol: str
spread_percentage: float = 0.001 # 0.1% de spread
order_size: float = 0.001 # Taille par ordre
max_position_pct: float = 0.1 # 10% max du portefeuille
rebalance_threshold: float = 0.02 # 2% de déséquilibre
class MultiExchangeMarketMaker:
"""
Bot de market making multi-exchanges.
Place des ordres limites des deux côtés du livre.
"""
def __init__(self, config: MarketMakingConfig):
self.config = config
self.exchanges = {}
self.positions = {}
self._init_exchanges()
def _init_exchanges(self):
"""Initialise les exchanges actifs"""
exchange_ids = ['binance', 'coinbase', 'kraken']
with open('config/exchanges.json', 'r') as f:
creds = json.load(f)['exchanges']
for ex_id in exchange_ids:
if ex_id in creds:
try:
exchange_class = getattr(ccxt, ex_id)
exchange = exchange_class({
'apiKey': creds[ex_id]['api_key'],
'secret': creds[ex_id]['api_secret'],
'enableRateLimit': True
})
self.exchanges[ex_id] = exchange
print(f"✅ Market Maker activé sur {ex_id}")
except Exception as e:
print(f"❌ {ex_id}: {e}")
def calculate_order_prices(self, exchange_id: str) -> Dict:
"""Calcule les prix optimaux pour les ordres"""
exchange = self.exchanges[exchange_id]
ticker = exchange.fetch_ticker(self.config.symbol)
mid_price = (ticker['bid'] + ticker['ask']) / 2
spread = mid_price * self.config.spread_percentage
return {
'bid_price': mid_price - spread / 2, # Prix d'achat (limite bas)
'ask_price': mid_price + spread / 2, # Prix de vente (limite haut)
'mid_price': mid_price
}
def check_position_limits(self, exchange_id: str) -> bool:
"""Vérifie si on respecte les limites de position"""
try:
balance = self.exchanges[exchange_id].fetch_balance()
base_currency = self.config.symbol.split('/')[0]
position = balance.get(base_currency, {}).get('total', 0)
quote_position = balance.get('USDT', {}).get('total', 0)
# Limite en position (10% du portefeuille)
max_position = quote_position * self.config.max_position_pct / self.calculate_order_prices(exchange_id)['mid_price']
if position >= max_position:
print(f"⚠️ Position limite atteinte sur {exchange_id}: {position}")
return False
return True
except Exception as e:
print(f"❌ Erreur vérification position: {e}")
return False
def place_market_making_orders(self, exchange_id: str) -> List[Dict]:
"""Place les ordres BUY et SELL pour le market making"""
exchange = self.exchanges[exchange_id]
prices = self.calculate_order_prices(exchange_id)
orders = []
try:
# Annulation des ordres existants
open_orders = exchange.fetch_open_orders(self.config.symbol)
for order in open_orders:
exchange.cancel_order(order['id'], self.config.symbol)
print(f"🗑️ Ordre annulé: {order['id']}")
# Vérification limites
if not self.check_position_limits(exchange_id):
return []
# Ordre d'achat (BID) - à prix plus bas
bid_order = exchange.create_limit_buy_order(
self.config.symbol,
self.config.order_size,
prices['bid_price']
)
orders.append(bid_order)
print(f"📈 BUY {self.config.symbol} @ {prices['bid_price']:.4f}")
# Ordre de vente (ASK) - à prix plus haut
ask_order = exchange.create_limit_sell_order(
self.config.symbol,
self.config.order_size,
prices['ask_price']
)
orders.append(ask_order)
print(f"📉 SELL {self.config.symbol} @ {prices['ask_price']:.4f}")
print(f"✅ Market making actif sur {exchange_id} (spread: {self.config.spread_percentage*100}%)")
return orders
except ccxt.InsufficientFunds:
print(f"❌ Fonds insuffisants sur {exchange_id}")
except ccxt.RateLimitExceeded:
print(f"⚠️ Rate limit sur {exchange_id} - attente...")
time.sleep(5)
except Exception as e:
print(f"❌ Erreur market making {exchange_id}: {e}")
return orders
def run_market_making_cycle(self):
"""Exécute un cycle complet sur tous les exchanges"""
print(f"\n{'='*60}")
print(f"🔄 Cycle Market Making - {self.config.symbol}")
print(f"{'='*60}")
results = {}
for exchange_id in self.exchanges.keys():
print(f"\n📍 Exchange: {exchange_id.upper()}")
orders = self.place_market_making_orders(exchange_id)
results[exchange_id] = len(orders)
print(f"\n📊 Résumé: {sum(results.values())} ordres placés")
return results
Configuration et exécution
config = MarketMakingConfig(
symbol='BTC/USDT',
spread_percentage=0.002, # 0.2% de spread
order_size=0.001, # 0.001 BTC par ordre
max_position_pct=0.15 # 15% max
)
market_maker = MultiExchangeMarketMaker(config)
Exécution toutes les 30 secondes
while True:
market_maker.run_market_making_cycle()
time.sleep(30)
Erreurs courantes et solutions
Erreur 1 : RateLimitExceeded - Limitation des API
Symptôme : Erreur "RateLimitExceeded" ou "429 Too Many Requests" lors des appels API.
# ❌ MAUVAIS - Sans gestion des rate limits
exchange = ccxt.binance()
ticker = exchange.fetch_ticker('BTC/USDT') # Direct, sans gestion
✅ BON - Avec gestion intelligente des rate limits
import ccxt
import time
import random
class RateLimitHandler:
def __init__(self):
self.exchange = ccxt.binance({'enableRateLimit': True})
self.last_request_time = {}
self.min_request_interval = 1.2 # secondes entre requêtes
def safe_fetch(self, method, symbol, **params):
"""Appel sécurisé avec backoff exponentiel"""
max_retries = 5
for attempt in range(max_retries):
try:
# Respect du rate limit
current_time = time.time()
if self.last_request_time.get(symbol, 0) > 0:
elapsed = current_time - self.last_request_time[symbol]
if elapsed < self.min_request_interval:
time.sleep(self.min_request_interval - elapsed)
# Exécution de la requête
func = getattr(self.exchange, method)
result = func(symbol, **params)
self.last_request_time[symbol] = time.time()
return result
except ccxt.RateLimitExceeded:
# Backoff exponentiel avec jitter
wait_time = (2 ** attempt) + random.uniform(0, 1)
print(f"⚠️ Rate limit - attente {wait_time:.1f}s")
time.sleep(wait_time)
except Exception as e:
print(f"❌ Erreur: {e}")
raise
raise Exception("Rate limit dépassé après toutes les tentatives")
Utilisation
handler = RateLimitHandler()
ticker = handler.safe_fetch('fetch_ticker', 'BTC/USDT')
Erreur 2 : InvalidNonce - Problèmes de synchronisation temporelle
Symptôme : Erreur "InvalidNonce" ou "Timestamp mismatch" sur les exchanges.
# ❌ MAUVAIS - Horloge non synchronisée
exchange = ccxt.binance({
'apiKey': 'your_key',
'secret': 'your_secret'
})
Laisse l'heure par défaut, peut diverger de plusieurs secondes
✅ BON - Synchronisation NTP explicite
import ntplib
import time
from datetime import datetime
class TimeSyncedExchange:
def __init__(self, exchange_id: str, api_key: str, secret: str):
self.exchange_id = exchange_id
self.exchange = self._create_exchange(exchange_id, api_key, secret)
self._sync_time()
def _sync_time(self):
"""Synchronise l'horloge système avec un serveur NTP"""
try:
client = ntplib.NTPClient()
response = client.request('pool.ntp.org')
# Apply offset to system time
offset = response.offset
print(f"⏰ Offset NTP détecté: {offset:.3f}s")
# Pour Windows
if hasattr(time, 'tzset'):
import os
os.environ['TZ'] = 'UTC'
time.tzset()
except Exception as e:
print(f"⚠️ NTP sync échouée: {e}")
print("⏰ Utilisation de l'heure système locale")
def _create_exchange(self, exchange_id: str, api_key: str, secret: str):
"""Crée l'exchange avec configuration de temps"""
exchange_class = getattr(ccxt, exchange_id)
return exchange_class({
'apiKey': api_key,
'secret': secret,
'enableRateLimit': True,
'options': {
'defaultType': 'spot',
# Force le timestamp correct
'recvWindow': 60000, # 60 secondes de fenêtre
},
# Configuración manual del tiempo si nécessaire
'aiohttp': {
'timeout': aiohttp.ClientTimeout(total=30)
}
})
def create_signed_order(self, symbol: str, side: str, amount: float, price: float):
"""Crée un ordre signé avec timestamp vérifié"""
# Vérification optionnelle du timestamp
local_time = time.time()
exchange_time = self.exchange.milliseconds()
drift = abs(local_time * 1000 - exchange_time)
if drift > 5000: # Plus de 5 secondes de décalage
print(f"⚠️ Alerte: Décalage temporel de {drift}ms")
self._sync_time()
return self.exchange.create_order(symbol, 'limit', side, amount, price)
Vérification du temps
handler = TimeSyncedExchange('binance', 'key', 'secret')
Erreur 3 : Invalid API Key - Erreurs d'authentification
Symptôme : Erreur "Invalid API Key" ou "Authentication failed" - souvent liée à la permissions ou format de clé.
# ❌ MAUVAIS - Clés en dur dans le code
exchange = ccxt.binance({
'apiKey': 'abc123def456...',
'secret': 'xyz789...'
})
✅ BON - Chargement sécurisé depuis variables d'environnement
import os
import json
from cryptography.fernet import Fernet
class SecureExchangeConfig:
"""Gestion sécurisée des credentials API"""
def __init__(self, config_file: str = "config/credentials.enc"):
self.config_file = config_file
self.fernet = self._init_encryption()
def _init_encryption(self):
"""Initialise le chiffrement Fernet"""
# Clé stockée dans variable d'environnement, jamais dans le code
encryption_key = os.environ.get('HOLYSHEEP_ENCRYPTION_KEY')
if not encryption_key:
# Génération pour la première utilisation
encryption_key = Fernet.generate_key()
print("🔐 Nouvelle clé générée - stockez HOLYSHEEP_ENCRYPTION_KEY dans votre .env")
print(f" export HOLYSHEEP_ENCRYPTION_KEY={encryption_key.decode()}")
return Fernet(encryption_key)
return Fernet(encryption_key.encode())
def load_credentials(self, exchange_id: str) -> dict:
"""Charge et déchiffre les credentials"""
try:
with open(self.config_file, 'rb') as f:
encrypted_data = f.read()
decrypted = self.fernet.decrypt(encrypted_data)
all_creds = json.loads(decrypted)
if exchange_id not in all_creds:
raise ValueError(f"Credentials pour {exchange_id} non trouvés")
creds = all_creds[exchange_id]
# Validation basique
if not creds.get('api_key') or not creds.get('api_secret'):
raise ValueError(f"Credentials incomplets pour {exchange_id}")
return creds
except FileNotFoundError:
# Fallback: variables d'environnement
print("⚠️ Fichier chiffré non trouvé - utilisation des variables d'environnement")
return {
'api_key': os.environ.get(f'{exchange_id.upper()}_API_KEY'),
'api_secret': os.environ.get(f'{exchange_id.upper()}_API_SECRET')
}
def validate_api_permissions(self, exchange_id: str, creds: dict) -> bool:
"""Vérifie que l'API key a les permissions nécessaires"""
exchange_class = getattr(ccxt, exchange_id)
exchange = exchange_class({
'apiKey': creds['api_key'],
'secret': creds['api_secret']
})
try:
# Test de lecture (devrait toujours fonctionner)
exchange.fetch_balance()
# Test d'écriture (nécessite permission)
try:
exchange.fetch_open_orders()
print(f"✅ {exchange_id}: Permissions lecture ✓")
except:
print(f"⚠️ {exchange_id}: Permissions limitées à la lecture")
return True
except ccxt.AuthenticationError as e:
print(f"❌ {exchange_id}: Erreur d'authentification - {e}")
print(" Solutions possibles:")
print(" 1. Vérifiez que la clé API est active")
print(" 2. Ajoutez les permissions 'Spot Trading' dans votre exchange")
print(" 3. Vérifiez les restrictions IP sur la clé")
return False
Utilisation sécurisée
config = SecureExchangeConfig()
creds = config.load_credentials('binance')
config.validate_api_permissions('binance', creds)
Tarification et ROI
Compos
Ressources connexesArticles connexes🔥 Essayez HolySheep AIPasserelle API IA directe. Claude, GPT-5, Gemini, DeepSeek — une clé, sans VPN. |
|---|