@backtest-kit/cli 9.2.0 → 9.4.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.
package/README.md CHANGED
@@ -728,11 +728,55 @@ Broker.useBrokerAdapter(MyBroker);
728
728
  Broker.enable();
729
729
  ```
730
730
 
731
- ## 🔀 Import Aliases (`alias.module`)
731
+ ## ⚙️ Setup Hook (`config/setup.config`)
732
732
 
733
- `@backtest-kit/cli` lets you override any nodejs module import without touching the strategy code. Drop a `config/alias.module` file in your project root and export a mapping from module name to replacement module.
733
+ `@backtest-kit/cli` loads a `{projectRoot}/config/setup.config` file once before any module hooks or strategy code run. Use it to perform one-time initialization that must happen before the first persistence call — registering a custom storage backend, configuring a logger, seeding global state, or anything else the process needs before `backtest-kit` starts.
734
734
 
735
- The alias table is loaded once (on the first `import` call) from `{projectRoot}/config/alias.module` and applied globally to every subsequent module load via `require`/ `import`.
735
+ **Important:** When `setup.config` is present, the CLI skips its own default adapter registration — it does **not** call `usePersist()` / `useLocal()` / `useMemory()` for any of the persistence slots. This means your config takes full ownership of the persistence layer: whatever adapters you register in `{projectRoot}/config/setup.config` are the ones `backtest-kit` uses, with no interference from the CLI defaults.
736
+
737
+ ### Example: MongoDB + Redis persistence via `@backtest-kit/mongo`
738
+
739
+ The most common use-case is swapping the default file-based persistence for a production-grade backend. Install `@backtest-kit/mongo` and call `setup()` — it registers all 15 persistence adapters in one call and reads connection parameters from environment variables:
740
+
741
+ ```bash
742
+ npm install @backtest-kit/mongo
743
+ ```
744
+
745
+ ```ts
746
+ // config/setup.config.ts
747
+ import { setup } from '@backtest-kit/mongo';
748
+
749
+ setup();
750
+ ```
751
+
752
+ ```env
753
+ # .env
754
+ CC_MONGO_CONNECTION_STRING=mongodb://localhost:27017/backtest-kit
755
+ CC_REDIS_HOST=127.0.0.1
756
+ CC_REDIS_PORT=6379
757
+ ```
758
+
759
+ Or pass connection parameters explicitly:
760
+
761
+ ```ts
762
+ // config/setup.config.ts
763
+ import { setup } from '@backtest-kit/mongo';
764
+
765
+ setup({
766
+ CC_MONGO_CONNECTION_STRING: 'mongodb://mongo:27017/mydb',
767
+ CC_REDIS_HOST: 'redis',
768
+ CC_REDIS_PORT: 6379,
769
+ CC_REDIS_PASSWORD: 'secret',
770
+ });
771
+ ```
772
+
773
+ No changes to strategy code are needed — `setup()` wires up the adapters transparently before `backtest-kit` makes its first persistence call.
774
+
775
+ ## 🔀 Import Aliases (`config/alias.config`)
776
+
777
+ `@backtest-kit/cli` lets you override any nodejs module import — without touching the strategy code. Drop a `config/alias.config` file in your project root and export a mapping from module name to replacement module.
778
+
779
+ The alias table is loaded once (on the first `import` call) from `{projectRoot}/config/alias.config` and applied globally to every subsequent module load via `require`/ `import`.
736
780
 
737
781
  **Use cases:**
738
782
 
@@ -740,19 +784,19 @@ The alias table is loaded once (on the first `import` call) from `{projectRoot}/
740
784
  - Swap any external api for a mock during CI runs
741
785
 
742
786
  ```ts
743
- // config/alias.module.ts — named export
787
+ // config/alias.config.ts — named export
744
788
  export const ccxt = require("./stubs/ccxt.stub.cjs");
745
789
  ```
746
790
 
747
791
  ```js
748
- // config/alias.module.cjs — default export
792
+ // config/alias.config.cjs — default export
749
793
  module.exports = {
750
794
  ccxt: require("./stubs/ccxt.stub.cjs"),
751
795
  };
752
796
  ```
753
797
 
754
798
  ```js
755
- // config/alias.module.mjs — default export
799
+ // config/alias.config.mjs — default export
756
800
  import ccxtStub from "./stubs/ccxt.stub.mjs";
757
801
 
758
802
  export default {
package/build/index.cjs CHANGED
@@ -24,7 +24,7 @@ var jsdom = require('jsdom');
24
24
  var Mustache = require('mustache');
25
25
  var standalone = require('@babel/standalone');
26
26
  var pluginUMD = require('@babel/plugin-transform-modules-umd');
27
- var module$1 = require('module');
27
+ var Module = require('module');
28
28
  var BacktestKitGraph = require('@backtest-kit/graph');
29
29
  var BacktestKitOllama = require('@backtest-kit/ollama');
30
30
  var BacktestKitPinets = require('@backtest-kit/pinets');
@@ -266,6 +266,136 @@ const TYPES = {
266
266
 
267
267
  const entrySubject = new functoolsKit.BehaviorSubject();
268
268
 
269
+ const SETUP_ADAPTER_FN = () => {
270
+ {
271
+ BacktestKit.Dump.useMarkdown();
272
+ }
273
+ {
274
+ BacktestKit.SessionLive.usePersist();
275
+ BacktestKit.SessionBacktest.useLocal();
276
+ }
277
+ {
278
+ BacktestKit.StorageLive.usePersist();
279
+ BacktestKit.StorageBacktest.useMemory();
280
+ }
281
+ {
282
+ BacktestKit.RecentLive.usePersist();
283
+ BacktestKit.RecentBacktest.useMemory();
284
+ }
285
+ {
286
+ BacktestKit.NotificationLive.usePersist();
287
+ BacktestKit.NotificationBacktest.useMemory();
288
+ }
289
+ {
290
+ BacktestKit.RecentLive.usePersist();
291
+ BacktestKit.RecentBacktest.useMemory();
292
+ }
293
+ {
294
+ BacktestKit.MemoryLive.usePersist();
295
+ BacktestKit.MemoryBacktest.useLocal();
296
+ }
297
+ {
298
+ BacktestKit.StateLive.usePersist();
299
+ BacktestKit.StateBacktest.useLocal();
300
+ }
301
+ {
302
+ BacktestKit.Markdown.useDummy();
303
+ BacktestKit.Log.useJsonl();
304
+ }
305
+ };
306
+ class SetupUtils {
307
+ constructor() {
308
+ this.enable = functoolsKit.singleshot(() => {
309
+ cli.loggerService.debug("SetupUtils enable");
310
+ {
311
+ const config = cli.configService.getNotificationConfig();
312
+ BacktestKit.Notification.enable(config);
313
+ }
314
+ {
315
+ BacktestKit.Recent.enable();
316
+ BacktestKit.Storage.enable();
317
+ }
318
+ {
319
+ BacktestKit.Markdown.enable();
320
+ BacktestKit.Report.enable();
321
+ BacktestKit.Dump.enable();
322
+ BacktestKit.State.enable();
323
+ BacktestKit.Memory.enable();
324
+ }
325
+ if (!cli.configConnectionService.hasConfig("setup.config")) {
326
+ SETUP_ADAPTER_FN();
327
+ }
328
+ });
329
+ this.clear = () => {
330
+ cli.loggerService.debug("SetupUtils clear");
331
+ if (!this.enable.hasValue()) {
332
+ return;
333
+ }
334
+ this.enable.clear();
335
+ {
336
+ BacktestKit.Recent.disable();
337
+ BacktestKit.Storage.disable();
338
+ BacktestKit.Notification.disable();
339
+ }
340
+ {
341
+ BacktestKit.Markdown.disable();
342
+ BacktestKit.Report.disable();
343
+ BacktestKit.Dump.disable();
344
+ BacktestKit.Memory.disable();
345
+ }
346
+ {
347
+ BacktestKit.Markdown.clear();
348
+ BacktestKit.Report.clear();
349
+ BacktestKit.MarkdownWriter.clear();
350
+ BacktestKit.ReportWriter.clear();
351
+ }
352
+ {
353
+ BacktestKit.PersistSignalAdapter.clear();
354
+ BacktestKit.PersistRiskAdapter.clear();
355
+ BacktestKit.PersistScheduleAdapter.clear();
356
+ BacktestKit.PersistPartialAdapter.clear();
357
+ BacktestKit.PersistBreakevenAdapter.clear();
358
+ BacktestKit.PersistCandleAdapter.clear();
359
+ BacktestKit.PersistStorageAdapter.clear();
360
+ BacktestKit.PersistNotificationAdapter.clear();
361
+ BacktestKit.PersistLogAdapter.clear();
362
+ BacktestKit.PersistMeasureAdapter.clear();
363
+ BacktestKit.PersistIntervalAdapter.clear();
364
+ BacktestKit.PersistMemoryAdapter.clear();
365
+ BacktestKit.PersistRecentAdapter.clear();
366
+ BacktestKit.PersistStateAdapter.clear();
367
+ BacktestKit.PersistSessionAdapter.clear();
368
+ }
369
+ {
370
+ BacktestKit.Dump.clear();
371
+ BacktestKit.Log.clear();
372
+ BacktestKit.Markdown.clear();
373
+ }
374
+ {
375
+ BacktestKit.StorageLive.clear();
376
+ BacktestKit.StorageBacktest.clear();
377
+ }
378
+ {
379
+ BacktestKit.NotificationLive.clear();
380
+ BacktestKit.NotificationBacktest.clear();
381
+ }
382
+ {
383
+ BacktestKit.RecentLive.clear();
384
+ BacktestKit.RecentBacktest.clear();
385
+ }
386
+ };
387
+ this.update = () => {
388
+ cli.loggerService.debug("SetupUtils update");
389
+ if (cli.configConnectionService.hasConfig("setup.config")) {
390
+ return;
391
+ }
392
+ BacktestKit.Log.useJsonl();
393
+ BacktestKit.Dump.useMarkdown();
394
+ };
395
+ }
396
+ }
397
+ const Setup = new SetupUtils();
398
+
269
399
  const __filename$3 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
270
400
  const __dirname$3 = path.dirname(__filename$3);
271
401
  let _is_launched = false;
@@ -327,7 +457,7 @@ class ResolveService {
327
457
  {
328
458
  const cwd = process.cwd();
329
459
  process.chdir(moduleRoot);
330
- cwd !== moduleRoot && BacktestKit.Log.useJsonl();
460
+ cwd !== moduleRoot && Setup.update();
331
461
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
332
462
  dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
333
463
  this.loaderService.import(absolutePath);
@@ -753,123 +883,6 @@ const notifyVerbose = functoolsKit.singleshot(() => {
753
883
  });
754
884
  });
755
885
 
756
- class SetupUtils {
757
- constructor() {
758
- this.enable = functoolsKit.singleshot(() => {
759
- cli.loggerService.debug("SetupUtils enable");
760
- {
761
- const config = cli.configService.getNotificationConfig();
762
- BacktestKit.Notification.enable(config);
763
- }
764
- {
765
- BacktestKit.Recent.enable();
766
- BacktestKit.Storage.enable();
767
- }
768
- {
769
- BacktestKit.Markdown.enable();
770
- BacktestKit.Report.enable();
771
- BacktestKit.Dump.enable();
772
- BacktestKit.State.enable();
773
- BacktestKit.Memory.enable();
774
- }
775
- {
776
- BacktestKit.Dump.useMarkdown();
777
- }
778
- {
779
- BacktestKit.SessionLive.usePersist();
780
- BacktestKit.SessionBacktest.useLocal();
781
- }
782
- {
783
- BacktestKit.StorageLive.usePersist();
784
- BacktestKit.StorageBacktest.useMemory();
785
- }
786
- {
787
- BacktestKit.RecentLive.usePersist();
788
- BacktestKit.RecentBacktest.useMemory();
789
- }
790
- {
791
- BacktestKit.NotificationLive.usePersist();
792
- BacktestKit.NotificationBacktest.useMemory();
793
- }
794
- {
795
- BacktestKit.RecentLive.usePersist();
796
- BacktestKit.RecentBacktest.useMemory();
797
- }
798
- {
799
- BacktestKit.MemoryLive.usePersist();
800
- BacktestKit.MemoryBacktest.useLocal();
801
- }
802
- {
803
- BacktestKit.StateLive.usePersist();
804
- BacktestKit.StateBacktest.useLocal();
805
- }
806
- {
807
- BacktestKit.Markdown.useDummy();
808
- BacktestKit.Log.useJsonl();
809
- }
810
- });
811
- this.clear = () => {
812
- cli.loggerService.debug("SetupUtils clear");
813
- if (!this.enable.hasValue()) {
814
- return;
815
- }
816
- this.enable.clear();
817
- {
818
- BacktestKit.Recent.disable();
819
- BacktestKit.Storage.disable();
820
- BacktestKit.Notification.disable();
821
- }
822
- {
823
- BacktestKit.Markdown.disable();
824
- BacktestKit.Report.disable();
825
- BacktestKit.Dump.disable();
826
- BacktestKit.Memory.disable();
827
- }
828
- {
829
- BacktestKit.Markdown.clear();
830
- BacktestKit.Report.clear();
831
- BacktestKit.MarkdownWriter.clear();
832
- BacktestKit.ReportWriter.clear();
833
- }
834
- {
835
- BacktestKit.PersistSignalAdapter.clear();
836
- BacktestKit.PersistRiskAdapter.clear();
837
- BacktestKit.PersistScheduleAdapter.clear();
838
- BacktestKit.PersistPartialAdapter.clear();
839
- BacktestKit.PersistBreakevenAdapter.clear();
840
- BacktestKit.PersistCandleAdapter.clear();
841
- BacktestKit.PersistStorageAdapter.clear();
842
- BacktestKit.PersistNotificationAdapter.clear();
843
- BacktestKit.PersistLogAdapter.clear();
844
- BacktestKit.PersistMeasureAdapter.clear();
845
- BacktestKit.PersistIntervalAdapter.clear();
846
- BacktestKit.PersistMemoryAdapter.clear();
847
- BacktestKit.PersistRecentAdapter.clear();
848
- BacktestKit.PersistStateAdapter.clear();
849
- BacktestKit.PersistSessionAdapter.clear();
850
- }
851
- {
852
- BacktestKit.Dump.clear();
853
- BacktestKit.Log.clear();
854
- BacktestKit.Markdown.clear();
855
- }
856
- {
857
- BacktestKit.StorageLive.clear();
858
- BacktestKit.StorageBacktest.clear();
859
- }
860
- {
861
- BacktestKit.NotificationLive.clear();
862
- BacktestKit.NotificationBacktest.clear();
863
- }
864
- {
865
- BacktestKit.RecentLive.clear();
866
- BacktestKit.RecentBacktest.clear();
867
- }
868
- };
869
- }
870
- }
871
- const Setup = new SetupUtils();
872
-
873
886
  const DEFAULT_CACHE_LIST$1 = ["1m", "15m", "30m", "1h", "4h"];
874
887
  const GET_CACHE_INTERVAL_LIST_FN$1 = () => {
875
888
  const { values } = getArgs();
@@ -892,10 +905,12 @@ class BacktestMainService {
892
905
  this.frontendProviderService = inject(TYPES.frontendProviderService);
893
906
  this.telegramProviderService = inject(TYPES.telegramProviderService);
894
907
  this.moduleConnectionService = inject(TYPES.moduleConnectionService);
908
+ this.configConnectionService = inject(TYPES.configConnectionService);
895
909
  this.run = functoolsKit.singleshot(async (payload) => {
896
910
  this.loggerService.log("backtestMainService run", {
897
911
  payload,
898
912
  });
913
+ await this.configConnectionService.loadConfig("setup.config");
899
914
  {
900
915
  await this.configService.waitForInit();
901
916
  Setup.enable();
@@ -910,7 +925,7 @@ class BacktestMainService {
910
925
  }
911
926
  {
912
927
  await this.resolveService.attachJavascript(payload.entryPoint);
913
- await this.moduleConnectionService.loadModule("./backtest.module");
928
+ await this.moduleConnectionService.loadModule("backtest.module");
914
929
  }
915
930
  {
916
931
  this.exchangeSchemaService.addSchema();
@@ -1011,8 +1026,10 @@ class WalkerMainService {
1011
1026
  this.symbolSchemaService = inject(TYPES.symbolSchemaService);
1012
1027
  this.cacheLogicService = inject(TYPES.cacheLogicService);
1013
1028
  this.moduleConnectionService = inject(TYPES.moduleConnectionService);
1029
+ this.configConnectionService = inject(TYPES.configConnectionService);
1014
1030
  this.run = functoolsKit.singleshot(async (payload) => {
1015
1031
  this.loggerService.log("walkerMainService run", { payload });
1032
+ await this.configConnectionService.loadConfig("setup.config");
1016
1033
  {
1017
1034
  await this.configService.waitForInit();
1018
1035
  Setup.enable();
@@ -1031,7 +1048,7 @@ class WalkerMainService {
1031
1048
  Setup.enable();
1032
1049
  }
1033
1050
  {
1034
- cwd !== moduleRoot && BacktestKit.Log.useJsonl();
1051
+ cwd !== moduleRoot && Setup.update();
1035
1052
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
1036
1053
  dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
1037
1054
  }
@@ -1050,7 +1067,7 @@ class WalkerMainService {
1050
1067
  const cwd = process.cwd();
1051
1068
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
1052
1069
  }
1053
- await this.moduleConnectionService.loadModule("./walker.module");
1070
+ await this.moduleConnectionService.loadModule("walker.module");
1054
1071
  {
1055
1072
  this.exchangeSchemaService.addSchema();
1056
1073
  this.symbolSchemaService.addSchema();
@@ -1106,7 +1123,7 @@ class WalkerMainService {
1106
1123
  }
1107
1124
  restoreSnapshot();
1108
1125
  {
1109
- cwd !== moduleRoot && BacktestKit.Log.useJsonl();
1126
+ cwd !== moduleRoot && Setup.update();
1110
1127
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
1111
1128
  dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
1112
1129
  }
@@ -1232,10 +1249,12 @@ class LiveMainService {
1232
1249
  this.frontendProviderService = inject(TYPES.frontendProviderService);
1233
1250
  this.telegramProviderService = inject(TYPES.telegramProviderService);
1234
1251
  this.moduleConnectionService = inject(TYPES.moduleConnectionService);
1252
+ this.configConnectionService = inject(TYPES.configConnectionService);
1235
1253
  this.run = functoolsKit.singleshot(async (payload) => {
1236
1254
  this.loggerService.log("liveMainService run", {
1237
1255
  payload,
1238
1256
  });
1257
+ await this.configConnectionService.loadConfig("setup.config");
1239
1258
  {
1240
1259
  await this.configService.waitForInit();
1241
1260
  Setup.enable();
@@ -1250,7 +1269,7 @@ class LiveMainService {
1250
1269
  }
1251
1270
  {
1252
1271
  await this.resolveService.attachJavascript(payload.entryPoint);
1253
- await this.moduleConnectionService.loadModule("./live.module");
1272
+ await this.moduleConnectionService.loadModule("live.module");
1254
1273
  }
1255
1274
  {
1256
1275
  this.exchangeSchemaService.addSchema();
@@ -1318,8 +1337,10 @@ class PaperMainService {
1318
1337
  this.frontendProviderService = inject(TYPES.frontendProviderService);
1319
1338
  this.telegramProviderService = inject(TYPES.telegramProviderService);
1320
1339
  this.moduleConnectionService = inject(TYPES.moduleConnectionService);
1340
+ this.configConnectionService = inject(TYPES.configConnectionService);
1321
1341
  this.run = functoolsKit.singleshot(async (payload) => {
1322
1342
  this.loggerService.log("paperMainService init");
1343
+ await this.configConnectionService.loadConfig("setup.config");
1323
1344
  {
1324
1345
  await this.configService.waitForInit();
1325
1346
  Setup.enable();
@@ -1334,7 +1355,7 @@ class PaperMainService {
1334
1355
  }
1335
1356
  {
1336
1357
  await this.resolveService.attachJavascript(payload.entryPoint);
1337
- await this.moduleConnectionService.loadModule("./paper.module");
1358
+ await this.moduleConnectionService.loadModule("paper.module");
1338
1359
  }
1339
1360
  {
1340
1361
  this.exchangeSchemaService.addSchema();
@@ -2532,12 +2553,22 @@ class ModuleConnectionService {
2532
2553
  this.loggerService = inject(TYPES.loggerService);
2533
2554
  this.resolveService = inject(TYPES.resolveService);
2534
2555
  this.loaderService = inject(TYPES.loaderService);
2535
- this.loadModule = async (fileName) => {
2536
- this.loggerService.log("moduleConnectionService loadModule", {
2556
+ this.hasModule = (fileName) => {
2557
+ this.loggerService.log("moduleConnectionService hasModule", {
2537
2558
  fileName,
2538
2559
  });
2539
- return await LOAD_MODULE_MODULE_FN(fileName, this);
2560
+ return this.loadModule.has(fileName);
2540
2561
  };
2562
+ this.loadModule = functoolsKit.memoize(([fileName]) => `${fileName}`, async (fileName) => {
2563
+ this.loggerService.log("moduleConnectionService loadModule", {
2564
+ fileName,
2565
+ });
2566
+ const module = await LOAD_MODULE_MODULE_FN(fileName, this);
2567
+ if (!module) {
2568
+ this.loadModule.clear(fileName);
2569
+ }
2570
+ return module;
2571
+ });
2541
2572
  }
2542
2573
  }
2543
2574
 
@@ -2580,6 +2611,18 @@ class BabelService {
2580
2611
  }
2581
2612
  }
2582
2613
 
2614
+ const require$1 = Module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
2615
+ const ModuleWithCache = Module;
2616
+ function overrideModule(moduleName, newExports) {
2617
+ const cache = ModuleWithCache._cache;
2618
+ const key = require$1.resolve(moduleName);
2619
+ if (!cache[key]) {
2620
+ cache[key] = new ModuleWithCache(key);
2621
+ cache[key].loaded = true;
2622
+ }
2623
+ cache[key].exports = newExports;
2624
+ }
2625
+
2583
2626
  /**
2584
2627
  * This file is used to define any aliases for imports in the client code. This is useful for mocking modules during testing or for providing alternative implementations of certain modules.
2585
2628
  * For example, if we want to mock the "pinets" module during testing, we can add an entry to the IMPORT_ALIAS object that points to our mock implementation. Then, when the client code tries to import "pinets", it will receive our mock implementation instead of the actual "pinets" module.
@@ -2594,7 +2637,7 @@ class BabelService {
2594
2637
  const IMPORT_ALIAS = {};
2595
2638
 
2596
2639
  const USE_ESMODULE_DEFAULT = false;
2597
- const IMPORT_PATHS_EXCLUDE = new Set(["dump", "logs", "modules", "node_modules"]);
2640
+ const IMPORT_PATHS_EXCLUDE = new Set(["dump", "logs", "modules", "config", "node_modules"]);
2598
2641
  const TRANSPILE_FN = functoolsKit.memoize(([path]) => `${path}`, (path, code, self, require) => {
2599
2642
  const __filename = self.__filename;
2600
2643
  const __dirname = self.__dirname;
@@ -2762,7 +2805,7 @@ class ClientLoader {
2762
2805
  this.params.logger.log("ClientLoader baseRequire", {
2763
2806
  basePath: this.params.path,
2764
2807
  });
2765
- return module$1.createRequire(this.__filename);
2808
+ return Module.createRequire(this.__filename);
2766
2809
  });
2767
2810
  this.__filename = path.join(params.path, "index.cjs");
2768
2811
  this.__dirname = path.dirname(this.__filename);
@@ -2816,16 +2859,21 @@ globalThis.BacktestKitGraph = BacktestKitGraph__namespace;
2816
2859
  globalThis.BacktestKitOllama = BacktestKitOllama__namespace;
2817
2860
  globalThis.BacktestKitPinets = BacktestKitPinets__namespace;
2818
2861
  globalThis.BacktestKitSignals = BacktestKitSignals__namespace;
2862
+ overrideModule('backtest-kit', BacktestKit__namespace);
2863
+ overrideModule('@backtest-kit/cli', BacktestKitCli);
2864
+ overrideModule('@backtest-kit/ui', BacktestKitUi__namespace);
2865
+ overrideModule('@backtest-kit/graph', BacktestKitGraph__namespace);
2866
+ overrideModule('@backtest-kit/ollama', BacktestKitOllama__namespace);
2867
+ overrideModule('@backtest-kit/pinets', BacktestKitPinets__namespace);
2868
+ overrideModule('@backtest-kit/signals', BacktestKitSignals__namespace);
2819
2869
 
2820
2870
  const GET_ALIAS_EXPORTS_FN = (self) => {
2821
2871
  const instance = self.getInstance(self.resolveService.OVERRIDE_CONFIG_DIR);
2822
- if (!instance.check("alias.module")) {
2872
+ if (!instance.check("alias.config")) {
2823
2873
  return null;
2824
2874
  }
2825
- const exports = instance.import("alias.module");
2826
- return "default" in exports
2827
- ? exports.default
2828
- : exports;
2875
+ const exports = instance.import("alias.config");
2876
+ return "default" in exports ? exports.default : exports;
2829
2877
  };
2830
2878
  const INIT_ALIAS_FN = (self) => {
2831
2879
  const alias = GET_ALIAS_EXPORTS_FN(self);
@@ -2835,7 +2883,10 @@ const INIT_ALIAS_FN = (self) => {
2835
2883
  if (!functoolsKit.isObject(alias)) {
2836
2884
  return;
2837
2885
  }
2838
- Object.assign(IMPORT_ALIAS, alias);
2886
+ {
2887
+ Object.entries(alias).forEach(([name, module]) => overrideModule(name, module));
2888
+ Object.assign(IMPORT_ALIAS, alias);
2889
+ }
2839
2890
  };
2840
2891
  class LoaderService {
2841
2892
  constructor() {
@@ -2906,12 +2957,22 @@ class ConfigConnectionService {
2906
2957
  this.loggerService = inject(TYPES.loggerService);
2907
2958
  this.resolveService = inject(TYPES.resolveService);
2908
2959
  this.loaderService = inject(TYPES.loaderService);
2909
- this.loadConfig = (fileName) => {
2910
- this.loggerService.log("configConnectionService loadConfig", {
2960
+ this.hasConfig = (fileName) => {
2961
+ this.loggerService.log("configConnectionService hasConfig", {
2911
2962
  fileName,
2912
2963
  });
2913
- return LOAD_CONFIG_CONFIG_FN(fileName, this);
2964
+ return this.loadConfig.has(fileName);
2914
2965
  };
2966
+ this.loadConfig = functoolsKit.memoize(([fileName]) => `${fileName}`, async (fileName) => {
2967
+ this.loggerService.log("configConnectionService loadConfig", {
2968
+ fileName,
2969
+ });
2970
+ const config = await LOAD_CONFIG_CONFIG_FN(fileName, this);
2971
+ if (!config) {
2972
+ this.loadConfig.clear(fileName);
2973
+ }
2974
+ return config;
2975
+ });
2915
2976
  }
2916
2977
  }
2917
2978
 
@@ -3067,7 +3128,7 @@ const main$g = async () => {
3067
3128
  if (MODES.some((mode) => values[mode])) {
3068
3129
  return;
3069
3130
  }
3070
- process.stdout.write(`@backtest-kit/cli ${"9.2.0"}\n`);
3131
+ process.stdout.write(`@backtest-kit/cli ${"9.3.0"}\n`);
3071
3132
  process.stdout.write("\n");
3072
3133
  process.stdout.write(`Run with --help to see available commands.\n`);
3073
3134
  process.stdout.write("\n");
@@ -3257,10 +3318,10 @@ const main$b = async () => {
3257
3318
  main$b();
3258
3319
 
3259
3320
  const MODE_MODULE = {
3260
- backtest: "./backtest.module",
3261
- live: "./live.module",
3262
- paper: "./paper.module",
3263
- walker: "./walker.module",
3321
+ backtest: "backtest.module",
3322
+ live: "live.module",
3323
+ paper: "paper.module",
3324
+ walker: "walker.module",
3264
3325
  };
3265
3326
  const resolveMode = (values) => {
3266
3327
  const enabled = ["backtest", "live", "paper", "walker"].filter((mode) => Boolean(values[mode]));
@@ -3355,8 +3416,11 @@ const main$a = async () => {
3355
3416
  if (!values.noFlush) {
3356
3417
  await flush(entryPoint);
3357
3418
  }
3358
- await cli.configService.waitForInit();
3359
- Setup.enable();
3419
+ await cli.configConnectionService.loadConfig("setup.config");
3420
+ {
3421
+ await cli.configService.waitForInit();
3422
+ Setup.enable();
3423
+ }
3360
3424
  cli.frontendProviderService.connect();
3361
3425
  cli.telegramProviderService.connect();
3362
3426
  {
@@ -3451,7 +3515,8 @@ const main$7 = async () => {
3451
3515
  const cwd = process.cwd();
3452
3516
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
3453
3517
  }
3454
- await cli.moduleConnectionService.loadModule("./pine.module");
3518
+ await cli.configConnectionService.loadConfig("setup.config");
3519
+ await cli.moduleConnectionService.loadModule("pine.module");
3455
3520
  {
3456
3521
  await cli.exchangeSchemaService.addSchema();
3457
3522
  await cli.symbolSchemaService.addSchema();
@@ -3528,6 +3593,7 @@ const main$6 = async () => {
3528
3593
  console.warn("--editor and --pine are mutually exclusive. Use one at a time.");
3529
3594
  process.exit(1);
3530
3595
  }
3596
+ await cli.configConnectionService.loadConfig("setup.config");
3531
3597
  {
3532
3598
  await cli.configService.waitForInit();
3533
3599
  Setup.enable();
@@ -3536,7 +3602,7 @@ const main$6 = async () => {
3536
3602
  const cwd = process.cwd();
3537
3603
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
3538
3604
  }
3539
- await cli.moduleConnectionService.loadModule("./editor.module");
3605
+ await cli.moduleConnectionService.loadModule("editor.module");
3540
3606
  {
3541
3607
  await cli.exchangeSchemaService.addSchema();
3542
3608
  }
@@ -3569,7 +3635,8 @@ const main$5 = async () => {
3569
3635
  const cwd = process.cwd();
3570
3636
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
3571
3637
  }
3572
- await cli.moduleConnectionService.loadModule("./dump.module");
3638
+ await cli.configConnectionService.loadConfig("setup.config");
3639
+ await cli.moduleConnectionService.loadModule("dump.module");
3573
3640
  {
3574
3641
  await cli.exchangeSchemaService.addSchema();
3575
3642
  await cli.symbolSchemaService.addSchema();
@@ -3636,7 +3703,8 @@ const main$4 = async () => {
3636
3703
  const cwd = process.cwd();
3637
3704
  dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
3638
3705
  }
3639
- await cli.moduleConnectionService.loadModule("./pnldebug.module");
3706
+ await cli.configConnectionService.loadConfig("setup.config");
3707
+ await cli.moduleConnectionService.loadModule("pnldebug.module");
3640
3708
  {
3641
3709
  await cli.exchangeSchemaService.addSchema();
3642
3710
  await cli.symbolSchemaService.addSchema();
@@ -4090,7 +4158,7 @@ const main$1 = async () => {
4090
4158
  if (!values.help) {
4091
4159
  return;
4092
4160
  }
4093
- process.stdout.write(`@backtest-kit/cli ${"9.2.0"}\n\n`);
4161
+ process.stdout.write(`@backtest-kit/cli ${"9.3.0"}\n\n`);
4094
4162
  process.stdout.write(HELP_TEXT);
4095
4163
  process.exit(0);
4096
4164
  };
@@ -4104,7 +4172,7 @@ const main = async () => {
4104
4172
  if (!values.version) {
4105
4173
  return;
4106
4174
  }
4107
- process.stdout.write(`@backtest-kit/cli ${"9.2.0"}\n`);
4175
+ process.stdout.write(`@backtest-kit/cli ${"9.3.0"}\n`);
4108
4176
  process.exit(0);
4109
4177
  };
4110
4178
  main();