OnMarketData emits values which is one of the three MarketDataType: Last, Bid, Ask.
protected override void OnMarketData(MarketDataEventArgs e) { Print("Datetype: " +e.MarketDataType + "| Volume: " + e.Volume + " | Price:" + e.Price); }
And samelike, trade might happen (.Last event) anytime, independently what happens to orderbook (has no connection with .Bid/.Ask events) . So, trades might happen and you might get any number of .Last events, without any event of .Bid/.Ask change (if the bid-ask prices stays unchanged in that market/orderbook).
So, we agree that .Last -and Level1 (.Bid/.Ask) events are totally independent events, right?
then the problem lies within .Last events itself. In any traditional/stock/etc trading, there does not exist a generic "last" trade without one more detail - the side. Whenever trade happens, either buyer buys at someone's ask price, or seller sells on someone's bid price. So, trade happens from initiator (a.k.a. TAKER) always. it's impossible (unless forcemajour cases) that the trade didn't have a side. Someone always have pending orders (MAKER) in orderbook, and trade happens only when another side initiates order which ends up being as MARKET Order (even if it's limit order, if the price crosses opposite bid/ask price, then it becomes MARKET order).
So, ninjatrader emits MarketDataType.Last event, however, there is no way to know (from the adapter connection) whether it was buyer or seller.
What does happen in the backgrounds of NT, when you open the chart with i.e. 1-tick timeframe , with DataType - ASK?
it fetches (from adapter connection) the trades that happens on the ASK side, right? (so, the trades which were initiated by BUYERS)... and similarly logic applies when you open BID datatype chart.
However, we (or any trader) can't reliable open a chart, where is both (BID & ASK) historical data merged. You might say that we can open .LAST based chart, but if we do so, then it's impossible to look on historical bars and say whether which of them was BID or ASK bar. You are still forced to additionally load BID & ASK dataseries (thus, ending up loading 3 dataseries from adapter connection).
The solution is simple - whenever users opens chart i.e. XYZ symbol, with tick timeframe and .Last datatype, then Adapter Connection (developer) can just add the this within RequestBars:
for (var i=0; i< records.length; i++) { ... ... var tradeSide = record.XyzValue ==="ask" ? TradeSide.Ask : record.XyzValue ==="bid" ? TradeSide.Bid : TradeSide.Unknown; .Add(price, price, price, price, time, volume, double.MinValue, double.MinValue, tradeSide) // instead of just //.Add(price, price, price, price, time, volume, double.MinValue, double.MinValue) ... ... }
1) in REALTIME ONMARKETDATA events, when you get .Last event, you will be able to identify which `TradeSide` it was (either BID, ASK or unknown), and you wont be dependent to manually calculate/store what was the last bid/ask price (moreover, due to asynchronous nature from broker connections or due to many other events, it's not fully reliable way, as BID/ASK price might change and be out of the range when the .Last event comes in)
2) more importantly, not just realtime , but in HISTORICAL(which is why I open this topic) 1-TICK chart, you can identify which tick was which TradeSide, thus you dont need to additionally load another 2 dataseries ( bid/ask) and we can have something like .TradeSide property in OnBarUpdate so we can program strategies and indicators, which can be applied to .LAST datatype charts, and could identify whether bar is TradeType.Bid or TradeType.Ask.
3) additionally to above, it will open a huge door to ONRENDER functionality, to use that data, as a this moment, it's impossible and we can only get i.e. ...bars.GetClose(idx), but we will be able to know the the side of that tick-bar too, by having i.e. bars.GetBarTradeSide(idx) [of course, it will return 'TradeSide.Unknown' for any scenario other than 1-tick chart].
Thus, people can create more advanced logic by using `1-TICK .LAST` series, from either ninjascripts or even merely using a chart for analysis.
Comment