Tradovate API

Erreur 404 sur le point de terminaison liquidatePosition de l'API Tradovate

Vous envoyez une requête POST au point de terminaison liquidate en attendant une clôture propre, mais vous obtenez plutôt 404 Not Found. Neuf fois sur dix, il s'agit d'un chemin mal orthographié en casse, du mauvais hôte ou du mauvais verbe HTTP, et non d'un compte ou d'une charge utile défectueux.

Vérifié par l'équipe Trading Systems de PickMyTrade Dernière mise à jour
· Lecture de 8 minutes
Client de l'API Tradovate affichant une réponse 404 Not Found lors d'un POST vers order/liquidateposition

Vous voulez clôturer une position depuis votre code, donc vous envoyez un POST au point de terminaison liquidate en attendant une clôture propre. Au lieu de cela, le serveur renvoie 404 Not Found. Votre jeton est valide, vos autres appels d'ordres fonctionnent, le JSON semble parfait, et pourtant cette route se comporte comme si elle n'existait pas. C'est frustrant, car on a l'impression que le point de terminaison est cassé ou absent.

Ce n'est pas le cas. Une erreur 404 est plus limitée qu'il n'y paraît: elle ne concerne ni votre compte, ni votre position, ni votre charge utile. Elle signifie que l'URL exacte à laquelle vous avez envoyé le POST ne correspond à aucune route sur le serveur de Tradovate. Neuf fois sur dix, c'est l'une de ces trois choses: le chemin est mal orthographié en casse, vous visez le mauvais hôte, ou vous avez envoyé le mauvais verbe HTTP. Éliminons-les dans l'ordre, puis fixons l'appel correct pour que vous puissiez clôturer proprement.

Ce qu'une erreur 404 vous indique réellement

Chaque erreur HTTP pointe vers une couche différente, et les confondre vous fait modifier la mauvaise chose. Un 404 signifie que le chemin n'existe pas. Un 401 signifie que le chemin existe mais que vous n'étiez pas autorisé. Un 400 signifie que le chemin et l'authentification étaient corrects mais que votre corps de requête était mal formé. Un 429 signifie que vous atteignez la limite de débit. Donc, si vous êtes face à un véritable 404, arrêtez de modifier votre corps JSON: le serveur n'est jamais allé assez loin pour s'en soucier. Il n'a même pas pu trouver la route.

Ce seul fait réduit considérablement le champ de recherche. Tout ce qui produit un 404 se trouve dans la ligne de requête: la méthode, l'hôte, le segment de version et l'orthographe du chemin. Passez en revue ces quatre points et l'erreur disparaîtra.

Cause 1 : le chemin est mal orthographié ou a une casse incorrecte

C'est le grand classique, et il piège presque tout le monde au moins une fois. Les chemins REST de Tradovate sont sensibles à la casse. L'opération s'écrit exactement liquidatePosition, avec un l minuscule et un P majuscule en camelCase. Écrivez-la autrement et le routeur n'a rien à quoi la faire correspondre, il répond donc 404. Tout mettre en minuscules est l'erreur classique, généralement parce que vous l'avez tapée de mémoire ou parce que votre framework a normalisé l'URL à votre place.

Ce que vous avez envoyé Résultat
/v1/order/liquidatePositionRoute correcte
/v1/order/liquidateposition404 Not Found
/v1/order/LiquidatePosition404 Not Found
/v1/order/liquidate_position404 Not Found
/v1/order/liquidate-position404 Not Found
Schéma décomposant l'URL correcte de liquidatePosition de Tradovate en hôte, segment de version et chemin en camelCase

La solution est ennuyeuse mais fiable: copiez le nom de l'opération directement depuis la référence de l'API et collez-le, plutôt que de le retaper. Un seul caractère mal orthographié en casse suffit. Pendant que vous y êtes, vérifiez qu'il n'y a pas de barre oblique finale accidentelle ou de segment dupliqué comme /order/order/liquidatePosition qu'un générateur d'URL peut glisser.

Cause 2 : mauvais hôte ou segment de version manquant

