Tradovate API

Correction de l'erreur Tradovate 'Not Found: md/subscribeQuote'

Votre flux d'authentification fonctionne, votre socket de compte tourne sans problème, et md/subscribeQuote renvoie quand même Not found alors que l'endpoint figure bien dans la documentation. Vous avez envoyé la requête au mauvais WebSocket.

On This Page

Votre flux d'authentification a fonctionné, votre socket de compte tourne sans problème, puis vous envoyez un md/subscribeQuote pour démarrer le flux de prix en direct et le serveur vous renvoie Not found: md/subscribeQuote, souvent déformé en quelque chose comme "\"Not found: md/subscribeQuote\"" avec des caractères d'échappement empilés. L'endpoint est bien dans la documentation. Alors pourquoi Tradovate agit-il comme s'il n'existait pas ?

Voici la version courte : vous avez envoyé la requête au mauvais WebSocket. Les abonnements aux cotations ne vivent pas sur la même connexion que celle que vous utilisez pour synchroniser votre compte ou passer des ordres. Corrigez le socket auquel la requête est envoyée et l'erreur disparaît. Voyons précisément pourquoi cela arrive, comment router correctement et ce qui a tendance à casser ensuite une fois la trame enfin arrivée.

Ce que « Not Found » signifie réellement ici

Traitez cela comme un 404 sur un appel REST. Un 404 indique que le chemin d'URL n'existe pas sur ce serveur. Sur le WebSocket de Tradovate, la logique est identique : chaque trame que vous envoyez nomme un endpoint, et si le socket auquel vous êtes connecté ne sert pas cet endpoint, le serveur répond Not found en vous renvoyant le nom de l'endpoint.

Lisez bien cela, car cela écarte beaucoup d'hypothèses. Il ne vous dit pas que votre symbole est mauvais. Il ne vous dit pas que votre jeton a expiré. Il ne vous dit pas que votre JSON est mal formé. Il vous dit une seule chose : « il n'existe aucune route pour md/subscribeQuote sur cette connexion ». Et il n'y a qu'une seule raison courante à cela.

La cause : vous êtes sur le socket de compte, pas sur le socket de données de marché

Tradovate exploite deux services WebSocket distincts, qui ne sont pas interchangeables. Beaucoup câblent le premier, l'autorisent, voient les données de compte et d'ordres circuler parfaitement, puis supposent que cette même connexion gère tout. Ce n'est pas le cas.

  • Le socket de compte / API gère les ordres, les positions, les exécutions, la synchronisation du compte et le reste des données d'entités. C'est ici que se trouvent user/syncRequest, order/placeOrder et account/list. En réel : wss://live.tradovateapi.com/v1/websocket ; en démo : wss://demo.tradovateapi.com/v1/websocket.
  • Le socket de données de marché gère les prix en direct, les cotations, le DOM, les graphiques et les histogrammes. C'est ici que vit chaque endpoint md/, y compris md/subscribeQuote, md/subscribeDOM et md/getChart. En réel : wss://md.tradovateapi.com/v1/websocket ; en démo : wss://md-demo.tradovateapi.com/v1/websocket.

Envoyez md/subscribeQuote au socket de compte et il n'existe tout simplement aucune route correspondante, d'où le retour de Not found: md/subscribeQuote. Le socket de compte ne vous laissera pas entendre que vous frappez à la mauvaise porte, il signale simplement que l'endpoint est manquant. Voici la carte complète des hôtes pour aligner votre environnement :

Usage Démo / Simulation Réel
Base REST d'authentificationhttps://demo.tradovateapi.com/v1/https://live.tradovateapi.com/v1/
Socket de compte / API (user/syncRequest, order/placeOrder)wss://demo.tradovateapi.com/v1/websocketwss://live.tradovateapi.com/v1/websocket
Socket de données de marché (md/subscribeQuote, md/getChart)wss://md-demo.tradovateapi.com/v1/websocketwss://md.tradovateapi.com/v1/websocket

La solution : ouvrir et autoriser un second socket pour les cotations

Vous ne déplacez pas votre socket de compte. Vous ajoutez un socket de données de marché à côté. Conservez la connexion de compte pour les ordres et la synchronisation ; ouvrez un tout nouveau WebSocket vers l'hôte de données de marché pour les prix. Voici la séquence qui élimine l'erreur.

1

Récupérez les deux jetons dans votre réponse d'authentification

Lorsque vous vous authentifiez, la réponse de Tradovate contient plus d'un jeton. À côté du accessToken habituel, vous verrez un mdAccessToken et un expirationTime. Ce second jeton n'est pas décoratif, il est émis spécifiquement pour le flux de données de marché. Conservez-le.

2

