Gli ordini bracket (OSO/OCO) dell'API Tradovate falliscono
La sua entrata viene eseguita su ES o NQ e lo stop-loss o il take-profit non compare mai. Ecco cosa significano davvero il 200 OK, il 404 e il rifiuto 'Wrong OCO combination', e come correggere ciascuno di essi.
La sua automazione invia un ordine bracket dell'API Tradovate, l'entrata viene eseguita su ES o NQ, e poi… nulla. Niente stop-loss, niente take-profit. Ora si trova a un tick sbagliato da una posizione priva di protezione, e il suo log riporta che l'ordine è stato “inviato correttamente”. Questa è la trappola. Nel 2026 l'errore classico non è più una schermata rossa di errore, ma uno stato HTTP 200 OK che nasconde un failureReason e un failureText nel corpo, oppure una chiamata a orderStrategy che torna come un semplice 404. Le varianti più comuni: un 404 (undocumented) da startOrderStrategy, un errore di parsing Invalid JSON, un rifiuto Wrong OCO combination, e il più insidioso, un'esecuzione parziale silenziosa in cui sopravvive solo l'entrata. Ecco cosa significa davvero ciascun errore, come correggere i problemi di endpoint e di campo che li causano, e come PickMyTrade impedisce che un'esecuzione priva di protezione arrivi mai al suo conto.
Checklist rapida per gli ordini bracket (OSO/OCO) che falliscono
- Legga il corpo della risposta, non solo il codice HTTP. Tradovate le restituisce
200 OKanche quando l'ordine è già morto in partenza. La verità si trova infailureReason/failureText. - Confermi l'endpoint. Usi
order/placeOSOper un'entrata che invia gambe di stop/target,order/placeOCOper due uscite collegate, eorderStrategy/startOrderStrategyper un bracket lato server. - Invii entrambi i campi account. Servono sia l'
accountIdnumerico (daaccount/list) sia il nome accountaccountSpec. Se ne manca uno, o non corrispondono, otterràAccess is denied. - Serializzi JSON reale. Invii un corpo JSON (
json=in Pythonrequests), non un dict grezzo, altrimenti otterràInvalid JSON: expected '{'. - Usi
orderStrategyTypeId: 2. È l'unico valore valido. Un1le procura un404 (undocumented). - Tenga pronto un fallback. Se l'endpoint di strategia continua a fallire, piazzi l'entrata, poi alleghi uno stop/target
placeOCOnon appena è aperta la posizione.
Cosa significano «Wrong OCO Combination» e gli errori 404
Tradovate offre diversi modi per inviare ordini protetti, e ciascuno fallisce a modo suo. Un bracket è un ordine di entrata più due gambe figlie, uno stop protettivo e un obiettivo di profitto, dove l'esecuzione o l'annullamento di una figlia annulla l'altra. Sull'API REST lo si costruisce con order/placeOSO (One-Sends-Other): un ordine padre porta oggetti bracket1 e bracket2 che si attivano solo dopo l'esecuzione del padre. order/placeOCO (One-Cancels-Other) collega due ordini in modo che l'esecuzione di uno annulli l'altro, comodo per agganciare uno stop e un target a una posizione già detenuta.
La parte confusa: questi endpoint restituiscono allegramente 200 OK pur rifiutando comunque l'ordine. Tradovate segnala gli errori di logica di business all'interno del corpo della risposta, non nello stato HTTP. Quindi un payload che raggiunge il server in modo pulito può comunque tornare con {"failureReason": "InvalidPrice", "failureText": "Wrong OCO combination"}, il che significa che i livelli di prezzo o l'abbinamento di tipi d'ordine scelti non formano un OCO valido. Uno stop e un limite posti sul lato sbagliato del mercato bastano a provocarlo. Consideri qualsiasi corpo contenente failureReason come un rifiuto, punto, indipendentemente da ciò che dice la riga di stato.
L'endpoint orderStrategy/startOrderStrategy è tutta un'altra bestia. Esegue una strategia bracket lato server, l'equivalente API di una strategia ATM, ed è molto più esigente riguardo al proprio payload. Se invia l'orderStrategyTypeId sbagliato, o lo chiama via REST semplice quando si aspetta un frame WebSocket, ottiene un 404 (undocumented) poco utile. Sembra una rotta mancante, ma in realtà è una richiesta rifiutata.
Principali cause di fallimento degli ordini bracket dell'API Tradovate
1. Ha controllato solo lo stato HTTP, non il corpo
Questa è la trappola numero uno. Il suo client vede 200 OK, registra “ordine inviato” e prosegue, ma l'entrata è stata rifiutata, oppure è passato solo l'ordine padre. Analizzi ogni risposta OSO/OCO alla ricerca di failureReason e failureText prima di considerare il bracket attivo.
2. orderStrategyTypeId errato su startOrderStrategy
Molti provano con orderStrategyTypeId: 1 e ottengono solo un 404 (undocumented) per il disturbo. Esiste un solo valore valido, ed è 2. Qualsiasi altro valore viene rifiutato prima ancora che la strategia venga costruita.