L'URL complète comporte quatre parties qui doivent toutes être correctes: le schéma, l'hôte, le segment de version /v1 et le chemin. En les assemblant, vous obtenez:

  • Démo/simulation: https://demo.tradovateapi.com/v1/order/liquidatePosition
  • Live: https://live.tradovateapi.com/v1/order/liquidatePosition

Omettez le /v1 et vous obtenez un 404, car la racine de l'API n'a aucune route /order/liquidatePosition directement rattachée. Une faute de frappe dans l'hôte produit le même résultat, ou fait échouer purement et simplement la résolution DNS. Et n'utilisez pas l'hôte de données de marché ici: md.tradovateapi.com sert les cotations, le DOM et les graphiques, pas les opérations d'ordres, donc un hôte md ne routera pas non plus un appel de liquidation.

Une subtilité mérite d'être signalée: mélanger les environnements, un jeton demo contre l'hôte live, ou l'inverse, se manifeste plus souvent par un 401 que par un 404, mais cela vaut tout de même la peine d'être vérifié une fois votre chemin propre. Les noms d'hôte sont parfois mis à jour, confirmez donc les noms actuels dans la documentation développeur officielle de Tradovate plutôt que de faire confiance à une URL copiée depuis un vieux gist.

Cause 3 : vous avez envoyé la mauvaise méthode HTTP

L'opération de liquidation est uniquement en POST. Envoyez un GET et le serveur n'a aucun gestionnaire GET pour ce chemin, ce qui se traduit par une erreur de type introuvable ou méthode non autorisée selon la façon dont votre client la signale. Il est facile de tomber dans ce piège si vous testez en collant l'URL dans la barre d'adresse du navigateur, cela reste toujours un GET, donc cela échouera toujours ici.

Testez avec un véritable POST depuis un client adapté. Vous avez également besoin des bons en-têtes sur la requête: Content-Type: application/json et Authorization: Bearer <yourAccessToken>. Un POST avec le corps mal placé, ou sans type de contenu JSON, peut échouer de manières qui ressemblent à un problème de routage même lorsque le chemin est correct.

Cause 4 : singulier ou pluriel, lequel est le bon ?

C'est de là que vient une grande partie de la confusion du type “le point de terminaison n'existe pas”. L'opération canonique, par position, est la route au singulier /order/liquidatePosition. Elle prend un accountId et un seul contractId et clôture cette unique position nette. C'est la route que vous trouverez documentée, et celle qui répond systématiquement.

Certaines bibliothèques clientes et extraits communautaires font référence à une variante plurielle de type batch qui prend un tableau positions au lieu d'un seul contrat. Si vous copiez un exemple au pluriel alors que votre cible n'expose que la route au singulier, ou si vous supposez que le singulier accepte un tableau, vous obtiendrez soit un 404, soit vous enverrez un corps que le point de terminaison ignorera. En cas de doute, utilisez par défaut le singulier /order/liquidatePosition avec accountId et contractId, et vérifiez le nom exact de l'opération et sa structure par rapport à la référence API en vigueur pour la version que vous appelez. L'orthographe et le choix entre singulier et pluriel sont exactement les deux détails qui produisent discrètement un 404.

L'appel correct, champ par champ

Une fois la ligne de requête correcte, le corps est court.

POST https://demo.tradovateapi.com/v1/order/liquidatePosition
{ "accountId": 12345, "contractId": 67890, "admin": false, "customTag50": "" }

Champ Ce que c'est
accountIdL'identifiant numérique du compte, pas le nom du compte ni sa spécification. Récupérez-le via /account/list.
contractIdL'identifiant numérique du contrat que vous détenez, issu de /position/list. Doit être supérieur à zéro.
adminUn booléen, et il doit être présent. Réglez-le sur false, sauf si votre utilisateur API dispose réellement de la permission admin (voir le piège ci-dessous).
customTag50Étiquette facultative de 50 caractères maximum qui accompagne l'ordre. Une chaîne vide convient.
Réponse JSON de position/list de Tradovate avec les champs accountId et contractId mis en évidence

