Tradovate API

Gli endpoint fill/position dell'API Tradovate non restituiscono dati

I suoi ordini vengono eseguiti senza problemi, ma il prezzo di fill o la dimensione della posizione aperta torna vuoto. Due delle tre cause sono problemi di formato della chiamata che può risolvere in pochi minuti, una è una particolarità di tempistica da considerare nella progettazione.

Verificato dal Trading Systems Team di PickMyTrade Ultimo aggiornamento
· Lettura di 8 minuti
Chiamata all'API fill/list di Tradovate che restituisce HTTP 200 con un array vuoto in un client REST

I suoi ordini vengono eseguiti senza problemi. Poi chiede all'API l'unica cosa di cui ha davvero bisogno, il prezzo di fill o la dimensione della posizione aperta, e non le restituisce nulla. Un array vuoto. Un null. Un 200 OK pulito con [] nel corpo. Tre chiamate mandano in confusione quasi tutti qui: fill/list (o fill/items) torna vuota, order/item funziona ma non riporta il prezzo di fill, e position/find?name=... non trova mai la sua posizione. Due di questi sono problemi di formato della chiamata che può risolvere in un paio di minuti. Uno è una particolarità di tempistica con cui deve fare i conti nella progettazione. E in una piccola parte dei casi è davvero Tradovate a restituire dati in modo inaffidabile, nel qual caso la cosa giusta da fare è controllare incrociando alcuni endpoint e segnalarlo al supporto. Separiamo i tre casi.

Lista di controllo rapida

  • Interroghi durante la sessione. REST mostra solo la giornata di negoziazione corrente. Dopo la chiusura del mercato la sessione viene archiviata e le chiamate più vecchie restituiscono risultati vuoti.
  • Smetta di usare /find sulle posizioni. L'entità Position non ha un campo name, quindi position/find?name=MNQZ5 non troverà mai corrispondenza. Cerchi le posizioni tramite contractId.
  • Il prezzo di fill non si trova sull'ordine. Lo legga dal campo price del fill, non da order/item.
  • Faccia corrispondere l'endpoint al parametro. /item?id= accetta un id; /items?ids= accetta un elenco; /list non ne accetta nessuno. I parametri vanno in minuscolo.
  • Confermi host e token. Un token demo su un host live, o un token scaduto, restituisce un risultato vuoto o non autorizzato ancora prima che si applichi qualsiasi problema di dati.
  • Se le chiamate corrette continuano a tornare vuote durante una sessione live con attività nota, acquisisca richiesta e risposta e lo segnali al supporto.

Cosa significa davvero "restituisce None"

C'è una distinzione importante dietro questi fallimenti, e cambia il modo in cui li risolve. Un 200 OK con un array vuoto significa che la chiamata è stata accettata, autenticata e compresa, ma il server semplicemente non aveva dati da fornire con quei parametri. Questo quasi mai è un bug di Tradovate; è un disallineamento di ambito o di tempistica dal suo lato. Un 404, al contrario, significa che il record specifico richiesto non è raggiungibile in questo momento, comune in una ricerca item?id= dopo che la sessione è stata archiviata. E un 401 significa che il server non è nemmeno arrivato a cercare dati. Quindi, prima di concludere che «l'endpoint è rotto», verifichi quale di questi tre stia effettivamente ricevendo. Punta direttamente alla causa.

Perché le chiamate a fill, order e position tornano vuote

1. REST mostra solo la sessione corrente

Questa è la causa principale, e colpisce chi fa test dopo l'orario di mercato. Tradovate archivia la sessione di ogni giornata alla chiusura del mercato. Una volta accaduto, gli endpoint di interrogazione REST, fill/list, order/list, fillPair/list, cashBalanceLog/list e simili, vedono solo i record della sessione corrente. Se chiede i fill di ieri ottiene un 200 con un array vuoto; se chiede un ordine archiviato specifico tramite order/item?id= può ottenere un 404. Non c'è nulla che non va nella sua autenticazione o nella sintassi. I dati semplicemente non sono più nella cache live. Il segnale rivelatore è che la stessa identica chiamata funzionava bene un'ora prima durante la sessione e ora torna vuota.

