Table of Contents

Call model

Every extension is called by the platform, never the other way round, and every kind is called by its own host: the chart, the heatmap, the SmartDOM, the Watchlist, a module panel, the connection manager. This page puts the rules of all the kinds side by side: who calls your code and when, on which thread, how long a call may take, and what happens when it throws. The articles of the kinds describe the details; read the one of your kind before you rely on this summary.

The two models

The kinds fall into two groups.

Chart indicators and chart strategies are called directly from the threads where things happen: the calculation from the data threads, the drawing from the drawing thread, the trading events from the trading connection. Only OnCalculate is protected from itself; everything else may run at the same time as the calculation, and you share data between the threads yourself. An exception is logged and the indicator stays on the chart.

Heatmap indicators, SmartDOM and Watchlist columns and custom modules run behind an adapter: the platform copies the data, delivers it on a thread of its own and never calls one instance concurrently, so their fields need no locks. In return a call has a time budget, and an exception, or calls that are slow again and again, stop the instance.

Connectors are a third case: they feed the platform rather than read from it, and they own a processing queue of their own.

Summary

Kind Calls Thread Concurrent calls Time limit When your code throws
Chart indicator OnCalculate for the history and every tick; market data and trading callbacks; OnRender; the timer Data threads, the drawing thread, background threads Yes, except OnCalculate with itself None; live calls for the same bar are skipped when the calculation is slow Logged (OnCalculate and OnRender at most once per 10 s per instance); the indicator keeps running
Chart strategy As an indicator, plus OnStarted, OnStopping, OnStopped, the order events As an indicator As an indicator None Logged; see the warning below
Heatmap indicator ConfigureAsync, ProcessTicksAsync, ProcessProfileAsync, ProcessMboAsync, the timer, warm-up and reset The instance's own background task No, except GetRequiredProfilePeriods 2 s per call, 30 s for WarmUpAsync, through the cancellation token The indicator is stopped; so are 3 timeouts within 30 s
SmartDOM column Data callbacks, OnTimer about 10 times a second, OnDrawCell, clicks, OnSettingsChanged Data on a background thread, drawing on the drawing thread No 100 ms per call; 5 slow calls within 10 s stop the column The instance is released (OnDispose), the header shows «Error»
Watchlist column Data callbacks, OnTimer about once a second, OnSettingsChanged A background thread, within about 0.1 s of the data No; all rows of a column share one lock 100 ms per call; 5 slow calls within 10 s stop the column The whole column is stopped, every row; the header shows «Error»
Custom module Constructor and OnInitialize, data callbacks, OnTimer about 10 times a second, OnRender, input, header buttons Data, constructor and OnInitialize on a background thread; drawing and input on the thread of the panel No 100 ms per call; 5 slow calls within 10 s stop the module The module is stopped, the panel shows «Error»
Connector OnConnect, OnDisconnect, OnSearchSecurities, the subscription methods, OnProcess OnConnect and OnDisconnect on the thread pool, searches and subscriptions on the caller's thread (possibly the UI thread), processing on the connector's queue thread Yes; serialize through the queue OnConnected within ConnectTimeout (60 s by default) In OnConnect: the attempt fails and is not retried; in OnProcess or a queued action: logged, the queue continues

Rules for every kind

  • Construct cheaply, start late. The constructor of every kind runs before the extension is attached to its host, often on a background thread, and again whenever the host recreates it (a chart reload, a template, a changed layout). Create fields and defaults there; start subscriptions, timers and tasks in OnInitialize (or OnConnect for a connector).
  • Release what you started. Every kind has a place where the platform says goodbye: OnDispose for indicators, columns and modules, OnStopping and OnStopped for strategies, OnDisconnect for connectors. The platform releases its own subscriptions (timers, candle series, options, other instruments); tasks, event handlers and native resources of your own are yours.
  • Never block a callback. A call that waits for the network, a file or a lock held elsewhere stalls the thread it runs on: the chart's data, the drawing of a panel, the queue of a connector. Start a task and give its result to the next call.
  • UI work goes through the host. A chart indicator uses DoActionInGuiThread; SmartDOM columns and modules draw in OnDrawCell or OnRender and ask for a frame with Redraw(); a Watchlist column sets the values of its cells; a heatmap indicator writes its visual state and the heatmap draws it. Do not touch WPF or Avalonia objects from your own threads.
  • Exceptions are not control flow. For the adapter kinds an exception ends the instance; for chart indicators it loses the data of the call. Check the inputs and catch what you expect.
Warning

Chart strategies: an exception in OnStopping leaves the strategy started. The platform calls OnStopping before it resets the strategy; when OnStopping throws, the exception is logged and the reset does not happen. Catch the exceptions of the code that closes the position and cancels the orders there. An exception in OnStarted is logged too, and the strategy stays started.