Ce sont les deux identifiants qui bloquent le plus souvent les gens, alors procédez méthodiquement. Appelez /account/list et relevez l'id de l'objet compte avec lequel vous voulez trader. Appelez /position/list, et chaque position ouverte vous fournit à la fois un accountId et un contractId, ainsi que sa quantité nette. Copiez ces chiffres exacts, le point de terminaison fonctionne sur la paire (accountId, contractId), pas sur un identifiant de position ni sur une chaîne de symbole.

Client de l'API Tradovate affichant un POST réussi vers order/liquidatePosition renvoyant une réponse 200

Le piège admin : un 401 caché derrière votre correctif

Ce piège se referme au moment même où vous résolvez le 404. Le champ admin est obligatoire dans le corps, mais la valeur que vous lui donnez compte. Réglez admin: true alors que votre utilisateur API n'est pas provisionné pour un accès admin, et l'appel bascule directement vers 401 Unauthorized. Réglez admin: false et la même requête passe. Donc, à moins que vous ne sachiez que votre utilisateur dispose du périmètre admin, envoyez "admin": false. Si vous venez de corriger un 404 et que vous vous retrouvez face à un 401 dès la tentative suivante, c'est presque toujours la raison, pas votre jeton, pas l'identifiant de votre compte.

Ce que le point de terminaison vous donne, et ce qu'il ne donne pas

Quelques comportements méritent d'être connus avant de construire sur cet appel :

  • Il clôture l'intégralité de la position nette pour cette paire (accountId, contractId). En coulisses, il place un ordre de clôture, ce qui signifie qu'il ne s'exécutera pas si le marché est fermé, exécutez-le pendant les heures de négociation de l'instrument.
  • C'est un appel par contrat. Pour tout clôturer sur un compte, récupérez /position/list et bouclez, en déclenchant un liquidatePosition par contractId ouvert. Il n'existe pas de corps unique “clôturer tout le compte” sur cette route.
  • Il est sûr face aux conditions de concurrence (race-safe). Si la position s'est déjà clôturée entre votre vérification et l'appel, par exemple parce qu'un stop a été exécuté, vous obtenez un 200 propre avec un corps vide plutôt qu'une erreur. C'est délibéré, et c'est plus sûr que de synthétiser un ordre du côté opposé, qui pourrait accidentellement ouvrir une position inverse.
  • Il ne renvoie aucun orderId. Comme il n'y a pas d'identifiant d'ordre dans la réponse, vous ne pouvez pas lire directement le prix d'exécution de clôture. Si vous avez besoin de ce prix pour le P&L, rapprochez-vous des rapports d'exécution et de fill (execution reports, fill pairs) ou du journal des positions.

Une checklist rapide pour résoudre le 404

Vérification Ce qu'il faut confirmer
Orthographe exacteliquidatePosition en camelCase, pas en minuscules, pas en snake_case, pas avec des tirets.
URL complèteSchéma + hôte + /v1 + /order/liquidatePosition, avec le segment de version présent.
Bon hôtedemo.tradovateapi.com ou live.tradovateapi.com, jamais l'hôte de données de marché md.
POST, pas GETPOST avec Content-Type: application/json et un jeton Bearer ; pas de tests via la barre d'adresse du navigateur.
Identifiants numériquesaccountId depuis /account/list, contractId depuis /position/list, tous deux supérieurs à zéro.
Valeur d'adminIncluez admin ; réglez-le sur false sauf si votre utilisateur dispose de la permission admin, pour éviter un 401 en cascade.

Où PickMyTrade s'intègre

La plupart des personnes aux prises avec ce 404 ne veulent pas vraiment devenir des plombiers de l'API Tradovate, elles veulent une stratégie qui ouvre, gère et clôture les positions sans avoir à surveiller sans cesse les points de terminaison, les identifiants et les jetons. PickMyTrade achemine les alertes TradingView vers Tradovate et peut clôturer ou liquider des positions dans le cadre d'une stratégie, afin que vous n'ayez pas à construire manuellement des appels de liquidation, à courir après les identifiants de compte et de contrat, ni à gérer les jetons.

  • Aucun appel de liquidation construit manuellement votre stratégie ouvre et clôture des positions sur Tradovate sans une seule requête API codée à la main.
  • Résolution du compte et du contrat prise en charge les identifiants qui font trébucher les appels bruts sont résolus pour vous.
  • Authentification gérée les jetons et les hôtes sont gérés automatiquement, de sorte qu'un 401 caché derrière un 404 ne devient jamais votre problème.
  • Routage sûr vis-à-vis des limites de débit espace le flux d'ordres pour que rien ne se heurte aux limites de requêtes de Tradovate.

