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.
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.
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.
Any tool you use for this has to answer all three. A tool that only draws markers on a chart answers none of them.
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.
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.
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.
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.
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.
Roughly in order of how much damage each can do if you get it wrong. Start at the top.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.