3. Chiamare startOrderStrategy via REST invece che via WebSocket
Anche con l'id di tipo corretto, questo endpoint non è affidabile via HTTP REST semplice. È costruito per funzionare su un WebSocket, e funziona in modo affidabile quando lo si pilota in quel modo. Una chiamata REST che continua a restituire 404 spesso ha successo, invariata, nel momento in cui la si invia come frame WebSocket.
4. JSON malformato o un dict grezzo invece di un corpo JSON
Un errore comune di placeOCO è Invalid JSON: expected '{', offset: 0x00000075. Ciò accade quando la richiesta invia un dizionario codificato come form invece di una stringa JSON serializzata, in Python, ad esempio passando data=payload invece di json=payload (o dimenticando json.dumps()). Il server non vede mai JSON valido, quindi scarta l'intero bracket.
5. accountSpec mancante, accountId errato o combinazione di prezzo illegale
Gli endpoint bracket richiedono sia l'accountId numerico (ricavato da account/list) sia la stringa accountSpec (il nome del suo account). Ometta uno dei due e otterrà Access is denied. Separatamente, placeOCO e placeOSO controllano che le due gambe formino una combinazione legale, uno stop e un limite quotati sul lato sbagliato del mercato tornano come Wrong OCO combination. I bracket con entrata Market aggiungono un'ulteriore complicazione: poiché l'API richiede livelli di prezzo concreti per le gambe figlie, generalmente non è possibile agganciare un TP/SL relativo in tick a una semplice entrata Market tramite placeOSO. O calcola lei stesso i livelli di prezzo, oppure lascia che sia il motore di strategia a gestire gli scostamenti.
Come correggere gli ordini bracket dell'API Tradovate: passo dopo passo
Correggere la trappola «200 OK ma nessuna gamba»
- Dopo ogni chiamata a
placeOSO/placeOCO/startOrderStrategy, analizzi il corpo JSON. - Verifichi la presenza di una chiave
failureReason. Se c'è, tratti l'ordine come rifiutato e leggafailureTextper la causa. - Consideri il bracket attivo solo quando ha gli ID ordine confermati sia per il padre sia per entrambe le gambe figlie, esegua polling su
order/listoppure si iscriva agli eventi ordine via WebSocket. - Registri il corpo completo, non solo il codice di stato, in modo che le esecuzioni parziali compaiano nella sua traccia di audit.
Correggere i 404 di startOrderStrategy
- Imposti
orderStrategyTypeIdsu2, l'unico valore accettato. - Invii sia
accountIdsiaaccountSpec, oltre asymbol,actione l'oggettoparams(con la suaentryVersione ibrackets). - Invii la richiesta come frame WebSocket anziché come POST REST. Questo endpoint è progettato per funzionare via WebSocket, e il formato di frame atteso è ben documentato.
- Riprovi lo stesso payload tramite il socket prima di presumere che il suo JSON sia malformato, il 404 è di solito un problema di trasporto, non di schema.

Correggere Invalid JSON e Wrong OCO combination
- Serializzi il payload come JSON. In Python
requests, usirequests.post(url, headers=..., json=payload), maidata=payloadcon un dict. - Confermi che l'header
Content-Type: application/jsonsia impostato. - Per
placeOCO, controlli la geometria delle due gambe: lo stop e il limite devono trovarsi su lati opposti e validi rispetto al prezzo attuale, in base alla direzione della posizione. Se vedeWrong OCO combination, inverta la gamba sul lato sbagliato. - Per un'entrata
Market, attenda l'esecuzione e alleghi uno stop/targetplaceOCOalla posizione risultante, oppure passi astartOrderStrategy, che accetta scostamenti relativi.
Il fallback affidabile: entrata separata + OCO
Quando un bracket nativo semplicemente non collabora, disaccoppi l'entrata dalle uscite. Piazzi l'ordine di entrata da solo con order/placeOrder, confermi l'esecuzione, quindi invii un placeOCO che abbina lo stop protettivo all'obiettivo di profitto sulla posizione ormai aperta. È un giro di andata e ritorno in più, ma aggira completamente l'endpoint di strategia e le dà un controllo esplicito su ogni gamba.

