Subject: Best Practice for Modifying an ATM Stop Using account.Change()

Hello Moderators,

I’m working on a NinjaTrader 8 AddOn that dynamically manages the stop on an ATM strategy after the entry order has filled.

We know this type of functionality is possible because there are existing NinjaTrader tools, such as ATR Trade Shield, that dynamically modify ATM stop orders after entry. Our goal, however, is to build our own AddOn because we want a different workflow, including ATR-based stop management and custom profit targets such as a ½ ATR target.

We’ve narrowed the project down to one specific issue and are hoping you can point us toward the recommended implementation.

Current Status

  • We successfully detect the ATM execution.

  • We successfully capture the ATM Stop1 Order object.

  • We successfully call account.Change().

  • We have successfully moved the stop once, which confirms that the API path is working.

  • However, the stop moved 10 points in the wrong direction.

  • We then added additional logic to prevent that, but the stop no longer moved. At this point we’re not sure whether that was caused by our logic, replay state, or event timing.

Our Question

Since we’ve already confirmed that we can modify the stop order, what is the recommended way to calculate and apply the new stop price?

Specifically:

  • Should the new stop price be calculated relative to the entry price, the current stop price, or another value?

  • Is there a preferred event in the ATM lifecycle where the stop should be modified to ensure the change is applied reliably?

  • Is there a recommended pattern for updating an existing ATM stop order using account.Change()?

We’re trying to avoid continuing with trial-and-error when we’re likely just missing the recommended implementation pattern.

If it would help, we’re happy to post the relevant sections of our code showing how we’re capturing the stop order and calling account.Change(). We didn’t want to post several hundred lines of code unless it’s needed.

Thank you for your time and guidance.

This is what I got when researching your issue. I can’t be sure it will work unless I test it myself but hopefully this points you in the right direction.

Since you’re in an AddOn, stick with account.Change() — the AtmStrategyChangeStopTarget() helpers aren’t in scope outside a strategy/indicator, so your order-level approach is the right one. A few things to fix:

Calculate the new stop as an absolute price off the entry price (or off current price if you want a true trail), not off the current stop price. Round it to tick. The sign has to branch on side — long stops go below entry, short stops above — and getting that backwards is almost certainly your wrong-direction bug.

For timing, don’t fire on the fill itself — gate every change on the stop order’s state being Working, and confirm you actually captured Stop1. Drive the recalculation from your ATR updates, but let that state check decide whether the change goes out.

For the change itself in an AddOn: set StopPriceChanged on the captured Stop1 order and then call account.Change() — you don’t pass the new price into Change() directly, which is the step people most often miss. Wrap it with a tighten-only guard (never loosen the stop) and skip the call when the price is unchanged.

One more thing that would explain “it moved once then stopped”: if your ATM template has any auto-management on (auto-breakeven, auto-trail, or a multi-step stop strategy), the ATM re-asserts its own stop and undoes your change. Use a template with a plain static stop so your logic is the only thing touching Stop1.

Hope this helps!