La soluzione è in due parti. Per l'attività live, esegua le query nella stessa sessione in cui sono avvenuti i trade. Per tutto ciò che è storico, la riconciliazione di fine giornata, un diario P&L, un registro dei trade, usi la Reporting API su rpt-live.tradovateapi.com (o rpt-demo.tradovateapi.com per il demo), pensata per servire dati archiviati per intervallo di date. Gli endpoint di trading generici non lo sono.

Diagramma che confronta l'API di trading della sessione corrente con la Reporting API per i fill storici

2. /find funziona solo su entità con un campo name

Provare a individuare una posizione aperta con position/find?name=MNQZ5 fallirà ogni singola volta, e non perché la sua posizione manchi. L'operazione /find è definita solo per le entità che hanno un campo name. I contratti ne hanno uno. I prodotti ne hanno uno. L'entità Position no, quindi una ricerca per nome su di essa non restituisce nulla, qualunque cosa passi. Le posizioni sono indicizzate per contractId, un intero, non per la stringa del simbolo che vede sul grafico.

Quindi proceda in due passaggi. Prima risolva il simbolo in un id di contratto: contract/find?name=MNQZ5 restituisce l'oggetto contract, incluso il suo id numerico. (Per una corrispondenza parziale o anticipata, contract/suggest?t=MNQ&l=10 restituisce dei candidati.) Poi recuperi le sue posizioni con position/list, oppure position/deps?masterid={accountId} per un account specifico, e filtri i risultati dove contractId corrisponde all'id appena cercato. Legga netPos per la dimensione con segno. Quella è la posizione che stava cercando di «trovare».

Risoluzione di un simbolo in un contractId con contract/find, poi corrispondenza nell'elenco delle posizioni

3. L'oggetto order non riporta il prezzo di fill

Questo è davvero controintuitivo. order/item?id= restituisce l'ordine, il suo stato, il lato, la quantità, il tipo di ordine, i timestamp. Ciò che non restituisce è il prezzo a cui è stato eseguito, perché un ordine e la sua esecuzione sono due record distinti. Il prezzo di esecuzione si trova sull'entità fill, nel suo campo price. Un ordine può generare più fill a prezzi diversi, ed è esattamente per questo che il numero non può stare come valore singolo sull'ordine.

Per ottenere il prezzo di fill di un ordine, vada ai fill. Ogni fill fa riferimento al proprio ordine padre tramite un campo orderId e al proprio strumento tramite contractId, e riporta price, qty, action (Buy/Sell) e un timestamp. Recuperi fill/list per la sessione e faccia corrispondere l'orderId che le interessa, oppure carichi direttamente i fill dipendenti dell'ordine. Per il lavoro in tempo reale, la fonte più pulita sono gli eventi executionReport / fill sul WebSocket, che arrivano nell'istante stesso in cui avviene un'esecuzione. Se le serve il P&L realizzato invece dei prezzi di fill grezzi, fillPair/list le fornisce le coppie buy/sell abbinate.

4. Endpoint giusto, parametro sbagliato

Gli endpoint di interrogazione di Tradovate seguono una forma rigida, sensibile alle maiuscole/minuscole, e mescolarli produce risultati vuoti o errori che sembrano problemi di dati. Lo schema è: /item?id=123 per un singolo record, /items?ids=1,2,3 per più record, /list per tutto ciò che rientra nell'ambito senza parametri, /deps?masterid=123 per i dipendenti di un genitore, e /ldeps?masterids=1,2 per più genitori. Una chiamata come fill/items?Id=XXX viola silenziosamente due regole contemporaneamente, usa l'endpoint plurale /items (che si aspetta ids=) con un parametro Id singolare e maiuscolo che il server non riconosce. Passi a fill/item?id=XXX per un record oppure a fill/items?ids=XXX per un elenco, e mantenga il parametro in minuscolo.

