Strategies

Strategies

Overview & lifecycle

Automated trading logic in one class: managed orders, parameters, indicators, ATM brackets, backtest and live, driven by a small set of lifecycle hooks.

The strategy model

A strategy subclasses Strategy in the SabrTrader.Pipeline.Strategies namespace, overrides a few lifecycle hooks, and calls the protected helpers (bars, position, orders, logging) to do its work. The helpers delegate to an IStrategyContext the runner binds before the first callback. The data feed, the trading service and the runner stay out of sight, so the same class runs unchanged in a backtest and against a live broker account.

Three guarantees shape how you store state and reason about concurrency:

  • One instance, one run. Every backtest or live launch creates a fresh instance, and fields hold per-run state. The runner never resets a strategy's fields; running again means a new instance.
  • Single-threaded. Every On… hook runs on the run's serialised strategy thread, so author code needs no locks and no volatile. Custom chart rendering is the one exception (see RenderingStrategy on the reference page and custom rendering).
  • Same code in both modes. The strategy depends only on the IStrategyContext seam, so the identical class runs deterministically in a backtest and live.

Order operations are fire-and-forget. PlaceOrder, CancelOrder, ModifyOrder and Flatten return immediately; the outcome arrives later through OnOrderUpdate, OnFill and OnPositionUpdate.

Lifecycle hooks

The runner calls the hooks in a fixed order: declare once, start once, a callback per bar, order, fill and position events interleaved as the market responds, and a clean-shutdown hook at the end. Every hook is optional; one you do not override does nothing.

Hook When Use it for
OnInitialize() Once, first, before any bar Declare parameters and indicators, set Calculate.
OnStart() Once, after parameter overrides, before the first bar callback Read final parameter values, warm up, call UseAtm.
OnBar() Per bar, at the Calculate cadence Entry and exit logic.
OnOrderUpdate(Order) An order of this run changed state React to working, filled, cancelled, rejected.
OnFill(Fill) One execution Per-execution bookkeeping, commission.
OnPositionUpdate(Position) The run's net position changed Track PnL, reconcile state.
OnDecision(DecisionAnswer) A decision model answered an ask Act on the answer. See Decision models.
OnDataConnectionChanged(DataConnectionStatus) Live runs, when the instrument's data connection drops, reconnects or fails React to stale prices, for example cancel a working entry. See Live data connection.
OnMarketByOrder, OnMarketDepth, OnOrderBookLifecycle Backtests replaying a recorded MBO or L2 tape Order-book logic. See Recorded order book.
OnStop() Clean shutdown Release external resources. It is skipped when the run faults.
Declare, then read. Declare parameters and indicators in OnInitialize and read their values from OnStart onward. The host applies parameter overrides between the two hooks, so a value read in OnInitialize is still the default. The runner collects declarations once, between OnInitialize and OnStart; declarations made later are ignored.

How a run flows

The runner drives the lifecycle and isolates faults: an exception thrown in any hook moves the run to Faulted and releases its subscriptions, and the host keeps running. The state machine is one-way, with Faulted as an exit from any non-terminal state.

graph LR;
  C[Created] --> I[Initialized];
  I --> R[Running];
  R --> S[Stopped];
  R -. throws .-> F[Faulted];
  I -. throws .-> F;

Stopped and Faulted are terminal. OnStop runs on a clean stop only: after a fault the strategy is in an unknown state, and running its teardown could compound the failure. The State property returns the current StrategyState.

Compared with indicators

Strategies and indicators share CalculationMode, ParameterEditorKind, the decision client and the order-book hooks, but the authoring shapes differ. If you already write indicators, this is the mapping:

Concept Indicator (IndicatorBase) Strategy (Strategy)
Setup public override void OnInit(IIndicatorContext ctx) protected override void OnInitialize()
History OnDataLoaded(ctx), one pass over the backfill No hook: history is readable through GetBar from OnStart, and declared indicators arrive backfilled
Per bar OnBarUpdate(ctx) OnBar()
Teardown OnDispose() OnStop() (clean stop only)
Run context The ctx argument and the protected Context Protected properties on the base class (CurrentBar, Position, …)
Parameters [IndicatorParameter] on public properties IntParameter, DoubleParameter, … called in OnInitialize
Catalog metadata IndicatorDisplayNameAttribute, IndicatorDescriptionAttribute, IndicatorFolderAttribute, IndicatorCategoryAttribute [StrategyMetadata(DisplayName = …, Description = …)]
Cadence Calculate (CalculationMode) Calculate (CalculationMode), same enum and default
Order flow [RequiresOrderFlow] IOrderFlowAwareStrategy, or a declared [RequiresOrderFlow] indicator
Data connection OnDataConnectionChanged(status, ctx) OnDataConnectionChanged(status)

Each page builds on the model above. Start with your first strategy and work down the list.

Page What it covers
Your first strategy A complete moving-average crossover, end to end.
Discovery & metadata How the catalog finds your class and what [StrategyMetadata] controls.
Parameters Optimizable and fixed inputs, and the override flow.
Using indicators Declaring an indicator inside a strategy and reading it each bar.
Bars & position state History, the current bar, position, account, session and instrument metadata.
Managed orders Position-aware intent: enter and exit with reversal handling.
Raw orders & brackets Order requests, modifies, cancels and the enum reference.
Advanced trade management (ATM) Multi-target brackets, auto-breakeven and trailing.
Calculation cadence On bar close, on price change and on each tick.
Backtest & live Running the same class in the Strategy Analyzer and live, and reading the result.
Chart trader panel A control tab for the strategy on the chart.
Decision models Asking a connected decision model and acting on its answer.