AI and LLM Integration for Trading Signal Generation
Integrate LLMs from 11 providers into your trading strategies using @backtest-kit/ollama, with structured output enforcement, token rotation, and trading-specific context injection.
Use this file to discover all available pages before exploring further.
Backtest Kit has first-class support for LLM-powered trading strategies. Every provider integration, structured output schema, and context injection pattern is designed to slot directly into a getSignal function — meaning your LLM runs in the same backtest/live duality as any other strategy, with automatic look-ahead bias protection, the same VWAP exits, and the same crash-safe persistence. The result is a reproducible audit trail: you can replay a backtest and watch the exact conversation that produced every signal.
agent-swarm-kit provides the addOutline, json, and commitPrompt primitives used for structured output enforcement. @backtest-kit/ollama wraps 11 LLM providers into a unified HOF API.
getCandles automatically respects the current backtest or live temporal context via Node.js AsyncLocalStorage — there is no risk of look-ahead bias regardless of which timeframe you request.
@backtest-kit/ollama uses agent-swarm-kit’s outline system to enforce a typed JSON schema on every LLM response. Malformed responses are automatically retried.
For Ollama and other providers that support multiple API keys, pass an array to enable automatic rotation. When the active key hits a rate limit, the wrapper rotates to the next key in the array:
The Memory persistence adapter stores conversation history across ticks. This is useful for strategies that want the LLM to remember previous reasoning or market summaries.
import { getMemoryData, setMemoryData } from 'backtest-kit';// Load previous contextconst history = await getMemoryData('market-context', signal.id) ?? [];// Append new messages and pass to LLMconst messages = [...history, ...newMessages];const result = await json(messages);// Save updated context for the next tickawait setMemoryData('market-context', signal.id, messages.slice(-20));
The Memory adapter supports soft delete — history is logically removed without physical deletion, preserving the audit trail.
The Session adapter caches expensive indicator calculations between ticks. This prevents recomputing the same 50-indicator bundle on every 1-minute tick when your strategy only runs every 5 minutes.
import { getSessionData, setSessionData } from 'backtest-kit';// Check cache firstconst cached = await getSessionData('indicators', symbol);if (cached) return cached;// Compute indicators (expensive)const indicators = await computeMultiTimeframeIndicators(symbol);// Cache for the duration of the current sessionawait setSessionData('indicators', symbol, indicators);return indicators;
Use @backtest-kit/signals to automatically compute 50+ technical indicators
across four timeframes (1m, 15m, 30m, 1h) and inject the results as
formatted Markdown into your LLM message context. This eliminates manual
indicator calculation in getSignal and produces context that LLMs parse
more reliably than raw OHLCV numbers.
npm install @backtest-kit/signals backtest-kit
The package handles RSI, MACD, Bollinger Bands, Stochastic, ADX, ATR, CCI,
Fibonacci levels, support/resistance, and order book analysis — all with
intelligent per-timeframe TTL caching.
LLM strategies often need to fetch external data — news, funding rates, on-chain signals — on a schedule rather than on every tick. Backtest Kit’s built-in Cron scheduler runs in virtual time, so the same Cron.register call works in both backtest and live modes.
import { Cron, Backtest } from 'backtest-kit';// Global hourly fetch — fires once per virtual hour across all parallel backtests.// Use this to fetch news, macro data, or Telegram signals into MongoDB before// the strategy reads them on the next tick.Cron.register({ name: 'fetch-news', interval: '1h', handler: async ({ symbol, when, backtest }) => { await fetchNewsToMongo(when); },});// Fire-once warm-up — runs exactly once on the first tick, then never again// (until Cron.clear() or re-registration). Use to pre-warm LLM context or// pull the full signal history for a backtest frame.Cron.register({ name: 'warm-cache', // No interval → fire-once handler: async ({ symbol, when, backtest }) => { await warmupLLMContext(); },});// Wire Cron to the engine once at startup — must be called before Backtest.background().Cron.enable();for (const symbol of ['BTCUSDT', 'ETHUSDT', 'SOLUSDT']) { Backtest.background(symbol, { strategyName, exchangeName, frameName });}
A global job (symbols omitted) fires once per virtual boundary across all parallel backtests — no double-fires on expensive fetches. A fan-out job (symbols: ['BTC', 'ETH']) fires once per boundary per whitelisted symbol. See the Multi-Symbol Parallel guide for coordination details.