Tradovate API

Tradovate API: Fill-/Position-Endpunkte liefern keine Daten

Ihre Orders werden problemlos ausgeführt, aber der Fill-Preis oder die Größe der offenen Position kommt leer zurück. Zwei der drei Ursachen sind falsch aufgebaute Anfragen, die Sie in wenigen Minuten beheben können, eine ist eine Timing-Eigenheit, auf die Sie Ihr Design ausrichten müssen.

Geprüft vom PickMyTrade Trading Systems Team Zuletzt aktualisiert
· 8 Minuten Lesezeit
Tradovate-API-Aufruf fill/list liefert HTTP 200 mit einem leeren Array in einem REST-Client

Ihre Orders werden problemlos ausgeführt. Dann fragen Sie die API nach genau der einen Sache, die Sie wirklich brauchen, dem Fill-Preis oder der Größe der offenen Position, und sie liefert Ihnen nichts. Ein leeres Array. Ein null. Ein sauberes 200 OK mit [] im Body. Drei Aufrufe bringen hier fast jeden ins Stolpern: fill/list (oder fill/items) kommt leer zurück, order/item funktioniert, enthält aber keinen Fill-Preis, und position/find?name=... findet Ihre Position nie. Zwei davon sind falsch aufgebaute Anfragen, die Sie in ein paar Minuten beheben können. Eine ist eine Timing-Eigenheit, auf die Sie Ihr Design ausrichten müssen. Und in einem kleinen Teil der Fälle liefert Tradovate die Daten tatsächlich unzuverlässig, dann ist es richtig, ein paar Endpunkte gegenzuprüfen und es dem Support zu melden. Trennen wir die drei Fälle.

Kurzcheckliste

  • Innerhalb der Session abfragen. REST zeigt nur den aktuellen Handelstag. Nach Handelsschluss wird die Session archiviert, und ältere Aufrufe liefern ein leeres Ergebnis.
  • Verwenden Sie /find nicht mehr für Positionen. Die Position-Entität hat kein name-Feld, daher trifft position/find?name=MNQZ5 niemals zu. Suchen Sie Positionen über contractId.
  • Der Fill-Preis steht nicht auf der Order. Lesen Sie ihn aus dem price-Feld des Fills, nicht aus order/item.
  • Endpunkt und Parameter aufeinander abstimmen. /item?id= nimmt eine id; /items?ids= nimmt eine Liste; /list nimmt keine. Parameter sind kleingeschrieben.
  • Host und Token prüfen. Ein Demo-Token auf einem Live-Host oder ein abgelaufener Token liefert leere oder nicht autorisierte Antworten, noch bevor überhaupt ein Datenproblem greift.
  • Wenn die richtigen Aufrufe während einer Live-Session mit bekannter Aktivität weiterhin leer bleiben, erfassen Sie Request und Response und melden Sie es dem Support.

Was "None zurückgeben" tatsächlich bedeutet

In diesen Fehlschlägen steckt ein wichtiger Unterschied, der bestimmt, wie Sie sie beheben. Ein 200 OK mit einem leeren Array bedeutet, dass der Aufruf akzeptiert, authentifiziert und verstanden wurde, der Server unter diesen Parametern aber einfach keine Daten zu liefern hatte. Das ist so gut wie nie ein Fehler bei Tradovate; es ist ein Scope- oder Timing-Mismatch auf Ihrer Seite. Ein 404 bedeutet dagegen, dass der konkrete angefragte Datensatz gerade nicht erreichbar ist, häufig bei einer item?id=-Abfrage nach dem Rollover der Session. Und ein 401 bedeutet, dass der Server gar nicht erst so weit gekommen ist, nach Daten zu suchen. Prüfen Sie also, bevor Sie schließen “der Endpunkt ist kaputt,” welchen dieser drei Codes Sie tatsächlich erhalten. Er weist direkt auf die Ursache hin.

Warum die Fill-, Order- und Position-Aufrufe leer zurückkommen

1. REST zeigt nur die aktuelle Session

Das ist der Hauptgrund, und er erwischt Leute, die nach Handelsschluss testen. Tradovate archiviert die Session jedes Tages nach Handelsschluss. Danach sehen die REST-Abfrage-Endpunkte, fill/list, order/list, fillPair/list, cashBalanceLog/list und Verwandte, nur noch die Datensätze der aktuellen Session. Fragen Sie nach den Fills von gestern, erhalten Sie ein 200 mit einem leeren Array; fragen Sie über order/item?id= nach einer bestimmten archivierten Order, kann ein 404 kommen. Mit Ihrer Authentifizierung oder Syntax stimmt nichts nicht. Die Daten liegen einfach nicht mehr im Live-Cache. Das Erkennungszeichen ist, dass genau derselbe Aufruf eine Stunde zuvor während der Session noch funktionierte und jetzt leer zurückkommt.