Come controllare incrociando gli endpoint passo dopo passo

Quando una chiamata a fill, order o position torna vuota, esegua questa sequenza prima di dare per scontato che la colpa sia della piattaforma. Isola la causa in pochi minuti.

1

Escluda i problemi di autenticazione

Esegua una chiamata autenticata banale come account/list. Un 401 qui significa che il problema è nel suo token o host, non negli endpoint fill/position, risolva prima quello.

2

Confermi l'ambiente

Si assicuri che l'host chiamato (demo vs. live) corrisponda al token con cui si è autenticato. Un token valido puntato sull'ambiente sbagliato non restituisce dati.

3

Confermi che c'è attività in questa sessione

Se sta facendo test dopo la chiusura del mercato, potrebbe davvero non esserci nulla nella cache live. Riproduca durante una sessione attiva con una posizione aperta nota o un fill recente.

4

Risolva il simbolo

Esegua contract/find?name=YOURSYMBOL e annoti l'id numerico. Ogni filtro di posizione e di fill si basa su questo, non sul testo del simbolo.

5

Confronti tre viste

Recuperi order/list, fill/list e position/list per lo stesso account e li confronti incrociando per contractId e orderId. Se l'ordine risulta eseguito ma non compare alcun fill corrispondente, quello è il disallineamento che merita di essere segnalato.

Confronto incrociato affiancato delle risposte di order/list, fill/list e position/list per contractId

Tabella di risoluzione dei problemi

Sintomo Causa probabile Soluzione
fill/list restituisce 200 + [] fuori orarioSessione archiviata; REST serve solo la giornata correnteInterroghi durante la sessione; usi la Reporting API per lo storico
position/find?name= sempre vuotoPosition non ha un campo nameRisolva simbolo → contractId, poi filtri position/list
order/item funziona ma senza prezzo di fillIl prezzo si trova sul fill, non sull'ordineLegga il prezzo dal fill corrispondente (per orderId)
order/item?id= restituisce 404Record archiviato dopo la chiusura del mercatoInterroghi durante la sessione o lo recuperi dalla Reporting API
/items?Id= restituisce vuoto o erroriForma endpoint/parametro errataUsi /item?id= (uno) o /items?ids= (elenco), in minuscolo
Tutte le chiamate corrette vuote durante una sessione livePossibile problema di affidabilità lato piattaformaAcquisisca richiesta/risposta e lo segnali al supporto

Lo schema affidabile: sincronizzare una volta, poi fare streaming

Interrogare REST ripetutamente chiedendo «la mia posizione è già aggiornata?» è il modo fragile di procedere, ed è uno dei motivi principali per cui si vedono risposte obsolete o vuote, si intercetta l'endpoint tra un aggiornamento e l'altro. Lo schema verso cui Tradovate stessa indirizza gli sviluppatori è diverso: iscriversi, non interrogare a ripetizione.

Apra il WebSocket di trading e invii un user/syncrequest. In risposta ottiene un unico snapshot consolidato, account, posizioni, ordini, fill, saldi di cassa, tutto quanto. Da quel momento in poi, il socket le invia ogni variazione non appena si verifica: un nuovo fill, un aggiornamento di posizione, un movimento di saldo. Mantiene un modello locale sincronizzato a partire da quegli eventi invece di reinterrogare REST. Per il lato storico, i trade già archiviati fuori dalla sessione live, esegua il backfill iniziale tramite la Reporting API, poi passi la mano al WebSocket per tutto ciò che segue. Questa combinazione è ciò che mantiene la visione di un bot su fill e posizioni sia completa che aggiornata.

Quando segnalarlo al supporto

Nella maggior parte dei casi queste risposte vuote si riconducono a una delle quattro cause sopra, e può risolverle senza l'aiuto di nessuno. Ma esiste un sottoinsieme reale in cui la chiamata corretta, effettuata durante una sessione attiva, contro un account con attività confermata, continua a non restituire nulla, oppure un ordine risulta eseguito mentre non compare mai alcun record di fill. Questo non è qualcosa che può aggirare con il codice, ed è utile segnalarlo. Quando lo fa, includa l'endpoint esatto e la query string, l'id dell'account, il timestamp UTC, se era su demo o live, e il corpo di risposta 200 grezzo che mostra il risultato vuoto. Una segnalazione così controllata incrociando i dati viene gestita molto più rapidamente di «l'API non funziona».