Ouvrez le WebSocket de données de marché

Connectez-vous à l'hôte de données de marché correspondant à votre environnement : wss://md-demo.tradovateapi.com/v1/websocket si votre jeton provient de l'endpoint d'authentification démo, ou wss://md.tradovateapi.com/v1/websocket s'il provient du réel. Croiser un jeton réel avec l'hôte démo (ou l'inverse) vous fait rejeter avant même que l'abonnement n'ait de l'importance. Attendez la trame o d'ouverture du socket avant d'envoyer quoi que ce soit.

3

Autorisez d'abord le socket

C'est l'étape que l'on saute. Un socket neuf ne répond à rien tant que vous ne l'avez pas autorisé. La toute première trame envoyée doit être la trame authorize portant votre jeton, utilisez le mdAccessToken pour la connexion de données de marché. Les trames Tradovate sont du texte délimité par des sauts de ligne, et non du JSON brut : l'endpoint, l'identifiant de requête, une ligne de requête (souvent vide), puis le corps. Envoyez la trame authorize, attendez la réponse confirmant que le socket est autorisé, et seulement ensuite passez à la suite. Si vous lancez un abonnement avant la fin de cette poignée de main, il ne sera pas pris en compte.

4

Envoyez maintenant md/subscribeQuote

Avec le socket ouvert et autorisé, l'abonnement dispose enfin d'une route. Envoyez-le comme une trame de même forme, avec un corps JSON nommant un seul contrat. Vous pouvez désigner le contrat par sa chaîne de symbole (comme ESU6 pour l'E-mini S&P de septembre 2026) ou par son identifiant numérique de contrat, les deux fonctionnent. Le serveur accuse réception de la requête puis commence à pousser des événements de cotation avec le bid, l'ask et le dernier prix de ce contrat. L'erreur Not found disparaît parce que l'endpoint existe sur la connexion que vous utilisez désormais.

Trame authorize :
authorize
1

<yourMdAccessToken>


Trame subscribe :
md/subscribeQuote
2

{"symbol":"ESU6"}

Abonnez-vous une fois par symbole, pas en bloc

Un piège rapide qu'il vaut la peine de nommer : md/subscribeQuote accepte un seul symbole par appel. Il n'existe pas de forme tableau où vous fournissez une liste pour tout obtenir d'un coup. Si vous voulez suivre ES, NQ et CL ensemble, envoyez trois trames d'abonnement distinctes sur le même socket de données de marché, chacune avec son propre identifiant de requête. Un socket peut porter de nombreux abonnements de cotations en direct simultanément, il suffit de les enregistrer un par un. Lorsque vous en avez fini avec un contrat, désabonnez-vous avec md/unsubscribeQuote pour ne pas recevoir un flux que vous ne lisez plus.

Ce qui casse ensuite : le socket est bon, mais aucun prix ne s'affiche

Une fois l'erreur not-found disparue, la classe de problème suivante est d'une autre nature. La requête atteint désormais le moteur de données de marché ; tout échec à partir de là concerne donc ce que vous avez demandé et si vous y avez droit, et non une route manquante.

« Symbol is inaccessible »

Si l'appel d'abonnement renvoie une réponse d'inaccessibilité ou de symbole inconnu, deux éléments sont généralement en jeu. D'abord, le symbole doit être un véritable contrat à échéance rapprochée, entièrement qualifié, ESU6, et non la racine ES seule, ni un contrat déjà expiré et basculé sur le trimestre suivant. Ensuite, votre compte a besoin des droits pour voir ces données : la Contract Library plus un abonnement actif aux données de marché de la bourse. Sans cela, une requête parfaitement formée ne renvoie rien d'exploitable. C'est un problème distinct, avec sa propre solution.

Le socket se coupe sans cesse

Le WebSocket de Tradovate attend un heartbeat périodique. Si vous vous connectez, autorisez, vous abonnez puis restez silencieux, le serveur ferme la connexion et vos cotations s'arrêtent net. Envoyez une trame heartbeat vide à l'intervalle indiqué par Tradovate (un intervalle court, de l'ordre de quelques secondes) afin que le socket de données de marché reste ouvert aussi longtemps que vous avez besoin des prix. Beaucoup de signalements du type « ça a marché une minute puis c'est mort » remontent directement à un heartbeat manquant.

Le jeton a expiré en pleine session

Les jetons d'accès ne durent pas éternellement. Si votre socket de données de marché s'est bien autorisé au début de la session puis cesse de répondre, votre jeton a peut-être simplement expiré. Renouvelez-le avant son expiration plutôt que d'attendre l'échec des appels, puis réautorisez le socket avec le nouveau jeton.

Une liste de vérification rapide pour éliminer l'erreur

Vérification Ce qu'il faut confirmer
Bon socketmd/subscribeQuote va vers md.tradovateapi.com (réel) ou md-demo.tradovateapi.com (démo), jamais vers le socket de compte.
Environnement cohérentJeton réel → hôte de données de marché réel ; jeton démo → hôte démo.
Autoriser d'abordEnvoyez la trame authorize avec votre mdAccessToken avant toute requête md/.
Symbole de contrat completUtilisez un symbole à échéance rapprochée entièrement qualifié comme ESU6, et non la racine ES ou un contrat expiré.
Un symbole par appelEnvoyez une trame d'abonnement distincte par contrat ; il n'existe pas de forme tableau en bloc.
Heartbeats + jetonMaintenez le socket actif avec des heartbeats et renouvelez le jeton avant son expiration.

Oubliez le câblage de sockets bruts

La plupart de ceux qui rencontrent Not found: md/subscribeQuote ne poursuivent pas un projet de fournisseur de données, ils veulent simplement qu'une stratégie trade sur Tradovate sans avoir à surveiller deux sockets, deux jetons, des heartbeats et des formats de trame. Si c'est votre cas, il existe un chemin bien plus court que de coder à la main toute la couche WebSocket.

Pour les problèmes qui apparaissent souvent juste après celui-ci, ces guides vont plus loin : si vos symboles reviennent inaccessibles plutôt que not-found, il s'agit d'un problème distinct de droits et de format de symbole ; pour obtenir des prix en temps réel en premier lieu, s'abonner aux données de marché en temps réel de Tradovate est le point de départ ; et si votre socket s'autorise bien puis cesse silencieusement de répondre, c'est généralement le jeton d'accès de 90 minutes qui expire en pleine session.

Oubliez le câblage de sockets bruts

Vous voulez que votre stratégie TradingView trade sur Tradovate sans câbler vous-même une seule trame WebSocket ? Découvrez comment PickMyTrade automatise tout le flux d'ordres.

Commencez votre essai gratuit de 7 jours

Questions fréquentes

Parce que md/subscribeQuote n'existe que sur le WebSocket de données de marché de Tradovate, pas sur le socket de compte que vous utilisez pour user/syncRequest et order/placeOrder. Si vous envoyez une requête md/ au socket de compte, le serveur n'a aucune route pour elle sur cette connexion et renvoie Not found: md/subscribeQuote. Ouvrez une seconde connexion vers l'hôte de données de marché et envoyez-y l'abonnement.

Les données de marché en réel utilisent wss://md.tradovateapi.com/v1/websocket et la démo utilise wss://md-demo.tradovateapi.com/v1/websocket. Ce sont des hôtes distincts des sockets de compte. Vérifiez les noms d'hôte actuels dans la documentation développeur de Tradovate avant de les figer dans votre code, car ils peuvent changer.

La réponse d'authentification de Tradovate renvoie deux jetons, accessToken et mdAccessToken, ainsi qu'un délai d'expiration. Le mdAccessToken est émis pour le flux de données de marché ; utilisez-le donc pour autoriser le socket de données de marché. Chaque socket a d'abord besoin de sa propre trame authorize ; un socket non autorisé ne répond à rien.

C'est un autre problème. Une fois que la requête atteint le moteur de données de marché, elle nécessite un symbole de contrat à échéance rapprochée valide et entièrement qualifié, ainsi que des droits d'accès : la Contract Library et un abonnement actif aux données de marché de la bourse. Sans cela, le symbole est renvoyé comme inaccessible même avec une trame correcte. Sur un compte prop ou d'évaluation, c'est généralement la société qui contrôle ces données.

Non. Chaque requête md/subscribeQuote accepte un seul symbole. Pour suivre plusieurs contrats, envoyez une requête d'abonnement par symbole sur le même socket de données de marché, chacune avec son propre identifiant de requête. Maintenez la connexion active avec des heartbeats et un seul socket peut porter de nombreux abonnements de cotations à la fois.

Ce guide est fourni à des fins strictement éducatives et informatives et ne constitue pas un conseil financier, d'investissement ou de trading. Le trading de contrats à terme et d'autres produits à effet de levier comporte un risque de perte important et ne convient pas à tous les investisseurs. PickMyTrade est une plateforme d'automatisation tierce indépendante, qui n'est ni affiliée à Tradovate, Inc. ou Bookmap, ni approuvée ni parrainée par ces sociétés. Tous les noms, logos et marques associés sont la propriété de leurs détenteurs respectifs. Les fonctionnalités et les étapes de la plateforme évoluent avec le temps ; vérifiez donc toujours la procédure en vigueur dans la documentation officielle de la plateforme avant d'agir.