Die Lösung besteht aus zwei Teilen. Für Live-Aktivität führen Sie Ihre Abfragen in derselben Session aus, in der die Trades stattgefunden haben. Für alles Historische, den Tagesabschluss, ein P&L-Journal, ein Trade-Log, nutzen Sie die Reporting API unter rpt-live.tradovateapi.com (oder rpt-demo.tradovateapi.com für Demo), die dafür gebaut ist, archivierte Daten nach Datumsbereich zu liefern. Die allgemeinen Trading-Endpunkte sind das nicht.

Diagramm, das die Trading-API der aktuellen Session mit der Reporting API für historische Fills vergleicht

2. /find funktioniert nur bei Entitäten mit einem Name-Feld

Der Versuch, eine offene Position mit position/find?name=MNQZ5 zu finden, schlägt jedes Mal fehl, und nicht, weil Ihre Position fehlt. Die /find-Operation ist nur für Entitäten definiert, die ein name-Feld tragen. Contracts haben eines. Products haben eines. Die Position-Entität hat keines, daher liefert eine Namenssuche darauf nichts, egal was Sie übergeben. Positionen werden über contractId indiziert, eine Ganzzahl, nicht über die Symbolzeichenfolge, die Sie im Chart sehen.

Gehen Sie also in zwei Schritten vor. Lösen Sie zuerst das Symbol in eine Contract-ID auf: contract/find?name=MNQZ5 liefert das Contract-Objekt einschließlich seiner numerischen id. (Für einen Teil- oder Vorwärtstreffer liefert contract/suggest?t=MNQ&l=10 Kandidaten.) Rufen Sie dann Ihre Positionen mit position/list ab, oder position/deps?masterid={accountId} für ein bestimmtes Konto, und filtern Sie die Ergebnisse dort, wo contractId der gerade nachgeschlagenen id entspricht. Lesen Sie netPos für die vorzeichenbehaftete Größe. Das ist die Position, die Sie “finden” wollten.

Auflösen eines Symbols zu einer contractId mit contract/find und Abgleich in der Positionsliste

3. Das Order-Objekt enthält keinen Fill-Preis

Das ist wirklich kontraintuitiv. order/item?id= liefert die Order, ihren Status, ihre Seite, Menge, Ordertyp, Zeitstempel. Was es nicht liefert, ist der Preis, zu dem Sie gefüllt wurden, denn eine Order und ihre Ausführung sind zwei unterschiedliche Datensätze. Der Ausführungspreis liegt auf der Fill-Entität, in deren price-Feld. Eine Order kann mehrere Fills zu unterschiedlichen Preisen erzeugen, genau deshalb kann die Zahl nicht als Einzelwert auf der Order liegen.

Um den Fill-Preis für eine Order zu erhalten, gehen Sie zu den Fills. Jeder Fill referenziert seine übergeordnete Order über ein orderId-Feld und sein Instrument über contractId und trägt price, qty, action (Buy/Sell) und einen timestamp. Rufen Sie fill/list für die Session ab und gleichen Sie über die gesuchte orderId ab, oder laden Sie die abhängigen Fills der Order direkt. Für Echtzeitarbeit ist die sauberste Quelle die executionReport-/fill-Events auf dem WebSocket, die genau in dem Moment eintreffen, in dem eine Ausführung stattfindet. Wenn Sie realisiertes P&L statt roher Fill-Preise brauchen, liefert fillPair/list zusammengeführte Buy/Sell-Paare.

4. Richtiger Endpunkt, falscher Parameter

Die Abfrage-Endpunkte von Tradovate folgen einer strikten, groß-/kleinschreibungssensitiven Struktur, und sie zu vermischen erzeugt leere Ergebnisse oder Fehler, die wie Datenprobleme aussehen. Das Muster ist: /item?id=123 für einen einzelnen Datensatz, /items?ids=1,2,3 für mehrere, /list für alles im Scope ohne Parameter, /deps?masterid=123 für die Abhängigen eines übergeordneten Objekts, und /ldeps?masterids=1,2 für mehrere übergeordnete Objekte. Ein Aufruf wie fill/items?Id=XXX bricht still zwei Regeln gleichzeitig, er verwendet den Plural-Endpunkt /items (der ids= erwartet) mit einem singulären, großgeschriebenen Id-Parameter, den der Server nicht erkennt. Wechseln Sie entweder zu fill/item?id=XXX für einen Datensatz oder zu fill/items?ids=XXX für eine Liste, und schreiben Sie den Parameter klein.

