Automating TradingView Strategies

How to connect a Pine Script strategy to NinjaTrader with position tracking, sync protection, and exit management.

This guide covers the full workflow for automating a TradingView strategy (not an indicator). If you're using an indicator, see Guide 2: Automating a TradingView Indicator instead. Not sure which one you have? If your Pine Script starts with strategy(...), it's a strategy. If it starts with indicator(...), it's an indicator. That distinction matters more than you'd think.

Strategies vs. Indicators: Why It Matters

TradingView strategies and indicators produce alerts differently, and the differences directly affect how you set up CrossTrade.

Strategies give you access to dynamic variables like {{strategy.order.action}} and {{strategy.order.contracts}}, which means the alert can automatically populate BUY or SELL and the contract quantity based on what the strategy does. Strategies also expose position state variables ({{strategy.market_position}}, {{strategy.prev_market_position}}) that CrossTrade's Strategy Sync feature uses to keep NinjaTrader aligned with TradingView.

The catch: TradingView requires every strategy to have offsetting actions. An entry must eventually have an exit. A long must eventually close or reverse. This is a Pine Script requirement for backtesting — not a CrossTrade limitation. The {{strategy.order.action}} variable only produces buy or sell. There's no built-in way to distinguish between "this is an entry" and "this is an exit" from the variable alone. Strategy Sync exists to solve this problem.

Indicators give you full control. You decide exactly when to fire a BUY alert and when to fire a SELL alert. You hardcode the action and quantity. There's no offsetting requirement and no ambiguity about entries vs. exits. The tradeoff is that you don't get dynamic variables for action or quantity — everything is explicit.

circle-info

The rule of thumb: If your strategy does clean entries and exits with position tracking (long when in position, flat when out), Strategy Sync works well. If your strategy does stop-and-reverse (constantly flipping between long and short without going flat), you're often better off converting the logic to an indicator or using flatten_first without sync. If your strategy has complex exits managed by NT8 (ATMs, trailing stops), use strategy_exit_block=true; to prevent TV's exit signals from interfering.

The Basic Strategy Payload

Here's the starting point for any TradingView strategy automation. This uses Strategy Sync to keep your NinjaTrader position aligned with your TradingView strategy's position:

key=your-secret-key;
command=PLACE;
account=Sim101;
instrument=ES1!;
action={{strategy.order.action}};
qty={{strategy.order.contracts}};
order_type=MARKET;
tif=DAY;
sync_strategy=true;
market_position={{strategy.market_position}};
prev_market_position={{strategy.prev_market_position}};
out_of_sync=flatten;

Let's break down what the sync-specific lines do.

sync_strategy=true; turns on position synchronization. With this enabled, CrossTrade compares what TradingView thinks the position is versus what NinjaTrader actually has before placing any order.

market_position={{strategy.market_position}}; tells CrossTrade what position the strategy wants to be in after this order executes. TradingView fills this in automatically — long, short, or flat.

prev_market_position={{strategy.prev_market_position}}; tells CrossTrade what position the strategy was in before this signal. Combined with market_position, this defines the intended transition (e.g., flat→long, long→flat, long→short).

out_of_sync=flatten; defines what happens when TradingView and NinjaTrader disagree. With flatten, CrossTrade will close the NT8 position to reset everything to flat, then wait for the next clean entry signal. Other options:

  • wait — blocks the order and does nothing (safest, but requires manual intervention)

  • resync — automatically submits a corrective order to align NT8 with the strategy's expected position (most hands-off, requires v1.12.0+)

  • ignore — places the order anyway despite the mismatch (advanced use only)

For most traders, flatten is the right default. Use resync if you want fully automatic recovery and understand the implications.

Setting Up the TradingView Alert

circle-info

To keep this article short and direct, we are not including the images associated with each step. Please see the other more detailed guides Here and Here if you need specific instructions on setting up TradingView alerts.

Create your alert in TradingView with the Condition set to your strategy. Make sure you select the strategy from the condition dropdown — not a price level or indicator.

In the Message field, delete all default text and paste the payload above (with your actual secret key and account name).

In the Notifications tab, check the Webhook box and paste your CrossTrade webhook URL.

Set the alert to fire Every time the strategy fires an order (not "Once" or "Once per bar"). Strategy Sync needs to receive every signal the strategy generates.

Important: TradingView alerts snapshot the strategy settings at the time the alert is created. If you change the strategy's inputs after creating the alert (different SMA lengths, different risk parameters, etc.), the alert will still use the old values. You need to delete the old alert and create a new one. TradingView doesn't warn you about this, and it's one of the most common sources of confusion.

Understanding Out-of-Sync Scenarios

Your strategy and NinjaTrader will get out of sync. It's not a question of if, it's when. Common causes:

You manually close a position in NT8 while the TV strategy is still running. The strategy still thinks it's in a position and will eventually send an exit signal for a position that no longer exists.

An alert is missed or delayed. TradingView alert delivery isn't guaranteed to be instant. Server load at the top of the hour, news events, or connectivity issues can delay alerts. If an entry arrives but the exit doesn't (or vice versa), the state drifts.

