Guide

How to Pause a NinjaScript Strategy Around News

A discretionary trader can glance at a calendar. An automated strategy cannot — it will trade into Non-Farm Payrolls with exactly the same conviction as it trades a quiet Tuesday. This guide covers how to get release times into NinjaScript, what to do with them, and why the backtest will lie to you about it.

Why an automated strategy needs to know about news

NinjaTrader 8 has no economic calendar available to NinjaScript. A strategy sees bars, and a release-driven spike is just a large bar — indistinguishable from any other large bar, and often a very convincing one. Momentum entries fire into the spike, mean-reversion entries fire into the fade, and both are filled in a book that has thinned out precisely because everyone else knew the number was coming.

The fix is not clever logic. It is giving the strategy the schedule it is missing, and then writing three or four lines that act on it.

The three things a strategy needs to know

Any tool you use for this has to answer all three. A tool that only draws markers on a chart answers none of them.

Question 1

Am I inside a blackout window right now?

A boolean-shaped answer the strategy can check on every bar. This is the one that gates entries. Exposed as a numeric series — 1.0 inside a window, 0.0 outside — because NinjaScript series are doubles.

Question 2

How long until the next one?

A countdown in minutes lets the strategy wind down gracefully instead of stopping dead: stop opening new positions at T-15, tighten or flatten at T-5. A strategy that only knows "in window / not in window" cannot do either.

Question 3

What is the event?

The title of the upcoming release. Not needed for the logic, essential for the log — when you review a session and find a gap in the trade list, you want the reason written down rather than reconstructed.

Reading news state from a NinjaScript strategy

The pattern is the standard one for reading any indicator from a strategy: hold a private reference, instantiate it in State.DataLoaded, and index its series in OnBarUpdate. The example below uses News Markers PRO, which publishes its blackout state for exactly this purpose.

public class NewsAwareStrategy : Strategy
{
    private BadBuddha_NewsMarkers_PRO news;

    protected override void OnStateChange()
    {
        if (State == State.SetDefaults)
        {
            Name        = "NewsAwareStrategy";
            Calculate   = Calculate.OnBarClose;
        }
        else if (State == State.DataLoaded)
        {
            // NinjaTrader generates this wrapper from the indicator's own
            // inputs. Calling it bare takes every default; pass them
            // positionally to override. IntelliSense shows the signature
            // once the add-on has been imported.
            news = BadBuddha_NewsMarkers_PRO();
            AddChartIndicator(news);
        }
    }

    protected override void OnBarUpdate()
    {
        if (CurrentBar < BarsRequiredToTrade)
            return;

        // Series are doubles, so compare against a midpoint rather than
        // testing equality with 1.0.
        bool inNewsWindow = news.InNewsWindowSeries[0] > 0.5;

        if (inNewsWindow)
        {
            if (Position.MarketPosition != MarketPosition.Flat)
                Print($"{Time[0]}  holding through: {news.UpcomingEventTitle}");

            return;   // no new entries while the window is open
        }

        // ... normal entry logic below
    }
}

Two details worth keeping. Instantiate in State.DataLoaded, not State.Configure — the bars the indicator needs are not available yet in Configure. And compare the series against a midpoint rather than testing equality with 1.0: NinjaScript series are doubles, and exact equality on a double is a habit that will eventually cost you a session.

Winding down instead of stopping dead

A binary in-window check is blunt. The countdown series let the strategy taper — stop opening new positions well before the print, then decide separately what to do with anything already open:

double minutesToHigh = news.MinutesToNextHighSeries[0];

// Wind down rather than stopping dead.
if (minutesToHigh > 0 && minutesToHigh <= 15)
    return;                                   // stop opening new positions

if (minutesToHigh > 0 && minutesToHigh <= 5 &&
    Position.MarketPosition == MarketPosition.Long)
{
    Print($"{Time[0]}  flattening {minutesToHigh:F1} min before " +
          $"{news.UpcomingEventTitle}");
    ExitLong("NewsFlat", "");
}

MinutesToNextMediumSeries works the same way for medium-impact releases, which most strategies will want to treat differently — visibility and a log line rather than a full stand-down.

What to actually do inside the window

