@backtest-kit/cli 9.6.0 → 9.7.0

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.
Files changed (34) hide show
  1. package/README.md +1854 -1738
  2. package/build/index.cjs +268 -204
  3. package/build/index.mjs +268 -204
  4. package/config/notification.config.mjs +13 -13
  5. package/config/symbol.config.mjs +460 -460
  6. package/docker/.env.example +2 -2
  7. package/docker/README.md +1 -0
  8. package/docker/content/feb_2026/feb_2026.strategy.ts +11 -11
  9. package/docker/content/feb_2026/modules/backtest.module.ts +83 -83
  10. package/docker/docker-compose.yaml +46 -46
  11. package/docker/package.json +38 -38
  12. package/docker/tsconfig.json +36 -36
  13. package/package.json +126 -126
  14. package/template/average-buy.mustache +22 -22
  15. package/template/breakeven.mustache +21 -21
  16. package/template/cancel-scheduled.mustache +14 -14
  17. package/template/cancelled.mustache +21 -21
  18. package/template/close-pending.mustache +16 -16
  19. package/template/closed.mustache +23 -23
  20. package/template/opened.mustache +22 -22
  21. package/template/partial-loss.mustache +22 -22
  22. package/template/partial-profit.mustache +22 -22
  23. package/template/project/README.md +1 -0
  24. package/template/project/config/symbol.config.ts +460 -460
  25. package/template/project/package.mustache +28 -28
  26. package/template/risk.mustache +19 -19
  27. package/template/scheduled.mustache +22 -22
  28. package/template/signal-close.mustache +22 -22
  29. package/template/signal-info.mustache +20 -20
  30. package/template/signal-open.mustache +22 -22
  31. package/template/source/CLAUDE.md +160 -160
  32. package/template/trailing-stop.mustache +21 -21
  33. package/template/trailing-take.mustache +21 -21
  34. package/types.d.ts +1 -6
