Troubleshooting & FAQ
Troubleshooting & FAQ
Problems organised by symptom: a plugin that does not load, an indicator that renders nothing, a strategy without callbacks, a venue that is not listed, missing live data, NaN values and threading errors. Each entry gives the cause, the fix and where to read more.
On this page
Symptom: plugin does not load or appear
The plugin DLL was built but its types do not show up: no indicator in the picker, no strategy in the strategy list, no column in the Market Analyzer.
| Cause | Fix |
|---|---|
The type is not public, is abstract, an interface or an open generic, or has no constructor the platform can call |
Meet the discovery rules. The most common miss is a constructor with a required parameter. |
The DLL is not directly in Documents\SabrTrader\Plugins (a subfolder, the wrong Documents folder, or a file name that matches a built-in plugin assembly) |
See Where to deploy. |
| The plugin was built against a newer or different SDK version than the platform ships | Rebuild against the matching SDK version. See Versions & targeting. |
| A rebuilt DLL failed to load, so the previous build is still registered | Read the reload error in the log and fix it; the next successful build replaces the previous one. |
The full loading checklist is in Building & deploying: Troubleshooting.
Symptom: indicator loads but renders nothing
The indicator appears in the picker and can be added to a chart, but draws nothing.
-
No plot was registered, or no values were written to it. An indicator draws the values in the
series behind its plots. Check that the constructor calls
AddPlotand thatOnDataLoadedandOnBarUpdatewrite a value for every bar. See Plots & styles. -
Every value is
NaN. A series that is allNaNrenders as empty; see NaN values below. -
The calculation runs at a different cadence than you expect. Check the indicator's
Calculatemode and which callbacks you override. See Calculation & market data. -
Custom rendering throws or draws outside the panel. An exception from
OnCustomRenderis caught by the chart and logged asOnCustomRender threw, and nothing from that call is drawn. Check the log and your coordinates againstPlotArea. See Custom rendering.
Symptom: strategy gets no callbacks
The strategy is selected and started, but your OnBar logic never seems to run.
-
It was not discovered as a strategy. A strategy must be a public, top-level, concrete
subclass of
Strategywith a public parameterless constructor. See Discovery & metadata. - No data series is loaded. Callbacks are driven by incoming bars; without instrument data there is nothing to call back on. Check that the run has a data series.
- Cadence mismatch. If you expect per-tick calls but the strategy runs per bar (or the other way round), the callbacks fire at a different granularity than you assume. See Calculation cadence.
-
It threw on the first call. An exception in
OnInitializeorOnStartstops the strategy before it does visible work; check the log. - You rebuilt it while it was running. A running strategy keeps the build it started with. Stop it and start it again to run the new build.
Symptom: venue not listed in Connections
You wrote an IVenuePlugin but its venues do not appear in the Connections dialog.
-
The plugin type failed a discovery rule. The
IVenuePluginimplementation must be public, concrete and constructible without arguments. See Discovery rules. -
Venuesis empty. The platform lists one entry perIVenueDescriptorinIVenuePlugin.Venues. Return every descriptor from that property, and give each one aVenueManifest. See Venue plugins. - The DLL did not load. Go through the loading checklist above.
Symptom: no live data
A venue is connected but no live ticks, quotes or depth arrive.
- The symbol or exchange is wrong. A symbol that does not match the venue's listing gives an empty subscription. Check the instrument and exchange.
- Backfill works but live data does not (or the other way round). History and live ticks are separate parts of a data provider. Check that both are implemented and exposed. See Live ticks & depth and Backfill.
- Authentication failed for part of the connection. A venue can connect for public market data while a login failure elsewhere is only logged. Check the log for connect and authentication errors.
Symptom: NaN values in a series
A plot or indicator series reads as NaN and renders as a gap or nothing at all.
-
The calculation ran before enough history existed. A 20-period average has no value on bar 3,
and
NaNis the correct output there. Guard the calculation with a warmup check. -
A division by zero or a
NaNinput. OneNaNin an arithmetic chain makes the resultNaN; validate inputs before using them. -
NaNis the "no value" marker. A bar written asdouble.NaNrenders as a gap. That is expected.
NaN, not 0, for "no value". Writing 0 where you have no value draws a line at
zero; writing double.NaN draws a gap. See
Reading bars & series.
Symptom: threading exceptions
You see cross-thread exceptions such as "The calling thread cannot access this object because a different thread owns it", or intermittent corrupted state.
- Share state between data callbacks and rendering safely. Write output through series (one writer, many readers), or publish immutable snapshots that the render callback reads.
- Avoid blocking calls in a callback. Long or blocking work in a per-tick callback stalls the feed behind it. Start the work elsewhere and pick up the result in a later callback.
Common mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| Constructor takes a required parameter | Type not discovered, no error line | Add a parameterless constructor; expose settings as parameters. |
| Strategy or drawing tool with only an all-optional constructor | Type not discovered | Add a public parameterless constructor. |
| Deploying into a subfolder, or into a Documents folder that is not the real one | Builds fine, never appears | Deploy directly into Documents\SabrTrader\Plugins. The SDK's DeploySabrTraderPlugin target finds the real Documents folder, a redirected one included. |
Copying the whole bin folder |
Slower loading, log noise | Copy your DLL, its PDB and third-party libraries the platform does not ship. |
| Writing 0 where there is no value | A line at zero | Write double.NaN for "no value". |
| Building against a newer SDK than the platform ships | Plugin fails to load | Build against the SDK version that matches the platform release. |
FAQ
Do I need to register my plugin anywhere?
No. There is no registration call or configuration file; the platform discovers your public types by the contracts they implement. Venue plugins and add-ons describe themselves with a manifest object in code. Copy the DLL into the plugin folder and it loads.
Can one DLL contain several plugin kinds?
Yes. One assembly can carry any mix of indicators, strategies, bar types, drawing tools, Market Analyzer columns, venue plugins and add-ons. Each type is cataloged by the contract it implements.
Where does the DLL go?
Directly into Documents\SabrTrader\Plugins. See
Where to deploy.
Why does my plugin build but never show up?
Usually one of two reasons: the DLL is not directly in the plugin folder the platform reads, or a discovery rule failed (most often a required constructor parameter). Check the Log tab.
Can I ship third-party libraries?
Yes. Libraries the platform does not ship go next to your plugin DLL and load into your plugin's own
context. The SabrTrader.* contract assemblies and any library the platform already ships
always come from the platform. See Dependencies &
isolation.
Can two plugins use different versions of the same library?
Not from the plugin folder. It is one flat folder, so it holds one copy of each library file name. Each plugin loads that file into its own context, so the plugins do not share statics, but they do share the version.
Do I need to restart SabrTrader after a rebuild?
No. The platform watches the plugin folder and reloads a rebuilt DLL while it runs. Indicators on open charts switch to the new build; a running strategy keeps its build until it stops, and a connected venue switches at its next connect. See The build and reload loop.
What framework should I target?
net10.0, the framework of the SDK assemblies and the platform.
Does a failing plugin crash the platform?
A malformed DLL, a missing dependency or a type that fails to register is logged in the Log tab, and the platform continues. A rebuilt DLL that fails to load leaves the previous build registered.