An ATM strategy closes the position. If you're using an ATM template and the stop loss or profit target hits, NT8 closes the position. TradingView doesn't know this happened and will continue as if the position is still open.

A connection drops. If the XT Add-On loses connection to CrossTrade's servers, alerts during the outage are missed.

This is exactly why Strategy Sync exists. When a mismatch is detected, the out_of_sync behavior kicks in. With flatten, the position gets closed and both sides reset to flat. The strategy will eventually generate a new entry from flat, and trading resumes cleanly.

The Alert History on your web dashboardarrow-up-right will show sync warnings when they occur, including what TradingView expected vs. what NT8 had. Check here first when debugging.

Using Strategy Sync with ATM Strategies

This is a common setup, and it requires one critical addition: strategy_exit_block=true;.

Here's why. An ATM template manages exits through stop losses and profit targets on NT8. But your TradingView strategy doesn't know the ATM exists — it will still generate exit signals (because Pine Script strategies require offsetting actions). Without blocking those exit signals, you'll have TradingView trying to close the position at the same time the ATM is managing it. This creates conflicts.

What changed from the basic payload:

atm_strategy=YourATMTemplateName; applies your saved NinjaTrader ATM template. The name must match exactly — case-sensitive, spaces included. And the qty in your alert must match the contract quantity saved in the ATM template. If they don't match, NT8 will silently fail. No error, no log entry, just nothing happens.

flatten_first=true; closes any existing position and cancels pending bracket orders before placing the new entry. Always use this with ATMs to prevent orphaned stop/target orders from a previous ATM.

strategy_exit_block=true; blocks any signal where the strategy is transitioning out of a position (where prev_market_position is not flat). This means only fresh entries from flat get through to NT8. The ATM handles the exit.

Be aware: When the ATM closes a position (TP or SL hit), the strategy will detect the mismatch and report an out-of-sync condition. This is expected. With out_of_sync=flatten;, it will attempt to flatten (which is already flat) and wait for the next entry. This is normal behavior, not a bug.

If you need dynamic TP/SL levels (levels that change per trade), don't use an ATM — use take_profit= and stop_loss= in the payload instead. ATM templates have fixed bracket levels defined in advance. See Guide 5: Exit Management for the full breakdown.

The {{strategy.order.alert_message}} Variable

You may have seen this variable referenced elsewhere. It works differently from the other strategy variables.

{{strategy.order.alert_message}} is a passthrough variable. It doesn't produce the action or quantity — it passes whatever text you defined inside your Pine Script's strategy.entry() or strategy.exit() calls using the alert_message parameter.

This means {{strategy.order.alert_message}} only works if the CrossTrade payload is already constructed inside your Pine Script code. If you didn't build the payload in Pine, this variable will be empty or contain default text, and your alert will fail.

For most users, it's simpler to paste the full payload directly into the TradingView alert message field and use the individual variables ({{strategy.order.action}}, etc.) rather than constructing the entire payload in Pine Script. The only advantage of alert_message is if you want to dynamically set fields like instrument or account name based on Pine Script logic.

For an example of how to construct the payload in Pine Script, see the Example Strategiesarrow-up-right page.

Adding Position Protection

Beyond Strategy Sync, you can layer on additional protection:

require_market_position=flat; — blocks the alert entirely unless your NT8 position is flat. Use this if you never want to enter a new trade while an existing position is open. This is evaluated per-instrument, not per-account — an open NQ position won't block an ES entry.

max_positions=1; — blocks the alert if you already have a position open in any instrument on the account. Use this if you only want one trade open at a time across all instruments.

trading_window=HH:MM-HH:MM ET; — restricts when alerts are accepted. Alerts outside the window are silently dropped. See Trading Window docsarrow-up-right for formatting.

These are all optional and can be combined with Strategy Sync. They provide defense-in-depth for scenarios where sync alone isn't sufficient.

Testing Your Setup

Before going live, test the full pipeline:

  1. Use the Webhook Trader on the CrossTrade web dashboard to send test commands manually. This lets you verify that the command format is correct and NT8 responds before involving TradingView at all.

  2. Set up the TradingView alert on a sim account. Let it run through at least a few entry/exit cycles. Watch the Alert History for any sync warnings.

  3. Deliberately break it: manually close a position in NT8 while the strategy is running. Watch how the sync recovery behaves. This is the scenario you want to be confident about before real money is involved.

  4. Check the XT Add-On log in NinjaTrader and the Alert History on the web dashboard after each test. Both should tell a consistent story.

For detailed troubleshooting of common errors, see the Troubleshooting docsarrow-up-right.


Related Guides:

  • Guide 1: Your First Automated Trade — if you haven't sent a working alert yet, start here

  • Guide 2: Automating a TradingView Indicator — the simpler path if you don't need strategy variables

  • Guide 5: Exit Management — deep dive on ATMs, brackets, and strategy exits

Reference Docs:

Last updated