Function createSignalState

  • Creates a bound [getState, setState] tuple scoped to a bucket and initial value.

    Both returned functions resolve the active pending or scheduled signal and the backtest/live flag automatically from execution context — no signalId argument required.

    Automatically detects backtest/live mode from execution context.

    Intended for LLM-driven capitulation strategies that accumulate per-trade metrics (e.g. peakPercent, minutesOpen) across onActivePing ticks. Profitable trades endure -0.5–2.5% drawdown and reach peak 2–3%+. SL trades show peak < 0.15% (Feb08, Feb13) or never go positive (Feb25). Rule: if minutesOpen >= N and peakPercent < threshold (e.g. 0.3%) — exit.

    Type Parameters

    • Value extends object = object

    Parameters

    • params: IStateParams<Value>
      • bucketName

        Logical namespace for grouping state buckets within a signal

      • initialValue

        Default value when no persisted state exists

    Returns SignalStateTuple<Value>

    Tuple [getState, setState] bound to the bucket and initial value

    import { createSignalState } from "backtest-kit";

    const [getTradeState, setTradeState] = createSignalState({
    bucketName: "trade",
    initialValue: { peakPercent: 0, minutesOpen: 0 },
    });

    // in onActivePing:
    await setTradeState((s) => ({
    peakPercent: Math.max(s.peakPercent, currentUnrealisedPercent),
    minutesOpen: s.minutesOpen + 1,
    }));
    const { peakPercent, minutesOpen } = await getTradeState();
    if (minutesOpen >= 15 && peakPercent < 0.3) await commitMarketClose(symbol);