@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 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
@@ -91,7 +91,7 @@ var BacktestKitSignals__namespace = /*#__PURE__*/_interopNamespaceDefault(Backte
91
91
  BacktestKit.Notification.enable();
92
92
  }
93
93
  {
94
- BacktestKit.Markdown.disable();
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 overridePath = path.join(self.resolveService.OVERRIDE_MODULES_DIR, fileName);
1721
- const targetPath = path.join(process.cwd(), "modules", fileName);
1722
- const hasOverride = await fs$1
1723
- .access(overridePath, fs.constants.F_OK | fs.constants.R_OK)
1724
- .then(() => true)
1725
- .catch(() => false);
1726
- const resolvedFile = hasOverride ? overridePath : targetPath;
1727
- try {
1728
- if (self.loaderService.check(resolvedFile)) {
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.disable();
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 overridePath = path.join(self.resolveService.OVERRIDE_MODULES_DIR, fileName);
1695
- const targetPath = path.join(process.cwd(), "modules", fileName);
1696
- const hasOverride = await fs$1
1697
- .access(overridePath, constants.F_OK | constants.R_OK)
1698
- .then(() => true)
1699
- .catch(() => false);
1700
- const resolvedFile = hasOverride ? overridePath : targetPath;
1701
- try {
1702
- if (self.loaderService.check(resolvedFile)) {
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.5.3",
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.5.3",
64
- "@backtest-kit/graph": "5.5.3",
65
- "@backtest-kit/ollama": "5.5.3",
66
- "@backtest-kit/pinets": "5.5.3",
67
- "@backtest-kit/signals": "5.5.3",
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.5.3",
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.5.3",
91
- "@backtest-kit/graph": "^5.5.3",
92
- "@backtest-kit/ollama": "^5.5.3",
93
- "@backtest-kit/pinets": "^5.5.3",
94
- "@backtest-kit/signals": "^5.5.3",
95
- "backtest-kit": "^5.5.3",
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