So prüfen Sie die Endpunkte Schritt für Schritt gegen

Wenn ein Fill-, Order- oder Position-Aufruf leer zurückkommt, führen Sie diese Sequenz aus, bevor Sie annehmen, dass die Plattform fehlerhaft ist. Sie isoliert die Ursache in wenigen Minuten.

1

Auth ausschließen

Rufen Sie einen trivialen authentifizierten Endpunkt wie account/list auf. Ein 401 hier bedeutet, dass das Problem bei Ihrem Token oder Host liegt, nicht bei den Fill-/Position-Endpunkten, beheben Sie das zuerst.

2

Umgebung bestätigen

Stellen Sie sicher, dass der aufgerufene Host (Demo vs. Live) zum Token passt, mit dem Sie sich authentifiziert haben. Ein gültiger Token, der auf die falsche Umgebung zeigt, liefert keine Daten.

3

Aktivität in dieser Session bestätigen

Wenn Sie nach Handelsschluss testen, ist im Live-Cache möglicherweise tatsächlich nichts vorhanden. Reproduzieren Sie es während einer aktiven Session mit einer bekannten offenen Position oder einem frischen Fill.

4

Symbol auflösen

Führen Sie contract/find?name=YOURSYMBOL aus und notieren Sie die numerische id. Jeder Positions- und Fill-Filter richtet sich danach, nicht nach dem Symboltext.

5

Drei Ansichten vergleichen

Rufen Sie order/list, fill/list und position/list für dasselbe Konto ab und gleichen Sie über contractId und orderId ab. Zeigt die Order als gefüllt, erscheint aber kein passender Fill, ist das die Diskrepanz, die eine Eskalation wert ist.

Gegenprüfung der Antworten von order/list, fill/list und position/list nebeneinander nach contractId

Tabelle zur Fehlerbehebung

Symptom Wahrscheinliche Ursache Lösung
fill/list liefert 200 + [] nach HandelsschlussSession archiviert; REST bedient nur den aktuellen TagInnerhalb der Session abfragen; für Historisches die Reporting API nutzen
position/find?name= ist immer leerPosition hat kein name-FeldSymbol → contractId auflösen, dann position/list filtern
order/item funktioniert, aber kein Fill-PreisPreis liegt auf dem Fill, nicht auf der OrderPreis aus dem passenden Fill lesen (über orderId)
order/item?id= liefert 404Datensatz nach Handelsschluss archiviertInnerhalb der Session abfragen oder aus der Reporting API abrufen
/items?Id= liefert leer oder FehlerFalsche Endpunkt-/Parameterform/item?id= (eins) oder /items?ids= (Liste) verwenden, kleingeschrieben
Alle korrekten Aufrufe während einer Live-Session leerMögliches plattformseitiges ZuverlässigkeitsproblemRequest/Response erfassen und dem Support melden

Das zuverlässige Muster: einmal synchronisieren, dann streamen

REST immer wieder mit “ist meine Position schon aktualisiert?” abzufragen ist der fragile Weg, das zu tun, und ein Hauptgrund dafür, dass Leute veraltete oder leere Antworten sehen, Sie erwischen den Endpunkt zwischen zwei Updates. Das Muster, auf das Tradovate selbst Entwickler hinweist, ist ein anderes: abonnieren, nicht pollen.

Öffnen Sie den Trading-WebSocket und senden Sie ein user/syncrequest. Als Antwort erhalten Sie einen einzigen konsolidierten Snapshot, Konten, Positionen, Orders, Fills, Kassenbestände, das ganze Paket. Ab diesem Zeitpunkt sendet Ihnen der Socket jede Änderung, sobald sie eintritt: ein neuer Fill, ein Positions-Update, eine Kassenbestandsänderung. Sie halten ein lokales Modell anhand dieser Events synchron, statt REST erneut zu befragen. Für die historische Seite, die Trades, die bereits aus der Live-Session archiviert wurden, führen Sie den anfänglichen Backfill über die Reporting API durch und übergeben dann für alles Weitere an den WebSocket. Diese Kombination hält die Sicht eines Bots auf Fills und Positionen sowohl vollständig als auch aktuell.

Wann Sie es dem Support melden sollten

Meistens lassen sich diese leeren Antworten auf eine der vier oben genannten Ursachen zurückführen, und Sie können sie ohne fremde Hilfe beheben. Aber es gibt eine reale Teilmenge, in der der korrekte Aufruf, während einer aktiven Session, gegen ein Konto mit bestätigter Aktivität, immer noch nichts liefert, oder eine Order als gefüllt angezeigt wird, während nie ein Fill-Datensatz erscheint. Das können Sie nicht wegcodieren, und es lohnt sich, es zu melden. Geben Sie dabei den genauen Endpunkt und Query-String, die Konto-ID, den UTC-Zeitstempel, ob Sie auf Demo oder Live waren, und den rohen 200-Response-Body mit dem leeren Ergebnis an. Ein so gegengeprüfter Bericht wird deutlich schneller bearbeitet als “die API funktioniert nicht.”

