Quel VPS choisir pour un bot de trading ?
Découvrez les vrais besoins d’un bot de trading sur VPS : redémarrage systemd, horloge exacte, clés API protégées, heartbeats et limites réelles de latence.
Ce dont un bot de trading a besoin sur un VPS
Un VPS destiné à un bot de trading s’évalue selon quatre critères : le processus redémarre-t-il après un arrêt, l’horloge est-elle exacte, les clés d’API (application programming interface) sont-elles suffisamment protégées contre le vol, et êtes-vous informé lorsque le bot s’arrête ? Pour un bot de détail, la vitesse brute arrive loin derrière ces critères, car la partie la plus lente du chemin d’exécution de votre ordre est votre broker et la distance qui vous en sépare, pas l’hôte qui exécute votre code Python.
Il s’agit d’un guide technique. Ce document ne constitue pas un conseil financier et ne traite d’aucune stratégie.
La disponibilité dépend de la discipline de redémarrage, pas d’un nombre affiché sur une page commerciale
Les engagements de disponibilité annoncés varient. AWS indique au moins 99.5 pour cent pour une instance EC2 unique et 99.99 pour cent pour les déploiements éligibles répartis sur plusieurs zones de disponibilité. Ces engagements couvrent la disponibilité de l’infrastructure, pas l’état de santé de votre bot. Un bot peut s’arrêter à cause d’une exception non gérée, d’une websocket qui ne se reconnecte jamais ou du tueur OOM (out of memory), alors que le serveur reste disponible pendant toute la durée du problème. La question utile est donc de savoir ce qui se passe dans les dix secondes qui suivent l’arrêt de votre processus.
Exécutez le bot comme un service systemd et laissez le système init gérer le redémarrage. Un fichier d’unité permet de le faire.
[Unit]
Description=Trading bot
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=bot
WorkingDirectory=/opt/tradingbot
EnvironmentFile=/etc/tradingbot/api.env
ExecStart=/opt/tradingbot/venv/bin/python -m tradingbot
Restart=always
RestartSec=10
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/tradingbot
[Install]
WantedBy=multi-user.targetStartLimitIntervalSec=0 est la ligne que beaucoup oublient. Par défaut, systemd autorise 5 démarrages en 10 secondes, en comptant le démarrage initial et les démarrages manuels ; la configuration du manager peut remplacer ces valeurs par défaut. Lorsque la limite est atteinte, les tentatives de redémarrage automatique s’arrêtent, mais l’unité peut être démarrée manuellement, par un timer ou par une socket une fois l’intervalle écoulé. La valeur 0 désactive la limite de fréquence. Un bot qui redémarre en boucle continue donc d’essayer au lieu de s’arrêter silencieusement. RestartSec=10 empêche cette boucle de saturer l’exchange avec des reconnexions.
Vérifiez le fichier avant de lui faire confiance, puis démarrez le service :
sudo systemd-analyze verify /etc/systemd/system/tradingbot.service
sudo systemctl daemon-reload
sudo systemctl enable --now tradingbot
systemctl status tradingbotenable est la partie qui permet au service de survivre à un redémarrage, et les mises à jour du kernel nécessitent des redémarrages. Pour vérifier si le bot s’arrête discrètement, demandez à systemd le compteur de redémarrages :
systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50NRestarts=0 compte les tâches de redémarrage automatique depuis la dernière réinitialisation du compteur ; il ne prouve pas que le bot est sain ou qu’il n’a connu aucun crash pendant une semaine. Les redémarrages manuels et systemctl reset-failed réinitialisent le compteur, et un bot bloqué peut toujours afficher zéro. NRestarts=812 compte 812 tâches de redémarrage, pas les reconnexions réussies à l’exchange ni les trades, et n’indique pas quand elles ont eu lieu. Consultez le journal pour connaître la chronologie et la cause, y compris les échecs survenus avant la connexion du bot. L’anatomie complète du fichier d’unité, y compris les timers pour les tâches planifiées comme un rapport quotidien, est présentée dans exécuter un programme comme service systemd.
Définir l’horloge sur UTC et vérifier sa synchronisation
Les API d’échange utilisent des horodatages pour valider les requêtes signées ; Binance Spot utilise par défaut une fenêtre de réception de 5 secondes et rejette les horodatages qui avancent d’au moins 1 seconde sur l’heure du serveur. Une horloge qui dérive produit des erreurs qui ressemblent à des échecs d’authentification. Vous pouvez donc renouveler les clés pendant des heures avant de vérifier l’heure. Avec les API de type Binance, le message est explicite : Timestamp for this request was 1000ms ahead of the server's time.
Définissez le serveur sur UTC. Les fuseaux horaires locaux introduisent des sauts liés à l’heure d’été dans les heures affichées. Les timestamps Unix utilisés par les API ne changent pas lorsque le fuseau d’affichage est modifié.
sudo timedatectl set-timezone UTC
timedatectlUbuntu utilise par défaut chrony à partir de la version 25.10. Les installations plus anciennes peuvent utiliser systemd-timesyncd, un client SNTP (simple network time protocol). systemd-timesyncd ajuste l’horloge, mais ne peut pas interroger plusieurs serveurs simultanément pour détecter une source horaire incorrecte. Utilisez plutôt chrony :
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
chronyc tracking
chronyc sources -vLa ligne à lire dans chronyc tracking est System time, par exemple System time : 0.000031415 seconds fast of NTP time. Une petite valeur indique qu’il reste une faible correction à appliquer à l’horloge NTP de chrony. Vérifiez également la synchronisation, Root delay et Root dispersion avant d’évaluer la précision. Si la valeur est Leap status : Not synchronised, chrony n’est pas synchronisé, même si les serveurs ont répondu ; les mesures peuvent être rejetées parce qu’elles sont trop imprécises. Attendez une minute, puis vérifiez à nouveau avant de modifier les règles du pare-feu.
Ne copiez pas les clés d’API dans des emplacements non sécurisés
Une clé d’exchange divulguée est plus dangereuse qu’une clé SSH divulguée, car l’autorisation de retrait permet de convertir immédiatement l’accès en argent. Deux habitudes couvrent la plupart des risques.
Premièrement, n’accordez jamais l’autorisation de retrait à une clé utilisée par un bot. Lorsque l’exchange le permet, liez aussi la clé à l’adresse IP de votre serveur. C’est le contrôle le plus efficace pour rendre une clé volée presque inutilisable.
Deuxièmement, gardez le secret en dehors du répertoire du code. Tout ce qui se trouve dans /opt/tradingbot finit tôt ou tard dans un dépôt git ou une archive de sauvegarde. Placez-le dans un fichier appartenant à root que systemd pourra lire :
sudo install -d -m 750 -o root -g bot /etc/tradingbot
sudo install -m 640 -o root -g bot /dev/null /etc/tradingbot/api.env
sudo nano /etc/tradingbot/api.envLe fichier contient des lignes KEY=value en clair, sans guillemets ni export. Le mode 640 autorise le propriétaire root à lire et écrire le fichier, ainsi que les membres du groupe bot à le lire. Les autres utilisateurs n’ont aucun droit. Vérifiez d’abord avec sudo -u bot cat /etc/tradingbot/api.env, puis avec un utilisateur non privilégié qui n’appartient pas au groupe bot. Dans ce second cas, la commande doit échouer avec Permission denied.
Le bot ne doit pas s’exécuter avec root ni avec votre utilisateur de connexion. Créez un compte système avec un shell nologin et /var/lib/tradingbot comme répertoire personnel avant de démarrer le service ou de créer des fichiers appartenant au groupe bot :
sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home botLe rôle de chacun de ces indicateurs, ainsi que la portée réelle de ProtectSystem=strict, est expliqué dans exécuter des services avec un utilisateur non privilégié. Le reste de la configuration de base du serveur, notamment les clés SSH et un firewall, est décrit dans les dix premières minutes sur un nouveau VPS.
Détectez la panne avant votre broker
systemctl status indique que le processus est en cours d’exécution. Cela ne signifie pas que le bot fait quoi que ce soit. Un processus bloqué dans une boucle de nouvelle tentative contre un websocket hors service passe les contrôles du processus dans l’unité précédente.
Utilisez plutôt un heartbeat. Uptime Kuma propose des monitors push : il attend que votre bot appelle une URL selon une périodicité définie et vous alerte lorsque les appels cessent d’arriver. Placez l’appel à la fin de votre boucle principale, après la partie qui prouve que le bot est opérationnel, par exemple après une lecture réussie des données de marché.
curl -fsS "http://monitor.example.com:3001/api/push/YOUR_TOKEN?status=up&msg=loop_ok"Définissez l’intervalle du monitor à environ deux fois la durée de votre boucle afin que les variations normales ne déclenchent pas d’alerte. Exécutez le monitor sur un serveur différent de celui du bot, car un monitor qui tombe en panne avec le service surveillé ne signale rien. La procédure est décrite dans la supervision de statut auto-hébergée avec Uptime Kuma.
Ajoutez également une alerte de disque. Un bot qui écrit des logs très détaillés remplira le système de fichiers root en quelques semaines. Un disque plein empêche l’écriture dans la base de données, mais pas l’appel réseau, ce qui produit des symptômes difficiles à interpréter. journalctl --vacuum-time=14d et une ligne SystemMaxUse= dans /etc/systemd/journald.conf limitent la taille du journal.
La réalité : la latence ne dépend généralement pas de votre serveur
C’est à ce stade que le marché des VPS de trading cesse d’être technique. Les pages marketing annoncent des chiffres inférieurs à la milliseconde et laissent entendre que le serveur est ce qui vous sépare de l’exécution d’un ordre. Pour presque tous les bots de particuliers, ce n’est pas le cas.
Votre ordre circule entre le bot et le endpoint de l’exchange ou du broker via Internet. Ce trajet dépend surtout de la distance physique et du peering entre votre fournisseur et celui de l’exchange ou du broker. Les systèmes du broker ajoutent ensuite leur propre file d’attente, leurs contrôles de risque et leurs limites de débit.
Mesurez au lieu de faire des suppositions. curl indique les temps de connexion et de réception du premier octet pour un endpoint réel :
curl -s -o /dev/null -w 'dns=%{time_namelookup}s connect=%{time_connect}s ttfb=%{time_starttransfer}s\n' \
https://api.kraken.com/0/public/Time
mtr -rwzc 100 api.kraken.comExécutez cette commande depuis un serveur candidat avant de vous engager. Si connect vaut 0.180 seconde, cette valeur inclut la résolution DNS et l’établissement de la connexion TCP ; elle ne permet pas de déterminer sur quel continent vous vous trouvez. Si connect vaut 0.004 seconde et ttfb vaut 0.140 seconde, la différence inclut l’établissement de TLS, la transmission de la requête, les délais réseau et le traitement côté serveur. Un changement d’hébergeur peut modifier certains de ces composants. Comparez donc les mesures depuis plusieurs emplacements candidats.
Dans quels cas le serveur compte-t-il réellement ? Lorsque vous êtes en colocation ou connecté directement à la plateforme et que vous êtes en concurrence sur la position dans la file d’attente. Il s’agit alors d’une activité différente, avec un budget différent. Le serveur compte aussi lorsque votre propre code est le goulot d’étranglement : un bot qui recalcule les indicateurs sur tout l’historique à chaque tick peut consommer 200 millisecondes de CPU par boucle. C’est une latence réelle que vous pouvez réduire gratuitement. Profilez la boucle avant de chercher un serveur plus rapide.
Pour choisir un hébergeur, privilégiez la proximité géographique, un réseau stable et une mémoire suffisante pour que l’OOM killer n’intervienne jamais. Ajoutez de la mémoire si vous conservez l’historique des ticks dans une base de données locale.
Une courte checklist avant la mise en production
systemctl is-enabled tradingbotafficheenabled, et le service survit àsudo reboot.chronyc trackingindique une synchronisation, un décalage de l’heure système inférieur à quelques millisecondes, ainsi qu’un délai et une dispersion root conformes à votre budget de synchronisation.- La clé API dispose de l’autorisation de trading, mais pas de l’autorisation de retrait. Elle utilise aussi une liste d’adresses IP autorisées si l’exchange en propose une.
- L’arrêt du processus avec
sudo systemctl kill -s SIGKILL tradingbotle relance après le délaiRestartSecet le temps de démarrage. - Le monitor de heartbeat vous alerte après l’intervalle configuré et réessaie lorsque vous arrêtez volontairement le bot.
- La taille des logs est limitée et le système de fichiers root dispose d’une marge suffisante dans
df -h.
Exécutez l’ensemble dans la sandbox de l’exchange ou en paper trading pendant une semaine avant d’utiliser des fonds réels. Chaque élément ci-dessus échoue au moins une fois pendant cette semaine. C’est précisément le but de cette semaine.
FAQ
Un bot de trading a-t-il besoin d’un serveur à faible latence ou d’un serveur bare metal ?
Uniquement si vous êtes en concurrence sur la vitesse d’exécution avec d’autres participants automatisés sur la même place de marché. Dans ce cas, la colocation est généralement plus adaptée qu’un VPS généraliste. Pour un bot de trading de détail, le temps aller-retour dépend surtout de la distance géographique et du traitement effectué par le broker. Choisissez donc un serveur proche de l’endpoint de l’API et mesurez avec curl et mtr avant de payer pour une solution plus rapide.
De combien de RAM et de CPU un bot de trading a-t-il besoin ?
La plupart des bots utilisant une seule stratégie sont limités par le réseau et restent inactifs entre deux événements. La mémoire devient le facteur limitant si vous conservez l’historique des ticks en mémoire ou si vous exécutez une base de données locale. Surveillez donc free -h et le journal pour repérer les messages de type OOM kill au lieu d’estimer les besoins.
Pourquoi l’API de mon exchange rejette-t-elle les requêtes avec une erreur d’horodatage ?
L’horodatage de la requête est en dehors de la fenêtre acceptée par l’exchange. La dérive de l’horloge et les délais des requêtes peuvent toutes deux être en cause. Installez chrony, vérifiez que chronyc tracking indique un faible décalage System time et un état leap synchronisé, puis contrôlez également le délai racine et la dispersion. Configurer la machine en UTC garantit la cohérence des heures affichées, mais ne corrige pas la dérive de l’horloge. Régénérer la clé API ne résout pas un problème d’horloge.
Comment empêcher mon bot de s’arrêter pendant la nuit sans que je le sache ?
Exécutez-le avec systemd en utilisant Restart=always et StartLimitIntervalSec=0. Ainsi, une boucle de crash continue ses tentatives au lieu d’atteindre la limite de fréquence des démarrages. Ajoutez ensuite un heartbeat envoyé par le bot à la fin de chaque boucle exécutée avec succès. Le redémarrage gère le processus. Le heartbeat détecte le cas où le processus est actif, mais bloqué.
Puis-je exécuter le bot et ma supervision sur le même VPS ?
Oui, mais la supervision vous induira en erreur le jour où cela compte, car une panne qui arrête le bot arrêtera aussi la supervision. Hébergez les alertes sur une machine distincte, idéalement chez un autre fournisseur ou dans une autre région, et utilisez le serveur du bot uniquement pour le bot et ses journaux.