OSO Tradovate : 'Accès refusé' dans Market Replay
Le même bracket OSO qui se déclenche sans problème en démo revient avec Access is denied dans Market Replay. Replay s'authentifie différemment, et le refus provient presque toujours de la façon dont le token a été transmis au socket de replay.
Vous avez un bracket OSO qui se déclenche sans problème en démo. Même code, même contrat, même body, vous le pointez vers Market Replay pour backtester une session, et Tradovate vous renvoie {"failureReason":"UnknownReason","failureText":"Access is denied"}. Rien n'a changé de votre côté à part l'environnement, donc cela ressemble à un bug de permissions. Ce n'en est pas un. Replay s'authentifie différemment de démo et live, et le «refus» provient presque toujours d'une seule chose : le token n'a jamais été correctement présenté au socket de replay, ou l'ordre vise un compte que la session de replay ne possède pas. Corrigez le flux d'authentification et l'OSO qui fonctionne en démo fonctionnera aussi en Replay. Voici exactement ce qui se passe et comment le corriger.
Version courte : Replay n'a pas d'endpoint d'authentification propre, un POST vers
replay.tradovateapi.com/v1/auth/accessTokenRequestrenvoie simplement un 404. Demandez l'access token à l'endpoint d'authentificationdemo(oulive), ouvrezwss://replay.tradovateapi.com/v1/websocket, envoyez un frameauthorizeavec ce token, puis routez chaque appel, y compris votre OSO, via ce même socket, contre le compte que la session de replay a créé.
À quoi ressemble l'erreur
L'indice, c'est que le body de la requête est identique octet pour octet à celui qui fonctionne. Déclenchez l'OSO en démo et vous obtenez un ensemble propre d'ID d'ordre :
-
{"orderId":3696709628,"oso1Id":3696709629,"oso2Id":3696709630}
Envoyez le même payload dans Replay et, au lieu des ID, vous obtenez le refus :
-
{"failureReason":"UnknownReason","failureText":"Access is denied"}
Le contrat est valide pour la fenêtre de replay (disons MNQM2 pendant une session qui la couvre), le token s'est authentifié, et vous pouvez même récupérer les données du compte. Seul le placement de l'ordre est refusé. Ce schéma, tout se lit correctement, l'écriture est refusée, est la signature d'un problème de portée d'autorisation, pas d'un identifiant incorrect.
Pourquoi Market Replay renvoie "Access Is Denied"
Deux particularités de conception de l'environnement de replay causent presque tous ces refus.
Replay n'a pas d'endpoint d'authentification HTTP
En démo et en live, vous êtes habitué à un monde REST : vous faites un POST vers auth/accessTokenRequest, obtenez un token, puis envoyez les ordres par POST vers order/placeOrder en HTTPS. L'hôte de replay ne fonctionne pas ainsi. Il n'y a pas de auth/accessTokenRequest sur replay.tradovateapi.com, donc un POST vers https://replay.tradovateapi.com/v1/auth/accessTokenRequest renvoie un 404 Not Found. Les gens voient ce 404, supposent que l'endpoint a été déplacé, et se mettent à deviner des URL, alors que la vraie réponse est que replay n'en a jamais eu.