Tabella di risoluzione dei problemi
| Errore | Significato | Soluzione |
|---|---|---|
| 200 OK con failureReason nel corpo | Ordine rifiutato a livello di business logic nonostante uno stato HTTP pulito | Analizzi il corpo; non si fidi mai solo del codice di stato |
| 404 (undocumented) su startOrderStrategy | orderStrategyTypeId errato, oppure REST usato dove è previsto WebSocket | Imposti orderStrategyTypeId: 2 e invii via WebSocket |
| Invalid JSON: expected '{', offset: 0x... | È stato inviato un dict grezzo / corpo form invece di JSON serializzato | Invii un corpo JSON (json= in requests) o applichi prima json.dumps() |
| failureReason: InvalidPrice, failureText: Wrong OCO combination | Le due gambe OCO non formano un abbinamento prezzo/tipo valido | Riquoti in modo che stop e limite siano su lati opposti validi |
| Access is denied | accountId o accountSpec mancante o errato | Invii l'accountId numerico da account/list insieme al nome accountSpec |
| L'entrata viene eseguita, nessuno stop/target appare | Le gambe figlie sono state rifiutate silenziosamente mentre il padre è stato accettato | Confermi tutti e tre gli ID ordine, oppure ripieghi su entrata + placeOCO |
Come previene tutto questo PickMyTrade
Costruire manualmente i payload OSO/OCO significa farsi carico di ciascuna delle modalità di errore sopra descritte. PickMyTrade si posiziona tra i suoi alert TradingView e Tradovate e gestisce per lei l'idraulica del bracket:
- Gestione bracket e OCO, allega correttamente le gambe di stop-loss e take-profit, così un'entrata non resta mai priva di protezione.
- Validazione delle risposte, ispeziona l'intera risposta dell'ordine, non solo lo stato HTTP, e fa emergere i rifiuti reali invece di un falso “successo”.
- Filtri di entitlement e rischio, rispetta lo stato dell'accordo dati del suo account e i limiti della prop firm prima che un ordine venga instradato.
- Instradamento sicuro rispetto ai rate limit, distanzia il flusso di ordini così che le gambe del bracket non urtino i tetti di richiesta.
- Sincronizzazione multi-account, replica lo stesso bracket protetto su ogni account collegato.
Faccia trading senza rifiuti
Avvii la sua prova gratuita di 5 giorni, colleghi oggi stesso i suoi alert e lasci che PickMyTrade agganci correttamente stop-loss e take-profit ogni volta.
Avvii la sua prova gratuita di 5 giorniDomande frequenti
Usi order/placeOSO quando una singola entrata deve inviare uno stop e un target come bracket1 e bracket2. Usi order/placeOCO per collegare due ordini di uscita in modo che l'esecuzione di uno annulli l'altro. Usi orderStrategy/startOrderStrategy per una strategia bracket lato server con scostamenti relativi.
Tradovate segnala i rifiuti di business logic all'interno del corpo della risposta, non nello stato HTTP. Analizzi il corpo alla ricerca di failureReason e failureText, e consideri il bracket attivo solo quando ha gli ID ordine confermati per il padre ed entrambe le gambe figlie.
È un rifiuto InvalidPrice che significa che le sue due gambe OCO non formano un abbinamento legale, tipicamente lo stop e il limite sono quotati sul lato sbagliato del mercato rispetto alla direzione della posizione. Riquoti la gamba incriminata.
Quasi sempre un orderStrategyTypeId errato (deve essere 2) oppure una chiamata REST dove Tradovate si aspetta un frame WebSocket. Corregga l'id di tipo e reinvii via WebSocket.
Sta inviando un dizionario grezzo o un corpo codificato come form. Serializzi prima il payload in JSON, in Python requests, passi json=payload invece di data=payload.
Non direttamente, placeOSO si aspetta livelli di prezzo concreti per le sue gambe figlie. O calcoli lei stesso i prezzi esatti prima dell'invio, attenda l'esecuzione e alleghi un placeOCO, oppure usi startOrderStrategy, che accetta scostamenti relativi.
Disaccoppi il flusso. Piazzi l'entrata con order/placeOrder, confermi l'esecuzione, quindi invii un placeOCO che abbina stop e target alla posizione aperta. Evita completamente l'endpoint di strategia.
Sì. Gli endpoint bracket si aspettano l'accountId numerico da account/list e il nome account accountSpec come stringa. Omettere uno dei due restituisce Access is denied.
Questa guida ha scopo esclusivamente educativo e informativo e non costituisce consulenza finanziaria, di investimento o di trading. Il trading di futures e altri prodotti a leva comporta un rischio sostanziale di perdita e non è adatto a ogni investitore. PickMyTrade è una piattaforma di automazione indipendente di terze parti e non è affiliata, sostenuta o sponsorizzata da Tradovate, Inc. o Bookmap. Tutti i nomi, i loghi e i marchi correlati sono di proprietà dei rispettivi titolari. Le funzionalità e i passaggi della piattaforma cambiano nel tempo, quindi confermi sempre il processo attuale nella documentazione ufficiale della piattaforma prima di agire.