OnTick vs OnBarUpdate Execution in NinjaTrader
This topic has been breaking my head for over a few years now for quite a few reasons. Let's review a few of the main ones.
First of all we need to say that NinjaTrader architecture has two possible ways of executing inside the OnBarUpdate method which are either on each incoming tick or on each incoming bar close. Now, I will skip the on price change one which I don't use at all.
The reason I don't use the on price change method is because it does not guarantee that IsFirstTickOfBar method will work on every first tick of bar because OnBarUpdate might not happen due to the fact that there was no price change!
So why do we need to execute on tick anyway? The reason for that is the logic that you want to take on during live execution like eg. bringing up the trails or doing something on an intra bar basis. You won't be able to do this on the left side or the historical execution part of the chart where you strategy trades through the backtest in order to gradually bring you into the live part on the right hand side.
The main problem with writing code for the on tick is this mix of execution desribed above. Its easy and clear to write for on bar close but when you start writing for on tick you start running into a bunch of issues with indexing.
So for example, during your live execution in order to get your bar close price you would write if (IsFirstTickOfBar) Close[1] which would mean whilst at the first tick of bar give me the previous bar close.
Now if you were to do this during the historical execution this would actually return the wrong bar because IsFirstTickOfBar is always true and you would get the close of a preceding bar.
Because of the above said the indexing for the live and for the historical part of the exectuion becomes hard to handle. You need to distinguish between the State.Realtime and State.Historical and use either 0 or 1 for the index and this becomes a nasty code smell!
However, there is a solution to this issue which is elegant. Truth is, when you are creating a on tick based strategy there are two cases. You are creating it only for the live and then pretty much you don't really care unless the live part also includes a lot of on bar close logic or you wish your indicators to calculate on the live bar as well. Unfortunately, with the indicators case there is no solution at all, if that is what you are after that is it you have to execute on tick, same with if you want to look at a higher timeframe eg. a running daily bar or something like that...
Nevertheless if you are looking for something like bringing up a breakeven stop to a certain level on a tick based basis you can use OnMarketDataUpdate event whilst still executing on bar close inside the OnBarUpdate method! Same can work for trail stops, synthetic market if touch orders and time exits that would requite precise reaction after a certain tick arrives outside a time window.
protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)
{
if (State != State.Realtime)
return;
var price = marketDataUpdate.Last;
}