Dove si inserisce PickMyTrade

Mettere insieme ricerche di contratto, corrispondenza dei fill, query consapevoli della sessione e un ciclo di sincronizzazione WebSocket è molto codice da scrivere e mantenere solo per conoscere il proprio prezzo di fill e la propria dimensione aperta. PickMyTrade si colloca tra TradingView e Tradovate e gestisce questo livello al posto suo:

  • Monitoraggio live di posizioni e fill, la connessione resta sincronizzata con lo stato del suo account, quindi non interroga endpoint che tornano vuoti tra un aggiornamento e l'altro.
  • Gestione dei simboli fatta bene, la risoluzione dei contratti e il rollover sono gestiti sotto il cofano, quindi non farà mai corrispondere l'id sbagliato.
  • Esecuzione sicura per sessione, gli ordini vengono instradati e confermati senza che debba gestire manualmente le finestre di dati archiviati contro live.
  • Nessun codice per token o WebSocket, autenticazione, rinnovo e flusso di sincronizzazione sono gestiti, quindi i suoi alert raggiungono semplicemente Tradovate e vengono eseguiti.

Automatizzi senza lottare con l'API

Avvii la sua prova gratuita e automatizzi Tradovate senza lottare con l'API.

Avvii la sua prova gratuita di 5 giorni

Domande frequenti

Gli endpoint REST di lista ed elemento espongono solo la sessione di trading corrente. Una volta che la sessione viene archiviata alla chiusura del mercato, le chiamate per attività precedenti restituiscono un 200 OK con un array vuoto (o un 404 su una ricerca per elemento). Interroghi durante la stessa sessione in cui sono avvenuti i fill, e usi la Reporting API per tutto ciò che è storico.

L'oggetto order riporta lo stato dell'ordine, non i dettagli di esecuzione. Il prezzo di fill medio o per lotto si trova nel campo price dell'entità fill. Recuperi i fill per quell'order id, tramite fill/list o l'endpoint delle dipendenze dei fill, e legga price lì, oppure resti in ascolto dell'evento executionReport sul WebSocket.

L'operazione /find funziona solo su entità che hanno un campo name. L'entità Position non ha un campo name, quindi una ricerca per nome restituisce sempre un risultato vuoto, indipendentemente dalla sua posizione aperta. Le posizioni sono indicizzate per contractId. Risolva prima il simbolo in un id di contratto con contract/find?name=MNQZ5, poi confronti quell'id con position/list.

I contratti hanno un campo name, quindi contract/find?name=MNQZ5 restituisce l'oggetto contract, incluso il suo id numerico. Per corrispondenze parziali usi contract/suggest?t=MNQ&l=10. Prenda quel contractId e lo usi per filtrare posizioni e fill, poiché entrambi fanno riferimento al contratto tramite id e non tramite il testo del simbolo.

Non interroghi REST in un ciclo continuo. Apra il WebSocket di trading e invii user/syncrequest per ottenere uno snapshot unico di account, posizioni, ordini, fill e saldo di cassa, poi lasci che il socket trasmetta ogni aggiornamento da quel momento in poi. Usi la Reporting API per il backfill storico iniziale.

Questa guida ha scopo esclusivamente educativo e informativo e non costituisce consulenza finanziaria, di investimento o di trading. Il trading di future e altri prodotti a leva comporta un rischio sostanziale di perdita e non è adatto a tutti gli investitori. PickMyTrade è una piattaforma di automazione indipendente di terze parti e non è affiliata, approvata o sponsorizzata da Tradovate, Inc. 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 verifichi sempre la procedura attuale sulla piattaforma e nella documentazione ufficiali di Tradovate prima di agire.