SignalAI

SDK reference

The public surface of the signalai-quant crate (crates.io). Bring it all in through the prelude:

use signalai_quant::prelude::*;
// Strategy, Ctx, Bar, Trade, Quote, Timer, OrderEvent, OrderStatus, OrderType,
// Side, Price, Qty, SymbolId, Resolution, TradingType, Portfolio, Instrument,
// SignalValue, Risk, and the `indicators` module.

Add it to a project with cargo add signalai-quant. The crate ships no engine — it's the contract you code against, so your strategy type-checks and compiles locally exactly as it will on the server. Backtests run in the cloud (submit from the Studio or Claude).

  • Strategy — the trait you implement + the Ctx you drive.
  • Events & typesBar, Trade, Quote, OrderEvent, Timer, Side, OrderType, Price, Qty.
  • Results & stats — the equity curve, trade ledger, and summary stats a backtest returns.
  • CLI — the legacy signalai command line.

Trading types

Every strategy declares a trading type from trading_type() (drives accounting):

  • TradingType::Swing — the default; holds across days (overnight carry, compounding).
  • TradingType::Day — intraday only; goes flat at each session close, each day from the same capital.
fn trading_type(&self) -> TradingType { TradingType::Day }

Investing and Hft exist in the enum but aren't supported yet. See Trading types.

Identifiers & scalars

Instruments and prices are typed, not raw strings/floats:

  • SymbolId — a compact id for an instrument; every event carries one. The run's symbols come from ctx.universe() (never hard-code tickers).
  • Price / Qty — fixed-point newtypes. Read with .as_f64(); build with Price::from_f64(x) and Qty::shares(n). Qty also has .is_zero().
  • Resolution — bar resolution: Resolution::Day1 or Resolution::Min1.

Data subscription

A strategy declares what it consumes in init, via Ctx:

  • ctx.subscribe_bars(sym, Resolution::Day1) — route that symbol's bars to on_bar.
  • ctx.subscribe_trades(sym) / ctx.subscribe_quotes(sym) — tick data → on_trade / on_quote.
  • ctx.subscribe_signal("aapl-sentiment") — a SignalAI signal feed → on_signal.
  • ctx.every("7d") — a periodic timer → on_timer (interval strings like "7d", "1h", "30m").

Order lifecycle

Orders enqueue and fill as later events (no re-entrancy — see Fills). Fills report back through on_order:

  • OrderStatus — the order state (Submitted, PartiallyFilled, Filled, Cancelled, Rejected, …).
  • OrderEvent — one event per transition, keyed by the OrderId returned from ctx.order(...), carrying the fill detail.

Parameters

Tunable knobs are declared per-strategy (the Studio shows an input for each, and validates type/bounds before a run) and read from Ctx at run time:

  • ctx.param_f64("threshold") — a float (returns 0.0 if unset).
  • ctx.param_i64("lookback") — an int (returns 0 if unset).
  • ctx.param_bool("long_only") — a flag (returns false if unset).

Always pass a default when declaring a param, so an unset value is sensible. Example: declare lookback (int, default 50) and read let n = ctx.param_i64("lookback") as usize;.