# Strategy Synchronization

### Overview

The `sync_strategy` functionality is an advanced safety feature available for the `PLACE` command. Its purpose is to prevent "state drift" between your external signaling system (e.g., a TradingView strategy) and the actual market position held in your NinjaTrader 8 account.

Automated strategies are stateful; they "know" whether they are currently long, short, or flat. However, situations can arise where the trading software becomes different from what the strategy expects. This can happen due to manual interventions, connection issues, or partial fills.

When state drift occurs, a signal to "add to a long position" might be sent when you are actually flat, or a signal to "reverse from long to short" might be sent when you are already short. These scenarios can lead to unintended trades and significant risk.

`sync_strategy` acts as a gatekeeper, comparing your strategy's expected state with NinjaTrader's actual state before placing an order. If they don't align, it can prevent the order, flatten the position, or — starting in v1.12.0 — automatically correct the mismatch.

{% hint style="info" %}
`sync_strategy` is available in add-on versions v1.9.0+. The `resync` mode and `target_quantity` parameter require v1.12.0+.
{% endhint %}

***

### How It Works

When you enable `sync_strategy`, the add-on performs a series of checks before submitting the order. This process can be broken down into three steps: Activation, State Comparison, and Action

{% hint style="success" %}
The following information is for educational purposes only for technical discussion on how strategy sync works. In **all practical cases**, a trader will not be manually inputting the values for `market_position` and `prev_market_position`. Instead, we should rely on TradingView's dynamic replacement variables:\
\
`market_position={{strategy.market_position}};` \
`prev_market_position={{strategy.prev_market_position}};`\
`target_quantity={{strategy.position_size}};`
{% endhint %}

#### Activation & Required Parameters

To activate the feature, you must include `sync_strategy=true;` in your `PLACE` command payload. When this parameter is present, three additional parameters become essential:

| Parameter              | Required? | Description                                                                                                              | Valid Values                                                                                                                             |
| ---------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `sync_strategy`        | Yes       | Enables or disables the synchronization check.                                                                           | `true`                                                                                                                                   |
| `market_position`      | Yes       | The **target** market position your strategy wants to be in *after* this order is executed.                              | `long`, `short`, `flat`                                                                                                                  |
| `prev_market_position` | Yes       | The market position your strategy was in *before* this signal was generated.                                             | `long`, `short`, `flat`                                                                                                                  |
| `out_of_sync`          | Optional  | Defines the behavior if a state mismatch is detected. Defaults to `wait` if not provided.                                | `wait`, `flatten`, `ignore`, `resync`                                                                                                    |
| `target_quantity`      | Optional  | The absolute target position size. When provided, sync logic uses quantity-based comparison instead of transition-based. | Signed or unsigned integer (positive = long, negative = short, 0 = flat). Unsigned integers will assume the `market_position` direction. |
| `strategy_exit_block`  | Optional  | Block any opening order (i.e., where `prev_market_position` is not flat).                                                | `true`                                                                                                                                   |

If `sync_strategy=true` is provided but `market_position` or `prev_market_position` are missing or invalid, the command will fail with an error.

#### State Comparison

The core of the logic compares the **Remote Expected State Transition** (provided by you) with the **Local NT8 State Transition** (calculated by the add-on).

1. **Remote State:** Defined by your `prev_market_position` and `market_position`.
2. **Local State:** The add-on checks the current actual position in NinjaTrader and then calculates what the position *would be* after executing the requested order (`action` and `quantity`).

An order is considered **"in-sync"** if the local state transition perfectly matches one of the five valid remote state transitions:

1. **Opening a Position:** Remote `flat` → `long`/`short` matches Local `flat` → `long`/`short`.
2. **Adding to Position:** Remote `long` → `long` matches Local `long` → `long` (with increased quantity).
3. **Reversing a Position:** Remote `long` → `short` matches Local `long` → `short`.
4. **Closing to Flat:** Remote `long`/`short` → `flat` matches Local `long`/`short` → `flat`.
5. **Staying Flat:** Remote `flat` → `flat` matches Local `flat` → `flat`.

When `target_quantity` is provided, the sync logic switches from transition-based comparison to **absolute quantity comparison**. Instead of asking "does flat→long match flat→long?", it asks "will the resulting position be exactly N contracts in the right direction?"&#x20;

> **The Critical "New Entry" Rule**
>
> There is an overriding safety constraint: **You cannot open a new position in NinjaTrader if your remote strategy believes it was already in a position.** If the add-on detects that the local NT8 account is `flat` but your `prev_market_position` was `long` or `short`, it will *always* consider this an out-of-sync condition, regardless of other rules. This prevents accidental entries when your strategy has lost its state.

***

### Handling Mismatches (`out_of_sync` Behavior)

If the state comparison fails, the `out_of_sync` parameter determines the outcome.

#### `out_of_sync=wait` (Default)

**Action:** The requested order is **rejected**.

**Result:** The system returns a `success: true` response with a `warning` message detailing the mismatch and stating that it is waiting. No trade is placed.

**Use Case:** This is the safest option. It prevents any action and alerts you to the discrepancy, allowing for manual intervention or waiting for a safe re-entry condition (e.g., both remote and local state are `flat`).

#### `out_of_sync=flatten`

**Action:** The requested order is **rejected**. If the NinjaTrader account is currently not flat, a `Flatten` command is immediately issued for the instrument.

**Result:** The system returns a `success: true` response with a `warning` message. The goal is to reset the local position to `flat` to prepare for a clean entry on the next signal.

**Use Case:** An automated "reset button." Use this if your strategy is designed to re-establish its position from a flat state after a detected error.

