backtest-kit 1.10.1 โ†’ 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Petr Tripolsky
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Petr Tripolsky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,259 +1,259 @@
1
- <img src="./assets/triangle.svg" height="105px" align="right">
2
-
3
- # ๐Ÿงฟ Backtest Kit
4
-
5
- > A TypeScript framework for backtesting and live trading strategies on multi-asset, crypto, forex or [DEX (peer-to-peer marketplace)](https://en.wikipedia.org/wiki/Decentralized_finance#Decentralized_exchanges) with crash-safe persistence, signal validation, and AI optimization.
6
-
7
- ![future](./assets/prophet.png)
8
-
9
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/tripolskypetr/backtest-kit)
10
- [![npm](https://img.shields.io/npm/v/backtest-kit.svg?style=flat-square)](https://npmjs.org/package/backtest-kit)
11
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue)]()
12
-
13
- Build reliable trading systems: backtest on historical data, deploy live bots with recovery, and optimize strategies using LLMs like Ollama.
14
-
15
- ๐Ÿ“š **[API Reference](https://backtest-kit.github.io/documents/example_02_first_backtest.html)** | ๐ŸŒŸ **[Quick Start](https://github.com/tripolskypetr/backtest-kit/tree/master/demo)** | **๐Ÿ“ฐ [Article](https://backtest-kit.github.io/documents/article_02_second_order_chaos.html)**
16
-
17
- ## โœจ Why Choose Backtest Kit?
18
-
19
- - ๐Ÿš€ **Production-Ready**: Seamless switch between backtest/live modes; identical code across environments.
20
- - ๐Ÿ’พ **Crash-Safe**: Atomic persistence recovers states after crashes, preventing duplicates or losses.
21
- - โœ… **Validation**: Checks signals for TP/SL logic, risk/reward ratios, and portfolio limits.
22
- - ๐Ÿ”„ **Efficient Execution**: Streaming architecture for large datasets; VWAP pricing for realism.
23
- - ๐Ÿค– **AI Integration**: LLM-powered strategy generation (Optimizer) with multi-timeframe analysis.
24
- - ๐Ÿ“Š **Reports & Metrics**: Auto Markdown reports with PNL, Sharpe Ratio, win rate, and more.
25
- - ๐Ÿ›ก๏ธ **Risk Management**: Custom rules for position limits, time windows, and multi-strategy coordination.
26
- - ๐Ÿ”Œ **Pluggable**: Custom data sources (CCXT), persistence (file/Redis), and sizing calculators.
27
- - ๐Ÿงช **Tested**: 300+ unit/integration tests for validation, recovery, and events.
28
- - ๐Ÿ”“ **Self hosted**: Zero dependency on third-party node_modules or platforms; run entirely in your own environment.
29
-
30
- ## ๐Ÿ“‹ Supported Order Types
31
-
32
- - Market/Limit entries
33
- - TP/SL/OCO exits
34
- - Grid with auto-cancel on unmet conditions
35
- - Partial profit/loss levels
36
- - Trailing stop-loss
37
- - Breakeven protection
38
-
39
- ## ๐Ÿš€ Quick Start
40
-
41
- > **Talk is cheap.** Let me show you **the code**
42
- >
43
- > Link to ๐Ÿ‘‰ [the demo app](https://github.com/tripolskypetr/backtest-kit/tree/master/demo) ๐Ÿ‘ˆ
44
-
45
- ### ๐Ÿ“ฆ Installation
46
- ```bash
47
- npm install backtest-kit ccxt ollama uuid
48
- ```
49
-
50
- ### โš™๏ธ Basic Configuration
51
- ```typescript
52
- import { setLogger, setConfig } from 'backtest-kit';
53
-
54
- // Enable logging
55
- setLogger({
56
- log: console.log,
57
- debug: console.debug,
58
- info: console.info,
59
- warn: console.warn,
60
- });
61
-
62
- // Global config (optional)
63
- setConfig({
64
- CC_PERCENT_SLIPPAGE: 0.1, // % slippage
65
- CC_PERCENT_FEE: 0.1, // % fee
66
- CC_SCHEDULE_AWAIT_MINUTES: 120, // Pending signal timeout
67
- });
68
- ```
69
-
70
- ### ๐Ÿ”ง Register Components
71
- ```typescript
72
- import ccxt from 'ccxt';
73
- import { addExchange, addStrategy, addFrame, addRisk } from 'backtest-kit';
74
-
75
- // Exchange (data source)
76
- addExchange({
77
- exchangeName: 'binance',
78
- getCandles: async (symbol, interval, since, limit) => {
79
- const exchange = new ccxt.binance();
80
- const ohlcv = await exchange.fetchOHLCV(symbol, interval, since.getTime(), limit);
81
- return ohlcv.map(([timestamp, open, high, low, close, volume]) => ({ timestamp, open, high, low, close, volume }));
82
- },
83
- formatPrice: (symbol, price) => price.toFixed(2),
84
- formatQuantity: (symbol, quantity) => quantity.toFixed(8),
85
- });
86
-
87
- // Risk profile
88
- addRisk({
89
- riskName: 'demo',
90
- validations: [
91
- // TP at least 1%
92
- ({ pendingSignal, currentPrice }) => {
93
- const { priceOpen = currentPrice, priceTakeProfit, position } = pendingSignal;
94
- const tpDistance = position === 'long' ? ((priceTakeProfit - priceOpen) / priceOpen) * 100 : ((priceOpen - priceTakeProfit) / priceOpen) * 100;
95
- if (tpDistance < 1) throw new Error(`TP too close: ${tpDistance.toFixed(2)}%`);
96
- },
97
- // R/R at least 2:1
98
- ({ pendingSignal, currentPrice }) => {
99
- const { priceOpen = currentPrice, priceTakeProfit, priceStopLoss, position } = pendingSignal;
100
- const reward = position === 'long' ? priceTakeProfit - priceOpen : priceOpen - priceTakeProfit;
101
- const risk = position === 'long' ? priceOpen - priceStopLoss : priceStopLoss - priceOpen;
102
- if (reward / risk < 2) throw new Error('Poor R/R ratio');
103
- },
104
- ],
105
- });
106
-
107
- // Time frame
108
- addFrame({
109
- frameName: '1d-test',
110
- interval: '1m',
111
- startDate: new Date('2025-12-01'),
112
- endDate: new Date('2025-12-02'),
113
- });
114
- ```
115
-
116
- ### ๐Ÿ’ก Example Strategy (with LLM)
117
- ```typescript
118
- import { v4 as uuid } from 'uuid';
119
- import { addStrategy, dumpSignal, getCandles } from 'backtest-kit';
120
- import { json } from './utils/json.mjs'; // LLM wrapper
121
- import { getMessages } from './utils/messages.mjs'; // Market data prep
122
-
123
- addStrategy({
124
- strategyName: 'llm-strategy',
125
- interval: '5m',
126
- riskName: 'demo',
127
- getSignal: async (symbol) => {
128
-
129
- const candles1h = await getCandles(symbol, "1h", 24);
130
- const candles15m = await getCandles(symbol, "15m", 48);
131
- const candles5m = await getCandles(symbol, "5m", 60);
132
- const candles1m = await getCandles(symbol, "1m", 60);
133
-
134
- const messages = await getMessages(symbol, {
135
- candles1h,
136
- candles15m,
137
- candles5m,
138
- candles1m,
139
- }); // Calculate indicators / Fetch news
140
-
141
- const resultId = uuid();
142
- const signal = await json(messages); // LLM generates signal
143
- await dumpSignal(resultId, messages, signal); // Log
144
-
145
- return { ...signal, id: resultId };
146
- },
147
- });
148
- ```
149
-
150
- ### ๐Ÿงช Run Backtest
151
- ```typescript
152
- import { Backtest, listenSignalBacktest, listenDoneBacktest } from 'backtest-kit';
153
-
154
- Backtest.background('BTCUSDT', {
155
- strategyName: 'llm-strategy',
156
- exchangeName: 'binance',
157
- frameName: '1d-test',
158
- });
159
-
160
- listenSignalBacktest((event) => console.log(event));
161
- listenDoneBacktest(async (event) => {
162
- await Backtest.dump(event.symbol, event.strategyName); // Generate report
163
- });
164
- ```
165
-
166
- ### ๐Ÿ“ˆ Run Live Trading
167
- ```typescript
168
- import { Live, listenSignalLive } from 'backtest-kit';
169
-
170
- Live.background('BTCUSDT', {
171
- strategyName: 'llm-strategy',
172
- exchangeName: 'binance', // Use API keys in .env
173
- });
174
-
175
- listenSignalLive((event) => console.log(event));
176
- ```
177
-
178
- ### ๐Ÿ“ก Monitoring & Events
179
-
180
- - Use `listenRisk`, `listenError`, `listenPartialProfit/Loss` for alerts.
181
- - Dump reports: `Backtest.dump()`, `Live.dump()`.
182
-
183
- ## ๐ŸŒ Global Configuration
184
-
185
- Customize via `setConfig()`:
186
-
187
- - `CC_SCHEDULE_AWAIT_MINUTES`: Pending timeout (default: 120).
188
- - `CC_AVG_PRICE_CANDLES_COUNT`: VWAP candles (default: 5).
189
-
190
- ## ๐Ÿ’ป Developer Note
191
-
192
- Backtest Kit is **not a data-processing library** - it is a **time execution engine**. Think of the engine as an **async stream of time**, where your strategy is evaluated step by step.
193
-
194
- ### ๐Ÿ” How getCandles Works
195
-
196
- backtest-kit uses Node.js `AsyncLocalStorage` to automatically provide
197
- temporal time context to your strategies.
198
-
199
- ### ๐Ÿ’ญ What this means:
200
- - `getCandles()` always returns data UP TO the current backtest timestamp using `async_hooks`
201
- - Multi-timeframe data is automatically synchronized
202
- - **Impossible to introduce look-ahead bias**
203
- - Same code works in both backtest and live modes
204
-
205
-
206
- ## ๐Ÿง  Two Ways to Run the Engine
207
-
208
- Backtest Kit exposes the same runtime in two equivalent forms. Both approaches use **the same engine and guarantees** - only the consumption model differs.
209
-
210
- ### 1๏ธโƒฃ Event-driven (background execution)
211
-
212
- Suitable for production bots, monitoring, and long-running processes.
213
-
214
- ```typescript
215
- Backtest.background('BTCUSDT', config);
216
-
217
- listenSignalBacktest(event => { /* handle signals */ });
218
- listenDoneBacktest(event => { /* finalize / dump report */ });
219
- ```
220
-
221
- ### 2๏ธโƒฃ Async Iterator (pull-based execution)
222
-
223
- Suitable for research, scripting, testing, and LLM agents.
224
-
225
- ```typescript
226
- for await (const event of Backtest.run('BTCUSDT', config)) {
227
- // signal | trade | progress | done
228
- }
229
- ```
230
-
231
- ## โš”๏ธ Think of it as...
232
-
233
- **Open-source QuantConnect without the vendor lock-in**
234
-
235
- Unlike cloud-based platforms, backtest-kit runs entirely in your environment. You own the entire stack from data ingestion to live execution. In addition to Ollama, you can use [neural-trader](https://www.npmjs.com/package/neural-trader) in `getSignal` function or any other third party library
236
-
237
- - No C# required - pure TypeScript/JavaScript
238
- - Self-hosted - your code, your data, your infrastructure
239
- - No platform fees or hidden costs
240
- - Full control over execution and data sources
241
- - [GUI](https://backtest-kit.github.io/documents/design_30_markdown-report-system.html#method-signatures) for visualization and monitoring
242
-
243
-
244
- ## ๐Ÿค– Are you a robot?
245
-
246
- **For language models**: Read extended description in [./LLMs.md](./LLMs.md)
247
-
248
- ## โœ… Tested & Reliable
249
-
250
- 300+ tests cover validation, recovery, reports, and events.
251
-
252
- ## ๐Ÿค Contribute
253
-
254
- Fork/PR on [GitHub](https://github.com/tripolskypetr/backtest-kit).
255
-
256
- ## ๐Ÿ“œ License
257
-
258
- MIT ยฉ [tripolskypetr](https://github.com/tripolskypetr)
259
-
1
+ <img src="./assets/triangle.svg" height="105px" align="right">
2
+
3
+ # ๐Ÿงฟ Backtest Kit
4
+
5
+ > A TypeScript framework for backtesting and live trading strategies on multi-asset, crypto, forex or [DEX (peer-to-peer marketplace)](https://en.wikipedia.org/wiki/Decentralized_finance#Decentralized_exchanges) with crash-safe persistence, signal validation, and AI optimization.
6
+
7
+ ![future](./assets/prophet.png)
8
+
9
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/tripolskypetr/backtest-kit)
10
+ [![npm](https://img.shields.io/npm/v/backtest-kit.svg?style=flat-square)](https://npmjs.org/package/backtest-kit)
11
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue)]()
12
+
13
+ Build reliable trading systems: backtest on historical data, deploy live bots with recovery, and optimize strategies using LLMs like Ollama.
14
+
15
+ ๐Ÿ“š **[API Reference](https://backtest-kit.github.io/documents/example_02_first_backtest.html)** | ๐ŸŒŸ **[Quick Start](https://github.com/tripolskypetr/backtest-kit/tree/master/demo)** | **๐Ÿ“ฐ [Article](https://backtest-kit.github.io/documents/article_02_second_order_chaos.html)**
16
+
17
+ ## โœจ Why Choose Backtest Kit?
18
+
19
+ - ๐Ÿš€ **Production-Ready**: Seamless switch between backtest/live modes; identical code across environments.
20
+ - ๐Ÿ’พ **Crash-Safe**: Atomic persistence recovers states after crashes, preventing duplicates or losses.
21
+ - โœ… **Validation**: Checks signals for TP/SL logic, risk/reward ratios, and portfolio limits.
22
+ - ๐Ÿ”„ **Efficient Execution**: Streaming architecture for large datasets; VWAP pricing for realism.
23
+ - ๐Ÿค– **AI Integration**: LLM-powered strategy generation (Optimizer) with multi-timeframe analysis.
24
+ - ๐Ÿ“Š **Reports & Metrics**: Auto Markdown reports with PNL, Sharpe Ratio, win rate, and more.
25
+ - ๐Ÿ›ก๏ธ **Risk Management**: Custom rules for position limits, time windows, and multi-strategy coordination.
26
+ - ๐Ÿ”Œ **Pluggable**: Custom data sources (CCXT), persistence (file/Redis), and sizing calculators.
27
+ - ๐Ÿงช **Tested**: 300+ unit/integration tests for validation, recovery, and events.
28
+ - ๐Ÿ”“ **Self hosted**: Zero dependency on third-party node_modules or platforms; run entirely in your own environment.
29
+
30
+ ## ๐Ÿ“‹ Supported Order Types
31
+
32
+ - Market/Limit entries
33
+ - TP/SL/OCO exits
34
+ - Grid with auto-cancel on unmet conditions
35
+ - Partial profit/loss levels
36
+ - Trailing stop-loss
37
+ - Breakeven protection
38
+
39
+ ## ๐Ÿš€ Quick Start
40
+
41
+ > **Talk is cheap.** Let me show you **the code**
42
+ >
43
+ > Link to ๐Ÿ‘‰ [the demo app](https://github.com/tripolskypetr/backtest-kit/tree/master/demo) ๐Ÿ‘ˆ
44
+
45
+ ### ๐Ÿ“ฆ Installation
46
+ ```bash
47
+ npm install backtest-kit ccxt ollama uuid
48
+ ```
49
+
50
+ ### โš™๏ธ Basic Configuration
51
+ ```typescript
52
+ import { setLogger, setConfig } from 'backtest-kit';
53
+
54
+ // Enable logging
55
+ setLogger({
56
+ log: console.log,
57
+ debug: console.debug,
58
+ info: console.info,
59
+ warn: console.warn,
60
+ });
61
+
62
+ // Global config (optional)
63
+ setConfig({
64
+ CC_PERCENT_SLIPPAGE: 0.1, // % slippage
65
+ CC_PERCENT_FEE: 0.1, // % fee
66
+ CC_SCHEDULE_AWAIT_MINUTES: 120, // Pending signal timeout
67
+ });
68
+ ```
69
+
70
+ ### ๐Ÿ”ง Register Components
71
+ ```typescript
72
+ import ccxt from 'ccxt';
73
+ import { addExchange, addStrategy, addFrame, addRisk } from 'backtest-kit';
74
+
75
+ // Exchange (data source)
76
+ addExchange({
77
+ exchangeName: 'binance',
78
+ getCandles: async (symbol, interval, since, limit) => {
79
+ const exchange = new ccxt.binance();
80
+ const ohlcv = await exchange.fetchOHLCV(symbol, interval, since.getTime(), limit);
81
+ return ohlcv.map(([timestamp, open, high, low, close, volume]) => ({ timestamp, open, high, low, close, volume }));
82
+ },
83
+ formatPrice: (symbol, price) => price.toFixed(2),
84
+ formatQuantity: (symbol, quantity) => quantity.toFixed(8),
85
+ });
86
+
87
+ // Risk profile
88
+ addRisk({
89
+ riskName: 'demo',
90
+ validations: [
91
+ // TP at least 1%
92
+ ({ pendingSignal, currentPrice }) => {
93
+ const { priceOpen = currentPrice, priceTakeProfit, position } = pendingSignal;
94
+ const tpDistance = position === 'long' ? ((priceTakeProfit - priceOpen) / priceOpen) * 100 : ((priceOpen - priceTakeProfit) / priceOpen) * 100;
95
+ if (tpDistance < 1) throw new Error(`TP too close: ${tpDistance.toFixed(2)}%`);
96
+ },
97
+ // R/R at least 2:1
98
+ ({ pendingSignal, currentPrice }) => {
99
+ const { priceOpen = currentPrice, priceTakeProfit, priceStopLoss, position } = pendingSignal;
100
+ const reward = position === 'long' ? priceTakeProfit - priceOpen : priceOpen - priceTakeProfit;
101
+ const risk = position === 'long' ? priceOpen - priceStopLoss : priceStopLoss - priceOpen;
102
+ if (reward / risk < 2) throw new Error('Poor R/R ratio');
103
+ },
104
+ ],
105
+ });
106
+
107
+ // Time frame
108
+ addFrame({
109
+ frameName: '1d-test',
110
+ interval: '1m',
111
+ startDate: new Date('2025-12-01'),
112
+ endDate: new Date('2025-12-02'),
113
+ });
114
+ ```
115
+
116
+ ### ๐Ÿ’ก Example Strategy (with LLM)
117
+ ```typescript
118
+ import { v4 as uuid } from 'uuid';
119
+ import { addStrategy, dumpSignal, getCandles } from 'backtest-kit';
120
+ import { json } from './utils/json.mjs'; // LLM wrapper
121
+ import { getMessages } from './utils/messages.mjs'; // Market data prep
122
+
123
+ addStrategy({
124
+ strategyName: 'llm-strategy',
125
+ interval: '5m',
126
+ riskName: 'demo',
127
+ getSignal: async (symbol) => {
128
+
129
+ const candles1h = await getCandles(symbol, "1h", 24);
130
+ const candles15m = await getCandles(symbol, "15m", 48);
131
+ const candles5m = await getCandles(symbol, "5m", 60);
132
+ const candles1m = await getCandles(symbol, "1m", 60);
133
+
134
+ const messages = await getMessages(symbol, {
135
+ candles1h,
136
+ candles15m,
137
+ candles5m,
138
+ candles1m,
139
+ }); // Calculate indicators / Fetch news
140
+
141
+ const resultId = uuid();
142
+ const signal = await json(messages); // LLM generates signal
143
+ await dumpSignal(resultId, messages, signal); // Log
144
+
145
+ return { ...signal, id: resultId };
146
+ },
147
+ });
148
+ ```
149
+
150
+ ### ๐Ÿงช Run Backtest
151
+ ```typescript
152
+ import { Backtest, listenSignalBacktest, listenDoneBacktest } from 'backtest-kit';
153
+
154
+ Backtest.background('BTCUSDT', {
155
+ strategyName: 'llm-strategy',
156
+ exchangeName: 'binance',
157
+ frameName: '1d-test',
158
+ });
159
+
160
+ listenSignalBacktest((event) => console.log(event));
161
+ listenDoneBacktest(async (event) => {
162
+ await Backtest.dump(event.symbol, event.strategyName); // Generate report
163
+ });
164
+ ```
165
+
166
+ ### ๐Ÿ“ˆ Run Live Trading
167
+ ```typescript
168
+ import { Live, listenSignalLive } from 'backtest-kit';
169
+
170
+ Live.background('BTCUSDT', {
171
+ strategyName: 'llm-strategy',
172
+ exchangeName: 'binance', // Use API keys in .env
173
+ });
174
+
175
+ listenSignalLive((event) => console.log(event));
176
+ ```
177
+
178
+ ### ๐Ÿ“ก Monitoring & Events
179
+
180
+ - Use `listenRisk`, `listenError`, `listenPartialProfit/Loss` for alerts.
181
+ - Dump reports: `Backtest.dump()`, `Live.dump()`.
182
+
183
+ ## ๐ŸŒ Global Configuration
184
+
185
+ Customize via `setConfig()`:
186
+
187
+ - `CC_SCHEDULE_AWAIT_MINUTES`: Pending timeout (default: 120).
188
+ - `CC_AVG_PRICE_CANDLES_COUNT`: VWAP candles (default: 5).
189
+
190
+ ## ๐Ÿ’ป Developer Note
191
+
192
+ Backtest Kit is **not a data-processing library** - it is a **time execution engine**. Think of the engine as an **async stream of time**, where your strategy is evaluated step by step.
193
+
194
+ ### ๐Ÿ” How getCandles Works
195
+
196
+ backtest-kit uses Node.js `AsyncLocalStorage` to automatically provide
197
+ temporal time context to your strategies.
198
+
199
+ ### ๐Ÿ’ญ What this means:
200
+ - `getCandles()` always returns data UP TO the current backtest timestamp using `async_hooks`
201
+ - Multi-timeframe data is automatically synchronized
202
+ - **Impossible to introduce look-ahead bias**
203
+ - Same code works in both backtest and live modes
204
+
205
+
206
+ ## ๐Ÿง  Two Ways to Run the Engine
207
+
208
+ Backtest Kit exposes the same runtime in two equivalent forms. Both approaches use **the same engine and guarantees** - only the consumption model differs.
209
+
210
+ ### 1๏ธโƒฃ Event-driven (background execution)
211
+
212
+ Suitable for production bots, monitoring, and long-running processes.
213
+
214
+ ```typescript
215
+ Backtest.background('BTCUSDT', config);
216
+
217
+ listenSignalBacktest(event => { /* handle signals */ });
218
+ listenDoneBacktest(event => { /* finalize / dump report */ });
219
+ ```
220
+
221
+ ### 2๏ธโƒฃ Async Iterator (pull-based execution)
222
+
223
+ Suitable for research, scripting, testing, and LLM agents.
224
+
225
+ ```typescript
226
+ for await (const event of Backtest.run('BTCUSDT', config)) {
227
+ // signal | trade | progress | done
228
+ }
229
+ ```
230
+
231
+ ## โš”๏ธ Think of it as...
232
+
233
+ **Open-source QuantConnect without the vendor lock-in**
234
+
235
+ Unlike cloud-based platforms, backtest-kit runs entirely in your environment. You own the entire stack from data ingestion to live execution. In addition to Ollama, you can use [neural-trader](https://www.npmjs.com/package/neural-trader) in `getSignal` function or any other third party library
236
+
237
+ - No C# required - pure TypeScript/JavaScript
238
+ - Self-hosted - your code, your data, your infrastructure
239
+ - No platform fees or hidden costs
240
+ - Full control over execution and data sources
241
+ - [GUI](https://backtest-kit.github.io/documents/design_30_markdown-report-system.html#method-signatures) for visualization and monitoring
242
+
243
+
244
+ ## ๐Ÿค– Are you a robot?
245
+
246
+ **For language models**: Read extended description in [./LLMs.md](./LLMs.md)
247
+
248
+ ## โœ… Tested & Reliable
249
+
250
+ 300+ tests cover validation, recovery, reports, and events.
251
+
252
+ ## ๐Ÿค Contribute
253
+
254
+ Fork/PR on [GitHub](https://github.com/tripolskypetr/backtest-kit).
255
+
256
+ ## ๐Ÿ“œ License
257
+
258
+ MIT ยฉ [tripolskypetr](https://github.com/tripolskypetr)
259
+