Automatisez l'ensemble du flux d'ordres

Vous voulez que votre stratégie TradingView ouvre et clôture des positions sur Tradovate sans coder à la main le moindre appel API ? Découvrez comment PickMyTrade automatise l'ensemble du flux d'ordres.

Démarrez votre essai gratuit de 5 jours

Questions fréquentes

Un 404 signifie que le chemin de l'URL n'existe pas exactement tel que vous l'avez envoyé. La cause la plus fréquente est la casse: les chemins REST de Tradovate sont sensibles à la casse, et l'opération s'écrit liquidatePosition avec un P majuscule. Envoyez un POST à /v1/order/liquidateposition tout en minuscules et vous obtenez 404 Not Found, car cette route n'est pas définie. Il se passe la même chose si vous omettez le segment de version /v1, si vous visez le mauvais hôte, ou si vous envoyez un GET au lieu d'un POST. Corrigez d'abord le chemin, avant de toucher au corps.

Le point de terminaison canonique, par position, est le singulier /order/liquidatePosition. Il prend un accountId numérique plus un seul contractId et clôture cette unique position nette. Certaines bibliothèques clientes et extraits de code font référence à une variante plurielle par lots qui accepte un tableau positions, donc copier un exemple au pluriel sur une route qui ne sert que le singulier (ou l'inverse) peut provoquer un 404. En cas de doute, utilisez le singulier /order/liquidatePosition avec accountId et contractId, et confirmez le nom exact de l'opération par rapport à la référence API en vigueur pour votre version.

Les deux sont des identifiants numériques, pas des noms. Appelez /account/list pour obtenir le champ id de votre compte, et appelez /position/list pour obtenir l'accountId et le contractId de chaque position ouverte. Copiez ces valeurs numériques directement dans le corps de la requête. Le contractId doit être supérieur à zéro, et il doit s'agir du contrat que vous détenez réellement, pas d'une racine de produit ni d'une chaîne de symbole.

Un 401 signifie que la route existe mais que la requête n'était pas autorisée, ce qui est un problème différent d'un 404. Sur ce point de terminaison, le déclencheur habituel est le champ admin. Il est obligatoire dans le corps, mais si vous réglez admin sur true alors que votre utilisateur API n'est pas provisionné pour la permission admin, l'appel revient avec 401 Unauthorized. Réglez admin sur false et la requête passe. Donc, si corriger le chemin a transformé votre 404 en 401, basculez admin sur false.

Non. Une liquidation réussie renvoie un 200 propre sans orderId, vous ne pouvez donc pas lire directement le prix d'exécution de clôture depuis la réponse. Elle est sûre face aux conditions de concurrence: si la position s'est déjà clôturée, vous obtenez tout de même un 200 avec un corps vide plutôt qu'une erreur. Pour récupérer le prix de clôture pour le P&L, rapprochez-vous des rapports d'exécution et de fill ou du journal des positions plutôt que d'attendre un identifiant d'ordre en retour.

Oui. PickMyTrade achemine les alertes TradingView vers Tradovate et peut clôturer ou liquider des positions dans le cadre d'une stratégie, afin que vous n'ayez pas à construire manuellement des appels liquidatePosition, à courir après les recherches d'accountId et de contractId, ni à gérer les jetons vous-même. C'est un raccourci pour l'automatisation, pas un remplacement de l'API brute lorsque vous avez spécifiquement besoin d'un contrôle bas niveau.

Ce guide est fourni à des fins éducatives et informatives uniquement 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 substantiel de perte et ne convient pas à tous les investisseurs. PickMyTrade est une plateforme d'automatisation tierce indépendante et n'est ni affiliée à Tradovate, Inc., ni approuvée ou parrainée par cette dernière. 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, confirmez donc toujours le processus actuel dans la plateforme et la documentation officielles de Tradovate avant d'agir.