How can I increase NinjaTrader timestamp precision?

Title: Title: How can I increase NinjaTrader timestamp precision?

Hi,

I have an indicator running on a 1-Tick chart with Tick Replay enabled. The indicator displays the execution time of every tick.

However, when I display the timestamp with higher precision, the microseconds are always 000 (and therefore the nanosecond portion is also 000).

For example:

03:52:05.5600000

I am using:

DateTime tickTime = e.Time;

Print(tickTime.ToString("HH:mm:ss.fffffff"));

With Rithmic as the real-time data provider, multiple consecutive market-data events can have different arrival times on my PC, but e.Time is always at exact millisecond precision.

My questions are:

  1. Does NinjaTrader preserve the original Rithmic timestamp precision internally?
  2. Does the Rithmic adapter expose the usecs / microsecond portion of the Rithmic timestamp?
  3. If MarketDataEventArgs.Time is limited to milliseconds, is there another API, event, AddOn interface, or internal data structure that exposes the original higher-precision timestamp?
  4. Is there any way to access the original exchange/Rithmic microsecond timestamp from NinjaScript or an AddOn?

I am specifically looking for microsecond-level timestamp precision, not simply higher DateTime formatting precision.

NinjaTrader version: 8.0.22.2
Data provider: Rithmic

1 Like

One distinction I would make here is between the precision of .NET DateTime and the precision actually populated by the NinjaTrader/provider adapter.

Formatting e.Time with fffffff only exposes whatever precision is already present in that DateTime; it cannot recover timestamp information that was never populated.

The interesting part of your test is therefore that the final four digits consistently remain zero.

NinjaTrader’s documentation exposes MarketDataEventArgs.Time simply as a DateTime, and the provider table lists Rithmic real-time timestamps as native, but I don’t see a documented NinjaScript field that separately exposes the original Rithmic microsecond component.

I would run one additional test before concluding where the precision is being lost:


Print($"{e.Time:O} | ticks={e.Time.Ticks}");

DateTime.Ticks has 100 ns representation granularity. If the value is consistently divisible by 10,000, then the actual DateTime reaching your NinjaScript is millisecond-aligned; this rules out the possibility that only the string formatting was hiding additional precision.

I would also assign a local monotonically increasing sequence number as the first operation in OnMarketData(). That will not recover the exchange timestamp, but it lets you distinguish two separate questions:

  1. What timestamp precision reaches NinjaScript?
  2. In what order did NinjaTrader deliver events that share that timestamp?

That second distinction becomes important if you’re using these timestamps for tick sequencing rather than simply displaying execution time.

If anyone knows of an adapter-level or AddOn API that exposes Rithmic’s original usecs field before it becomes MarketDataEventArgs.Time, that would be the key piece here.

1 Like

The incoming trade and quote ticks get their precision from the feed, so you can’t achieve sub-millisecond precision if Rithmic isn’t sending you that. You can stamp them with your own timestamp based on the computer’s clock, but then, that doesn’t have a way to know the lag of each individual message that arrived, only perhaps the lag on average, and further, that doesn’t tell you how lagged the data server is relative to the exchange, so there are too many ambiguities to do that in a way that has high confidence at that tight precision.

2 Likes

Additionally, you will find that the NT historical data is stamped only to the nearest .040 seconds because of the way the timestamps work (using a byte to store the 1/256 of a second part), so the historical trades will be even further from your goal. The lag inherent in how retail data feeds deliver this information is going to absolutely dwarf any sub-millisecond information by multiple orders of magnitude, making it where you could perhaps find some interesting tidbits using realtime stamping but totally unactionable in practice because of the lags involved in a retail feed.

2 Likes

Good point on the distinction between feed/exchange time and locally observed arrival time.

One small numerical correction on the historical timestamp point, though: if the fractional component is stored in units of 1/256 second, then each step is:

1 / 256 = 0.00390625 seconds

so roughly 3.906 ms, rather than .040 seconds / 40 ms.

That distinction matters here because it would explain why multiple historical events can fall into approximately 4 ms timestamp buckets even though they were separate events.

It also reinforces the sequencing issue: once multiple trades share the same stored timestamp, timestamp precision alone may no longer be enough to reconstruct their original ordering unless that ordering is preserved separately.

For the OP’s original Rithmic question, I think the remaining unknown is still whether higher-resolution upstream timestamps exist but are normalized before reaching MarketDataEventArgs.Time, or whether the adapter is receiving them at millisecond precision in the first place.

1 Like

You’re right. It had been a long day and I did that without a calculator and was off by a digit.

1 Like