Why Your NinjaTrader 8 Strategy Stopped Trading (And How to Keep It Running)

You walked back to the desk and the strategy was off. Or worse, it was still enabled, still showing green, and had not submitted an order in three hours while the exact setup you built it for came and went twice.

This is one of the most common questions in NinjaTrader 8 automated trading, and it is almost never random. NinjaTrader stops strategies for specific, documented reasons, and it writes most of them to the log before it acts. The trouble is that the default settings are tuned for safety rather than uptime, and nobody reads them until the day they cost something.

We run NQ algos on prop accounts, so a strategy that quietly disables itself at 9:41 AM is not an inconvenience. It is a missed evaluation day. Here is what NinjaTrader actually does, taken from the platform documentation, and the settings that decide whether your algo survives a bad ten seconds.

Two Failures That Look the Same and Are Not

Before you change a single setting, separate the two cases, because they have completely different causes.

The strategy is disabled. The checkbox in the Strategies tab is unticked, the chart icon is off, and NinjaTrader almost certainly wrote a line about it. Open the Control Center, go to the Log tab, and read backwards from the moment it stopped. Connection loss events and order rejections both get logged.

The strategy is enabled but silent. Nothing in the log, no errors, and no orders either. This is usually a start behavior problem, covered further down, and it is the one that fools people the longest because everything on screen looks healthy.

Cause One: A Rejected Order Flattened You

This is the most expensive failure on the list, because it does not just stop your algo. It closes your position first.

NinjaTrader's RealtimeErrorHandling documentation spells out the default: the property "defines the behavior of a strategy when a strategy generated order is returned from the broker's server in a 'Rejected' state. Default behavior is to stop the strategy, cancel any remaining working orders, and then close any open positions managed by the strategy by submitting one 'Close' order for each unique position."

Read the sequence again. Stop, cancel, close. One rejected order and your working stop is cancelled, your position is market-closed, and your strategy is off. If that rejection lands on a spike, you take the fill wherever the book happens to be.

Rejections are not exotic on funded accounts. They come from ordinary things: submitting more contracts than the account's maximum position size allows, sending an order outside the hours the account permits, running out of day trading buying power after a drawdown, or trying to trade an instrument the account is not enabled for. Every one of those is a normal Tuesday on a prop account, and every one of them trips the default handler.

The documented values are StopCancelClose (the default), StopCancelCloseIgnoreRejects, which "will perform default behavior on all errors except order rejections," and IgnoreAllErrors, which continues running through everything.

Do not reach straight for IgnoreAllErrors. NinjaTrader flags it as critical: "Setting this property value to IgnoreAllErrors can have serious adverse affects on a running strategy unless you have programmed your own order rejection handling in the OnOrderUpdate() method," and adds that "user defined rejection handling is advanced and should ONLY be addressed by experienced programmers." A strategy that ignores rejections without handling them will happily believe it has a stop working when the broker never accepted it.

The docs also note the property should only be set from OnStateChange() during State.SetDefaults or State.Configure. Setting it later does nothing useful.

The prop firm version of this problem

A rejected order that triggers the default handler produces a market exit you did not choose, at a price you did not choose. On an account with a trailing drawdown that resets off your high water mark, one of those on a fast bar can cost more than the trade was ever worth. Know which handling mode your strategy runs before it matters.

Cause Two: Ten Seconds of Bad Internet

The second big cause is connection loss handling, and the default is stricter than most traders expect.

Per the ConnectionLossHandling documentation, the default value is ConnectionLossHandling.Recalculate, and the strategy is stopped under three conditions:

Now the number that surprises people. The DisconnectDelaySeconds property "determines the amount of time a disconnect would have to last before connection loss handling takes action," and its default value is 10. Ten seconds. That is a router hiccup, a Windows update grabbing bandwidth, or a data provider blip you would never notice while trading manually.

The middle condition is the sneaky one, because no time limit applies to it at all. If the order feed drops for two seconds and your strategy happens to try to place an order during those two seconds, it is stopped. A strategy calculating on each tick has far more chances to land in that window than one calculating on bar close.

Here is how the three modes compare, using the behavior described in the documentation.

Mode What it does on reconnect Risk Reasonable for
Recalculate (default) Attempts to recalculate the strategy position when the connection is reestablished Recalculated position may not match what your account actually holds Strategies that can rebuild state from bars alone
Keep Running "Keeps the strategy running. When the connection is reestablished the strategy will resume as if no disconnect occurred" The strategy is blind to anything that happened while it was dark Riding out short blips without losing the session
Stop Strategy Stops on disconnects longer than the delay. "No action will be taken when a connection is reestablished" You are flat and off until a human intervenes Traders who would rather be out than uncertain

You set this per strategy in code, or platform wide under Tools, Options, Strategies, in the On connection loss category described in the Strategies settings documentation. That same page confirms the disconnect delay setting "sets the number of seconds a disconnection must persist before it is recognized by the Disconnect Handling logic."

The Restart Budget Nobody Reads

Even when NinjaTrader is willing to restart your strategy, it will not do so forever. Two settings govern it: Number of restart attempts, and Restarts within x minutes.

The documentation is blunt about what happens when you exhaust them. NinjaTrader "will attempt to restart a strategy within the 'Restarts within x minutes' time span. The strategy will only restart on a reestablished connection when there have been fewer restart attempts than 'Number of restart attempts' within the last 'Restarts within x minutes' time span. Otherwise the strategy will simply halt, and no further restart attempts will be made."