#### `out_of_sync=resync`

**Action:** The system calculates the exact delta needed to reach the target position and **submits a corrective order automatically**.

**Result:** Instead of blocking the order or flattening, the add-on figures out the difference between where the position is now and where it should be, and submits a market order to close that gap. If the position already matches the target, no order is placed.

**Use Case:** Fully automatic recovery from missed signals, partial fills, or connection drops. This mode is the best choice when you want hands-off position alignment.

{% hint style="info" %}
`out_of_sync=resync` requires v1.12.0+. It works best when paired with `target_quantity` for precise quantity targeting, but also works with standard transition-based sync.
{% endhint %}

**How resync handles different order types:**

* **Market orders** — treated as a request to reach an absolute position state. The system calculates the total delta required and submits a single market order. For example, if the target is long 5 and the account is currently long 3, resync submits Buy 2. If the account is long 7, it submits Sell 2 to trim back.
* **Limit/Stop orders** — the system cannot use a resting order to fix an immediate mismatch, so it performs two actions: first, a corrective market order to align the position to the "base target" (the target minus what the limit/stop order would contribute once filled), and then the original limit/stop order is submitted normally so it's in place for future price action.

{% hint style="warning" %}
Using `resync` with limit or stop orders is advanced. The correction fires immediately as a market order while the original limit/stop rests until triggered. Make sure you understand the resulting position math before using this combination. Test thoroughly in simulation first.
{% endhint %}

#### `out_of_sync=ignore`

**Action:** The synchronization check is **bypassed**. The requested order is placed regardless of the state mismatch.

**Result:** The system returns a response containing a `warning` message about the mismatch, but proceeds with the order placement.

**Use Case:** For advanced users who understand the risks and want to force an order through despite a detected state discrepancy. Use with caution.

***

### target\_quantity

The `target_quantity` parameter tells the sync logic the exact position size your strategy expects to have after this order executes. When provided, the sync comparison switches from directional (flat→long, long→short) to quantity-based — the system checks whether the resulting NT8 position will be exactly the specified number of contracts in the right direction.

**Example:** Your strategy wants to be long 5 ES. The account is currently long 3 with a resting limit buy for 1 more contract. With `target_quantity=5`, the sync logic recognizes that 3 (current) + 1 (pending limit) + 1 (this order) = 5, so the order is in sync. Without `target_quantity`, the sync logic would only compare directional transitions (long→long) without verifying the exact quantity.

When a subscriber receives a signal with `target_quantity` through Signal Share, any configured position multiplier is applied proportionally. A 2x follower receiving `target_quantity=5` targets 10 contracts.

***

### Exit Blocking

For users who want to offload the exit management to NT8, and deploy an ATM strategy in its place, we developed `strategy_exit_block`, which will check for `prev_market_position=flat` to ensure the last position was flat. If not, your orders will be blocked. This allows us to better control the strategy signals which are not defined in Pine Script as Entry & Exit, but only Buy & Sell. It's a requirement of all TV strategies that an offsetting order must always be used to ensure backtests can be properly calculated. Because of this requirement, the only way a TV strategy's exit can be avoided is if XT blocks the order request from flowing downstream to NT8.

Adding `strategy_exit_block=true;` will augment your Strategy Sync payload and allow blocking of any opening order (i.e., where `prev_market_position` is not flat).

{% hint style="warning" %}
`strategy_exit_block` is a very aggressive block that will only allow opening orders from a flat market position. It does not support scaling in/out of positions. Anything other than flat → long/short will be blocked.
{% endhint %}

***

### Practical Examples

#### Standard Sync with Flatten

A single alert payload can now run a fully automated strategy without the need for human intervention. The following payload will match the strategy order direction. If the strategy ever gets out of sync, the NT8 account is flattened until we reach new entry criteria — e.g., NT8 account is flat and the `prev_market_position` of the TV strategy is also flat and we're now opening a new position.

```
key=your-secret-key;
command=PLACE;
account=Sim101;
instrument=NQ1!;
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;
```

{% hint style="warning" %}
You do **NOT** want to sync with ATMs unless you use the `strategy_exit_block`. The purpose of strategy sync logic is to let TradingView control behavior across platforms. When you open an ATM directly in NinjaTrader, it overrides that logic and defeats the point of syncing unless you explicitly block the TV strategy from firing the required exit.
{% endhint %}

#### Sync with Resync (Automatic Correction)

This payload uses `resync` to automatically correct any mismatch instead of flattening. If your strategy says you should be long 2 but NT8 only has 1 contract, the system will buy 1 more to align. If the position is already correct, no action is taken.

```
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}};
target_quantity={{strategy.position_size}};
out_of_sync=resync;
```

#### Sync with target\_quantity (Absolute Position Targeting)

Example of what Strategy Sync + Resync looks like after TradingView (or your remote strategy) has done replacement of all dynamic variables.&#x20;

When you need precise quantity alignment — for example, when used with a strategy that tracks exact contract counts — include `target_quantity` alongside `resync`:

```
key=your-secret-key;
command=PLACE;
account=Sim101;
instrument=ES 06-26;
action=BUY;
qty=1;
order_type=MARKET;
tif=DAY;
sync_strategy=true;
market_position=long;
prev_market_position=long;
target_quantity=5;
out_of_sync=resync;
```

If the account is currently long 4 ES, the system detects a delta of 1 and submits a Buy 1 market order. If the account is already long 5, no order is placed. If the account is long 7, it submits a Sell 2 to trim back to the target.

{% embed url="<https://www.youtube.com/watch?v=vYVJNY0gLas>" %}