Wo PickMyTrade ansetzt

Contract-Lookups, Fill-Abgleich, sessionbewusste Abfragen und eine WebSocket-Sync-Schleife zusammenzufügen ist eine Menge Code, den man schreiben und pflegen muss, nur um den eigenen Fill-Preis und die offene Größe zu kennen. PickMyTrade sitzt zwischen TradingView und Tradovate und übernimmt diese Schicht für Sie:

  • Live-Positions- und Fill-Tracking, die Verbindung bleibt mit Ihrem Kontostatus synchron, sodass Sie keine Endpunkte abfragen, die zwischen Updates leer zurückkommen.
  • Symbolhandling richtig gemacht, Contract-Auflösung und Rollover werden im Hintergrund verwaltet, sodass Sie nie die falsche id abgleichen.
  • Sessionsichere Ausführung, Orders werden geroutet und bestätigt, ohne dass Sie archivierte vs. Live-Datenfenster manuell verwalten müssen.
  • Kein Token- oder WebSocket-Code, Auth, Erneuerung und der Sync-Stream werden gehandhabt, sodass Ihre Alerts einfach Tradovate erreichen und gefüllt werden.

Automatisieren, ohne mit der API zu kämpfen

Starten Sie Ihre kostenlose Testphase und automatisieren Sie Tradovate, ohne mit der API zu kämpfen.

Starten Sie Ihre kostenlose 5-Tage-Testphase

Häufig gestellte Fragen

Die REST-List- und Item-Endpunkte zeigen nur die aktuelle Handels-Session. Sobald die Session nach Handelsschluss archiviert wird, liefern Aufrufe für ältere Aktivität ein 200 OK mit einem leeren Array (oder einen 404 bei einer Item-Abfrage). Fragen Sie innerhalb derselben Session ab, in der die Fills stattfanden, und nutzen Sie für alles Historische die Reporting API.

Das Order-Objekt enthält den Orderstatus, nicht die Ausführungsdetails. Der durchschnittliche oder pro Los ermittelte Fill-Preis liegt im price-Feld der Fill-Entität. Rufen Sie die Fills für diese Order-ID ab, über fill/list oder den Fill-Dependency-Endpunkt, und lesen Sie dort price, oder hören Sie auf das executionReport-Event am WebSocket.

Die /find-Operation funktioniert nur bei Entitäten mit einem name-Feld. Die Position-Entität hat kein name-Feld, daher liefert eine Namenssuche immer ein leeres Ergebnis, unabhängig von Ihrer offenen Position. Positionen werden über contractId indiziert. Lösen Sie das Symbol zuerst mit contract/find?name=MNQZ5 in eine Contract-ID auf und gleichen Sie diese id dann gegen position/list ab.

Contracts haben ein name-Feld, daher liefert contract/find?name=MNQZ5 das Contract-Objekt einschließlich seiner numerischen id. Für Teiltreffer verwenden Sie contract/suggest?t=MNQ&l=10. Nehmen Sie diese contractId und nutzen Sie sie, um Positionen und Fills zu filtern, da beide auf den Contract über die id verweisen und nicht über den Symboltext.

Fragen Sie REST nicht in einer Schleife ab. Öffnen Sie den Trading-WebSocket und senden Sie user/syncrequest, um einen einmaligen Snapshot von Konten, Positionen, Orders, Fills und Kassenbestand zu erhalten, und lassen Sie den Socket danach jedes Update streamen. Nutzen Sie die Reporting API für den anfänglichen historischen Backfill.

Dieser Leitfaden dient ausschließlich Bildungs- und Informationszwecken und stellt keine Finanz-, Anlage- oder Handelsberatung dar. Der Handel mit Futures und anderen gehebelten Produkten birgt ein erhebliches Verlustrisiko und ist nicht für jeden Anleger geeignet. PickMyTrade ist eine unabhängige Drittanbieter-Automatisierungsplattform und steht in keiner Verbindung zu Tradovate, Inc. und wird von diesem Unternehmen weder unterstützt noch gesponsert. Alle zugehörigen Namen, Logos und Marken sind Eigentum ihrer jeweiligen Inhaber. Plattformfunktionen und -abläufe ändern sich im Laufe der Zeit. Bestätigen Sie daher stets den aktuellen Ablauf in der offiziellen Tradovate-Plattform und -Dokumentation, bevor Sie handeln.