That is the mechanism behind the classic story: the connection flapped four or five times over lunch, each drop spent one restart, and by 1:30 PM the strategy had halted permanently while the platform sat there looking perfectly normal. Nothing is broken. The budget just ran out.

If your connection is genuinely stable and the drops you see are short, a larger restart count paired with a tight minutes window is the configuration most people actually want. If your connection is not stable, no setting fixes that, and you should solve the network before you solve the software.

Cause Three: It Never Really Started

This is the silent version. Strategy enabled, no errors, no orders, and the trader slowly losing confidence in code that is working exactly as documented.

The StartBehavior property defaults to StartBehavior.WaitUntilFlat. The Syncing Account Positions guide explains what that means in practice: "If the Strategy Position is not flat, the strategy will place all trades in a 'virtual' sense until the Strategy Position reaches or crosses a flat state. Once a flat state is achieved the Strategy Position will be assumed to be in sync with the Account Position and all future orders will be placed live."

So if the historical processing at startup left your strategy thinking it holds a long, every trade it takes afterward is simulated until that imaginary long is closed. It can run for hours placing nothing. If you want to understand why the strategy believes it holds a position it never bought, our breakdown of why NinjaTrader 8 backtests do not match live trading covers the historical fill processing that creates it.

There is a second startup trap in the same document. Whichever mode you pick, the strategy first tries to cancel any active orders it previously generated, and "should the strategy be unable to cancel and receive confirmation on the cancellation of these orders within 40 seconds the strategy will not start and an alert will be issued." A slow broker response at the open is enough to burn 40 seconds.

The synchronize account variants will place real orders to fix the mismatch, and NinjaTrader warns about it directly: "Using Synchronize account can close or place live trades to your account." It also notes that the reconciliatory market order "is submitted outside of the strategy so your strategy will not be able to manage it from methods like OnOrderUpdate(), OnExecution(), etc." Your risk code will not see that fill.

"Please be aware that these options will only help you sync your Account Position to your Strategy Position once on startup. These options will not guarantee your Account Position remains in sync afterward."

That last point matters most for anyone running more than one thing at once. The same guide notes that placing manual trades or running multiple strategies on the same instrument can push the account position out of sync with the strategy position. If you trade by hand on the same account your algo runs on, you are creating this problem yourself. And if you want AdoptAccountPosition, the docs require you to set IsAdoptAccountPositionAware to true first, and to have written the strategy to handle an inherited position at all.

Cause Four: Your Own Code Threw

Sometimes the platform is fine and the script is the problem. An exception inside your logic will take the strategy down, and the usual culprit is an object that was not there yet.

NinjaTrader's NinjaScript best practices guide makes the point about relying on documented states: "although there are documented States where objects are available, the implementation could change. If you are accessing a reference object, please do so by first checking that the object is not null." The same page recommends the as keyword over direct casts to "prevent further errors," and tells you to avoid Thread.Sleep() in favor of Timer objects.

The practical version for a live algo: guard every external reference, check CurrentBar before reaching backward into a series, and never assume an order object assigned in OnBarUpdate() is populated the instant after you submitted it. A strategy that survives a month of replay can still die on the one bar where a null slipped through.

Cause Five: What Happens to Your Orders After It Stops

Here is the part that turns a stopped strategy into a losing day.

The Strategies settings page documents two separate switches: "Cancel entry orders when a strategy is disabled" and "Cancel exit orders when a strategy is disabled." They are independent, and the second one is the one that bites.

If exit cancellation is enabled and your strategy is disabled while holding a position, the working stop goes with it. You now have an open position on a funded account with no protective order and no algo watching it. If nobody is at the desk, that position runs until something else stops it, and on an account with a trailing drawdown that follows your high water mark, one unattended runner can end the account.

Go and look at how those two settings are configured on your machine right now. Whichever way you choose, choose it deliberately, and know what your account looks like the moment a strategy stops.

The Pre-Flight Pass We Run Before a Funded Account

  1. Decide your rejection policy on purpose. Default stop, cancel, and close is safe but blunt. If you change it, you are signing up to write your own handling in OnOrderUpdate().
  2. Set the disconnect delay to match your actual connection. Ten seconds is the default, not a recommendation. Measure your typical drop length before you pick a number.
  3. Give yourself a realistic restart budget. Enough attempts to survive a rough hour, in a window short enough that a truly broken connection still halts the strategy.
  4. Confirm the start behavior every single session. Enabled is not the same as live. If it has not traded and the log is clean, suspect virtual orders first.
  5. Test the disconnect deliberately. On a sim account with a position open, pull the network and watch what the platform does to your orders. Do this once and you will never guess again.
  6. Keep manual trades off the algo account. The documentation says it plainly, and it is the cheapest rule on this list to follow.

If you are still building the platform side of this, our walkthrough on how to set up automated trading on NinjaTrader 8 covers the connection, account, and enable steps that sit underneath every setting above.

The Honest Summary

A NinjaTrader 8 strategy that stops trading is usually doing exactly what it was configured to do. The defaults protect the account at the cost of uptime, and they were chosen for a platform that has to serve careful discretionary traders and unattended algos with the same set of switches.

Four numbers decide most of your outcomes: your error handling mode, your disconnect delay, your restart budget, and your start behavior. Set them yourself, write down why, and test the failure on sim before the market tests it for you. Then read the log first, every time, because NinjaTrader usually told you what happened before you noticed anything was wrong.

Run an Algo That Was Built for Unattended Sessions

NQ Ultra runs on NinjaTrader 8 with prop firm rules built in, including session controls and contract sizing. Configured and tested the long way so you are not debugging settings on a funded account.

Get NQ Ultra