Architectural Tip: Stop freezing NT8 during high volatility (Order Flow / Custom Tools)

Been noticing a recurring issue with custom order flow indicators freezing the platform right at the New York open or during massive news events. Most of the time it happens because developers are dumping heavy mathematical calculations directly inside the OnRender method synchronously
When you are processing raw tick data or building custom footprint visuals you have to remember that OnRender is called constantly by the UI thread to update the graphics. If you bog it down with volume aggregations or complex bid ask delta loops your whole chart simply locks up and you miss the move. A much better approach we use in low-latency environments is to completely decouple the data ingestion from the drawing logic. You should calculate your cumulative delta or volume nodes dynamically inside OnMarketData and store those pre-calculated values in a lightweight generic List or a Dictionary. Then when OnRender fires it literally just reads the cached state and draws the rectangles or text instantly without doing a single drop of math. It sounds basic but separating state calculation from visual rendering will drop your CPU load from 80% to something barely noticeable even when the tape is flying, just a quick architectural tip for anyone building custom volumetric tools who is tired of their charts freezing up.

1 Like

Come on man. Don’t give all the secrets away. :wink: :winking_face_with_tongue:

And you should probably consider using lock() or concurrent data structures during calculations to ensure those data structures aren’t being updated in the middle of a render. This commonly causes indicators to crash with missing dictionary keys with basic dictionaries.

2 Likes

Haha, fair point, I tried to keep the initial concept high-level without diving deep into thread safety mechanics so I wouldn’t scare off the beginners, but you are absolutely right to point that out for anyone actually implementing this

If you are decoupling data from the UI thread you essentially must use a ConcurrentDictionary or implement explicit lock objects before reading the cache inside OnRender. Otherwise the exact moment the market data thread writes while the UI thread is looping you get a collection modified exception and the whole thing crashes anyway, good looking out adding that caveat to the thread.

1 Like

È consigliabile calcolare dinamicamente i nodi delta o volume cumulativi all’interno di OnMarketData e memorizzare questi valori precalcolati in una List o un Dictionary generici e leggeri. Quindi, quando OnRender viene eseguito, legge semplicemente lo stato memorizzato nella cache e disegna i rettangoli o il testo istantaneamente senza eseguire alcun calcolo matematico. Perdonami non sono pratico di NINJa ( usavo Sierra Chart) in pratica e tencicamente ( settting ,chart modification, imput to changes of data ) puoi spiegare i passaggi da eseguire per realizzare quello che giustamente tu affermi. Ti sono molto grato per una tua cortese dettagliata speigazione x realizzare sulla mia piattafroma. Grazie

1 Like

Just curious which indicator code you have been examining to make this determination or by what deductions you have come to this conclusion. :slightly_smiling_face:

1 Like

Bidder, I don’t need to name drop specific commercial vendors here, but I’ve audited memory dumps from at least three major order flow suites that retail traders use daily, the fingerprint is always the same. When the tape speeds up during NFP or FOMC, the NinjaScript UI thread chokes because the developer locked the rendering loop while iterating over thousands of raw tick objects synchronously. It is a fundamental misunderstanding of WPF architecture, not an issue with NT8 itself. Decoupling data ingestion from the drawing context using thread-safe collections instantly solves the bottleneck

1 Like

Umberto Piacenza, the concept is straightforward but requires strict thread safety, inside your OnMarketData event, you calculate your Delta/Volume and push that data into a ConcurrentDictionary<int, CustomBarObject>. This runs purely in the background. Then, in your OnRender override, you absolutely never do any math. You simply iterate over that dictionary and call RenderTarget.DrawRectangle or DrawTextLayout. The trick is ensuring your rendering thread only reads cached state and never waits for new ticks to be processed, if you need a deeper architectural review of your specific Sierra Chart migration, feel free to shoot me a direct message.

1 Like

Here’s the right mental mode, performance optimization in NT8 is about reducing work, not relocating it. The wins I try to captured are the 4 things below.

  • Cache instead of allocate (TextLayout, TextFormat, brushes)
  • Look up once instead of repeatedly (CheckSlopes hoist)
  • Short-circuit instead of iterate fully (CheckTime early exit, signal loop break)
  • Build conditionally instead of unconditionally (RegimeUpdate string construction)

These reduce the absolute amount of work the data thread does. Moving work to background threads would just shift the cpu cycles to a different thread while adding synchronization overhead same total work, more complexity, slower decisions.

1 Like

maverick, you are confusing total cpu cycles with ui thread blocking, yes caching text formats and short-circuiting loops is standard wpf practice but that is basic micro-optimization, the issue isn’t the absolute amount of work, it is exactly where the work happens. If you process 5000 raw ticks synchronously inside the onrender dispatcher the ui thread physically cannot paint the screen until the math finishes, so the chart freezes. offloading state calculation to the onmarketdata thread doesn’t reduce total cpu work, it simply frees the rendering thread to do its only job which is drawing pixels, in heavy order flow environments preventing visual lockups is vastly more important than saving a few micro-seconds of background thread synchronization, relocating work is exactly how modern asynchronous architecture survives the tape

1 Like

Fully agree with and understand what Eduardo is attempting to explain here. I wouldn’t be able to explain it as well as he has. But if you’re doing any sort of heavy graphics in ninjascript (like footprint, volume profile, dom, etc), you’ll be able to make huge improvements in performance if you fully understand what he’s saying and apply it.

Personally, it took me a while to understand and figure this out on my own and I learned it the hard way. I wish Eduardo had posted this and hammered it in my head before I built my first iteration of footprint and volume profile LOL.

2 Likes