Le token provient toujours des endpoints d'authentification normaux. Vous le transportez ensuite vers le WebSocket de replay et vous autorisez à cet endroit. Tout ce qui suit, abonnements aux données de marché, contrôle de l'horloge et placement d'ordres, transite sous forme de messages encadrés sur ce socket unique. Si votre OSO continue à partir en HTTPS pendant que votre token vit sur le socket, Tradovate n'a aucune session autorisée à laquelle rattacher l'ordre, et vous obtenez «Access is denied.»
Chaque session de replay crée un compte jetable tout neuf
Replay ne négocie pas avec votre compte démo ou live. Quand vous appelez replay/initializeClock, Tradovate démarre une session et crée un tout nouveau compte de replay alimenté avec l'initialBalance que vous transmettez. Ce compte n'existe que pour la session et est abandonné quand celle-ci se termine. Une seule session de replay tourne par utilisateur à la fois, et rappeler initializeClock réinitialise ce qui était en cours.
Voici le piège qui produit les refus : votre OSO doit viser ce compte de replay, celui que la session actuelle vient tout juste de créer, pas l'id de votre compte démo, pas l'id de votre compte live, et pas un id périmé d'une session que vous avez déjà réinitialisée. Visez le mauvais compte avec l'ordre et Tradovate le refusera avec la même chaîne laconique.
La solution, étape par étape
Demandez le token à l'authentification demo ou live (jamais replay)
Authentifiez-vous auprès d'un vrai endpoint d'environnement et conservez l'accessToken renvoyé : le travail sim/backtest utilise https://demo.tradovateapi.com/v1/auth/accessTokenRequest ; le travail avec des identifiants live utilise https://live.tradovateapi.com/v1/auth/accessTokenRequest. Envoyez le jeu complet d'identifiants que votre environnement attend, name, password, appId, appVersion, cid, sec, et, surtout en live, un deviceId stable. Ne faites de POST vers aucun chemin d'authentification replay.tradovateapi.com ; c'est le piège du 404.
Ouvrez le socket de replay et autorisez-vous avec ce token
Connectez-vous à wss://replay.tradovateapi.com/v1/websocket. Tradovate ouvre le flux avec un frame d'ouverture d'un seul caractère, la lettre o. Dès que vous le voyez, envoyez le frame authorize en utilisant le token de l'étape 1 : authorize\n{id}\n\n{accessToken}. Cette forme délimitée par des sauts de ligne, endpoint, id de requête, ligne vide, body, est la façon dont chaque message de replay est encadré. Un authorize réussi est ce qui accorde réellement à votre session le droit de placer des ordres sur le socket. Sautez-le, et même un token parfaitement valide laisse le placement d'ordres non autorisé.
Initialisez l'horloge et capturez le compte de la session
Le socket étant autorisé, configurez la session de replay en envoyant replay/initializeClock avec votre fenêtre et votre vitesse : {"startTimestamp":"2019-08-26T16:43:00.000Z","speed":100,"initialBalance":51000}. speed est un pourcentage (environ 0–400), et initialBalance finance le compte de replay temporaire. Une fois l'horloge lancée, résolvez le compte rattaché à cette session et conservez son id numérique. C'est le compte que votre OSO doit référencer dans accountId / accountSpec, pas l'id que vous utiliseriez en démo ou en live.
Envoyez l'OSO via le socket de replay, contre ce compte
Placez maintenant le bracket comme un frame WebSocket sur le même socket autorisé, en utilisant le compte de la session de replay : order/placeorder\n{id}\n\n{orderBodyJson}. Gardez le même body OSO qui fonctionne en démo, mais remplacez-y l'id de compte de replay capturé à l'étape 3. Quand le compte et l'étape d'autorisation concordent, la réponse passe de failureText à de vraies valeurs orderId / oso1Id / oso2Id.
Gardez le token et le socket actifs
Les access tokens ont une durée de vie courte, comptez sur environ 80 à 90 minutes. Une longue session de replay peut dépasser la durée du token, et quand il expire en cours de session, l'ordre suivant se lit comme un refus. Envoyez des frames de heartbeat périodiques pour éviter que le socket ne devienne inactif, et renouvelez le token avant qu'il n'expire, pas après. Traitez un «Access is denied» soudain au milieu d'une session qui fonctionnait comme une expiration probable, pas comme un nouveau bug de permissions.


