I'm developing an Indicator for NinjaTrader, NinjaScript 8.
In my testing, I ask for daily historical data for a stock. I expect, and get, a call to my OnBarUpdate()
method once for each day - except the most recent day.
Why?
I've dug around, and I found someone else complain about the problem:
... but I've discovered no solutions.
Does anyone know how to coax NinjaTrader 8 into sending me that last Bar update?
UPDATE 1 - 8/19/2022 My OnBarUpdate()
method looks like this:
protected override void OnBarUpdate()
{
Print("OnBarUpdate: entering - currentbar is " + CurrentBar);
try {
// ...lots of code...
Print("OnBarUpdate: exiting");
} catch (Exception e) {
Print("OnBarUpdate: hit exception " + e.ToString());
}
}
Does that give enough context?
It should be clear that at least my Print()
should tell me whether I get called.
UPDATE 2 Adding the output from other diagnostic print statements in OnBarUpdate()
(not shown):
"CurrentBar","DateTime","Close"
0,"8/19/2021 12:00:00 AM",296.77
1,"8/20/2021 12:00:00 AM",304.36
2,"8/23/2021 12:00:00 AM",304.65
3,"8/24/2021 12:00:00 AM",302.62
... more records ...
246,"8/11/2022 12:00:00 AM",287.02
247,"8/12/2022 12:00:00 AM",291.91
248,"8/15/2022 12:00:00 AM",293.47
249,"8/16/2022 12:00:00 AM",292.71
Note that today is 8/17/2022. Really this doesn't add anything new, since I'm not seeing the initial "Print" - it's just that this illustrates how I'm getting called for all the Bars up to that last one.
UPDATE 3 - OK, I've slimmed down the code so you can see a "complete" method body - no smoke and mirrors.
Here's the code
/// <summary>
/// convert a string to a quoted string - handle imbedded quotes
/// </summary>
/// <param name="s"></param>
/// <returns>a string whose first and last value is the double-quote, with any double-quotes found seeing a backslash prepended.</returns>
private String Q(String s) {
return String.Format("\"{0}\"", s.Replace("\"", "\\\"") );
}
protected override void OnBarUpdate()
{
Print("OnBarUpdate: entering - currentbar is " + CurrentBar);
try {
DateTime timeValue = Bars.GetTime(CurrentBar);
Print(String.Format("{0},{1},{2}", CurrentBar, Q(timeValue.ToString()), Close[0]));
Print("OnBarUpdate: exiting");
} catch (Exception e) {
Print("OnBarUpdate: hit exception " + e.ToString());
}
}
Here's the diagnostic output:
OnBarUpdate: entering - currentbar is 0
0,"8/19/2021 12:00:00 AM",296.77
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 1
1,"8/20/2021 12:00:00 AM",304.36
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 2
2,"8/23/2021 12:00:00 AM",304.65
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 3
3,"8/24/2021 12:00:00 AM",302.62
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 4
4,"8/25/2021 12:00:00 AM",302.01
OnBarUpdate: exiting
... more lines ...
OnBarUpdate: entering - currentbar is 245
245,"8/10/2022 12:00:00 AM",289.16
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 246
246,"8/11/2022 12:00:00 AM",287.02
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 247
247,"8/12/2022 12:00:00 AM",291.91
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 248
248,"8/15/2022 12:00:00 AM",293.47
OnBarUpdate: exiting
OnBarUpdate: entering - currentbar is 249
249,"8/16/2022 12:00:00 AM",292.71
OnBarUpdate: exiting
OK, that's even more weird. Only goes up to 8/16. It's currently 11:21 PM on 8/19/2022; I'm in EST and I assume my data is coming from there too.
UPDATE 4 - see the comment - the chart line only goes up to 8/17/2022, so I'm back to my original question: why am I not getting a call to OnBarUpdate()
for that last day's Close?
Btw. I don't have enough reputation score here yet to make a comment so I have to reply with an answer. But I have run into this same issue and wanted to put something out there.
The particulars of when OnBarUpdate are called can be a somewhat complicated and I do not profess to know them all. But here are some that may be of interest to you.
I loaded up your code to an indicator and am running these tests on Saturday the 10th so the ES market is closed right now.
First Test:
Same results you got. Friday the 9th is missing.
Next test:
Change the calculate to ontick. Even though the market is closed and there are no ticks happening right now it forces the last bar to complete.
Let's say today was a trading day and it was Noon EST and there were 4 more hours in the session. If the indicator were applied to a daily chart with Calculate.OnClose specified todays bar would not be showing until the market close. By specifying Calculate.OnEachTick or Calculate.OnPriceChange it forces todays bar to print the OHLC as it currently stands. The only caveat to this approach is that OnBarUpdate gets called a lot while the market is open so you may have to put some logic in there to only do things when you want them to happen. Might look at "IsFirstTickOfBar"
Also, in the data series options there is a field called "Trading Hours". That also will impact when and if a daily bar is formed.
Hope this helps.