NinjaTrader ATM Trade Copier: Why Multi-Target Stops Break Copied Accounts
A NinjaTrader ATM strategy with two profit targets does not place one stop loss. It places two. When price reaches them your source account goes flat, exactly as intended, and your copied accounts can quietly end up short. This is the most common way a NinjaTrader trade copier fails, and almost nobody writes about it.
NinjaTrader creates one stop loss order per profit target, so a two-target ATM holds two stops at the same price. A stop-out fires them as two separate exits milliseconds apart. A copier that measures the destination position between those two exits reads a stale number, sends too many contracts, and flips the copied account into a fresh trade in the opposite direction. You can test your own copier for this in Sim in about ten minutes, and most of them fail.
If you trade NinjaTrader and copy to prop accounts, this is worth ten minutes of your time. Not because it is exotic, but because it looks like everything is working. The source account is flat. The log says the exit was copied. The order count looks slightly high, which is easy to write off as noise. Meanwhile one or more destinations are sitting in a live position you never took.
What is a NinjaTrader ATM strategy?
An Advanced Trade Management strategy, usually shortened to ATM, is NinjaTrader's built-in bracket system. When your entry order fills, NinjaTrader automatically submits the stop loss and profit target orders you configured in advance. You place one order and the protection appears on its own.
It is the reason most NinjaTrader traders never place a stop by hand. NinjaTrader positions ATM as the way to automate exits without writing code, and it is genuinely good at that.
The part that matters here is scaling out. An ATM can hold multiple profit targets so you take part of the position at one level and let the rest run. The strategy can include as many stop loss and profit target levels as the position size allows, with the target quantities adding up to your total order quantity.
How many stop orders does a two-target ATM actually place?
Two. NinjaTrader creates one stop loss order per profit target, not a single stop covering the whole position. A two-target ATM on two contracts holds two profit targets and two stop losses, with each stop OCO-paired to its own target so that filling one cancels the other in that bracket.
This is not an interpretation. It is in NinjaTrader's own tutorial. In ATM Strategy Example #2, an entry of 2 contracts at 1970.50 produces a first profit target at 1972.50, a second at 1973.50, and in NinjaTrader's words, "our 2 Stop Loss orders were submitted at 1969.25".
Two stops. Same price. Same instrument. Same account.
That last detail is why this catches people out. Because both stops sit at the same price, they draw on the chart as one line and sit in the Orders window as two nearly identical rows that are easy to skim past. Three targets means three stops. A six-contract position laddered across three rungs is carrying three separate stop orders, not one.
Nothing is wrong with that design. OCO pairing per bracket is exactly how you would build it. We covered the general mechanics in our guide to automated bracket orders and OCO. The design only becomes a problem once a second account is listening.
Why does a multi-target stop reverse a copied account?
Because both stops fire, so your copier sees two exit events rather than one. If it sizes the second exit against a destination position that has not finished shrinking from the first, it sends more contracts than you still own. Those surplus contracts do not close anything. They open a fresh position the other way.
Walk through it with a two-target ATM on twenty contracts, ten per bracket.
- Price hits the stop price. Both stop orders become marketable.
- Stop one fills for ten contracts. NinjaTrader reports an exit. The copier sends a ten-contract exit to the destination.
- Roughly two hundred milliseconds later, stop two fills for the other ten. NinjaTrader reports a second exit.
- The copier asks the destination how big its position is. The first exit order is still in flight and has not filled yet, so the answer comes back as twenty.
- The copier sends a second exit sized against twenty rather than ten.
- Both exits complete. Thirty contracts have been sold against a twenty contract position. The destination is now short ten.
The source account is flat and correct throughout. The destination is short, holding a trade nobody placed, with no stop on it and no target on it. On a funded account that is a drawdown breach waiting for the next adverse move, and prop firms do not issue warnings before closing an account.
The tell is that the surplus is always exactly the second bracket's quantity, and it repeats across every destination that was mid-exit. When we tracked this down on a live customer setup, four of five copied accounts were short by precisely the second leg's size, all at the same adverse move. The fifth was flat, and it was flat by luck: its stop had finished filling before the second exit arrived, so the copier correctly skipped it.
One account out of five getting the right answer by accident is a good description of the whole problem. It is a timing bug, so it is intermittent, so it survives testing.
Three ways a copier gets this wrong
There is not one bug here. There are three, and they all produce the same symptom, which is part of why this is hard to chase.
1. Reading a position size that has not caught up. Platform APIs report filled contracts. A market order sent three hundred milliseconds ago has not filled, so it is invisible to the position reading. Every exit that reads the same stale number will oversize by the same amount. The fix is not a better read, it is tracking your own in-flight orders and subtracting them.
2. Treating a cancel as if it already happened. When an exit arrives, the sensible move is to cancel the mirrored stop on the destination before closing the position, so you are not left with a stop covering contracts you no longer hold. But cancelling is a request, not a result. In the instant after you ask, a stop that is about to fill and a stop that is about to cancel look identical. Assume it cancelled and you can end up with the stop closing the position while your exit order reopens it the other way.
3. Two exits sizing off the same number. If exits are processed in parallel, both can read the position before either has subtracted its own contracts. Each one is individually correct. Together they are double.
All three are timing problems, which is why they cluster on multi-target ATM stop-outs. A single-target exit gives the platform time to settle. Two exits two hundred milliseconds apart do not.
How do you test your copier for this in ten minutes?
Put a NinjaTrader Sim account on both ends, build an ATM with two profit targets, enter with an even number of contracts, and let the trade run into the stop loss. Then look at the destination. If it is anything other than flat, your copier is mishandling multi-target exits.
The full version, worth doing properly:
- Use Sim101 and a second Sim account. Both inside NinjaTrader. No money involved, and NinjaTrader's Sim fills are quick enough to reproduce the race.
- Build a two-target ATM. Ten contracts split five and five is plenty. Put the stop close enough that it will actually get hit.
- Enter, then leave it alone. Do not close it manually. Manual closes are a single exit and will pass even on a broken copier.
- Let the stop take you out. This is the whole test. The bug only appears when both brackets stop out together.
- Check the destination position, not the log. The log will usually say the exit was copied, because it was. Twice. Look at the position and the P&L.
Then run it again with three targets. Some copiers survive two brackets and fall over on three. And if you scale out manually part way through, run that too, because testing a copier properly means deliberately creating partial fills, rapid entries and exits, and connection interruptions rather than only clean trades.
If the destination ends short, do not assume it is a display quirk. Check the P&L. A reversed position has real money attached to it.
What a copier has to do to get this right
Getting this correct is not about being faster. It is about refusing to act on a number you cannot trust yet. Six things separate a copier that handles multi-target ATM exits from one that mostly does.
- Know which protective orders are genuinely working before cancelling anything, rather than cancelling whatever is on file.
- Wait for each cancel to resolve into one of cancelled, rejected or filled. Those are different outcomes and they need different responses.
- Send nothing if the stop filled. The position already closed itself. The correct action is to record it and stay out of the way.
- Keep a ledger of exits already in flight and subtract them from every subsequent size calculation, because the platform will not do it for you.
- Process exits one at a time per account so two of them cannot size off the same stale figure.
- Time-box the wait. A copier that blocks an exit indefinitely while waiting for certainty has swapped a reversal problem for a trapped position problem, which is worse.
That last point is the one people skip. Correctness that can hang is not correctness. If the platform has not answered within a few hundred milliseconds, the exit still has to go out, with a warning logged so you know it happened.
It is also why a general position reconciler is not enough on its own. Reconcilers square up an account that has drifted out of sync after a disconnect, which is useful, but they run after the fact. A reversed position that gets reconciled thirty seconds later has still been live and unprotected for thirty seconds.
How Trade Dispensary handles NinjaTrader ATM exits
Trade Dispensary does all six of the things above, and it does them from inside NinjaTrader rather than guessing from outside. A NinjaScript Add-On runs in the platform and sees order state directly, which is the only way to tell a stop that filled from a stop that cancelled.
When an exit arrives on a NinjaTrader destination, the Add-On records which stops are genuinely live, requests the cancels, then waits up to four hundred milliseconds for each one to resolve. If a stop filled, no exit order is sent at all, because the position closed itself. Every in-flight exit is held in a ledger and subtracted from later sizing, and exits are serialised per account so two of them cannot read the same number.
We also show which source order each destination row came from, so a stop-out that produces two rows per account reads as what it is instead of looking like duplicated orders.
Worth being clear about what this does not change. If your ATM has two targets, your source account really does send two exits, and your Orders page really will show two rows per account. That is your ATM, faithfully mirrored. What changes is that the second row closes what is left rather than opening something new, and in practice you often see fewer rows, because by the time the second exit arrives the destination is already flat and it is skipped.
The wider NinjaTrader setup, including sources, destinations and instrument mapping, is covered in our NinjaTrader copy trading guide.
Why this matters more on prop accounts
On a personal account a reversed position is annoying and costs you a few points. On a funded account it can end the account.
A reversal leaves you holding a live trade with no stop and no target, in the opposite direction to the move that just stopped you out. That is the worst possible position to be unaware of. Multiply it across the four or five accounts most people copy to and a single stop-out can put every one of them into an unmanaged trade at the same time.
It is also a compliance problem, not just a risk one. Copying between accounts you own is permitted at most firms, but firms do watch for mechanical-looking execution patterns across accounts, and positions that appear out of nowhere are not a pattern you want on your record. Our guide to prop firm copy trading rules covers what is actually allowed.
Running the copier locally rather than through a shared cloud service helps here too, for reasons we set out in local copy trading for prop firms. And if you want limits that act before a bad session becomes a breach, the per-account risk guard in Trade Dispensary 4.0 is built for exactly that.
Three things to take away
First, a NinjaTrader ATM with two profit targets holds two stop orders, and a stop-out therefore produces two exits, not one. That is normal NinjaTrader behaviour and it is documented by NinjaTrader itself.
Second, whether that breaks your copied accounts comes down to whether your copier waits for certainty before it sizes an exit. Most do not, because on a single-target trade you never find out.
Third, you can settle the question yourself this afternoon. Two Sim accounts, a two-target ATM, one stop-out, then look at the destination. It is ten minutes and it tells you more than any feature list.
If you want a copier that already passes that test, Trade Dispensary is $129 once, with lifetime updates and no subscription. Or check the feature list first to confirm your platforms are covered.
Copy your trades. Keep your accounts.
Frequently asked questions
How many stop loss orders does a NinjaTrader ATM strategy place?
One per profit target. A NinjaTrader ATM with two profit targets submits two separate stop loss orders, and one with three targets submits three. Each stop is OCO-paired with its own target so that filling one cancels the other in that bracket. Because the stops usually sit at the same price, they overlap on the chart and look like a single order.
Why does my copied account end up short after the source stops out?
Because a multi-target stop-out produces one exit event per bracket rather than one for the whole position. If your copier sizes the second exit against a destination position that has not finished shrinking from the first, it sends more contracts than you still hold. The surplus contracts do not close anything, they open a new position in the opposite direction.
Can I use one profit target to avoid the problem?
Yes, a single-target ATM places one stop and produces one exit, which sidesteps the issue entirely. But that means giving up scaling out, which is the main reason to use multiple targets in the first place. A copier should handle multi-target exits correctly rather than forcing you to change how you trade.
How do I test whether my trade copier has this bug?
Use two NinjaTrader Sim accounts, one as source and one as destination. Build an ATM with two profit targets, enter with an even number of contracts, then let the trade run to the stop loss. Check the destination account afterwards. If it is anything other than flat, your copier is mishandling multi-target exits.
Does Trade Dispensary need a NinjaTrader Add-On to handle this?
Yes. Trade Dispensary uses a NinjaScript Add-On that runs inside NinjaTrader and sees order state directly, which is what makes it possible to tell a stop that filled from a stop that cancelled. The Add-On ships inside the download and is imported through Tools then Import then NinjaScript Add-On. Existing customers re-import it when a new version lands.
Tags:
Share this post
Related Posts
Continue learning about copy trading with these related articles: