@backtest-kit/cli 5.6.0 → 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 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
- | Mode | 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()` |
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
@@ -266,8 +266,13 @@ class ResolveService {
266
266
  this.loggerService = inject(TYPES.loggerService);
267
267
  this.loaderService = inject(TYPES.loaderService);
268
268
  this.DEFAULT_TEMPLATE_DIR = path.resolve(__dirname$1, '..', 'template');
269
+ this.DEFAULT_MODULES_DIR = path.resolve(__dirname$1, '..', 'modules');
269
270
  this.OVERRIDE_TEMPLATE_DIR = path.resolve(process.cwd(), 'template');
270
271
  this.OVERRIDE_MODULES_DIR = path.resolve(process.cwd(), 'modules');
272
+ this.getIsLaunched = () => {
273
+ this.loggerService.log("resolveService getIsLaunched");
274
+ return _is_launched;
275
+ };
271
276
  this.attachEntryPoint = async (entryPoint) => {
272
277
  this.loggerService.log("resolveService attachEntryPoint");
273
278
  if (_is_launched) {
@@ -1719,25 +1724,35 @@ class TelegramTemplateService {
1719
1724
  }
1720
1725
  }
1721
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
+ };
1722
1743
  const LOAD_MODULE_MODULE_FN = async (fileName, self) => {
1723
- const overridePath = path.join(self.resolveService.OVERRIDE_MODULES_DIR, fileName);
1724
- const targetPath = path.join(process.cwd(), "modules", fileName);
1725
- const hasOverride = await fs$1
1726
- .access(overridePath, fs.constants.F_OK | fs.constants.R_OK)
1727
- .then(() => true)
1728
- .catch(() => false);
1729
- const resolvedFile = hasOverride ? overridePath : targetPath;
1730
- try {
1731
- if (self.loaderService.check(resolvedFile)) {
1732
- self.loaderService.import(resolvedFile);
1733
- 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}`);
1734
1753
  }
1735
- return false;
1736
- }
1737
- catch {
1738
- console.warn(`Module module import failed for file: ${resolvedFile}`);
1739
- return false;
1740
1754
  }
1755
+ return false;
1741
1756
  };
1742
1757
  class ModuleConnectionService {
1743
1758
  constructor() {
@@ -2231,6 +2246,9 @@ function setLogger(logger) {
2231
2246
 
2232
2247
  let _is_started = false;
2233
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
+ }
2234
2252
  {
2235
2253
  if (_is_started) {
2236
2254
  throw new Error("Should be called only once");
package/build/index.mjs CHANGED
@@ -240,8 +240,13 @@ class ResolveService {
240
240
  this.loggerService = inject(TYPES.loggerService);
241
241
  this.loaderService = inject(TYPES.loaderService);
242
242
  this.DEFAULT_TEMPLATE_DIR = path.resolve(__dirname, '..', 'template');
243
+ this.DEFAULT_MODULES_DIR = path.resolve(__dirname, '..', 'modules');
243
244
  this.OVERRIDE_TEMPLATE_DIR = path.resolve(process.cwd(), 'template');
244
245
  this.OVERRIDE_MODULES_DIR = path.resolve(process.cwd(), 'modules');
246
+ this.getIsLaunched = () => {
247
+ this.loggerService.log("resolveService getIsLaunched");
248
+ return _is_launched;
249
+ };
245
250
  this.attachEntryPoint = async (entryPoint) => {
246
251
  this.loggerService.log("resolveService attachEntryPoint");
247
252
  if (_is_launched) {
@@ -1693,25 +1698,35 @@ class TelegramTemplateService {
1693
1698
  }
1694
1699
  }
1695
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
+ };
1696
1717
  const LOAD_MODULE_MODULE_FN = async (fileName, self) => {
1697
- const overridePath = path.join(self.resolveService.OVERRIDE_MODULES_DIR, fileName);
1698
- const targetPath = path.join(process.cwd(), "modules", fileName);
1699
- const hasOverride = await fs$1
1700
- .access(overridePath, constants.F_OK | constants.R_OK)
1701
- .then(() => true)
1702
- .catch(() => false);
1703
- const resolvedFile = hasOverride ? overridePath : targetPath;
1704
- try {
1705
- if (self.loaderService.check(resolvedFile)) {
1706
- self.loaderService.import(resolvedFile);
1707
- 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}`);
1708
1727
  }
1709
- return false;
1710
- }
1711
- catch {
1712
- console.warn(`Module module import failed for file: ${resolvedFile}`);
1713
- return false;
1714
1728
  }
1729
+ return false;
1715
1730
  };
1716
1731
  class ModuleConnectionService {
1717
1732
  constructor() {
@@ -2201,6 +2216,9 @@ function setLogger(logger) {
2201
2216
 
2202
2217
  let _is_started = false;
2203
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
+ }
2204
2222
  {
2205
2223
  if (_is_started) {
2206
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.6.0",
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.6.0",
64
- "@backtest-kit/graph": "5.6.0",
65
- "@backtest-kit/ollama": "5.6.0",
66
- "@backtest-kit/pinets": "5.6.0",
67
- "@backtest-kit/signals": "5.6.0",
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.6.0",
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.6.0",
91
- "@backtest-kit/graph": "^5.6.0",
92
- "@backtest-kit/ollama": "^5.6.0",
93
- "@backtest-kit/pinets": "^5.6.0",
94
- "@backtest-kit/signals": "^5.6.0",
95
- "backtest-kit": "^5.6.0",
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