Destinations: NinjaTrader vs Tradovate
The Tradovate destination is in alpha. Bugs are still present, and participating in the alpha means helping us find them. If an alert behaves unexpectedly, note the Order ID from Alert History and report it to support.
Every CrossTrade webhook is routed to a destination: the broker connection that actually executes the order. CrossTrade supports two destinations today.
| Destination | How it executes | Requires |
|---|---|---|
NinjaTrader 8 (nt8) | The CrossTrade Add-On running inside your NinjaTrader 8 desktop application receives the order and submits it through NinjaTrader. | NinjaTrader 8 open, Add-On installed and connected. |
Tradovate (tradovate) | CrossTrade sends the order directly to Tradovate's cloud API over HTTPS. No desktop software runs on your side. | A linked Tradovate account (My Account, Brokers tab). |
Choosing a destination
Add a destination= field to your alert. When you omit it, the order routes to NinjaTrader 8, which keeps every existing alert working exactly as before.
| In your alert | Routes to |
|---|---|
(no destination field) | NinjaTrader 8 (default) |
destination=nt8; | NinjaTrader 8 (explicit) |
destination=tradovate; | Your linked Tradovate account |
The destination value is case-insensitive, and only nt8 and tradovate are valid. Any other value is rejected with a clear error.
NinjaTrader (default)
key=your-secret-key;
command=place;
account=Sim101;
instrument=ES 09-26;
action=buy;
qty=1;
order_type=market;
tif=day;
Tradovate
key=your-secret-key;
command=place;
account=DemoAccount;
instrument=ES 09-26;
action=buy;
qty=1;
order_type=market;
tif=day;
destination=tradovate;
The account for a Tradovate order is the Tradovate account name shown in My Account, Brokers tab after you link. Instruments accept the same three forms as NinjaTrader: TradingView continuous (ES1!, front month auto-resolved), NinjaTrader style (ES 09-26), or Tradovate style (ESU6).
Connecting Tradovate
- Open My Account and select the Brokers tab.
- In the Tradovate card, click Link Live or Link Demo and authorize through Tradovate's OAuth screen.
- Your accounts appear under the card once linked. Live and Demo are separate environments, and you can link multiple Tradovate identities (for example a personal account plus a funded firm) under each.
Trading a prop firm account (Apex, Topstep, or any other Tradovate-based funded firm)? Click Link Demo and sign in with the Tradovate username and password your firm issued. Firm accounts are simulation accounts on Tradovate's Demo environment, and that includes funded/PA accounts: the account stays on Demo after you pass the evaluation, with the firm handling payouts on their side. Link Live is only for a personal real-money Tradovate brokerage login, and authorizing it with a firm-issued login will fail.
CrossTrade stores only an access token, refreshes it automatically, and never sees your Tradovate password.
About the "automated" flag
Tradovate's exchanges require that orders placed by a bot or any algorithmic process are flagged as automated. The field is isAutomated, it applies per order (not to login or to data requests), and CrossTrade sets it to true on every order it places to Tradovate for you. You do not add an automated= field to your webhook, and there is no such field. CrossTrade handles the compliance flag automatically.
If you place orders through Tradovate from another tool as well, make sure that tool also marks its automated orders correctly. CrossTrade only controls the flag on the orders it sends.
Command availability
Both destinations share the same command vocabulary. Where a command is unavailable on Tradovate, the reason is always the same kind of thing: the command is tied to a NinjaTrader-only concept (ATM strategies, the add-on's local order book, or a NinjaTrader-specific atomic primitive).
| Command | NT8 | Tradovate | Notes |
|---|---|---|---|
place | Yes | Yes | Core entry. Tradovate adds server-side brackets, trailing stops, iceberg, and GTD. See the option tables below. |
flatplace | Yes | Yes | Flatten the same account and instrument (which also cancels working orders), then enter. |
closeposition | Yes | Yes | Tradovate uses its liquidate endpoint for a full close. Partial close works the same as NinjaTrader: quantity closes up to that many contracts, percent (0 to 1, rounded up) closes that fraction. |
flatten | Yes | Yes | Same filter semantics on both: account, instrument, and market_position (long or short) are each optional. With no filters, every open position on every linked account is closed. |
flatteneverything | Yes | Yes | Both destinations flatten every position and cancel every working order across all accounts. On Tradovate you can optionally pass account to limit the sweep to one account. |
reverse | Yes | Yes | Flip the current position. A bare reverse (just account + instrument) flips the live position with a market order; include action, qty, and order_type to also enter when flat. |
reverseposition | Yes | Yes | Same as above with an explicit direction and full entry fields. |
cancel | Yes | Yes | Cancel one order by order_id — either the numeric Tradovate id or the order_id you set on the original place alert (tracked for 7 days). |
cancelorders | Yes | Yes | Account-scoped on both: cancels working orders on the named account, optionally narrowed to one instrument. |
cancelallorders | Yes | Yes | Cancels every working order across all linked accounts on both destinations. |
change | Yes | Yes | Modify a working order (price, quantity, type, TIF) by order_id. Partial changes are fine — unchanged values are read from the working order. |
cancelreplace | Yes | Yes | Cancels the referenced order, then places the new one. On Tradovate the replacement is only placed when the cancel succeeded, so a filled original never turns into doubled exposure. |
cancelandbracket | Yes | Yes | Cancels the instrument's working orders and wraps the live position in a TP/SL OCO. Same safety behavior as NinjaTrader: quantity clamps to the live position and the bracket is aborted if the position goes flat during the cancel window. Absolute prices only on Tradovate. |
closestrategy | Yes | No | Closes a NinjaTrader ATM strategy by id. Tradovate has no ATM strategy concept, so there is nothing to close. |
You never get a silent failure. If you set destination=tradovate with a command that is not supported, CrossTrade rejects the alert with a message naming the command and listing the supported set, and the rejection is recorded in your Alert History.
Order types and time in force
| Capability | NT8 | Tradovate | Notes |
|---|---|---|---|
| Market | Yes | Yes | |
| Limit | Yes | Yes | limit_price required. |
| Stop / Stopmarket | Yes | Yes | stop_price required. |
| Stoplimit | Yes | Yes | limit_price and stop_price required. |
| MIT (market if touched) | No | Yes | Tradovate native order type. The touch price goes in limit_price. |
| QTS | No | No | Listed in Tradovate's API schema but not actually placeable (Tradovate has confirmed it is unsupported). CrossTrade rejects it with a clear error. |
| Trailing stop | No (webhook) | Yes | order_type=trailingstop with stop_price (initial trigger) and trail_offset (trail distance). On NinjaTrader, trailing is handled through ATM strategies, not the webhook order type. |
| Trailing stop limit | No (webhook) | Yes | order_type=trailingstoplimit with stop_price, limit_price, and trail_offset. All three are required. |
| TIF Day, GTC | Yes | Yes | The documented NinjaTrader webhook values. |
| TIF IOC, FOK, GTD | No | Yes | Tradovate adds immediate-or-cancel, fill-or-kill, and good-till-date. GTD requires expire_time (ISO-8601). |
Options and fields on the Tradovate destination
Supported
These fields behave on Tradovate the same way you expect from NinjaTrader, unless a note says otherwise.
| Field | Behavior on Tradovate |
|---|---|
account | Tradovate account name (or comma list for multi-account, see below). |
instrument | ES1!, ES 09-26, or ESU6. Digit-bearing roots (M2K, 6E, M6E, ...) work in all three forms. |
action, qty, order_type, tif | Standard entry fields. |
limit_price, stop_price | Required for the matching order types. |
take_profit, stop_loss | Attaches a server-side OSO bracket. Absolute prices always work; relative offsets (percentage, tick, point, dollar) work when your NT8 Add-On is connected to supply the live quote, and are rejected with a clear error otherwise. |
flatten_first | true flattens the same account and instrument (and cancels working orders) before the entry, then enters whether or not a position existed. Matches the NinjaTrader behavior. |
order_id | On place, a tracking id you choose: CrossTrade remembers it for 7 days so later cancel / change / cancelreplace alerts can reference the same id, exactly like NinjaTrader. On those commands you can also pass the raw numeric Tradovate order id. |
cl_ord_id | Client order id passed to Tradovate (defaults to your order_id when set). |
require_market_position | Gate the command on the live Tradovate position: flat, long, short, or comma combinations like long,flat. Same semantics as NinjaTrader. |
max_positions | Blocks the order when the account already has that many open positions. |
quantity / percent on closeposition | Partial close. percent is a decimal between 0 and 1 and always rounds up; quantity wins when both are present. |
cancel_after | Limit-order timeout in minutes (1 to 180). Implemented as a Tradovate-native scheduled cancel, so it fires broker-side even if CrossTrade restarts. |
market_position on flatten | Filter the sweep to long or short positions. |
cycle_accounts | With a comma-separated account list, sends each signal to one account instead of all of them. (Account Manager monitor states are NinjaTrader-only today, so cycling always starts from the first listed account.) |
xtstrategy | Tags the signal for XT Strategy tracking, same as NinjaTrader. |
expire_time | ISO-8601 datetime, required with tif=gtd. |
max_show | Iceberg display quantity. |
trail_offset (alias peg_difference) | Trailing distance for trailing-stop order types. |
activation_time | On the cancel command only: schedules the cancel broker-side at the given ISO-8601 time. It does not delay order entry (use delay for that). |
notes | Free-form order note, sent to Tradovate as the order's text and visible on the order in Tradovate's own UI and reports. |
delay, rate_limit + id | Same delay and rate-limiting behavior as the NinjaTrader path. |
start_time, end_time, closing_only_after, bypass_trade_windows | Trade-window controls apply on both destinations. |
Accepted but ignored
These NinjaTrader fields do nothing on Tradovate. CrossTrade accepts them without error so a shared alert template does not break, but they have no effect because they describe NinjaTrader-only behavior.
| Field | Why it has no effect on Tradovate |
|---|---|
strategy, strategy_id, strategy_tag, append_atm | ATM strategies and strategy tags are NinjaTrader concepts. |
sync_strategy, prev_market_position, out_of_sync, target_quantity, strategy_exit_block | Strategy synchronization relies on the add-on's local strategy and position state. (market_position by itself is accepted — it filters flatten and is harmless on other commands, so shared TradingView templates don't break.) |
Not supported (rejected)
Sending these with destination=tradovate is rejected with a clear error, rather than quietly doing nothing. Most are tied to NinjaTrader concepts; custom_tag is refused by Tradovate itself.
| Field | Reason and Tradovate alternative |
|---|---|
oco_id | Manual OCO grouping is a NinjaTrader feature. On Tradovate, set both take_profit and stop_loss and the two legs are linked as an OCO bracket for you. |
stop_loss_stop, stop_loss_limit | The stop-limit stop-loss leg is a NinjaTrader bracket detail. Tradovate brackets use a single absolute stop price. |
playbook | Playbooks are server-defined lifecycle plans built for the NinjaTrader execution model and are NinjaTrader-only. |
custom_tag | Tradovate's customTag50 identifies registered B2B partners to the exchange; it is not a user fill tag, and Tradovate rejects normal API orders that carry it. Use cl_ord_id or notes instead. |
How Tradovate behaves differently from NinjaTrader
Routing the same alert to Tradovate changes more than the transport. Two broker-side behaviors have no NinjaTrader equivalent, and both are handled for you. Knowing about them explains the occasional warning row or an extra second of latency.
Accepted is not resting: late broker rejections
Tradovate's API can accept an order (your webhook gets a success response with an order id) and still reject it a moment later in its risk and execution layer. The classic case is a stop or limit price outside the product's exchange price limits: the placement is accepted, then the order is rejected about a second later with InvalidPrice.
CrossTrade re-checks every placed order a few seconds after acceptance, in the background. If Tradovate rejected it, the Alert History row is updated with a warning that carries Tradovate's reason and the row moves to the yellow warning status. So treat a green row as "accepted by Tradovate" and check back for warnings if your prices sit near the limits. The Tradovate order id is recorded on the row either way.
On NinjaTrader this gap does not exist in the same form: the add-on reports through the platform's own order state, and the platform shows rejections in its Orders tab.
Position reads can lag right after a fill
Tradovate's position endpoint (position/find) can keep reporting the pre-fill state for tens of seconds after a fill, even though the fill itself is visible immediately. CrossTrade therefore never trusts that endpoint alone for time-sensitive decisions: every command that acts on your live position (require_market_position, partial closeposition, a bare reverse, cancelandbracket, and the Tradovate copier's follower sizing) derives the live net position from the broker's real-time fill stream instead.
In practice, back-to-back alerts (an entry followed immediately by a close, reverse, or require_market_position gate) see the true position without waiting. On NinjaTrader, the add-on reads the platform's live position state directly, so neither the lag nor the workaround exists there.
What only Tradovate can do
Because Tradovate orders run in Tradovate's cloud, some things are possible that the NinjaTrader webhook path does not offer. Copy-paste examples for every item below, plus a breakdown of exactly which Tradovate API requests each command generates, live on the Tradovate: Exclusive Features & Execution Internals page.
- No desktop software. Orders execute even when your computer is off. There is no add-on to install, keep open, or reconnect.
- Server-side OSO brackets. A
placewithtake_profitandstop_lossbecomes a single broker-side bracket order. The target and stop are linked as an OCO and live on Tradovate's servers, so they survive a disconnect. - Broker-side limit-order timeouts.
cancel_afteris scheduled on Tradovate's servers, so the auto-cancel fires even if your machine and CrossTrade are both unreachable at that moment. - Native trailing stops from a webhook.
order_type=trailingstop(ortrailingstoplimit) withtrail_offset. - Iceberg orders.
max_showsets the displayed quantity below the true order size. - GTD orders.
tif=gtdwith anexpire_time. - Extra order types.
mit(market if touched, touch price inlimit_price).
What only NinjaTrader can do
- ATM strategies (
strategy,append_atm) and template-based bracket management. - Strategy synchronization and Signal Share sync (
sync_strategy,prev_market_position,out_of_sync,target_quantity). - Strategy tags and locks (
strategy_tag) for trade-copy coordination. - Opposing Position Protection across accounts.
- Playbooks (
playbook). - Relative bracket offsets without the add-on: percentage, tick, point, and dollar based prices need a live quote from the NT8 Add-On. They work on Tradovate too when the add-on is connected; NinjaTrader alerts always have it by definition.
closestrategy(there is no ATM strategy to close on Tradovate).- Fill-driven trade copying, including manual trades — the NT8 Trade Copier runs inside NinjaTrader and sees every fill. The Tradovate copier mirrors webhook-driven trades only.
- Connection health features: data watchdog and auto-reconnect, which monitor the add-on.
Multi-account placement
Both destinations accept a comma-separated account list and place the order on each account. Each account gets its own independent execution: the alert is replicated per account and every copy runs through the full pipeline (rate limit, trade windows, account switches) exactly as on NinjaTrader, and each shows as its own Alert History row. On Tradovate, every name must be a linked Tradovate account.
cycle_accounts=true works too: one account per signal instead of all of them. NinjaTrader cycles based on Account Manager monitor state (skipping stopped accounts); Tradovate accounts have no monitors yet, so cycling currently always selects the first listed account.
key=your-secret-key;
command=place;
account=APEX1234,APEX1235;
instrument=ES 09-26;
action=buy;
qty=1;
order_type=market;
tif=day;
destination=tradovate;
Seeing the destination in Alert History
Every alert is recorded in Alert History with its resolved destination. Orders routed to Tradovate carry a blue Tradovate badge next to the command, and the expanded row shows the destination in its Order Info panel. NinjaTrader orders are unbadged, since that is the default. This makes it easy to confirm at a glance that a non-NinjaTrader order went where you intended.
Bracket example on Tradovate
A market entry with a server-side target and stop, both absolute prices:
key=your-secret-key;
command=place;
account=DemoAccount;
instrument=ES 09-26;
action=buy;
qty=1;
order_type=market;
tif=day;
take_profit=5300.00;
stop_loss=5285.00;
destination=tradovate;
CrossTrade sends this as one OSO order: the entry plus a linked target and stop that cancel each other when one fills.
Trade copying on Tradovate
Tradovate accounts get their own copier: configure follower accounts that mirror every webhook-driven trade placed on a leader account (entries, brackets, closes, reversals, cancels, and changes) with per-follower sizing, symbol replacement, inversion, and stealth options. See the Tradovate Copier page for the full feature matrix against the NT8 Trade Copier.