@backtest-kit/cli 5.5.3 → 5.6.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/README.md +5 -5
- package/build/index.cjs +38 -17
- package/build/index.mjs +38 -17
- package/package.json +13 -13
- package/types.d.ts +2 -0
package/README.md
CHANGED
|
@@ -302,11 +302,11 @@ Requires `CC_TELEGRAM_TOKEN` and `CC_TELEGRAM_CHANNEL` in your environment.
|
|
|
302
302
|
|
|
303
303
|
The CLI supports **mode-specific module files** that are loaded as side-effect imports before the strategy starts. Each file is expected to call `Broker.useBrokerAdapter()` from `backtest-kit` to register a broker adapter.
|
|
304
304
|
|
|
305
|
-
|
|
|
306
|
-
|
|
307
|
-
| `--live`
|
|
308
|
-
| `--paper`
|
|
309
|
-
| `--backtest`
|
|
305
|
+
| Command Line Args | Module file | Loaded before |
|
|
306
|
+
|-------------------|---------------------------------|-----------------------------|
|
|
307
|
+
| `--live` | `./modules/live.module.mjs` | `Live.background()` |
|
|
308
|
+
| `--paper` | `./modules/paper.module.mjs` | `Live.background()` (paper) |
|
|
309
|
+
| `--backtest` | `./modules/backtest.module.mjs` | `Backtest.background()` |
|
|
310
310
|
|
|
311
311
|
> File is resolved relative to `cwd` (the strategy directory). All of `.mjs`, `.cjs`, `.ts` extensions are tried automatically. Missing module is a soft warning — not an error.
|
|
312
312
|
|
package/build/index.cjs
CHANGED
|
@@ -91,7 +91,7 @@ var BacktestKitSignals__namespace = /*#__PURE__*/_interopNamespaceDefault(Backte
|
|
|
91
91
|
BacktestKit.Notification.enable();
|
|
92
92
|
}
|
|
93
93
|
{
|
|
94
|
-
BacktestKit.Markdown.
|
|
94
|
+
BacktestKit.Markdown.enable();
|
|
95
95
|
BacktestKit.Report.enable();
|
|
96
96
|
}
|
|
97
97
|
{
|
|
@@ -102,6 +102,9 @@ var BacktestKitSignals__namespace = /*#__PURE__*/_interopNamespaceDefault(Backte
|
|
|
102
102
|
BacktestKit.NotificationLive.usePersist();
|
|
103
103
|
BacktestKit.NotificationBacktest.useMemory();
|
|
104
104
|
}
|
|
105
|
+
{
|
|
106
|
+
BacktestKit.Markdown.useDummy();
|
|
107
|
+
}
|
|
105
108
|
BacktestKit.setConfig({
|
|
106
109
|
CC_MAX_NOTIFICATIONS: 5000,
|
|
107
110
|
CC_MAX_SIGNALS: 750,
|
|
@@ -263,8 +266,13 @@ class ResolveService {
|
|
|
263
266
|
this.loggerService = inject(TYPES.loggerService);
|
|
264
267
|
this.loaderService = inject(TYPES.loaderService);
|
|
265
268
|
this.DEFAULT_TEMPLATE_DIR = path.resolve(__dirname$1, '..', 'template');
|
|
269
|
+
this.DEFAULT_MODULES_DIR = path.resolve(__dirname$1, '..', 'modules');
|
|
266
270
|
this.OVERRIDE_TEMPLATE_DIR = path.resolve(process.cwd(), 'template');
|
|
267
271
|
this.OVERRIDE_MODULES_DIR = path.resolve(process.cwd(), 'modules');
|
|
272
|
+
this.getIsLaunched = () => {
|
|
273
|
+
this.loggerService.log("resolveService getIsLaunched");
|
|
274
|
+
return _is_launched;
|
|
275
|
+
};
|
|
268
276
|
this.attachEntryPoint = async (entryPoint) => {
|
|
269
277
|
this.loggerService.log("resolveService attachEntryPoint");
|
|
270
278
|
if (_is_launched) {
|
|
@@ -1716,25 +1724,35 @@ class TelegramTemplateService {
|
|
|
1716
1724
|
}
|
|
1717
1725
|
}
|
|
1718
1726
|
|
|
1727
|
+
const GET_MODULE_VARIANTS_FN = (fileName, self) => {
|
|
1728
|
+
const result = [];
|
|
1729
|
+
result.push({
|
|
1730
|
+
filePath: path.join(process.cwd(), "modules", fileName),
|
|
1731
|
+
baseDir: path.join(process.cwd(), "modules")
|
|
1732
|
+
});
|
|
1733
|
+
result.push({
|
|
1734
|
+
filePath: path.join(self.resolveService.OVERRIDE_MODULES_DIR, fileName),
|
|
1735
|
+
baseDir: self.resolveService.OVERRIDE_MODULES_DIR,
|
|
1736
|
+
});
|
|
1737
|
+
result.push({
|
|
1738
|
+
filePath: path.join(self.resolveService.DEFAULT_MODULES_DIR, fileName),
|
|
1739
|
+
baseDir: self.resolveService.DEFAULT_MODULES_DIR,
|
|
1740
|
+
});
|
|
1741
|
+
return result;
|
|
1742
|
+
};
|
|
1719
1743
|
const LOAD_MODULE_MODULE_FN = async (fileName, self) => {
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
self.loaderService.import(resolvedFile);
|
|
1730
|
-
return true;
|
|
1744
|
+
for (const { filePath, baseDir } of GET_MODULE_VARIANTS_FN(fileName, self)) {
|
|
1745
|
+
try {
|
|
1746
|
+
if (await self.loaderService.check(filePath, baseDir)) {
|
|
1747
|
+
self.loaderService.import(filePath, baseDir);
|
|
1748
|
+
return true;
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
catch {
|
|
1752
|
+
console.warn(`Module module import failed for file: ${filePath}`);
|
|
1731
1753
|
}
|
|
1732
|
-
return false;
|
|
1733
|
-
}
|
|
1734
|
-
catch {
|
|
1735
|
-
console.warn(`Module module import failed for file: ${resolvedFile}`);
|
|
1736
|
-
return false;
|
|
1737
1754
|
}
|
|
1755
|
+
return false;
|
|
1738
1756
|
};
|
|
1739
1757
|
class ModuleConnectionService {
|
|
1740
1758
|
constructor() {
|
|
@@ -2228,6 +2246,9 @@ function setLogger(logger) {
|
|
|
2228
2246
|
|
|
2229
2247
|
let _is_started = false;
|
|
2230
2248
|
async function run(mode, args) {
|
|
2249
|
+
if (cli.resolveService.getIsLaunched()) {
|
|
2250
|
+
throw new Error("Entry point is already attached. Multiple entry points are not allowed.");
|
|
2251
|
+
}
|
|
2231
2252
|
{
|
|
2232
2253
|
if (_is_started) {
|
|
2233
2254
|
throw new Error("Should be called only once");
|
package/build/index.mjs
CHANGED
|
@@ -65,7 +65,7 @@ import * as BacktestKitSignals from '@backtest-kit/signals';
|
|
|
65
65
|
Notification.enable();
|
|
66
66
|
}
|
|
67
67
|
{
|
|
68
|
-
Markdown.
|
|
68
|
+
Markdown.enable();
|
|
69
69
|
Report.enable();
|
|
70
70
|
}
|
|
71
71
|
{
|
|
@@ -76,6 +76,9 @@ import * as BacktestKitSignals from '@backtest-kit/signals';
|
|
|
76
76
|
NotificationLive.usePersist();
|
|
77
77
|
NotificationBacktest.useMemory();
|
|
78
78
|
}
|
|
79
|
+
{
|
|
80
|
+
Markdown.useDummy();
|
|
81
|
+
}
|
|
79
82
|
setConfig({
|
|
80
83
|
CC_MAX_NOTIFICATIONS: 5000,
|
|
81
84
|
CC_MAX_SIGNALS: 750,
|
|
@@ -237,8 +240,13 @@ class ResolveService {
|
|
|
237
240
|
this.loggerService = inject(TYPES.loggerService);
|
|
238
241
|
this.loaderService = inject(TYPES.loaderService);
|
|
239
242
|
this.DEFAULT_TEMPLATE_DIR = path.resolve(__dirname, '..', 'template');
|
|
243
|
+
this.DEFAULT_MODULES_DIR = path.resolve(__dirname, '..', 'modules');
|
|
240
244
|
this.OVERRIDE_TEMPLATE_DIR = path.resolve(process.cwd(), 'template');
|
|
241
245
|
this.OVERRIDE_MODULES_DIR = path.resolve(process.cwd(), 'modules');
|
|
246
|
+
this.getIsLaunched = () => {
|
|
247
|
+
this.loggerService.log("resolveService getIsLaunched");
|
|
248
|
+
return _is_launched;
|
|
249
|
+
};
|
|
242
250
|
this.attachEntryPoint = async (entryPoint) => {
|
|
243
251
|
this.loggerService.log("resolveService attachEntryPoint");
|
|
244
252
|
if (_is_launched) {
|
|
@@ -1690,25 +1698,35 @@ class TelegramTemplateService {
|
|
|
1690
1698
|
}
|
|
1691
1699
|
}
|
|
1692
1700
|
|
|
1701
|
+
const GET_MODULE_VARIANTS_FN = (fileName, self) => {
|
|
1702
|
+
const result = [];
|
|
1703
|
+
result.push({
|
|
1704
|
+
filePath: path.join(process.cwd(), "modules", fileName),
|
|
1705
|
+
baseDir: path.join(process.cwd(), "modules")
|
|
1706
|
+
});
|
|
1707
|
+
result.push({
|
|
1708
|
+
filePath: path.join(self.resolveService.OVERRIDE_MODULES_DIR, fileName),
|
|
1709
|
+
baseDir: self.resolveService.OVERRIDE_MODULES_DIR,
|
|
1710
|
+
});
|
|
1711
|
+
result.push({
|
|
1712
|
+
filePath: path.join(self.resolveService.DEFAULT_MODULES_DIR, fileName),
|
|
1713
|
+
baseDir: self.resolveService.DEFAULT_MODULES_DIR,
|
|
1714
|
+
});
|
|
1715
|
+
return result;
|
|
1716
|
+
};
|
|
1693
1717
|
const LOAD_MODULE_MODULE_FN = async (fileName, self) => {
|
|
1694
|
-
const
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
self.loaderService.import(resolvedFile);
|
|
1704
|
-
return true;
|
|
1718
|
+
for (const { filePath, baseDir } of GET_MODULE_VARIANTS_FN(fileName, self)) {
|
|
1719
|
+
try {
|
|
1720
|
+
if (await self.loaderService.check(filePath, baseDir)) {
|
|
1721
|
+
self.loaderService.import(filePath, baseDir);
|
|
1722
|
+
return true;
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
catch {
|
|
1726
|
+
console.warn(`Module module import failed for file: ${filePath}`);
|
|
1705
1727
|
}
|
|
1706
|
-
return false;
|
|
1707
|
-
}
|
|
1708
|
-
catch {
|
|
1709
|
-
console.warn(`Module module import failed for file: ${resolvedFile}`);
|
|
1710
|
-
return false;
|
|
1711
1728
|
}
|
|
1729
|
+
return false;
|
|
1712
1730
|
};
|
|
1713
1731
|
class ModuleConnectionService {
|
|
1714
1732
|
constructor() {
|
|
@@ -2198,6 +2216,9 @@ function setLogger(logger) {
|
|
|
2198
2216
|
|
|
2199
2217
|
let _is_started = false;
|
|
2200
2218
|
async function run(mode, args) {
|
|
2219
|
+
if (cli.resolveService.getIsLaunched()) {
|
|
2220
|
+
throw new Error("Entry point is already attached. Multiple entry points are not allowed.");
|
|
2221
|
+
}
|
|
2201
2222
|
{
|
|
2202
2223
|
if (_is_started) {
|
|
2203
2224
|
throw new Error("Should be called only once");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backtest-kit/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.2",
|
|
4
4
|
"description": "Zero-boilerplate CLI runner for backtest-kit strategies. Run backtests, paper trading, and live bots with candle cache warming, web dashboard, and Telegram notifications — no setup code required.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Petr Tripolsky",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@babel/plugin-transform-modules-umd": "7.27.1",
|
|
62
62
|
"@babel/standalone": "7.29.1",
|
|
63
|
-
"@backtest-kit/ui": "5.
|
|
64
|
-
"@backtest-kit/graph": "5.
|
|
65
|
-
"@backtest-kit/ollama": "5.
|
|
66
|
-
"@backtest-kit/pinets": "5.
|
|
67
|
-
"@backtest-kit/signals": "5.
|
|
63
|
+
"@backtest-kit/ui": "5.6.2",
|
|
64
|
+
"@backtest-kit/graph": "5.6.2",
|
|
65
|
+
"@backtest-kit/ollama": "5.6.2",
|
|
66
|
+
"@backtest-kit/pinets": "5.6.2",
|
|
67
|
+
"@backtest-kit/signals": "5.6.2",
|
|
68
68
|
"@rollup/plugin-replace": "6.0.3",
|
|
69
69
|
"@rollup/plugin-typescript": "11.1.6",
|
|
70
70
|
"@types/image-size": "0.7.0",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@types/mustache": "4.2.6",
|
|
73
73
|
"@types/node": "22.9.0",
|
|
74
74
|
"@types/stack-trace": "0.0.33",
|
|
75
|
-
"backtest-kit": "5.
|
|
75
|
+
"backtest-kit": "5.6.2",
|
|
76
76
|
"glob": "11.0.1",
|
|
77
77
|
"markdown-it": "14.1.1",
|
|
78
78
|
"rimraf": "6.0.1",
|
|
@@ -87,12 +87,12 @@
|
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"@babel/plugin-transform-modules-umd": "^7.27.1",
|
|
89
89
|
"@babel/standalone": "^7.29.1",
|
|
90
|
-
"@backtest-kit/ui": "^5.
|
|
91
|
-
"@backtest-kit/graph": "^5.
|
|
92
|
-
"@backtest-kit/ollama": "^5.
|
|
93
|
-
"@backtest-kit/pinets": "^5.
|
|
94
|
-
"@backtest-kit/signals": "^5.
|
|
95
|
-
"backtest-kit": "^5.
|
|
90
|
+
"@backtest-kit/ui": "^5.6.2",
|
|
91
|
+
"@backtest-kit/graph": "^5.6.2",
|
|
92
|
+
"@backtest-kit/ollama": "^5.6.2",
|
|
93
|
+
"@backtest-kit/pinets": "^5.6.2",
|
|
94
|
+
"@backtest-kit/signals": "^5.6.2",
|
|
95
|
+
"backtest-kit": "^5.6.2",
|
|
96
96
|
"markdown-it": "^14.1.1",
|
|
97
97
|
"typescript": "^5.0.0"
|
|
98
98
|
},
|
package/types.d.ts
CHANGED
|
@@ -99,8 +99,10 @@ declare class ResolveService {
|
|
|
99
99
|
readonly loggerService: LoggerService;
|
|
100
100
|
readonly loaderService: LoaderService;
|
|
101
101
|
readonly DEFAULT_TEMPLATE_DIR: string;
|
|
102
|
+
readonly DEFAULT_MODULES_DIR: string;
|
|
102
103
|
readonly OVERRIDE_TEMPLATE_DIR: string;
|
|
103
104
|
readonly OVERRIDE_MODULES_DIR: string;
|
|
105
|
+
getIsLaunched: () => boolean;
|
|
104
106
|
attachEntryPoint: (entryPoint: string) => Promise<void>;
|
|
105
107
|
}
|
|
106
108
|
|