@backtest-kit/signals
v17.0.0
Published
Technical analysis and trading signal generation library for AI-powered trading systems. Computes 50+ indicators across 4 timeframes and generates markdown reports for LLM consumption.
Maintainers
Readme
📊 @backtest-kit/signals
Multi-timeframe technical analysis for AI trading on backtest-kit. Computes 50+ indicators across four timeframes plus order-book depth, and emits LLM-ready markdown reports — drop the whole market context into an LLM prompt in one call.

📚 Docs · 🌟 Reference implementation · 🐙 GitHub
npm install @backtest-kit/signals backtest-kitWhy
An LLM trading strategy is only as good as the market context you hand it. Computing 50+ indicators across four timeframes, formatting order-book depth, and laying it all out as clean markdown — by hand, every tick — is the unglamorous 200 lines that decides signal quality. This package is that work, pre-computed, cached, and synchronized with backtest-kit's timeline: one commitHistorySetup(symbol, messages) appends order book + candle history + indicators for 1m/15m/30m/1h to your LLM message array.
- 📈 Four synchronized timeframes — MicroTerm 1m · ShortTerm 15m · SwingTerm 30m · LongTerm 1h.
- 🎯 50+ indicators — RSI, MACD, Bollinger, Stochastic, ADX, ATR, CCI, Fibonacci, support/resistance, squeeze, volume trend.
- 📊 Order-book depth — best bid/ask, spread, top-20 levels, liquidity imbalance.
- 🤖 LLM-ready markdown — formatted tables for context injection.
- ⚡ Cached — per-timeframe TTL; cache cleared on error.
- 📦 Zero config — works out of the box on the engine's temporal context.
Quick start — one call
import { commitHistorySetup } from '@backtest-kit/signals';
const messages = [];
await commitHistorySetup('BTCUSDT', messages);
// messages now hold: order book + 1m/15m/30m/1h candle history
// + indicators for all 4 timeframes + system context (symbol, price, timestamp)
const signal = await llm(messages);import { v4 as uuid } from 'uuid';
import { addStrategy, dumpSignal } from 'backtest-kit';
import { commitHistorySetup } from '@backtest-kit/signals';
import { json } from './utils/json.mjs'; // your LLM wrapper
addStrategy({
strategyName: 'llm-strategy', interval: '5m', riskName: 'demo',
getSignal: async (symbol) => {
const messages = [{ role: 'system', content: 'You are a trading bot. Analyze the indicators and generate a signal.' }];
await commitHistorySetup(symbol, messages);
messages.push({ role: 'user', content: [
'Based on the technical analysis above, generate a trading signal.',
'Use position: "wait" if signals are unclear or contradictory.',
'Return JSON: { position: "long"|"short"|"wait", priceTakeProfit: number, priceStopLoss: number }',
].join('\n') });
const resultId = uuid();
const signal = await json(messages);
await dumpSignal(resultId, messages, signal); // archive for debugging
return { ...signal, id: resultId };
},
});Granular control
Prefer to choose exactly what goes into the prompt? Call the individual report functions — each appends one markdown section to messages.
import {
commitBookDataReport, // order book: bids/asks, spread, imbalance
commitOneMinuteHistory, commitFifteenMinuteHistory, // candle histories (last 15 / 8 …)
commitThirtyMinuteHistory, commitHourHistory,
commitMicroTermMath, commitShortTermMath, // indicator tables per timeframe
commitSwingTermMath, commitLongTermMath,
} from '@backtest-kit/signals';
const messages = [];
await commitBookDataReport('BTCUSDT', messages);
await commitOneMinuteHistory('BTCUSDT', messages);
await commitMicroTermMath('BTCUSDT', messages);
// …add only the sections you want, then call your LLMcommitHistorySetup is simply the orchestrator that runs all of these in the right order.
What each timeframe computes
| Timeframe | Candles | Indicators | Use case | |-----------|---------|------------|----------| | MicroTerm (1m) | 60 | RSI(9,14), MACD(8,21,5), Stochastic, ADX(9), Bollinger(8,2), ATR, CCI, Volume, Squeeze | Scalping, ultra-short entries | | ShortTerm (15m) | 144 | RSI(9), MACD(8,21,5), Stochastic(5,3,3), ADX(14), Bollinger(10,2), Fibonacci | Day trading | | SwingTerm (30m) | 96 | RSI(14), MACD(12,26,9), Stochastic(14,3,3), Bollinger(20,2), Support/Resistance | Swing trading | | LongTerm (1h) | 100 | RSI(14), MACD(12,26,9), ADX(14), Bollinger(20,2), SMA(50), DEMA, WMA, Volume Trend | Trend analysis |
Order book — symbol, best bid/ask, mid price, spread, depth imbalance ((bid_vol − ask_vol)/(bid_vol + ask_vol), + = buy pressure), and top-20 bid/ask levels with % of total.
Candle history — per-candle table: timestamp, OHLC, volume, volatility, body size.
Indicators — a wide per-bar table; e.g. MicroTerm columns: Price, RSI(9), RSI(14), MACD, Signal, Histogram, Stoch %K/%D, ADX, +DI, −DI, BB Upper/Middle/Lower, ATR(5/9), CCI(9), Volume, Vol Trend, Momentum, ROC, Support, Resistance, Squeeze, Pressure — followed by a Data Sources note listing every period used.
Cache TTL (cleared on error): 1m data → 1 min · 15m → 5 min · 30m → 15 min · 1h → 30 min · order book → 5 min.
- Support/Resistance — MicroTerm/SwingTerm look back N candles for significant highs/lows (±0.3% threshold); LongTerm uses a 4-candle pivot method.
- Fibonacci — levels 0 / 23.6 / 38.2 / 50 / 61.8 / 78.6 / 100 %, extensions 127.2 / 161.8 / 261.8 %; nearest level to price within 1.5% tolerance.
- Volume — MicroTerm: SMA(5) with increasing/decreasing/stable trend (±20%); LongTerm: 6-candle average (±10%).
- Order-book imbalance —
(bid − ask)/(bid + ask), positive = buy pressure.
import { setLogger } from '@backtest-kit/signals';
setLogger({ log: console.log, debug: console.debug, info: console.info, warn: console.warn });Why not compute indicators yourself?
// ❌ Manual — 40+ indicators, formatting, caching, all by hand
const candles = await getCandles('BTCUSDT', '1m', 60);
const rsi = calculateRSI(candles, 14);
const macd = calculateMACD(candles, 12, 26, 9);
const bb = calculateBollingerBands(candles, 20, 2);
// …and the markdown formatting, and the cache
messages.push({ role: 'user', content: formatToMarkdown(rsi, macd, bb /* … */) });
// ✅ With signals
await commitHistorySetup('BTCUSDT', messages);Pre-computed, cached, optimized · 50+ indicators × 4 timeframes · LLM-ready markdown · synchronized with the backtest timeline · validation & error handling built in.
API reference
| Export | Description |
|--------|-------------|
| commitHistorySetup(symbol, messages) | Orchestrator — appends order book + all candle histories + all indicators + context |
| commitBookDataReport(symbol, messages) | Order-book depth & imbalance section |
| commitOneMinuteHistory / commitFifteenMinuteHistory / commitThirtyMinuteHistory / commitHourHistory | Candle-history sections per timeframe |
| commitMicroTermMath / commitShortTermMath / commitSwingTermMath / commitLongTermMath | Indicator-table sections (1m / 15m / 30m / 1h) |
| setLogger(logger) | Replace the default no-op logger |
| lib | Internal IoC service container (advanced use) |
function/history.function.ts— the fourcommit*Historyfunctions.function/math.function.ts— the fourcommit*Mathfunctions.function/other.function.ts—commitBookDataReport+commitHistorySetup.tools/setup.tool.ts—setLogger.contract/{History,ReportFn}.contract.ts— report-function contracts.interfaces/Logger.interface.ts.lib/IoC:core/{di,provide,types},services/common/LoggerService,services/history/{One,Fifteen,Thirty}MinuteCandleHistoryService+HourCandleHistoryService,services/math/{MicroTerm,ShortTerm,SwingTerm,LongTerm}MathService+BookDataMathService(the math services are the package's bulk — 32–45 KB each). Every export maps to one of these; nothing insrc/is undocumented.
🤝 Contribute
Fork / PR on GitHub.
📜 License
MIT © tripolskypetr
