Skip to main content

Alert Payload Syntax & Reference

This page is the syntax reference for the text payloads CrossTrade accepts from TradingView (and any other webhook source). Payloads are key=value pairs separated by semicolons. Every field must end with a semicolon. Field names are normalized on the server, so case is technically not enforced, but values (instruments, actions, TIF) are case-sensitive in some cases — stick to the formats shown.

What does a basic CrossTrade alert payload look like?

A minimal market-buy payload to a single account:

key=your-secret-key;
command=PLACE;
account=sim101;
instrument=MNQ 06-25;
action=BUY;
qty=1;
order_type=MARKET;
tif=DAY;

Every line ends in a semicolon. key is your CrossTrade secret key, found under Security in My Account or on the Dashboard Manual Trading example.

What fields are required in every payload?

At minimum:

  • key — your CrossTrade secret key
  • command — what to do (e.g., PLACE, FLATTEN, CANCELORDERS)
  • account — the NT8 account name
  • instrument — the contract (in an NT8-recognized format)

For command=PLACE; you also need action, qty, order_type, and tif. NT8 requires a valid whole-number qty on every place order — if you send a payload without qty, NT8 will reject it with "Check message format, missing required field: QTY".

What are all the commands CrossTrade supports?

Common commands:

  • PLACE — submit a new order
  • CANCEL / CANCELORDERS — cancel working orders (e.g., by instrument)
  • FLATTEN — close all open positions and cancel all working orders for the account + instrument specified
  • FLATTENEVERYTHING — close all positions and orders across all accounts
  • CLOSEPOSITION — close an existing position (supports partial qty)
  • CHANGE — modify the limit price or quantity of a pending (unfilled) order; requires passing the order_id
  • CANCELANDBRACKET — cancels all working orders in the account + instrument, then places a bracket

See the full list at https://crosstrade.io/docs/webhooks/commands.

What's the difference between FLATTEN and CLOSEPOSITION?

  • FLATTEN closes positions and cancels any working orders (including orphaned ATM stop/target orders) for the specified account + instrument.
  • CLOSEPOSITION closes an existing position and supports partial quantity — you can send multiple CLOSEPOSITION commands with different qty values to exit in pieces.
  • FLATTENEVERYTHING is the nuclear option — closes all positions and orders across all accounts in the payload.

Example flatten-by-instrument:

key=your-secret-key;
command=FLATTEN;
account=Sim101;
instrument=MES 12-25;

What does command=CHANGE do and when do I use it?

CHANGE lets you modify a pending limit order. If you pass an order_id along with a PLACE-style payload, you can update the limit price or quantity of that order. It only works on orders that are still pending/unfilled — once an order fills, it's removed from the order book and no longer exists. For a resting limit, you can keep moving the price with CHANGE as often as you need while it's still open.

How do I send an alert to multiple accounts at once?

Put account names separated by commas (no spaces) inside the single account= field, and end with a semicolon:

key=your-secret-key;
command=PLACE;
account=Sim101,Sim102,Sim103;
instrument=ES 06-25;
action=BUY;
qty=1;
order_type=MARKET;
tif=DAY;

Do not separate accounts with semicolons — a payload like account=ACCT_A; ACCT_B; is a common error and will be parsed as a single malformed field.

Can I apply a different ATM template to each account in a multi-account payload?

No. The strategy= (ATM template) line accepts only one template name, and it's applied to every account listed in account=. If you need different ATMs per account, you have to send separate alerts.

How do I format instruments (the instrument field)?

All of these are valid NT8 contract formats:

MNQ1! (continuous / front-month auto-rollover)
MNQ 09-25 (numeric month-year)
MNQ SEP25 (month abbreviation)
MNQU5 (NT8 short code)
NQZ2025 (full-year NT8 short code)

Alerts must be in a format NinjaTrader recognizes. CrossTrade is just the message broker — we don't impose instrument limits.

Do I capitalize the instrument ticker?

Yes. NT8 expects the ticker capitalized. instrument=mes 06-25; is wrong; use instrument=MES 06-25;. Also make sure your TradingView {{ticker}} variable produces the same format your NT8 is configured for — if you're using MNQ SEP25 style, change NT8 to Month Abbreviation; if you want MNQ 09-25 style, keep NT8 on numerical.

What is MNQ1! (the continuous contract)?

MNQ1! is the continuous front-month contract — NT8 resolves it to whichever contract month is active (auto-rollover). This is the recommended format because you set it once and forget it; NT8 handles the roll.

Common mistake: writing MNQ! instead of MNQ1!. The 1 is required.

You can also use the 1! form for other tickers: ES1!, NQ1!, GC1!, MES1!, etc.

How do I handle contract rollover for open positions?

If you have an open position on an expiring contract during the week of rollover, the safest workflow is:

  1. Temporarily change your payload's instrument= from the continuous form (e.g., ES1!) to the explicit expiring contract (e.g., ESZ5 or ES 12-25) for the duration the position is open.
  2. Once the position on the old contract is closed, switch the payload back to the continuous form.