@@ -1,2 +1,2 @@
1
- CC_REDIS_HOST=host.docker.internal
2
- CC_MONGO_CONNECTION_STRING=mongodb://host.docker.internal:27017/backtest-kit?wtimeoutMS=15000
1
+ CC_REDIS_HOST=host.docker.internal
2
+ CC_MONGO_CONNECTION_STRING=mongodb://host.docker.internal:27017/backtest-kit?wtimeoutMS=15000
package/docker/README.md CHANGED
@@ -19,6 +19,7 @@ A self-contained Docker workspace for running [backtest-kit](https://github.com/
19
19
  | Strategy | Ticker | Period | Signal source | Net PNL | Sharpe |
20
20
  |---|---|---|---|---|---|
21
21
  | [DOTUSDT Feb 2021 — Python EMA Crossover](https://github.com/tripolskypetr/backtest-kit/tree/master/example/content/feb_2021.strategy) | DOTUSDT | Feb 2021 | Python EMA(9)/EMA(21) crossover via WebAssembly | **+5.52%** | **0.09** |
22
+ | [BTCUSDT Apr 2024 — Polymarket Δprob](https://github.com/tripolskypetr/backtest-kit/tree/master/example/content/apr_2024.strategy) | BTCUSDT | Apr 2024 | Polymarket "yes" probability shifts on crypto-prices markets | **+0.63%** | **0.055** |
22
23
  | [BTCUSDT Oct 2021 — TensorFlow Neural Network](https://github.com/tripolskypetr/backtest-kit/tree/master/example/content/oct_2021.strategy) | BTCUSDT | Oct 2021 | TensorFlow NN predicting next candle close | **+18.26%** | **0.31** |
23
24
  | [BTCUSDT Dec 2025 — Pine Script Range Breakout](https://github.com/tripolskypetr/backtest-kit/tree/master/example/content/dec_2025.strategy) | BTCUSDT | Dec 2025 | Pine Script BB + range detector + volume spike | **+2.40%** | **0.06** |
24
25
  | [TRXUSDT Jan 2026 — Liquidity Harvesting](https://github.com/tripolskypetr/backtest-kit/tree/master/example/content//jan_2026.strategy) | TRXUSDT | Jan 2026 | Telegram channel signals (inverted) | **+8.58%** | **1.14** |
@@ -1,11 +1,11 @@
1
- import {
2
- addStrategySchema,
3
- } from "backtest-kit";
4
-
5
- addStrategySchema({
6
- strategyName: "feb_2026_strategy",
7
- getSignal: async (_symbol, when) => {
8
- console.log(when);
9
- return null;
10
- },
11
- });
1
+ import {
2
+ addStrategySchema,
3
+ } from "backtest-kit";
4
+
5
+ addStrategySchema({
6
+ strategyName: "feb_2026_strategy",
7
+ getSignal: async (_symbol, when) => {
8
+ console.log(when);
9
+ return null;
10
+ },
11
+ });
@@ -1,83 +1,83 @@
1
- import { addExchangeSchema, addFrameSchema, roundTicks } from "backtest-kit";
2
- import { singleshot } from "functools-kit";
3
- import ccxt from "ccxt";
4
-
5
- const getExchange = singleshot(async () => {
6
- const exchange = new ccxt.binance({
7
- options: {
8
- defaultType: "spot",
9
- adjustForTimeDifference: true,
10
- recvWindow: 60000,
11
- },
12
- enableRateLimit: true,
13
- });
14
- await exchange.loadMarkets();
15
- return exchange;
16
- });
17
-
18
- addExchangeSchema({
19
- exchangeName: "ccxt-exchange",
20
- getCandles: async (symbol, interval, since, limit) => {
21
- const exchange = await getExchange();
22
- const candles = await exchange.fetchOHLCV(
23
- symbol,
24
- interval,
25
- since.getTime(),
26
- limit,
27
- );
28
- return candles.map(([timestamp, open, high, low, close, volume]) => ({
29
- timestamp,
30
- open,
31
- high,
32
- low,
33
- close,
34
- volume,
35
- }));
36
- },
37
- getOrderBook: async (symbol, depth, _from, _to, backtest) => {
38
- if (backtest) {
39
- throw new Error(
40
- "Order book fetching is not supported in backtest mode for the default exchange schema. Please implement it according to your needs.",
41
- );
42
- }
43
- const exchange = await getExchange();
44
- const bookData = await exchange.fetchOrderBook(symbol, depth);
45
- return {
46
- symbol,
47
- asks: bookData.asks.map(([price, quantity]) => ({
48
- price: String(price),
49
- quantity: String(quantity),
50
- })),
51
- bids: bookData.bids.map(([price, quantity]) => ({
52
- price: String(price),
53
- quantity: String(quantity),
54
- })),
55
- };
56
- },
57
- formatPrice: async (symbol, price) => {
58
- const exchange = await getExchange();
59
- const market = exchange.market(symbol);
60
- const tickSize = market.limits?.price?.min || market.precision?.price;
61
- if (tickSize !== undefined) {
62
- return roundTicks(price, tickSize);
63
- }
64
- return exchange.priceToPrecision(symbol, price);
65
- },
66
- formatQuantity: async (symbol, quantity) => {
67
- const exchange = await getExchange();
68
- const market = exchange.market(symbol);
69
- const stepSize = market.limits?.amount?.min || market.precision?.amount;
70
- if (stepSize !== undefined) {
71
- return roundTicks(quantity, stepSize);
72
- }
73
- return exchange.amountToPrecision(symbol, quantity);
74
- },
75
- });
76
-
77
- addFrameSchema({
78
- frameName: "feb_2026_frame",
79
- interval: "1m",
80
- startDate: new Date("2026-02-01T00:00:00Z"),
81
- endDate: new Date("2026-02-28T23:59:59Z"),
82
- note: "February 2026",
83
- });
1
+ import { addExchangeSchema, addFrameSchema, roundTicks } from "backtest-kit";
2
+ import { singleshot } from "functools-kit";
3
+ import ccxt from "ccxt";
4
+
5
+ const getExchange = singleshot(async () => {
6
+ const exchange = new ccxt.binance({
7
+ options: {
8
+ defaultType: "spot",
9
+ adjustForTimeDifference: true,
10
+ recvWindow: 60000,
11
+ },
12
+ enableRateLimit: true,
13
+ });
14
+ await exchange.loadMarkets();
15
+ return exchange;
16
+ });
17
+
18
+ addExchangeSchema({
19
+ exchangeName: "ccxt-exchange",
20
+ getCandles: async (symbol, interval, since, limit) => {
21
+ const exchange = await getExchange();
22
+ const candles = await exchange.fetchOHLCV(
23
+ symbol,
24
+ interval,
25
+ since.getTime(),
26
+ limit,
27
+ );
28
+ return candles.map(([timestamp, open, high, low, close, volume]) => ({
29
+ timestamp,
30
+ open,
31
+ high,
32
+ low,
33
+ close,
34
+ volume,
35
+ }));
36
+ },
37
+ getOrderBook: async (symbol, depth, _from, _to, backtest) => {
38
+ if (backtest) {
39
+ throw new Error(
40
+ "Order book fetching is not supported in backtest mode for the default exchange schema. Please implement it according to your needs.",
41
+ );
42
+ }
43
+ const exchange = await getExchange();
44
+ const bookData = await exchange.fetchOrderBook(symbol, depth);
45
+ return {
46
+ symbol,
47
+ asks: bookData.asks.map(([price, quantity]) => ({
48
+ price: String(price),
49
+ quantity: String(quantity),
50
+ })),
51
+ bids: bookData.bids.map(([price, quantity]) => ({
52
+ price: String(price),
53
+ quantity: String(quantity),
54
+ })),
55
+ };
56
+ },
57
+ formatPrice: async (symbol, price) => {
58
+ const exchange = await getExchange();
59
+ const market = exchange.market(symbol);
60
+ const tickSize = market.limits?.price?.min || market.precision?.price;
61
+ if (tickSize !== undefined) {
62
+ return roundTicks(price, tickSize);
63
+ }
64
+ return exchange.priceToPrecision(symbol, price);
65
+ },
66
+ formatQuantity: async (symbol, quantity) => {
67
+ const exchange = await getExchange();
68
+ const market = exchange.market(symbol);
69
+ const stepSize = market.limits?.amount?.min || market.precision?.amount;
70
+ if (stepSize !== undefined) {
71
+ return roundTicks(quantity, stepSize);
72
+ }
73
+ return exchange.amountToPrecision(symbol, quantity);
74
+ },
75
+ });
76
+
77
+ addFrameSchema({
78
+ frameName: "feb_2026_frame",
79
+ interval: "1m",
80
+ startDate: new Date("2026-02-01T00:00:00Z"),
81
+ endDate: new Date("2026-02-28T23:59:59Z"),
82
+ note: "February 2026",
83
+ });
@@ -1,46 +1,46 @@
1
- version: '3.8'
2
-
3
- services:
4
- backtest:
5
- image: tripolskypetr/backtest-kit
6
- platform: linux/amd64
7
- # network_mode: host
8
- extra_hosts:
9
- - "host.docker.internal:host-gateway"
10
- container_name: backtest
11
- ports:
12
- - "60050:60050"
13
- restart: unless-stopped
14
- volumes:
15
- - ./:/workspace
16
- working_dir: /workspace
17
- env_file:
18
- - .env
19
- environment:
20
- - MODE
21
- - STRATEGY_FILE
22
- - SYMBOL
23
- - STRATEGY
24
- - EXCHANGE
25
- - FRAME
26
- - UI
27
- - TELEGRAM
28
- - VERBOSE
29
- - NO_CACHE
30
- - NO_FLUSH
31
- - ENTRY
32
- healthcheck:
33
- test: ["CMD", "curl", "-f", "http://localhost:60050/api/v1/health/health_check"]
34
- interval: 30s
35
- timeout: 10s
36
- retries: 3
37
- # command:
38
- # - --backtest
39
- # - --symbol
40
- # - BTCUSDT
41
- # - --strategy
42
- # - feb_2026_strategy
43
- # - --exchange
44
- # - ccxt-exchange
45
- # - ./content/feb_2026/feb_2026.strategy.ts
46
- # - --ui
1
+ version: '3.8'
2
+
3
+ services:
4
+ backtest:
5
+ image: tripolskypetr/backtest-kit
6
+ platform: linux/amd64
7
+ # network_mode: host
8
+ extra_hosts:
9
+ - "host.docker.internal:host-gateway"
10
+ container_name: backtest
11
+ ports:
12
+ - "60050:60050"
13
+ restart: unless-stopped
14
+ volumes:
15
+ - ./:/workspace
16
+ working_dir: /workspace
17
+ env_file:
18
+ - .env
19
+ environment:
20
+ - MODE
21
+ - STRATEGY_FILE
22
+ - SYMBOL
23
+ - STRATEGY
24
+ - EXCHANGE
25
+ - FRAME
26
+ - UI
27
+ - TELEGRAM
28
+ - VERBOSE
29
+ - NO_CACHE
30
+ - NO_FLUSH
31
+ - ENTRY
32
+ healthcheck:
33
+ test: ["CMD", "curl", "-f", "http://localhost:60050/api/v1/health/health_check"]
34
+ interval: 30s
35
+ timeout: 10s
36
+ retries: 3
37
+ # command:
38
+ # - --backtest
39
+ # - --symbol
40
+ # - BTCUSDT
41
+ # - --strategy
42
+ # - feb_2026_strategy
43
+ # - --exchange
44
+ # - ccxt-exchange
45
+ # - ./content/feb_2026/feb_2026.strategy.ts
46
+ # - --ui
@@ -1,38 +1,38 @@
1
- {
2
- "name": "example",
3
- "version": "1.0.0",
4
- "description": "",
5
- "main": "index.js",
6
- "scripts": {
7
- "start": "node ./node_modules/@backtest-kit/cli/build/index.mjs",
8
- "start:debug": "node --inspect-brk ./node_modules/@backtest-kit/cli/build/index.mjs"
9
- },
10
- "keywords": [],
11
- "author": "",
12
- "license": "ISC",
13
- "type": "commonjs",
14
- "devDependencies": {
15
- "@types/node": "25.6.0"
16
- },
17
- "dependencies": {
18
- "@backtest-kit/cli": "9.6.0",
19
- "@backtest-kit/graph": "9.6.0",
20
- "@backtest-kit/pinets": "9.6.0",
21
- "@backtest-kit/signals": "9.6.0",
22
- "@backtest-kit/ui": "9.6.0",
23
- "@tavily/core": "0.7.2",
24
- "@tensorflow/tfjs": "4.22.0",
25
- "@tensorflow/tfjs-backend-wasm": "4.22.0",
26
- "@tensorflow/tfjs-core": "4.22.0",
27
- "agent-swarm-kit": "2.6.0",
28
- "backtest-kit": "9.6.0",
29
- "dayjs": "1.11.20",
30
- "functools-kit": "2.3.0",
31
- "garch": "1.2.3",
32
- "get-moment-stamp": "1.1.2",
33
- "jsonrepair": "3.12.0",
34
- "ollama": "0.6.3",
35
- "slugify": "1.6.9",
36
- "volume-anomaly": "1.2.3"
37
- }
38
- }
1
+ {
2
+ "name": "example",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "node ./node_modules/@backtest-kit/cli/build/index.mjs",
8
+ "start:debug": "node --inspect-brk ./node_modules/@backtest-kit/cli/build/index.mjs"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "type": "commonjs",
14
+ "devDependencies": {
15
+ "@types/node": "25.6.0"
16
+ },
17
+ "dependencies": {
18
+ "@backtest-kit/cli": "9.7.0",
19
+ "@backtest-kit/graph": "9.7.0",
20
+ "@backtest-kit/pinets": "9.7.0",
21
+ "@backtest-kit/signals": "9.7.0",
22
+ "@backtest-kit/ui": "9.7.0",
23
+ "@tavily/core": "0.7.2",
24
+ "@tensorflow/tfjs": "4.22.0",
25
+ "@tensorflow/tfjs-backend-wasm": "4.22.0",
26
+ "@tensorflow/tfjs-core": "4.22.0",
27
+ "agent-swarm-kit": "2.6.0",
28
+ "backtest-kit": "9.7.0",
29
+ "dayjs": "1.11.20",
30
+ "functools-kit": "2.3.0",
31
+ "garch": "1.2.3",
32
+ "get-moment-stamp": "1.1.2",
33
+ "jsonrepair": "3.12.0",
34
+ "ollama": "0.6.3",
35
+ "slugify": "1.6.9",
36
+ "volume-anomaly": "1.2.3"
37
+ }
38
+ }
@@ -1,36 +1,36 @@
1
- {
2
- "compilerOptions": {
3
- "ignoreDeprecations": "6.0",
4
- "lib": [
5
- "esnext",
6
- "dom"
7
- ],
8
- "types": [
9
- "node"
10
- ],
11
- "moduleDetection": "force",
12
- "target": "ES2020",
13
- "module": "ESNext",
14
- "moduleResolution": "bundler",
15
- "noEmit": true,
16
- "strict": false,
17
- "downlevelIteration": true,
18
- "noImplicitAny": false,
19
- "skipLibCheck": true,
20
- "noFallthroughCasesInSwitch": true,
21
- "noUnusedLocals": false,
22
- "noUnusedParameters": false,
23
- "noPropertyAccessFromIndexSignature": false,
24
- "paths": {
25
- "logic": ["./logic/index.ts"],
26
- "logic/*": ["./logic/*"],
27
- "utils": ["./utils/index.ts"],
28
- "utils/*": ["./utils/*"]
29
- }
30
- },
31
- "include": [
32
- "./logic",
33
- "./content",
34
- "./modules",
35
- ],
36
- }
1
+ {
2
+ "compilerOptions": {
3
+ "ignoreDeprecations": "6.0",
4
+ "lib": [
5
+ "esnext",
6
+ "dom"
7
+ ],
8
+ "types": [
9
+ "node"
10
+ ],
11
+ "moduleDetection": "force",
12
+ "target": "ES2020",
13
+ "module": "ESNext",
14
+ "moduleResolution": "bundler",
15
+ "noEmit": true,
16
+ "strict": false,
17
+ "downlevelIteration": true,
18
+ "noImplicitAny": false,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUnusedLocals": false,
22
+ "noUnusedParameters": false,
23
+ "noPropertyAccessFromIndexSignature": false,
24
+ "paths": {
25
+ "logic": ["./logic/index.ts"],
26
+ "logic/*": ["./logic/*"],
27
+ "utils": ["./utils/index.ts"],
28
+ "utils/*": ["./utils/*"]
29
+ }
30
+ },
31
+ "include": [
32
+ "./logic",
33
+ "./content",
34
+ "./modules",
35
+ ],
36
+ }