Position Management & Strategy Sync
Managing open positions is one of the trickier parts of automated trading. CrossTrade gives you several payload-level tools to handle reversals, prevent hedging, and keep NinjaTrader 8 in sync with your TradingView strategy. This page covers flatten_first, require_market_position, and the full strategy-sync toolkit including sync_strategy, \{\{strategy.market_position\}\}, and strategy_exit_block.
What is the difference between flatten_first and require_market_position?
They serve opposite purposes:
flatten_first=true;flattens all open positions and working orders for the account + instrument before the PLACE command executes. Use it when you already know the new signal is a reversal and you want the account zeroed out first.require_market_position=flat;(orlong/short) is a filter. It prevents the order from taking any action unless the current NT8 position state matches what you specified. If the state doesn't match, the order is silently blocked.
One forces a clean slate; the other gates the order on existing state.
How do I guarantee that NT8 ignores a new signal when I'm already in a position?
Use require_market_position=flat; in your payload. If the account isn't flat when the alert arrives, the order is blocked entirely — it won't flip, add, or reverse. max_position=1 alone does not prevent NT8 from reversing when the new signal is in the opposite direction.
How do I block orders that would create a same-direction add?
Use the filter to restrict which states allow an entry. For example, to only allow SELLs when flat or already short (blocking additional BUYs once long):
action=sell; require_market_position=flat/short;
If the account state isn't flat or short, the order is blocked. You can combine this with a max position count via the filter docs for finer control.
How do I prevent hedging across accounts on a prop firm?
You can check the market position (flat/long/short) of each account with require_market_position, but the filter applies per account — it does not check a group of accounts. Groups for Account Management are on the roadmap; for now, enforce the no-hedge rule on every account individually, or prevent opposing signals from being sent in the first place.
Does flatten_first flatten everything on the account, or just the instrument?
flatten_first is tied to the account + instrument. It only zeroes out the position and cancels working orders for that specific instrument on the specified account(s). Other instruments on the same account are untouched.
What's the easiest way to handle reversals in a payload?
If you know a given alert represents a reversal, set flatten_first=true; on that PLACE order. It will zero out the existing position and any working orders before entering the new one in a single webhook call — no second request needed.
How do I cancel hanging TP/SL orders when I close a position?
Two options:
- Issue a separate
CANCELORDERScommand in a second webhook request. - On the next PLACE order, include
flatten_first=true;— it cancels any working orders for the instrument before placing the new one.
Note: sending CLOSEPOSITION only cancels pending orders if a position is actually open. If you close a partial position and simultaneously send CANCELORDERS for a working stop, NT8 may treat the two as a race condition depending on how it queues them.
When should I use Strategy Sync instead of flatten_first?
Strategy Sync (sync_strategy=true;) is built for TradingView strategies where signals add to a position in one direction and only flatten when the direction flips. A typical pattern: keep adding on same-direction signals, but flatten-and-open-opposite when the direction changes — without having to hand-code flatten_first on every reversal alert.
You do not need flatten_first when you're using strategy sync; the sync logic already handles it. Remove flatten_first from alerts that use sync.
What do \{\{strategy.market_position\}\} and \{\{strategy.prev_market_position\}\} do?
They are TradingView placeholders that the strategy substitutes with the current and previous position state (long / short / flat) at alert fire time. When you enable sync_strategy=true; and pass these variables in the payload, CrossTrade can compare the TradingView strategy's expected state to the NT8 account's actual state and either trust it, sync it, or flatten on mismatch depending on your out_of_sync setting.
Example payload shape:
account=MyAccount; symbol=NQ; action={{strategy.order.action}}; qty={{strategy.order.contracts}};
sync_strategy=true; market_position={{strategy.market_position}}; prev_market_position={{strategy.prev_market_position}};
The variable values come from the strategy — you pass the template and the strategy fills them in.
What does out_of_sync=flatten actually do?
Strategy Sync performs a "nuclear" flatten on all positions and orders for that instrument when it detects a state mismatch between the TradingView strategy and NT8. It's a safety mechanism — if your platforms drift out of alignment (for example, a partial fill, a manual intervention, or a missed signal), flattening prevents you from stacking incorrect trades on top of bad state.
If you'd rather let the trade go through even when state doesn't agree, set out_of_sync=ignore; — but understand you lose the safety net.
What happens if I choose wait when the strategy is out of sync?
The order is held and no action is taken. Either you intervene manually, or the next signal that happens to match NT8's actual state will be processed. Subsequent signals that are also out of sync continue to wait.
What if Strategy Sync says it flattened but the position keeps running?
Strategy Sync issues a flatten on all positions and orders for that instrument. If the position still appears open after, it's usually a "ghost position" stuck in the NT8 UI. Restart NT8 — if the position disappears on restart, that confirms it was a UI-only artifact, not a real exchange position.
Why did Strategy Sync trigger a flatten on what looked like a fresh entry?
A webhook Success on the entry only confirms the order was accepted — it doesn't mean out_of_sync was involved. If a flatten fires shortly after, look at whether an Account Manager threshold (profit/loss), a trading window boundary, or a separate command triggered it. The out_of_sync action only runs when the strategy state and NT8 state genuinely disagree.
Can I use Strategy Sync with a stop-and-reverse strategy?
Stop-and-reverse strategies are the one case where Strategy Sync isn't the right tool. For those, most traders coding their own send a CLOSEPOSITION command on the strategy.exit event and a separate PLACE for the new direction — a plain strategy.exit in Pine will otherwise reverse the position instead of exiting cleanly, which isn't what you usually want.
How do I send a plain exit from a Pine strategy without reversing?
Wire your strategy.exit alert to issue a CLOSEPOSITION command rather than a PLACE order. That closes the open contracts without opening a new opposite position. See the close-position command docs for payload details.
What is strategy_exit_block?
It's a control related to strategy sync that prevents exit alerts from being executed when your account state doesn't match the strategy's expected state at the time of the exit. It protects against firing an exit against a position that doesn't exist or that's already been closed — useful when drift between TradingView and NT8 would otherwise cause a spurious reversal.
Do I have to use Strategy Sync?
No. Strategy Sync is a convenience for TradingView strategy users — it is not required. Many traders run CrossTrade with plain PLACE / CLOSEPOSITION commands and manage reversals manually with flatten_first. Use sync if it fits your workflow; skip it if simpler commands get the job done.
Do I still need the leading negative sign on offsets?
No. The old requirement that stop/target offsets be written with a negative sign (for example sl=-40ticks;) has been removed. Use positive values — formats like 40.0ticks; are accepted and passed through to NT8 correctly.
Can I partially close a position instead of flattening it?
Yes — scale out using CLOSEPOSITION with a quantity. Unlike flatten_first, which zeroes everything for the instrument, CLOSEPOSITION can take a specific number of contracts so you keep the remaining position open.
If I run the same strategy on multiple timeframes, how do I keep them from stepping on each other?
A commonly requested feature is a "strategy name" tag on each order so that a close from strategy A doesn't cancel out strategy B's position. That capability is on the roadmap. For today, the workable approaches are: run each timeframe on its own account, use require_market_position filters to gate direction, or use TradingView's built-in Pyramiding settings at the strategy level to control adds and reversals within a single strategy.
How do I add to a position on same-direction signals but flatten on a flip?
Two ways:
- TradingView Pyramiding — configure it in the strategy settings so same-direction signals add and opposite signals flatten-and-reverse. This is handled on TradingView's side before the alert even fires.
- Strategy Sync — let
sync_strategy=true;plus\{\{strategy.market_position\}\}handle the state transition, so CrossTrade knows when to add vs. when to reverse without you tagging every alert.