This manual intervention is recommended during the rollover week and avoids front-month discrepancies.

Why did CANCELORDERS stop working when I changed the instrument format?

NT8 understands both MNQ 06-25 and MNQ JUN25 for placing orders, but when you call CANCELORDERS, CrossTrade filter-matches working orders against the given instrument string. If an order was placed as MNQ 06-25 and you try to cancel with MNQ JUN25, the filter won't match. Keep the format consistent between placement and cancellation.

I get "no market data for ES 9-25" — what's wrong?

The format is wrong — use two-digit month: ES 09-25 (not ES 9-25). If it's still failing, the market may be closed, or the contract may have expired and you need to move to the new front month (e.g., out of 03-25 into 06-25, 09-25, 12-25, etc.).

Are /MNQ and /NQ treated as the same or different instruments?

They are different instruments. You can hold a long /MNQ and a short /NQ at the same time — CrossTrade treats them as independent.

What are the supported order types?

  • MARKET — executes immediately at market
  • LIMIT — rests at a given limit_price
  • STOPMARKET — stop order that fills at market once the stop_price trigger is hit
  • STOPLIMIT — stop that becomes a limit at the trigger (note: NT8 may reject some STOPLIMIT configurations; STOPMARKET is more reliable)

order_type=MARKET; guarantees a market order.

How do I send a LIMIT order with a price offset?

limit_price accepts three forms:

limit_price=12345; (absolute price)
limit_price=25 ticks; (offset in ticks from underlying)
limit_price=2%; (percentage offset)
limit_price=-250 ticks; (negative offset = below spot)

Example buy-limit using an offset away from spot:

key=your-secret-key;
command=PLACE;
account=sim101;
instrument=ES1!;
action=BUY;
qty=1;
order_type=LIMIT;
limit_price=-250 ticks;
tif=DAY;

If you submit order_type=LIMIT; with no limit_price, the order will be rejected.

How do I send a STOPMARKET order with stop_price?

Provide stop_price (absolute or offset) along with order_type=STOPMARKET;. Example with explicit prices:

key=your-secret-key;
command=PLACE;
account=Sim101;
instrument=MNQ1!;
action=BUY;
qty=5;
order_type=STOPMARKET;
stop_price=26555;
tif=DAY;
stop_loss=26500.50;
take_profit=26600.50;

Props sometimes reject orders whose limit_price or stop_price is too far from market — that's a broker restriction, not a CrossTrade restriction.

Can I set take_profit and stop_loss values with a STOPMARKET entry order?

Yes, but understand that when TP/SL are included with the XT order system they're sent as an OCO bracket, and the primary order is sent separately. In most cases you should use a market order with TP/SL rather than a limit/stop entry with TP/SL. Using STOPMARKET + TP/SL can produce three distinct working orders (entry, TP, SL) rather than a bound bracket on the NT8 side.

What values does take_profit / stop_loss accept?

Three accepted forms. A bare number is interpreted as a literal price level, not an offset:

take_profit=19700; (absolute price — MNQ trades to 19700)
take_profit=40 ticks; (offset in ticks)
take_profit=40ticks; (same — space optional)
stop_loss=-40 ticks; (offset below spot for a long)

If you write take_profit=225; on MNQ when MNQ is 19,586, NT8 will reject that order because you're telling it to take profit at price 225. To use offsets, always include the ticks (or %) unit.

Which side should be negative — take_profit or stop_loss?

It depends on the direction of the trade. The rule: negative = below the spot price, positive = above spot.

BUY (long):

take_profit=40 ticks; (above spot — positive)
stop_loss=-40 ticks; (below spot — negative)

SELL (short):

take_profit=-40 ticks; (below spot — negative)
stop_loss=40 ticks; (above spot — positive)

This trips up a lot of users at first. When you short, flip the signs from the long case. If you send stop_loss=100ticks; on a long, NT8 may interpret it as a sell-stop entry order rather than a stop loss because the stop sits above price.

What are the valid TIF (Time-In-Force) values?

  • DAY — expires at the end of the session
  • GTC — Good-Til-Canceled; use when you want to hold a position through the daily close (e.g., got in at 16:54 and want to hold past 17:00)
  • IOC — Immediate-Or-Cancel
  • FOK — Fill-Or-Kill

Example GTC for holding overnight / over the weekend on futures:

tif=GTC;

All four are valid; DAY and GTC are by far the most common.

What are the valid values for action?

Only BUY and SELL. Any other literal string (e.g., BUY OR SELL) will be rejected. When you use a TradingView strategy variable, use:

action=\{\{strategy.order.action\}\};

That variable only works if the alert is fired from a strategy (not an indicator). From an indicator, \{\{strategy.order.action\}\} passes through as literal text and the alert will fail.

Which TradingView variables work in payloads?