Roughly in order of how much damage each can do if you get it wrong. Start at the top.

Response 1

Block new entries

The minimum viable news filter, and the one that does most of the work. The strategy keeps managing whatever is already open but opens nothing new until the window closes. Low risk of making things worse, which is more than can be said for the others.

Response 2

Flatten before the release

Exit open positions ahead of the print. Removes release risk entirely, at the cost of exiting trades that would have worked — and the exit itself happens into the same thinning book, so flatten early in the window rather than at T-30 seconds.

Response 3

Reduce size

Keep trading, at a fraction of normal size. Reasonable when your edge genuinely persists through releases and you are managing slippage rather than avoiding it. Requires that you have actually measured that, not assumed it.

Response 4

Log and do nothing

Run the filter in observation mode first: record every bar where the strategy would have stood aside, and compare those trades against the rest. This is how you find out whether a news filter helps your strategy before you let it change your fills.

What a news filter does to a backtest

It will probably make the equity curve look better, and you should be suspicious of that. A backtest fills at bar prices. It does not model the widened spread, the thinned book, or the stop that sweeps twenty ticks to find size — which means the trades a news filter removes are exactly the trades the backtest was already scoring too generously. The improvement you see is real; it is just smaller than the number on the screen.

There is a second trap. A news indicator can only mark events it has calendar data for, so a backtest over a period the calendar does not cover runs with the filter silently disabled — and a filter that never fires appears to cost nothing. Check how far back your events actually load before reading anything into a multi-year result.

The honest test is a live or sim run with logging on. Run the filter in observation mode first, record every bar where the strategy would have stood aside, and compare those trades against the rest of the session. That comparison is worth more than any amount of historical optimisation.

Tools that expose news state to NinjaScript

Most NinjaTrader news indicators draw on the chart and stop there, which is enough for a discretionary trader and useless to a strategy. News Markers PRO publishes InNewsWindowSeries, MinutesToNextHighSeries, MinutesToNextMediumSeries, and UpcomingEventTitle as public members, which is what makes the code above possible. If you only need the markers on the chart, the free News Markers Lite pack covers that.

NinjaScript news filter FAQ

Can a NinjaScript strategy know when economic news is due?

Not on its own — NinjaTrader 8 does not expose an economic calendar to NinjaScript. The strategy needs an indicator that parses calendar data and publishes its state as a public series, which the strategy then holds a reference to and reads on each bar. Without that, a strategy has no way to distinguish a release-driven move from any other move.

How do you read an indicator value from a strategy in NinjaScript?

Declare a private field of the indicator type, instantiate it in State.DataLoaded using the wrapper method NinjaTrader generates from the indicator inputs, then index its series in OnBarUpdate — for example news.InNewsWindowSeries[0] for the current bar. Instantiating in State.DataLoaded rather than State.Configure is what ensures the bars the indicator needs are available.

How does News Markers PRO expose news state to a strategy?

Through four public members a strategy can read directly: InNewsWindowSeries, which is 1.0 while price is inside a configured blackout window and 0.0 otherwise; MinutesToNextHighSeries and MinutesToNextMediumSeries, which count down to the next high- and medium-impact release; and UpcomingEventTitle, the name of that release. Together they let a strategy gate entries, wind down ahead of a release, and log why it stood aside.

Should a strategy flatten or just stop entering before news?

Blocking new entries is the safer default and does most of the work. Flattening removes release risk completely but also exits trades that would have worked, and the exit goes into the same thinning order book — so if you flatten, do it early in the window rather than seconds before the print. Which is right depends on whether your strategy holds positions long enough for a release to matter.

Does a news filter improve backtest results?

Often it improves them for the wrong reason. A backtest fills at the bar price and does not model the widened spread and thin book that make release trading expensive, so the losses a news filter prevents are precisely the ones a backtest was already understating. Treat the backtest as a check that the filter does not break the strategy, and judge its real value on live or sim fills.

Can you backtest a news filter over historical dates?

Only as far back as the calendar data goes. A news indicator can only mark releases it has data for, so historical coverage is bounded by the calendar file rather than by your bar data. Check how far back your events actually load before drawing conclusions from a multi-year backtest — a filter that silently does nothing before a certain date will look free of cost.