Toujours "Access Is Denied" ? Passez cette checklist en revue
Si le flux d'authentification est correct et que l'OSO ne se place toujours pas, vérifiez ceci dans l'ordre :
- Décalage d'id de compte, confirmez que l'ordre vise le compte de la session de replay, pas un id démo/live ni un id périmé d'une session déjà réinitialisée avec un initializeClock plus récent.
- Permissions de la clé API, la clé avec laquelle vous vous êtes authentifié doit avoir Orders accordé, pas refusé. Une clé en lecture seule s'authentifie et liste les comptes mais est bloquée dès qu'elle tente de placer un ordre.
- Device id en live, si vous générez le token depuis l'hôte live, fournissez un deviceId stable et approuvé. Démo est tolérant à ce sujet ; live ne l'est pas, et les identifiants diffèrent entre les deux.
- Frame authorize sauté, assurez-vous d'avoir réellement envoyé authorize après le frame d'ouverture o et d'avoir reçu un succès avant qu'un ordre ne parte.
- Limite d'une seule session, rappelez-vous qu'une seule session de replay tourne par utilisateur. Si une autre session est active (depuis l'interface ou une exécution précédente), votre nouvelle session pourrait être en train de la réinitialiser sans que vous le sachiez.
- Fenêtre du contrat, le symbole doit être valide pour la date de replay, utilisez donc le contrat qui était le front month actif pendant votre startTimestamp, pas le front month d'aujourd'hui.
Tableau de dépannage
| Symptôme | Cause | Solution |
|---|---|---|
| 404 sur l'URL d'authentification replay | Replay n'a pas d'endpoint d'authentification HTTP | Obtenez le token via demo/live auth/accessTokenRequest, puis autorisez le socket de replay |
| OSO renvoie {"failureText":"Access is denied"} | Socket jamais autorisé, ou ordre visant le mauvais compte | Envoyez le frame authorize après o ; visez le compte de la session de replay |
| Fonctionne en démo, refusé en Replay | L'ordre passe encore par HTTPS au lieu du socket | Envoyez order/placeorder comme message encadré sur le WebSocket de replay |
| Timeout ou refus juste après initializeClock | Utilisation d'un ancien compte d'une session réinitialisée | Résolvez à nouveau et utilisez le compte rattaché à la session actuelle |
| Une session qui fonctionnait refuse soudain les ordres | Access token expiré en cours d'exécution | Envoyez des heartbeats au socket et renouvelez le token avant ~80–90 min |
| Refusé uniquement lors de l'authentification en live | deviceId manquant/non approuvé ou permission Orders refusée | Fournissez un device id stable approuvé ; accordez l'accès Orders à la clé |
Où PickMyTrade intervient
Câbler à la main la danse token démo vers socket replay est l'origine de la plupart de ces refus, un frame authorize oublié ou un mauvais id de compte, et toute la session refuse les ordres. Si votre objectif est de faire tourner une stratégie contre Tradovate à partir d'alertes TradingView plutôt que de surveiller des frames WebSocket, PickMyTrade gère la connexion pour vous : il gère le token, cible le bon compte et marque correctement les ordres automatisés pour que les entrées bracket se routent sans que vous ayez à déboguer du JSON à l'ouverture.
Routez vos brackets sans toucher à l'API
Démarrez votre essai gratuit de 5 jours, liez vos alertes et routez vos brackets vers Tradovate sans toucher à l'API.
Démarrez votre essai gratuit de 5 joursQuestions fréquentes
Démo et Replay sont des environnements différents avec une plomberie différente. Dans Replay, le token doit être généré depuis l'endpoint d'authentification demo ou live, puis présenté via le WebSocket de replay avec un frame authorize. Sautez cette étape d'authorization, ou envoyez l'ordre contre un compte que la session ne possède pas, et le même body qui réussit en démo revient avec failureText "Access is denied".
Il n'y a pas d'endpoint d'authentification sur l'hôte de replay. Un POST vers https://replay.tradovateapi.com/v1/auth/accessTokenRequest renvoie 404 par conception. Demandez l'access token via https://demo.tradovateapi.com/v1/auth/accessTokenRequest ou l'équivalent live, puis réutilisez ce token pour autoriser le WebSocket de replay.
Via le WebSocket. Une fois autorisé sur wss://replay.tradovateapi.com/v1/websocket, chaque appel, y compris order/placeOrder, est envoyé comme un message encadré du type order/placeorder\n{id}\n\n{body}. Les appels HTTP vers l'hôte de replay ne routeront pas vos ordres de replay.
replay/initializeClock démarre une session de replay et crée un compte de replay jetable, financé pour la session et abandonné à la fin de celle-ci. Une seule session de replay existe par utilisateur à la fois, et un nouvel initializeClock réinitialise la précédente. Les ordres doivent viser le compte rattaché à la session actuelle ; un id de compte périmé ou démo/live produit des erreurs d'accès refusé ou de timeout.
Oui. Les access tokens Tradovate ont une durée de vie courte, environ 80 à 90 minutes. Gardez le socket actif avec des frames de heartbeat périodiques et renouvelez le token avant qu'il n'expire, pour qu'une expiration en cours de session ne se fasse pas passer pour un refus.
Cela peut être le cas, surtout lorsque vous vous authentifiez contre live plutôt que demo. Live impose un deviceId stable et approuvé fourni lors de l'authentification, et les identifiants diffèrent entre demo et live. Si Replay fonctionne avec un token démo mais échoue avec un token live, vérifiez le device id et confirmez que la permission Orders de la clé API est accordée, pas refusée.
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 futures 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 sponsorisée par elle. Tous les noms, logos et marques associés sont la propriété de leurs détenteurs respectifs. Les fonctionnalités et é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.