Does Instrument.MarketData.Update guarantee event sequence, as OnMarketData() does?

Hello,

The help guide states this about OnMarketData():

“An event driven method which is called and guaranteed to be in the correct
sequence for every change in level one market data for the underlying
instrument.”

The same explicit sequence guarantee appears for OnOrderUpdate():

“OnOrderUpdate() method guarantees that you will see each order state change
in sequence”

I cannot find an equivalent statement anywhere for Instrument.MarketData.Update,
which is the subscription method shown in the MarketData help page example for
Add Ons.

My question is narrow and factual:

When subscribing via instrument.MarketData.Update inside an Add On, are Level 1
market data events delivered in the correct chronological sequence, with no
events dropped?

I am not asking whether it works in practice. I am asking whether the sequence
is guaranteed, because my use case cannot tolerate reordered or missing events:
I forward every Last event, with its Price and Volume, to an external process
that reconstructs bars and computes a volume-weighted average price. A single
reordered or dropped event produces a slightly wrong number with no error
raised, which is the worst possible failure mode for me.

Three related points I would like clarified:

  1. The “Multi-Threading Consideration” page says market data is distributed by a
    randomly assigned UI thread and that my object may not run on the calling
    event thread. Does that affect the ORDER in which my handler observes events,
    or only which thread it observes them on? These seem like different問題s and I
    want to be sure I am not conflating them.

  2. Dispatcher.InvokeAsync is recommended as best practice. If events are queued
    through a dispatcher, is their relative order preserved?

  3. If the sequence is NOT guaranteed for Add Ons, is an Indicator with
    OnMarketData() the recommended approach for a component that only forwards
    Level 1 data and contains no trading logic?

My component contains no strategy: it reads events and sends them out. I would
prefer an Add On for that reason, but only if the sequence guarantee holds.

Thank you.

Short answer: I would not treat Instrument.MarketData.Update as sequence-guaranteed.

The MarketData reference says it provides snapshots and an Update subscription, but it does not state the correct-sequence guarantee that the OnMarketData and OnOrderUpdate docs state explicitly. The multithreading page only explains thread affinity and recommends Dispatcher.InvokeAsync for marshaling work. That solves thread access. It does not create a missing delivery-order or no-drop contract.

For your case I would separate two guarantees:

  1. NinjaTrader callback order.
  2. Delivery from your callback to the external process.

If the Add-On path must be used, copy Price, Volume, Time and MarketDataType immediately in the handler, assign your own Interlocked sequence number there, and push the immutable record into one single-consumer queue. Log every sequence number and reconnect boundary. Do not perform socket I/O or bar construction inside the callback.

But that design can only preserve the order your handler receives. It cannot prove that Instrument.MarketData.Update itself never reordered or dropped an event.

So, based on the current public docs, an Indicator using OnMarketData is the only path with the documented sequence guarantee. If the Add-On is mandatory, I would ask NinjaTrader Support to confirm the contract in writing before relying on it for silent-error-sensitive VWAP reconstruction. Dispatcher.InvokeAsync alone is not enough.

References: