Interface SignalEventContract

Contract for pending signal lifecycle events (open and close).

Emitted by signalEventSubject when a pending position is opened (action "opened") or closed (action "closed") during tick()/backtest() processing. Lets consumers track the active phase of a signal without subscribing to the full signal stream.

Covers every way a position opens (new signal, immediate entry, scheduled activation, user activation) and every way it closes (take_profit / stop_loss / time_expired / user-close / broker fill / order no longer pending).

Consumers:

  • User callbacks via listenSignalEvent() / listenSignalEventOnce()
import { listenSignalEvent } from "backtest-kit";

listenSignalEvent((event) => {
if (event.action === "opened") {
console.log(`Opened ${event.symbol} @ ${event.data.priceOpen}`);
} else {
console.log(`Closed ${event.symbol} (reason: ${event.closeReason})`);
}
});
interface SignalEventContract {
    action: "closed" | "opened";
    backtest: boolean;
    closeReason?: StrategyCloseReason;
    currentPrice: number;
    data: IPublicSignalRow;
    exchangeName: string;
    frameName: string;
    strategyName: string;
    symbol: string;
    timestamp: number;
}

Properties

action: "closed" | "opened"

Lifecycle action for the pending signal.

  • "opened": a pending position was opened (new signal / immediate / scheduled or user activation)
  • "closed": the pending position was closed (TP / SL / time_expired / user / broker fill / ping)
backtest: boolean

Execution mode flag.

  • true: Event from backtest execution (historical candle data)
  • false: Event from live trading (real-time tick)
closeReason?: StrategyCloseReason

Close reason. Present only when action === "closed":

  • "take_profit": effective take-profit level reached
  • "stop_loss": effective stop-loss level reached
  • "time_expired": position exceeded minuteEstimatedTime
  • "closed": closed by user (closePending) or because the order is no longer open on the exchange

Always undefined when action === "opened".

currentPrice: number

Current market price of the symbol at the time of the event. For "opened" this is the effective entry (priceOpen); for "closed" the close price.

Complete pending signal row data in public form. Contains all signal information: id, position, priceOpen, priceTakeProfit, priceStopLoss, effective entry / trailing SL/TP, PnL, etc.

exchangeName: string

Exchange name where this pending signal lives.

frameName: string

Frame name (timeframe / date range) for the run. Empty string in live mode. Same value as the signal's frameName (data.frameName).

strategyName: string

Strategy name that owns this pending signal.

symbol: string

Trading pair symbol (e.g., "BTCUSDT"). Identifies which market this event belongs to.

timestamp: number

Event timestamp in milliseconds since Unix epoch.

Timing semantics:

  • Live mode: when.getTime() at the moment of the event
  • Backtest mode: candle.timestamp of the candle being processed