Il y a quelques semaines, j'ai décidé de construire mon propre robot pour Polymarket. La version complète m'a pris plusieurs semaines.
J'étais prêt à investir cet effort car il existe de réelles inefficacités sur Polymarket. Bien qu'il existe déjà quelques robots qui exploitent ces inefficacités pour réaliser des bénéfices, ils sont loin d'être suffisants. Les opportunités sur ce marché sont encore bien plus nombreuses que le nombre de robots.
Logique de construction du robot
La logique de ce robot est basée sur une stratégie que j'exécutais manuellement auparavant. Pour gagner en efficacité, je l'ai automatisée. Ce robot opère sur le marché « BTC 15 minutes HAUSSier / BAISsier (BTC 15-minute UP/DOWN) ».
Le robot exécute un programme de surveillance en temps réel capable de basculer automatiquement vers la période BTC de 15 minutes en cours, de diffuser en streaming les meilleurs prix d'achat/vente (best bid/ask) via WebSocket, d'afficher une interface utilisateur terminal fixe et de permettre un contrôle complet par des commandes texte.
En mode manuel, vous pouvez passer des ordres directement.
buy up
buyshares up
Le mode automatique exécute une boucle répétée en deux phases (two-leg).
Dans un premier temps, il observe les fluctuations de prix uniquement pendant les windowMin minutes suivant le début de chaque période. Si l'un des côtés baisse suffisamment rapidement (une baisse d'au moins movePct en environ 3 secondes), il déclenche la « Première phase (Leg 1) » en achetant le côté qui a chuté.
Après avoir terminé la Leg 1, le robot n'achètera plus jamais le même côté. Il attend la « Deuxième phase (Leg 2, c'est-à-dire la couverture) » et ne la déclenche que si la condition suivante est remplie : leg1EntryPrice + oppositeAsk <= sumTarget.
Lorsque cette condition est remplie, il achète le côté opposé. Une fois la Leg 2 terminée, la boucle se termine et le robot retourne à l'état d'observation, attendant le prochain signal de chute brutale avec les mêmes paramètres.
Si la période change pendant le processus de boucle, le robot abandonne cette boucle ouverte et recommence à la période suivante avec les mêmes paramètres.
Les paramètres du mode automatique sont définis comme suit : auto on
· shares : Taille de la position à utiliser pour les deux transactions.
· sum : Seuil autorisé pour la couverture.
· move (movePct) : Seuil de chute brutale (par exemple 0.15 = 15%).
· windowMin : Durée, à partir du début de chaque période, pendant laquelle l'exécution de la Leg 1 est autorisée.
Backtest
La logique du robot est simple : attendre une vente violente, acheter le côté qui vient de finir de baisser, puis attendre que les prix se stabilisent et se couvrir en achetant le côté opposé, tout en garantissant que : priceUP + priceDOWN < 1.
Mais cette logique devait être testée. Est-elle vraiment efficace sur le long terme ? Plus important encore, le robot a de nombreux paramètres (nombre de parts, somme, pourcentage de mouvement, minutes de fenêtre, etc.). Quel ensemble de paramètres est optimal et maximise les profits ?
Ma première idée était de faire tourner le robot en direct pendant une semaine et d'observer les résultats. Le problème est que cela prend trop de temps et ne permet de tester qu'un seul ensemble de paramètres, alors que j'avais besoin d'en tester plusieurs.
Ma deuxième idée était d'utiliser des données historiques en ligne provenant de l'API CLOB de Polymarket pour effectuer un backtest. Malheureusement, pour le marché BTC 15 minutes HAUSSier/BAISsier, le point de terminaison des données historiques renvoyait constamment un ensemble de données vide. Sans historique des ticks de prix, le backtest ne pouvait pas détecter les « chutes brutales en environ 3 secondes », ne déclenchait pas la Leg 1 et produisait 0 boucles et 0% de retour sur investissement (ROI), quels que soient les paramètres.
Après enquête, j'ai découvert que d'autres utilisateurs rencontraient le même problème pour obtenir des données historiques sur certains marchés. J'ai testé d'autres marchés qui renvoyaient bien des données historiques et j'en ai conclu que pour ce marché spécifique, les données historiques n'étaient tout simplement pas conservées.
En raison de cette limitation, la seule méthode fiable pour backtester cette stratégie était de créer mon propre jeu de données historiques en enregistrant les meilleurs prix de vente (best-ask) en temps réel pendant l'exécution du robot.
L'enregistreur écrit sur le disque des instantanés contenant :
· Un horodatage
· L'identifiant de la période (round slug)
· Le nombre de secondes restantes
· Les ID des jetons UP/DOWN
· Les meilleurs prix de vente UP/DOWN
Ensuite, le « backtest enregistré (recorded backtest) » rejoue ces instantanés et applique de manière déterministe la même logique automatique. Cela garantit d'obtenir les données haute fréquence nécessaires pour détecter les chutes brutales et les conditions de couverture.
J'ai collecté au total 6 Go de données sur 4 jours. J'aurais pu en enregistrer plus, mais j'ai estimé que c'était suffisant pour tester différents ensembles de paramètres.
J'ai commencé à tester cet ensemble de paramètres :
· Solde initial : 1 000 $
· 20 parts par transaction
· sumTarget = 0.95
· Seuil de chute brutale = 15%
· windowMin = 2 minutes
J'ai également appliqué des frais constants de 0.5% et un spread de 2% pour rester dans un scénario conservateur.
Le backtest a montré un ROI de 86%, 1 000 $ devenant 1 869 $ en quelques jours seulement.
Ensuite, j'ai testé un ensemble de paramètres plus agressif :
· Solde initial : 1 000 $
· 20 parts par transaction
· sumTarget = 0.6
· Seuil de chute brutale = 1%
· windowMin = 15 minutes
Résultat : ROI de -50% après 2 jours.
Cela montre clairement que le choix des paramètres est le facteur le plus important. Cela peut vous faire gagner beaucoup d'argent, ou entraîner des pertes importantes.
Limites du backtest
Même en incluant les frais et le spread, le backtest a ses limites.
· Premièrement, il n'utilise que quelques jours de données, ce qui est peut-être insuffisant pour avoir une vision globale du marché.
· Il s'appuie sur des instantanés enregistrés des meilleurs prix de vente ; en réalité, les ordres peuvent être partiellement exécutés, ou exécutés à des prix différents. De plus, la profondeur du carnet d'ordres et le volume disponible ne sont pas modélisés.
· Les micro-fluctuations inférieures à la seconde ne sont pas capturées (les données sont échantillonnées une fois par seconde). Bien que le backtest ait des horodatages à la seconde, beaucoup de choses peuvent se passer entre chaque seconde.
· Dans le backtest, le slippage est constant, les délais variables (par exemple 200–1500 ms) ou les pics de réseau ne sont pas simulés.
· Chaque transaction est considérée comme exécutée « instantanément » (pas de file d'attente d'ordres, pas d'ordres en attente).
· Les frais sont appliqués de manière uniforme, alors qu'en réalité, ils peuvent dépendre de : marché / jeton, maker vs taker, niveau de frais ou conditions.
Pour rester pessimiste (prudent), j'ai appliqué une règle : si la Leg 2 n'est pas exécutée avant la fermeture du marché, la Leg 1 est considérée comme une perte totale (total loss).
Ceci est délibérément conservateur, mais ne correspond pas toujours à la réalité :
· Parfois, la Leg 1 peut être clôturée plus tôt,
· Parfois, elle finit in the money (ITM) et gagne,
· Parfois, la perte peut être partielle et non totale.
Bien que la perte puisse être surestimée, cela fournit un scénario pratique de « pire cas ».
Plus important encore, le backtest ne peut pas simuler l'impact de vos gros ordres sur le carnet d'ordres ou le fait d'attirer d'autres traders qui pourraient vous chasser. En réalité, vos ordres peuvent :
· Perturber le carnet d'ordres,
· Attirer ou repousser d'autres traders,
· Entraîner un slippage non linéaire.
Le backtest suppose que vous êtes un preneur de liquidités pur (price taker), sans aucun impact.
Enfin, il ne simule pas les limites de débit (rate limits), les erreurs API, les ordres rejetés, les suspensions, les timeouts, les reconnexions, ou le fait que le robot soit occupé et rate un signal.
Le backtest est extrêmement précieux pour identifier de bonnes plages de paramètres, mais ce n'est pas une garantie à 100% car certains effets du monde réel ne peuvent pas être modélisés.
Infrastructure
Je prévois d'exécuter ce robot sur un Raspberry Pi pour éviter de consommer les ressources de mon ordinateur principal et de maintenir un fonctionnement 24/7.
Mais il y a encore une marge d'amélioration significative :
· Utiliser Rust au lieu de JavaScript offrirait des performances et un temps de traitement bien supérieurs.
· Exécuter un nœud RPC Polygon dédié réduirait encore la latence.
· Le déployer sur un VPS proche des serveurs de Polymarket réduirait également considérablement la latence.
Il y a certainement d'autres optimisations que je n'ai pas encore découvertes. Pour l'instant, j'apprends Rust car il devient un langage indispensable dans le développement Web3.