Common usable variables:

  • \{\{strategy.order.action\}\} — BUY or SELL
  • \{\{strategy.order.contracts\}\} — trade quantity (use for qty=)
  • \{\{strategy.order.quantity\}\} — same purpose, depending on script
  • \{\{strategy.market_position\}\} and \{\{strategy.prev_market_position\}\} — for sync
  • \{\{strategy.position_size\}\} — for target_quantity=
  • \{\{ticker\}\} — symbol from TradingView; only works if the ticker symbol is valid on both platforms
  • \{\{close\}\} — close price, usable for limit prices

All strategy variables require the alert to be fired from a TradingView strategy, not an indicator. A common typo is misspelling strategy (e.g., stratety) — if the value comes through literally in the payload, check the spelling.

Can I send a bracket (TP/SL) without a primary order?

No. You cannot submit a bracket on its own — every bracket needs a primary PLACE order. If you want separate entry and exit alerts, the entry alert still has to be a PLACE with action=BUY/SELL.

Is there a way to delay the TP/SL to a bar after entry?

Not in a single alert. That would require two separate alerts.

What's the standard "strategy" payload for a TradingView strategy?

key=your-secret-key;
command=PLACE;
account=sim101;
instrument=ES 06-25;
action=\{\{strategy.order.action\}\};
qty=\{\{strategy.order.contracts\}\};
order_type=MARKET;
tif=DAY;

If your strategy is stop-and-reverse, add flatten_first=true;. Otherwise that's everything you need for a basic strategy entry.

Yes. Send two separate LIMIT orders with the same oco_id=:

oco_id=bracket1;

When one fills, the other is canceled automatically. Both orders carry the same OCO ID.

What does cancel_after do and why did I get a CANCEL_AFTER error?

cancel_after only works with order_type=LIMIT;. Market orders execute immediately so they can't be canceled after a delay. If you try to use cancel_after with any non-limit order type, you'll get:

CANCEL_AFTER requested but order type is not LIMIT.

What's the most common payload formatting mistake?

Missing semicolons. Every field must end with ;. Frequent examples:

rate_limit=1 (missing — broken)
rate_limit=1; (correct)

strategy=sumotrail (missing — broken)
strategy=sumotrail; (correct)

A missing semicolon anywhere in the payload — including at the end — will cause "Check message format" failures.

What are other common payload errors?

  • Literal variable value: qty=\{\{stratety.order.contracts\}\};strategy is misspelled, so TradingView passes the text through unevaluated.
  • Wrong separator between accounts: account=ACCT_A; ACCT_B; — use comma: account=ACCT_A,ACCT_B;.
  • Wrong instrument case: instrument=mes 06-25; — capitalize: instrument=MES 06-25;.
  • Wrong action value: action=BUY OR SELL; — must be exactly BUY or SELL.
  • Wrong qty format: qty=5.00; — must be a whole number: qty=5;.
  • Missing qty: NT8 requires qty. A strategy that doesn't emit a number will error out.
  • Missing 1 in continuous contract: instrument=MNQ!; — should be instrument=MNQ1!;.
  • Partial apex account name: some prop accounts include an exclamation mark. Use the name exactly as it appears on the prop dashboard or Rtrader.
  • TP/SL treated as price: take_profit=225; on MNQ at 19,586 is interpreted as price 225. Use take_profit=225 ticks;.

Does field-name case matter in the payload?

Technically no — CrossTrade normalizes field names on the server. Key, KEY, and key all work. That said, lowercase is the convention in the docs and examples. Values are not normalized — BUY/SELL are case-sensitive for action, and instrument strings must match NT8's expected casing.

Can I add a note/comment to an alert?

Yes, use notes=:

notes=some-free-text;

You can drop TradingView variables into notes (e.g., notes=\{\{timenow\}\};) if you want them logged, though the practical value is limited.

How do I rate-limit an alert to fire only once per trading session?

Combine id= with rate_limit=1/86400; (once per 86,400 seconds = 1 day):

key=your-secret-key;
command=FLATTEN;
account=Sim101;
instrument=MES 12-25;
rate_limit=1/86400;
id=OncePerDay;

The id groups related alerts together for rate-limit counting. More info at https://crosstrade.io/docs/webhooks/advanced-options/rate-limiting.

Can I send sl_price alongside an ATM strategy?

Yes, but sl_price does not override or replace the ATM SL — it gets placed in addition to it. If you want the ATM stop replaced, you have to adjust the ATM template itself.

What does the CANCELANDBRACKET command do?

CANCELANDBRACKET cancels all working orders in the specified account + instrument, then places a bracket. Useful when a strategy keeps resubmitting limit entries and you need to wipe stale pending orders before the new one goes in.

key=your-secret-key;
command=CANCELANDBRACKET;
account=sim110;
instrument=ES1!;
action=SELL;
qty=1;
take_profit=100 ticks;

See https://crosstrade.io/docs/webhooks/commands/cancel-and-bracket.