Event listeners are the primary way to react to strategy events and control position management in Backtest Kit. They decouple your observation logic from your strategy logic: a strategy emits events as it runs, and any number of listeners can react to those events independently. All listener callbacks are wrapped withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/backtest-kit/backtest-kit-docs/llms.txt
Use this file to discover all available pages before exploring further.
queued from functools-kit, ensuring sequential async execution — your callback for event N completes before event N+1 is delivered, regardless of how long it takes.
Each listen* function returns an unsubscribe function. Call it to stop receiving events.
Signal Lifecycle Listeners
These listeners fire for every signal tick result — every state transition in the idle → opened → active → closed lifecycle.listenSignal(callback)
Subscribes to all signal events from both backtest and live runs.
Called for every tick result across all symbols and strategies, in both backtest and live mode.
listenSignalBacktest(callback)
Subscribes only to events emitted during backtest runs. Events from Live.background() are not delivered.
listenSignalLive(callback)
Subscribes only to events emitted during live trading runs. Events from Backtest.background() are not delivered.
listenSignalOnce(filterFn, callback)
Fires exactly once when the first event matching filterFn is received. Unsubscribes automatically after the first match.
Predicate function. The callback only fires when this returns
true.Executed exactly once on the first matching event.
listenSignalBacktestOnce(filterFn, callback) / listenSignalLiveOnce(filterFn, callback)
Same as listenSignalOnce but scoped to backtest-only or live-only events respectively.
Position Ping Listeners
Ping listeners fire on a per-minute heartbeat while a signal is in a specific state. They are the primary hook for DCA logic, partial profit-taking, trailing stop management, and breakeven adjustments.listenActivePing(callback)
Fires on every tick while a position is active (open, monitoring TP/SL). Use this for ongoing position management logic.
Receives an
ActivePingContract with the following fields:symbol— trading paircurrentPrice— VWAP at the time of the pingdata— the full active signal row (ISignalRow)strategyName,exchangeName,frameNamebacktest—trueduring backtestingtimestamp— ping timestamp in milliseconds
listenIdlePing(callback)
Fires on every tick when no position is active for the given symbol/strategy combination. Use for pre-signal analysis, warm-up logic, or running idle checks.
Receives an
IdlePingContract with symbol, currentPrice, strategyName, exchangeName, frameName, backtest, and timestamp.listenSchedulePing(callback)
Fires on every tick while a signal is in the scheduled state — waiting for the price to reach priceOpen before the position opens. Use for monitoring limit-entry orders or cancelling stale scheduled signals.
Receives a
SchedulePingContract with symbol, currentPrice, data (the scheduled signal), strategyName, exchangeName, frameName, backtest, and timestamp.Once Variants for Ping Listeners
All three ping listeners haveOnce variants that fire exactly once when the filter condition is met:
System Event Listeners
listenError(callback)
Fires when a non-fatal error occurs during background execution (e.g. a failed getCandles call, a rejected signal due to validation, or a failed commit retry). The strategy continues running after these errors.
Receives the Error object. Not async — errors in this callback are not caught.
listenRisk(callback)
Fires when a signal is rejected by a risk validation. Useful for monitoring your risk rules in production, alerting when trades are being blocked, or auditing the rejection reasons.
Receives a
RiskContract with symbol, currentSignal, strategyName, exchangeName, frameName, currentPrice, activePositionCount, rejectionNote, rejectionId, timestamp, and backtest.listenDone(callback) / listenDoneBacktest(callback) / listenDoneLive(callback)
Fires when a background run completes. For Backtest.background(), this fires after the frame window is exhausted. For Live.background(), this fires after the stop function is called and any open position has closed gracefully.
Receives a
DoneContract with symbol, strategyName, exchangeName, frameName, and backtest.listenDoneOnce(callback) / listenDoneBacktestOnce(filterFn, callback) / listenDoneLiveOnce(filterFn, callback)
Fires exactly once. The BacktestOnce and LiveOnce variants accept a filter predicate.
listenProgress(callback) / listenBacktestProgress(callback)
Fires periodically during a backtest with a progress percentage. Useful for progress bars in CLIs or UI dashboards.
Receives a
ProgressBacktestContract with symbol, strategyName, exchangeName, frameName, totalFrames, processedFrames, and progress (0–100).