Discovery & metadata
Discovery & metadata
How the host finds your strategy class without a registration step, and how
[StrategyMetadata] sets the name and description users see.
Discovery & metadata
There is no manifest and no registration call. When it loads your plugin, the host scans the assembly for
launchable Strategy subclasses and adds each one to its strategy catalog. A type is launchable
when it is a public, non-abstract Strategy subclass with a public
parameterless constructor, because the catalog creates one instance per run. Copying the plugin DLL into
the plugins folder is the whole deployment step.
Without metadata the catalog shows a name derived from the class name: it drops a trailing
Strategy and splits the PascalCase words, so MaCrossStrategy becomes
“Ma Cross”. Add [StrategyMetadata] (namespace
SabrTrader.Pipeline.Strategies.Catalog) to set a display name and a one-line description.
Both appear in the Strategy Analyzer and in the Control Center launch form.
C#using SabrTrader.Pipeline.Strategies;
using SabrTrader.Pipeline.Strategies.Catalog;
[StrategyMetadata(DisplayName = "Donchian Breakout", Description = "Buys a break of the N-bar high.")]
public sealed class DonchianBreakout : Strategy { /* ... */ }
OnInitialize. The protected helpers throw InvalidOperationException when called
from the constructor, because the run context is bound later.How parameters are discovered
For each launchable type the catalog creates a throwaway instance and runs its OnInitialize
once, unbound, to capture the parameters it declares. That is how the launch form knows your inputs and
their optimization ranges without running the strategy, and why OnInitialize should only
declare: touching bars, orders or the account there throws on the probe. Discovery tolerates failures: an
assembly that fails to load or a constructor that throws leaves that type out of the catalog, and an
OnInitialize that throws keeps the parameters declared before the throw.
The catalog
The host keeps the discovered strategies in its catalog. Each entry has a stable id, the full type name for a compiled strategy, so a saved run keeps resolving after a display-name change. A lookup matches the id, the display name, the type name or the full type name, case-insensitively. Strategy lists are sorted by display name. A plugin does not use the catalog; it ships a discoverable class.
Hot-reloaded and dynamic strategies
The catalog also holds entries added at runtime, and the host's strategy lists refresh when that set changes. A hot-reloaded plugin adds its compiled strategy, or replaces the earlier build of the same type (matched by full type name). Running instances keep their code; the next run uses the new build. A configuration-backed strategy is added by id, and its parameters come from the same probe a compiled type gets. A display name already used by another strategy is rejected.