Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theonetrade/backtest-kit/llms.txt

Use this file to discover all available pages before exploring further.

The Live singleton runs trading strategies against real-time market data. It is the production counterpart of Backtest and exposes an identical API surface—the same run(), background(), getData(), getReport(), dump(), and clear() methods—so strategy code works in both modes without changes. Live mode adds crash-safe persistence: signal state is written atomically to disk on every mutation, and the engine restores open positions automatically on process restart.

Key Differences from Backtest

BacktestLive
Time sourceFrame timestampsnew Date() (real clock)
Loop typeFinite (frame start → end)Infinite while(true)
PersistenceOptionalAlways enabled (crash-safe)
frameName requiredYesNo (omit or pass "")
Candle sourceHistorical cacheExchange API in real time

run()

Live.run(
  symbol: string,
  context: { strategyName: string; exchangeName: string }
): AsyncGenerator<
  IStrategyTickResultOpened | IStrategyTickResultClosed | IStrategyTickResultCancelled
>
Returns an infinite async generator. The generator never terminates on its own—use break, return, or the stop function to end it. On each iteration, the engine fetches the current VWAP price, evaluates the strategy, and yields results when a position opens or closes. Idle and active ticks are consumed internally.
import { Live } from 'backtest-kit';

for await (const result of Live.run('BTCUSDT', {
  strategyName: 'rsi-trend',
  exchangeName: 'binance',
})) {
  if (result.action === 'opened') {
    console.log(`Position opened: ${result.signal.position} @ ${result.signal.priceOpen}`);
  }
  if (result.action === 'closed') {
    console.log(`Closed with reason: ${result.closeReason}`);
    console.log(`PNL: ${result.pnl.pnlPercentage.toFixed(2)}%`);
  }
}

background()

Live.background(
  symbol: string,
  context: { strategyName: string; exchangeName: string }
): () => void
Event-driven background execution. Returns a stop function. Results are consumed internally; subscribe to global emitters to observe them. This is the recommended pattern for production deployments.
import { Live, listenSignalLive, listenDoneLive } from 'backtest-kit';

process.on('SIGINT', () => {
  console.log('Graceful shutdown initiated...');
  stop(); // stops new signals; current position closes naturally
});

const stop = Live.background('BTCUSDT', {
  strategyName: 'rsi-trend',
  exchangeName: 'binance',
});

listenSignalLive((event) => {
  if (event.action === 'opened') {
    console.log(`[LIVE] Opened ${event.signal.position} on ${event.symbol}`);
  }
  if (event.action === 'closed') {
    console.log(`[LIVE] Closed ${event.symbol}: ${event.pnl.pnlPercentage.toFixed(2)}%`);
  }
});

listenDoneLive(async (event) => {
  await Live.dump(event.symbol, {
    strategyName: event.strategyName,
    exchangeName: event.exchangeName,
  });
});

getData()

Live.getData(
  symbol: string,
  context: { strategyName: string; exchangeName: string }
): Promise<LiveStatisticsModel>
Returns aggregated statistics from all closed signals seen during this live session. Key fields on LiveStatisticsModel:
FieldDescription
eventListAll tick events (idle, opened, active, closed).
totalEventsTotal event count including idle ticks.
totalClosedCount of fully closed signals only.
winRateWin rate percentage (0–100), null if unsafe.
avgPnlAverage PNL per closed signal, null if unsafe.
totalPnlCumulative PNL, null if unsafe.
sharpeRatioRisk-adjusted return, null if unsafe.
sortinoRatioDownside deviation Sharpe variant.

getReport()

Live.getReport(
  symbol: string,
  context: { strategyName: string; exchangeName: string }
): Promise<string>
Returns a Markdown-formatted report string with all live trading events and performance statistics.

dump()

Live.dump(
  symbol: string,
  context: { strategyName: string; exchangeName: string },
  path?: string
): Promise<void>
Writes the Markdown report to disk. Default output path: ./dump/live/.

clear()

Live.clear(
  symbol: string,
  context: { strategyName: string; exchangeName: string }
): Promise<void>
Clears accumulated live trading data for the specified context.

Context Object

strategyName
string
required
Name of a registered strategy schema.
exchangeName
string
required
Name of a registered exchange schema.

Crash Recovery

When a live bot restarts after a crash, ClientStrategy.waitForInit() automatically loads the last persisted signal state from disk. If a position was open when the process died, the engine resumes monitoring it—no manual intervention required. The persistence layer uses atomic writes (writeFileAtomic) to prevent partial or corrupted state files.
Pair Live with Broker.enable() to connect exchange order execution. When a broker adapter is registered, every position open, close, partial, trailing-stop, and breakeven operation is forwarded to the adapter before the internal state mutates. If the adapter throws (e.g., the exchange rejects the order), the mutation is skipped and the framework retries automatically on the next tick.

Build docs developers (and LLMs) love