@backtest-kit/cli 9.3.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 +2 -0
- package/build/index.cjs +195 -140
- package/build/index.mjs +195 -140
- package/docker/package.json +6 -6
- package/package.json +13 -13
- package/template/project/package.mustache +5 -5
- package/types.d.ts +5 -2
package/README.md
CHANGED
|
@@ -732,6 +732,8 @@ Broker.enable();
|
|
|
732
732
|
|
|
733
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
|
+
**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
|
+
|
|
735
737
|
### Example: MongoDB + Redis persistence via `@backtest-kit/mongo`
|
|
736
738
|
|
|
737
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:
|
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
|
|
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 &&
|
|
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();
|
|
@@ -897,6 +910,7 @@ class BacktestMainService {
|
|
|
897
910
|
this.loggerService.log("backtestMainService run", {
|
|
898
911
|
payload,
|
|
899
912
|
});
|
|
913
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
900
914
|
{
|
|
901
915
|
await this.configService.waitForInit();
|
|
902
916
|
Setup.enable();
|
|
@@ -909,7 +923,6 @@ class BacktestMainService {
|
|
|
909
923
|
const cwd = process.cwd();
|
|
910
924
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
911
925
|
}
|
|
912
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
913
926
|
{
|
|
914
927
|
await this.resolveService.attachJavascript(payload.entryPoint);
|
|
915
928
|
await this.moduleConnectionService.loadModule("backtest.module");
|
|
@@ -1016,6 +1029,7 @@ class WalkerMainService {
|
|
|
1016
1029
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
1017
1030
|
this.run = functoolsKit.singleshot(async (payload) => {
|
|
1018
1031
|
this.loggerService.log("walkerMainService run", { payload });
|
|
1032
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
1019
1033
|
{
|
|
1020
1034
|
await this.configService.waitForInit();
|
|
1021
1035
|
Setup.enable();
|
|
@@ -1034,7 +1048,7 @@ class WalkerMainService {
|
|
|
1034
1048
|
Setup.enable();
|
|
1035
1049
|
}
|
|
1036
1050
|
{
|
|
1037
|
-
cwd !== moduleRoot &&
|
|
1051
|
+
cwd !== moduleRoot && Setup.update();
|
|
1038
1052
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1039
1053
|
dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
|
|
1040
1054
|
}
|
|
@@ -1053,7 +1067,6 @@ class WalkerMainService {
|
|
|
1053
1067
|
const cwd = process.cwd();
|
|
1054
1068
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1055
1069
|
}
|
|
1056
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
1057
1070
|
await this.moduleConnectionService.loadModule("walker.module");
|
|
1058
1071
|
{
|
|
1059
1072
|
this.exchangeSchemaService.addSchema();
|
|
@@ -1110,7 +1123,7 @@ class WalkerMainService {
|
|
|
1110
1123
|
}
|
|
1111
1124
|
restoreSnapshot();
|
|
1112
1125
|
{
|
|
1113
|
-
cwd !== moduleRoot &&
|
|
1126
|
+
cwd !== moduleRoot && Setup.update();
|
|
1114
1127
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1115
1128
|
dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
|
|
1116
1129
|
}
|
|
@@ -1241,6 +1254,7 @@ class LiveMainService {
|
|
|
1241
1254
|
this.loggerService.log("liveMainService run", {
|
|
1242
1255
|
payload,
|
|
1243
1256
|
});
|
|
1257
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
1244
1258
|
{
|
|
1245
1259
|
await this.configService.waitForInit();
|
|
1246
1260
|
Setup.enable();
|
|
@@ -1253,7 +1267,6 @@ class LiveMainService {
|
|
|
1253
1267
|
const cwd = process.cwd();
|
|
1254
1268
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1255
1269
|
}
|
|
1256
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
1257
1270
|
{
|
|
1258
1271
|
await this.resolveService.attachJavascript(payload.entryPoint);
|
|
1259
1272
|
await this.moduleConnectionService.loadModule("live.module");
|
|
@@ -1327,6 +1340,7 @@ class PaperMainService {
|
|
|
1327
1340
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
1328
1341
|
this.run = functoolsKit.singleshot(async (payload) => {
|
|
1329
1342
|
this.loggerService.log("paperMainService init");
|
|
1343
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
1330
1344
|
{
|
|
1331
1345
|
await this.configService.waitForInit();
|
|
1332
1346
|
Setup.enable();
|
|
@@ -1339,7 +1353,6 @@ class PaperMainService {
|
|
|
1339
1353
|
const cwd = process.cwd();
|
|
1340
1354
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1341
1355
|
}
|
|
1342
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
1343
1356
|
{
|
|
1344
1357
|
await this.resolveService.attachJavascript(payload.entryPoint);
|
|
1345
1358
|
await this.moduleConnectionService.loadModule("paper.module");
|
|
@@ -2540,12 +2553,22 @@ class ModuleConnectionService {
|
|
|
2540
2553
|
this.loggerService = inject(TYPES.loggerService);
|
|
2541
2554
|
this.resolveService = inject(TYPES.resolveService);
|
|
2542
2555
|
this.loaderService = inject(TYPES.loaderService);
|
|
2543
|
-
this.
|
|
2544
|
-
this.loggerService.log("moduleConnectionService
|
|
2556
|
+
this.hasModule = (fileName) => {
|
|
2557
|
+
this.loggerService.log("moduleConnectionService hasModule", {
|
|
2545
2558
|
fileName,
|
|
2546
2559
|
});
|
|
2547
|
-
return
|
|
2560
|
+
return this.loadModule.has(fileName);
|
|
2548
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
|
+
});
|
|
2549
2572
|
}
|
|
2550
2573
|
}
|
|
2551
2574
|
|
|
@@ -2588,6 +2611,18 @@ class BabelService {
|
|
|
2588
2611
|
}
|
|
2589
2612
|
}
|
|
2590
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
|
+
|
|
2591
2626
|
/**
|
|
2592
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.
|
|
2593
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.
|
|
@@ -2770,7 +2805,7 @@ class ClientLoader {
|
|
|
2770
2805
|
this.params.logger.log("ClientLoader baseRequire", {
|
|
2771
2806
|
basePath: this.params.path,
|
|
2772
2807
|
});
|
|
2773
|
-
return
|
|
2808
|
+
return Module.createRequire(this.__filename);
|
|
2774
2809
|
});
|
|
2775
2810
|
this.__filename = path.join(params.path, "index.cjs");
|
|
2776
2811
|
this.__dirname = path.dirname(this.__filename);
|
|
@@ -2824,6 +2859,13 @@ globalThis.BacktestKitGraph = BacktestKitGraph__namespace;
|
|
|
2824
2859
|
globalThis.BacktestKitOllama = BacktestKitOllama__namespace;
|
|
2825
2860
|
globalThis.BacktestKitPinets = BacktestKitPinets__namespace;
|
|
2826
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);
|
|
2827
2869
|
|
|
2828
2870
|
const GET_ALIAS_EXPORTS_FN = (self) => {
|
|
2829
2871
|
const instance = self.getInstance(self.resolveService.OVERRIDE_CONFIG_DIR);
|
|
@@ -2831,9 +2873,7 @@ const GET_ALIAS_EXPORTS_FN = (self) => {
|
|
|
2831
2873
|
return null;
|
|
2832
2874
|
}
|
|
2833
2875
|
const exports = instance.import("alias.config");
|
|
2834
|
-
return "default" in exports
|
|
2835
|
-
? exports.default
|
|
2836
|
-
: exports;
|
|
2876
|
+
return "default" in exports ? exports.default : exports;
|
|
2837
2877
|
};
|
|
2838
2878
|
const INIT_ALIAS_FN = (self) => {
|
|
2839
2879
|
const alias = GET_ALIAS_EXPORTS_FN(self);
|
|
@@ -2843,7 +2883,10 @@ const INIT_ALIAS_FN = (self) => {
|
|
|
2843
2883
|
if (!functoolsKit.isObject(alias)) {
|
|
2844
2884
|
return;
|
|
2845
2885
|
}
|
|
2846
|
-
|
|
2886
|
+
{
|
|
2887
|
+
Object.entries(alias).forEach(([name, module]) => overrideModule(name, module));
|
|
2888
|
+
Object.assign(IMPORT_ALIAS, alias);
|
|
2889
|
+
}
|
|
2847
2890
|
};
|
|
2848
2891
|
class LoaderService {
|
|
2849
2892
|
constructor() {
|
|
@@ -2914,12 +2957,22 @@ class ConfigConnectionService {
|
|
|
2914
2957
|
this.loggerService = inject(TYPES.loggerService);
|
|
2915
2958
|
this.resolveService = inject(TYPES.resolveService);
|
|
2916
2959
|
this.loaderService = inject(TYPES.loaderService);
|
|
2917
|
-
this.
|
|
2918
|
-
this.loggerService.log("configConnectionService
|
|
2960
|
+
this.hasConfig = (fileName) => {
|
|
2961
|
+
this.loggerService.log("configConnectionService hasConfig", {
|
|
2919
2962
|
fileName,
|
|
2920
2963
|
});
|
|
2921
|
-
return
|
|
2964
|
+
return this.loadConfig.has(fileName);
|
|
2922
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
|
+
});
|
|
2923
2976
|
}
|
|
2924
2977
|
}
|
|
2925
2978
|
|
|
@@ -3363,15 +3416,17 @@ const main$a = async () => {
|
|
|
3363
3416
|
if (!values.noFlush) {
|
|
3364
3417
|
await flush(entryPoint);
|
|
3365
3418
|
}
|
|
3366
|
-
await cli.
|
|
3367
|
-
|
|
3419
|
+
await cli.configConnectionService.loadConfig("setup.config");
|
|
3420
|
+
{
|
|
3421
|
+
await cli.configService.waitForInit();
|
|
3422
|
+
Setup.enable();
|
|
3423
|
+
}
|
|
3368
3424
|
cli.frontendProviderService.connect();
|
|
3369
3425
|
cli.telegramProviderService.connect();
|
|
3370
3426
|
{
|
|
3371
3427
|
const cwd = process.cwd();
|
|
3372
3428
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3373
3429
|
}
|
|
3374
|
-
await cli.configConnectionService.loadConfig("setup.config");
|
|
3375
3430
|
await cli.moduleConnectionService.loadModule(MODE_MODULE[mode]);
|
|
3376
3431
|
listenFinish();
|
|
3377
3432
|
createGracefulShutdown(mode)();
|
|
@@ -3538,6 +3593,7 @@ const main$6 = async () => {
|
|
|
3538
3593
|
console.warn("--editor and --pine are mutually exclusive. Use one at a time.");
|
|
3539
3594
|
process.exit(1);
|
|
3540
3595
|
}
|
|
3596
|
+
await cli.configConnectionService.loadConfig("setup.config");
|
|
3541
3597
|
{
|
|
3542
3598
|
await cli.configService.waitForInit();
|
|
3543
3599
|
Setup.enable();
|
|
@@ -3546,7 +3602,6 @@ const main$6 = async () => {
|
|
|
3546
3602
|
const cwd = process.cwd();
|
|
3547
3603
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3548
3604
|
}
|
|
3549
|
-
await cli.configConnectionService.loadConfig("setup.config");
|
|
3550
3605
|
await cli.moduleConnectionService.loadModule("editor.module");
|
|
3551
3606
|
{
|
|
3552
3607
|
await cli.exchangeSchemaService.addSchema();
|
package/build/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as BacktestKit from 'backtest-kit';
|
|
3
|
-
import { setConfig,
|
|
3
|
+
import { setConfig, Notification, Recent, Storage, Markdown, Report, Dump, State, Memory, MarkdownWriter, ReportWriter, PersistSignalAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistPartialAdapter, PersistBreakevenAdapter, PersistCandleAdapter, PersistStorageAdapter, PersistNotificationAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistIntervalAdapter, PersistMemoryAdapter, PersistRecentAdapter, PersistStateAdapter, PersistSessionAdapter, Log, StorageLive, StorageBacktest, NotificationLive, NotificationBacktest, RecentLive, RecentBacktest, SessionLive, SessionBacktest, MemoryLive, MemoryBacktest, StateLive, StateBacktest, listExchangeSchema, addExchangeSchema, roundTicks, listFrameSchema, addFrameSchema, listenDoneLive, listenDoneBacktest, shutdown, listenSignal, listStrategySchema, overrideExchangeSchema, Backtest, System, Cache, Interval, alignToInterval, addWalkerSchema, overrideWalkerSchema, Walker, listenDoneWalker, Live, getCandles, checkCandles, warmCandles, listenRisk, listenStrategyCommit, listenSync, listenSignalNotify, Exchange } from 'backtest-kit';
|
|
4
4
|
import { getErrorMessage, errorData, singleshot, str, BehaviorSubject, compose, createAwaiter, execpool, queued, sleep, randomString, TIMEOUT_SYMBOL, typo, retry, trycatch, memoize, isObject } from 'functools-kit';
|
|
5
5
|
import fs, { constants, realpathSync } from 'fs';
|
|
6
6
|
import * as stackTrace from 'stack-trace';
|
|
@@ -24,7 +24,7 @@ import { JSDOM } from 'jsdom';
|
|
|
24
24
|
import Mustache from 'mustache';
|
|
25
25
|
import { registerPlugin, transform } from '@babel/standalone';
|
|
26
26
|
import pluginUMD from '@babel/plugin-transform-modules-umd';
|
|
27
|
-
import { createRequire } from 'module';
|
|
27
|
+
import Module, { createRequire } from 'module';
|
|
28
28
|
import * as BacktestKitGraph from '@backtest-kit/graph';
|
|
29
29
|
import * as BacktestKitOllama from '@backtest-kit/ollama';
|
|
30
30
|
import * as BacktestKitPinets from '@backtest-kit/pinets';
|
|
@@ -241,6 +241,136 @@ const TYPES = {
|
|
|
241
241
|
|
|
242
242
|
const entrySubject = new BehaviorSubject();
|
|
243
243
|
|
|
244
|
+
const SETUP_ADAPTER_FN = () => {
|
|
245
|
+
{
|
|
246
|
+
Dump.useMarkdown();
|
|
247
|
+
}
|
|
248
|
+
{
|
|
249
|
+
SessionLive.usePersist();
|
|
250
|
+
SessionBacktest.useLocal();
|
|
251
|
+
}
|
|
252
|
+
{
|
|
253
|
+
StorageLive.usePersist();
|
|
254
|
+
StorageBacktest.useMemory();
|
|
255
|
+
}
|
|
256
|
+
{
|
|
257
|
+
RecentLive.usePersist();
|
|
258
|
+
RecentBacktest.useMemory();
|
|
259
|
+
}
|
|
260
|
+
{
|
|
261
|
+
NotificationLive.usePersist();
|
|
262
|
+
NotificationBacktest.useMemory();
|
|
263
|
+
}
|
|
264
|
+
{
|
|
265
|
+
RecentLive.usePersist();
|
|
266
|
+
RecentBacktest.useMemory();
|
|
267
|
+
}
|
|
268
|
+
{
|
|
269
|
+
MemoryLive.usePersist();
|
|
270
|
+
MemoryBacktest.useLocal();
|
|
271
|
+
}
|
|
272
|
+
{
|
|
273
|
+
StateLive.usePersist();
|
|
274
|
+
StateBacktest.useLocal();
|
|
275
|
+
}
|
|
276
|
+
{
|
|
277
|
+
Markdown.useDummy();
|
|
278
|
+
Log.useJsonl();
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
class SetupUtils {
|
|
282
|
+
constructor() {
|
|
283
|
+
this.enable = singleshot(() => {
|
|
284
|
+
cli.loggerService.debug("SetupUtils enable");
|
|
285
|
+
{
|
|
286
|
+
const config = cli.configService.getNotificationConfig();
|
|
287
|
+
Notification.enable(config);
|
|
288
|
+
}
|
|
289
|
+
{
|
|
290
|
+
Recent.enable();
|
|
291
|
+
Storage.enable();
|
|
292
|
+
}
|
|
293
|
+
{
|
|
294
|
+
Markdown.enable();
|
|
295
|
+
Report.enable();
|
|
296
|
+
Dump.enable();
|
|
297
|
+
State.enable();
|
|
298
|
+
Memory.enable();
|
|
299
|
+
}
|
|
300
|
+
if (!cli.configConnectionService.hasConfig("setup.config")) {
|
|
301
|
+
SETUP_ADAPTER_FN();
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
this.clear = () => {
|
|
305
|
+
cli.loggerService.debug("SetupUtils clear");
|
|
306
|
+
if (!this.enable.hasValue()) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
this.enable.clear();
|
|
310
|
+
{
|
|
311
|
+
Recent.disable();
|
|
312
|
+
Storage.disable();
|
|
313
|
+
Notification.disable();
|
|
314
|
+
}
|
|
315
|
+
{
|
|
316
|
+
Markdown.disable();
|
|
317
|
+
Report.disable();
|
|
318
|
+
Dump.disable();
|
|
319
|
+
Memory.disable();
|
|
320
|
+
}
|
|
321
|
+
{
|
|
322
|
+
Markdown.clear();
|
|
323
|
+
Report.clear();
|
|
324
|
+
MarkdownWriter.clear();
|
|
325
|
+
ReportWriter.clear();
|
|
326
|
+
}
|
|
327
|
+
{
|
|
328
|
+
PersistSignalAdapter.clear();
|
|
329
|
+
PersistRiskAdapter.clear();
|
|
330
|
+
PersistScheduleAdapter.clear();
|
|
331
|
+
PersistPartialAdapter.clear();
|
|
332
|
+
PersistBreakevenAdapter.clear();
|
|
333
|
+
PersistCandleAdapter.clear();
|
|
334
|
+
PersistStorageAdapter.clear();
|
|
335
|
+
PersistNotificationAdapter.clear();
|
|
336
|
+
PersistLogAdapter.clear();
|
|
337
|
+
PersistMeasureAdapter.clear();
|
|
338
|
+
PersistIntervalAdapter.clear();
|
|
339
|
+
PersistMemoryAdapter.clear();
|
|
340
|
+
PersistRecentAdapter.clear();
|
|
341
|
+
PersistStateAdapter.clear();
|
|
342
|
+
PersistSessionAdapter.clear();
|
|
343
|
+
}
|
|
344
|
+
{
|
|
345
|
+
Dump.clear();
|
|
346
|
+
Log.clear();
|
|
347
|
+
Markdown.clear();
|
|
348
|
+
}
|
|
349
|
+
{
|
|
350
|
+
StorageLive.clear();
|
|
351
|
+
StorageBacktest.clear();
|
|
352
|
+
}
|
|
353
|
+
{
|
|
354
|
+
NotificationLive.clear();
|
|
355
|
+
NotificationBacktest.clear();
|
|
356
|
+
}
|
|
357
|
+
{
|
|
358
|
+
RecentLive.clear();
|
|
359
|
+
RecentBacktest.clear();
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
this.update = () => {
|
|
363
|
+
cli.loggerService.debug("SetupUtils update");
|
|
364
|
+
if (cli.configConnectionService.hasConfig("setup.config")) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
Log.useJsonl();
|
|
368
|
+
Dump.useMarkdown();
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const Setup = new SetupUtils();
|
|
373
|
+
|
|
244
374
|
const __filename$2 = fileURLToPath(import.meta.url);
|
|
245
375
|
const __dirname$2 = path.dirname(__filename$2);
|
|
246
376
|
let _is_launched = false;
|
|
@@ -302,7 +432,7 @@ class ResolveService {
|
|
|
302
432
|
{
|
|
303
433
|
const cwd = process.cwd();
|
|
304
434
|
process.chdir(moduleRoot);
|
|
305
|
-
cwd !== moduleRoot &&
|
|
435
|
+
cwd !== moduleRoot && Setup.update();
|
|
306
436
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
307
437
|
dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
|
|
308
438
|
this.loaderService.import(absolutePath);
|
|
@@ -728,123 +858,6 @@ const notifyVerbose = singleshot(() => {
|
|
|
728
858
|
});
|
|
729
859
|
});
|
|
730
860
|
|
|
731
|
-
class SetupUtils {
|
|
732
|
-
constructor() {
|
|
733
|
-
this.enable = singleshot(() => {
|
|
734
|
-
cli.loggerService.debug("SetupUtils enable");
|
|
735
|
-
{
|
|
736
|
-
const config = cli.configService.getNotificationConfig();
|
|
737
|
-
Notification.enable(config);
|
|
738
|
-
}
|
|
739
|
-
{
|
|
740
|
-
Recent.enable();
|
|
741
|
-
Storage.enable();
|
|
742
|
-
}
|
|
743
|
-
{
|
|
744
|
-
Markdown.enable();
|
|
745
|
-
Report.enable();
|
|
746
|
-
Dump.enable();
|
|
747
|
-
State.enable();
|
|
748
|
-
Memory.enable();
|
|
749
|
-
}
|
|
750
|
-
{
|
|
751
|
-
Dump.useMarkdown();
|
|
752
|
-
}
|
|
753
|
-
{
|
|
754
|
-
SessionLive.usePersist();
|
|
755
|
-
SessionBacktest.useLocal();
|
|
756
|
-
}
|
|
757
|
-
{
|
|
758
|
-
StorageLive.usePersist();
|
|
759
|
-
StorageBacktest.useMemory();
|
|
760
|
-
}
|
|
761
|
-
{
|
|
762
|
-
RecentLive.usePersist();
|
|
763
|
-
RecentBacktest.useMemory();
|
|
764
|
-
}
|
|
765
|
-
{
|
|
766
|
-
NotificationLive.usePersist();
|
|
767
|
-
NotificationBacktest.useMemory();
|
|
768
|
-
}
|
|
769
|
-
{
|
|
770
|
-
RecentLive.usePersist();
|
|
771
|
-
RecentBacktest.useMemory();
|
|
772
|
-
}
|
|
773
|
-
{
|
|
774
|
-
MemoryLive.usePersist();
|
|
775
|
-
MemoryBacktest.useLocal();
|
|
776
|
-
}
|
|
777
|
-
{
|
|
778
|
-
StateLive.usePersist();
|
|
779
|
-
StateBacktest.useLocal();
|
|
780
|
-
}
|
|
781
|
-
{
|
|
782
|
-
Markdown.useDummy();
|
|
783
|
-
Log.useJsonl();
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
this.clear = () => {
|
|
787
|
-
cli.loggerService.debug("SetupUtils clear");
|
|
788
|
-
if (!this.enable.hasValue()) {
|
|
789
|
-
return;
|
|
790
|
-
}
|
|
791
|
-
this.enable.clear();
|
|
792
|
-
{
|
|
793
|
-
Recent.disable();
|
|
794
|
-
Storage.disable();
|
|
795
|
-
Notification.disable();
|
|
796
|
-
}
|
|
797
|
-
{
|
|
798
|
-
Markdown.disable();
|
|
799
|
-
Report.disable();
|
|
800
|
-
Dump.disable();
|
|
801
|
-
Memory.disable();
|
|
802
|
-
}
|
|
803
|
-
{
|
|
804
|
-
Markdown.clear();
|
|
805
|
-
Report.clear();
|
|
806
|
-
MarkdownWriter.clear();
|
|
807
|
-
ReportWriter.clear();
|
|
808
|
-
}
|
|
809
|
-
{
|
|
810
|
-
PersistSignalAdapter.clear();
|
|
811
|
-
PersistRiskAdapter.clear();
|
|
812
|
-
PersistScheduleAdapter.clear();
|
|
813
|
-
PersistPartialAdapter.clear();
|
|
814
|
-
PersistBreakevenAdapter.clear();
|
|
815
|
-
PersistCandleAdapter.clear();
|
|
816
|
-
PersistStorageAdapter.clear();
|
|
817
|
-
PersistNotificationAdapter.clear();
|
|
818
|
-
PersistLogAdapter.clear();
|
|
819
|
-
PersistMeasureAdapter.clear();
|
|
820
|
-
PersistIntervalAdapter.clear();
|
|
821
|
-
PersistMemoryAdapter.clear();
|
|
822
|
-
PersistRecentAdapter.clear();
|
|
823
|
-
PersistStateAdapter.clear();
|
|
824
|
-
PersistSessionAdapter.clear();
|
|
825
|
-
}
|
|
826
|
-
{
|
|
827
|
-
Dump.clear();
|
|
828
|
-
Log.clear();
|
|
829
|
-
Markdown.clear();
|
|
830
|
-
}
|
|
831
|
-
{
|
|
832
|
-
StorageLive.clear();
|
|
833
|
-
StorageBacktest.clear();
|
|
834
|
-
}
|
|
835
|
-
{
|
|
836
|
-
NotificationLive.clear();
|
|
837
|
-
NotificationBacktest.clear();
|
|
838
|
-
}
|
|
839
|
-
{
|
|
840
|
-
RecentLive.clear();
|
|
841
|
-
RecentBacktest.clear();
|
|
842
|
-
}
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
const Setup = new SetupUtils();
|
|
847
|
-
|
|
848
861
|
const DEFAULT_CACHE_LIST$1 = ["1m", "15m", "30m", "1h", "4h"];
|
|
849
862
|
const GET_CACHE_INTERVAL_LIST_FN$1 = () => {
|
|
850
863
|
const { values } = getArgs();
|
|
@@ -872,6 +885,7 @@ class BacktestMainService {
|
|
|
872
885
|
this.loggerService.log("backtestMainService run", {
|
|
873
886
|
payload,
|
|
874
887
|
});
|
|
888
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
875
889
|
{
|
|
876
890
|
await this.configService.waitForInit();
|
|
877
891
|
Setup.enable();
|
|
@@ -884,7 +898,6 @@ class BacktestMainService {
|
|
|
884
898
|
const cwd = process.cwd();
|
|
885
899
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
886
900
|
}
|
|
887
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
888
901
|
{
|
|
889
902
|
await this.resolveService.attachJavascript(payload.entryPoint);
|
|
890
903
|
await this.moduleConnectionService.loadModule("backtest.module");
|
|
@@ -991,6 +1004,7 @@ class WalkerMainService {
|
|
|
991
1004
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
992
1005
|
this.run = singleshot(async (payload) => {
|
|
993
1006
|
this.loggerService.log("walkerMainService run", { payload });
|
|
1007
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
994
1008
|
{
|
|
995
1009
|
await this.configService.waitForInit();
|
|
996
1010
|
Setup.enable();
|
|
@@ -1009,7 +1023,7 @@ class WalkerMainService {
|
|
|
1009
1023
|
Setup.enable();
|
|
1010
1024
|
}
|
|
1011
1025
|
{
|
|
1012
|
-
cwd !== moduleRoot &&
|
|
1026
|
+
cwd !== moduleRoot && Setup.update();
|
|
1013
1027
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1014
1028
|
dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
|
|
1015
1029
|
}
|
|
@@ -1028,7 +1042,6 @@ class WalkerMainService {
|
|
|
1028
1042
|
const cwd = process.cwd();
|
|
1029
1043
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1030
1044
|
}
|
|
1031
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
1032
1045
|
await this.moduleConnectionService.loadModule("walker.module");
|
|
1033
1046
|
{
|
|
1034
1047
|
this.exchangeSchemaService.addSchema();
|
|
@@ -1085,7 +1098,7 @@ class WalkerMainService {
|
|
|
1085
1098
|
}
|
|
1086
1099
|
restoreSnapshot();
|
|
1087
1100
|
{
|
|
1088
|
-
cwd !== moduleRoot &&
|
|
1101
|
+
cwd !== moduleRoot && Setup.update();
|
|
1089
1102
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1090
1103
|
dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
|
|
1091
1104
|
}
|
|
@@ -1216,6 +1229,7 @@ class LiveMainService {
|
|
|
1216
1229
|
this.loggerService.log("liveMainService run", {
|
|
1217
1230
|
payload,
|
|
1218
1231
|
});
|
|
1232
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
1219
1233
|
{
|
|
1220
1234
|
await this.configService.waitForInit();
|
|
1221
1235
|
Setup.enable();
|
|
@@ -1228,7 +1242,6 @@ class LiveMainService {
|
|
|
1228
1242
|
const cwd = process.cwd();
|
|
1229
1243
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1230
1244
|
}
|
|
1231
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
1232
1245
|
{
|
|
1233
1246
|
await this.resolveService.attachJavascript(payload.entryPoint);
|
|
1234
1247
|
await this.moduleConnectionService.loadModule("live.module");
|
|
@@ -1302,6 +1315,7 @@ class PaperMainService {
|
|
|
1302
1315
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
1303
1316
|
this.run = singleshot(async (payload) => {
|
|
1304
1317
|
this.loggerService.log("paperMainService init");
|
|
1318
|
+
await this.configConnectionService.loadConfig("setup.config");
|
|
1305
1319
|
{
|
|
1306
1320
|
await this.configService.waitForInit();
|
|
1307
1321
|
Setup.enable();
|
|
@@ -1314,7 +1328,6 @@ class PaperMainService {
|
|
|
1314
1328
|
const cwd = process.cwd();
|
|
1315
1329
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1316
1330
|
}
|
|
1317
|
-
await this.configConnectionService.loadConfig("setup.config");
|
|
1318
1331
|
{
|
|
1319
1332
|
await this.resolveService.attachJavascript(payload.entryPoint);
|
|
1320
1333
|
await this.moduleConnectionService.loadModule("paper.module");
|
|
@@ -2515,12 +2528,22 @@ class ModuleConnectionService {
|
|
|
2515
2528
|
this.loggerService = inject(TYPES.loggerService);
|
|
2516
2529
|
this.resolveService = inject(TYPES.resolveService);
|
|
2517
2530
|
this.loaderService = inject(TYPES.loaderService);
|
|
2518
|
-
this.
|
|
2519
|
-
this.loggerService.log("moduleConnectionService
|
|
2531
|
+
this.hasModule = (fileName) => {
|
|
2532
|
+
this.loggerService.log("moduleConnectionService hasModule", {
|
|
2520
2533
|
fileName,
|
|
2521
2534
|
});
|
|
2522
|
-
return
|
|
2535
|
+
return this.loadModule.has(fileName);
|
|
2523
2536
|
};
|
|
2537
|
+
this.loadModule = memoize(([fileName]) => `${fileName}`, async (fileName) => {
|
|
2538
|
+
this.loggerService.log("moduleConnectionService loadModule", {
|
|
2539
|
+
fileName,
|
|
2540
|
+
});
|
|
2541
|
+
const module = await LOAD_MODULE_MODULE_FN(fileName, this);
|
|
2542
|
+
if (!module) {
|
|
2543
|
+
this.loadModule.clear(fileName);
|
|
2544
|
+
}
|
|
2545
|
+
return module;
|
|
2546
|
+
});
|
|
2524
2547
|
}
|
|
2525
2548
|
}
|
|
2526
2549
|
|
|
@@ -2563,6 +2586,18 @@ class BabelService {
|
|
|
2563
2586
|
}
|
|
2564
2587
|
}
|
|
2565
2588
|
|
|
2589
|
+
const require = createRequire(import.meta.url);
|
|
2590
|
+
const ModuleWithCache = Module;
|
|
2591
|
+
function overrideModule(moduleName, newExports) {
|
|
2592
|
+
const cache = ModuleWithCache._cache;
|
|
2593
|
+
const key = require.resolve(moduleName);
|
|
2594
|
+
if (!cache[key]) {
|
|
2595
|
+
cache[key] = new ModuleWithCache(key);
|
|
2596
|
+
cache[key].loaded = true;
|
|
2597
|
+
}
|
|
2598
|
+
cache[key].exports = newExports;
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2566
2601
|
/**
|
|
2567
2602
|
* 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.
|
|
2568
2603
|
* 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.
|
|
@@ -2795,6 +2830,13 @@ globalThis.BacktestKitGraph = BacktestKitGraph;
|
|
|
2795
2830
|
globalThis.BacktestKitOllama = BacktestKitOllama;
|
|
2796
2831
|
globalThis.BacktestKitPinets = BacktestKitPinets;
|
|
2797
2832
|
globalThis.BacktestKitSignals = BacktestKitSignals;
|
|
2833
|
+
overrideModule('backtest-kit', BacktestKit);
|
|
2834
|
+
overrideModule('@backtest-kit/cli', BacktestKitCli);
|
|
2835
|
+
overrideModule('@backtest-kit/ui', BacktestKitUi);
|
|
2836
|
+
overrideModule('@backtest-kit/graph', BacktestKitGraph);
|
|
2837
|
+
overrideModule('@backtest-kit/ollama', BacktestKitOllama);
|
|
2838
|
+
overrideModule('@backtest-kit/pinets', BacktestKitPinets);
|
|
2839
|
+
overrideModule('@backtest-kit/signals', BacktestKitSignals);
|
|
2798
2840
|
|
|
2799
2841
|
const GET_ALIAS_EXPORTS_FN = (self) => {
|
|
2800
2842
|
const instance = self.getInstance(self.resolveService.OVERRIDE_CONFIG_DIR);
|
|
@@ -2802,9 +2844,7 @@ const GET_ALIAS_EXPORTS_FN = (self) => {
|
|
|
2802
2844
|
return null;
|
|
2803
2845
|
}
|
|
2804
2846
|
const exports = instance.import("alias.config");
|
|
2805
|
-
return "default" in exports
|
|
2806
|
-
? exports.default
|
|
2807
|
-
: exports;
|
|
2847
|
+
return "default" in exports ? exports.default : exports;
|
|
2808
2848
|
};
|
|
2809
2849
|
const INIT_ALIAS_FN = (self) => {
|
|
2810
2850
|
const alias = GET_ALIAS_EXPORTS_FN(self);
|
|
@@ -2814,7 +2854,10 @@ const INIT_ALIAS_FN = (self) => {
|
|
|
2814
2854
|
if (!isObject(alias)) {
|
|
2815
2855
|
return;
|
|
2816
2856
|
}
|
|
2817
|
-
|
|
2857
|
+
{
|
|
2858
|
+
Object.entries(alias).forEach(([name, module]) => overrideModule(name, module));
|
|
2859
|
+
Object.assign(IMPORT_ALIAS, alias);
|
|
2860
|
+
}
|
|
2818
2861
|
};
|
|
2819
2862
|
class LoaderService {
|
|
2820
2863
|
constructor() {
|
|
@@ -2885,12 +2928,22 @@ class ConfigConnectionService {
|
|
|
2885
2928
|
this.loggerService = inject(TYPES.loggerService);
|
|
2886
2929
|
this.resolveService = inject(TYPES.resolveService);
|
|
2887
2930
|
this.loaderService = inject(TYPES.loaderService);
|
|
2888
|
-
this.
|
|
2889
|
-
this.loggerService.log("configConnectionService
|
|
2931
|
+
this.hasConfig = (fileName) => {
|
|
2932
|
+
this.loggerService.log("configConnectionService hasConfig", {
|
|
2890
2933
|
fileName,
|
|
2891
2934
|
});
|
|
2892
|
-
return
|
|
2935
|
+
return this.loadConfig.has(fileName);
|
|
2893
2936
|
};
|
|
2937
|
+
this.loadConfig = memoize(([fileName]) => `${fileName}`, async (fileName) => {
|
|
2938
|
+
this.loggerService.log("configConnectionService loadConfig", {
|
|
2939
|
+
fileName,
|
|
2940
|
+
});
|
|
2941
|
+
const config = await LOAD_CONFIG_CONFIG_FN(fileName, this);
|
|
2942
|
+
if (!config) {
|
|
2943
|
+
this.loadConfig.clear(fileName);
|
|
2944
|
+
}
|
|
2945
|
+
return config;
|
|
2946
|
+
});
|
|
2894
2947
|
}
|
|
2895
2948
|
}
|
|
2896
2949
|
|
|
@@ -3334,15 +3387,17 @@ const main$a = async () => {
|
|
|
3334
3387
|
if (!values.noFlush) {
|
|
3335
3388
|
await flush(entryPoint);
|
|
3336
3389
|
}
|
|
3337
|
-
await cli.
|
|
3338
|
-
|
|
3390
|
+
await cli.configConnectionService.loadConfig("setup.config");
|
|
3391
|
+
{
|
|
3392
|
+
await cli.configService.waitForInit();
|
|
3393
|
+
Setup.enable();
|
|
3394
|
+
}
|
|
3339
3395
|
cli.frontendProviderService.connect();
|
|
3340
3396
|
cli.telegramProviderService.connect();
|
|
3341
3397
|
{
|
|
3342
3398
|
const cwd = process.cwd();
|
|
3343
3399
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3344
3400
|
}
|
|
3345
|
-
await cli.configConnectionService.loadConfig("setup.config");
|
|
3346
3401
|
await cli.moduleConnectionService.loadModule(MODE_MODULE[mode]);
|
|
3347
3402
|
listenFinish();
|
|
3348
3403
|
createGracefulShutdown(mode)();
|
|
@@ -3509,6 +3564,7 @@ const main$6 = async () => {
|
|
|
3509
3564
|
console.warn("--editor and --pine are mutually exclusive. Use one at a time.");
|
|
3510
3565
|
process.exit(1);
|
|
3511
3566
|
}
|
|
3567
|
+
await cli.configConnectionService.loadConfig("setup.config");
|
|
3512
3568
|
{
|
|
3513
3569
|
await cli.configService.waitForInit();
|
|
3514
3570
|
Setup.enable();
|
|
@@ -3517,7 +3573,6 @@ const main$6 = async () => {
|
|
|
3517
3573
|
const cwd = process.cwd();
|
|
3518
3574
|
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3519
3575
|
}
|
|
3520
|
-
await cli.configConnectionService.loadConfig("setup.config");
|
|
3521
3576
|
await cli.moduleConnectionService.loadModule("editor.module");
|
|
3522
3577
|
{
|
|
3523
3578
|
await cli.exchangeSchemaService.addSchema();
|
package/docker/package.json
CHANGED
|
@@ -15,17 +15,17 @@
|
|
|
15
15
|
"@types/node": "25.6.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@backtest-kit/cli": "9.
|
|
19
|
-
"@backtest-kit/graph": "9.
|
|
20
|
-
"@backtest-kit/pinets": "9.
|
|
21
|
-
"@backtest-kit/signals": "9.
|
|
22
|
-
"@backtest-kit/ui": "9.
|
|
18
|
+
"@backtest-kit/cli": "9.4.0",
|
|
19
|
+
"@backtest-kit/graph": "9.4.0",
|
|
20
|
+
"@backtest-kit/pinets": "9.4.0",
|
|
21
|
+
"@backtest-kit/signals": "9.4.0",
|
|
22
|
+
"@backtest-kit/ui": "9.4.0",
|
|
23
23
|
"@tavily/core": "0.7.2",
|
|
24
24
|
"@tensorflow/tfjs": "4.22.0",
|
|
25
25
|
"@tensorflow/tfjs-backend-wasm": "4.22.0",
|
|
26
26
|
"@tensorflow/tfjs-core": "4.22.0",
|
|
27
27
|
"agent-swarm-kit": "2.6.0",
|
|
28
|
-
"backtest-kit": "9.
|
|
28
|
+
"backtest-kit": "9.4.0",
|
|
29
29
|
"dayjs": "1.11.20",
|
|
30
30
|
"functools-kit": "2.3.0",
|
|
31
31
|
"garch": "1.2.3",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backtest-kit/cli",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0",
|
|
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",
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@babel/plugin-transform-modules-umd": "7.27.1",
|
|
65
65
|
"@babel/standalone": "7.29.1",
|
|
66
|
-
"@backtest-kit/graph": "9.
|
|
67
|
-
"@backtest-kit/ollama": "9.
|
|
68
|
-
"@backtest-kit/pinets": "9.
|
|
69
|
-
"@backtest-kit/signals": "9.
|
|
70
|
-
"@backtest-kit/ui": "9.
|
|
66
|
+
"@backtest-kit/graph": "9.4.0",
|
|
67
|
+
"@backtest-kit/ollama": "9.4.0",
|
|
68
|
+
"@backtest-kit/pinets": "9.4.0",
|
|
69
|
+
"@backtest-kit/signals": "9.4.0",
|
|
70
|
+
"@backtest-kit/ui": "9.4.0",
|
|
71
71
|
"@rollup/plugin-replace": "6.0.3",
|
|
72
72
|
"@rollup/plugin-typescript": "11.1.6",
|
|
73
73
|
"@types/image-size": "0.7.0",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@types/mustache": "4.2.6",
|
|
76
76
|
"@types/node": "22.9.0",
|
|
77
77
|
"@types/stack-trace": "0.0.33",
|
|
78
|
-
"backtest-kit": "9.
|
|
78
|
+
"backtest-kit": "9.4.0",
|
|
79
79
|
"glob": "11.0.1",
|
|
80
80
|
"markdown-it": "14.1.1",
|
|
81
81
|
"rimraf": "6.0.1",
|
|
@@ -90,12 +90,12 @@
|
|
|
90
90
|
"peerDependencies": {
|
|
91
91
|
"@babel/plugin-transform-modules-umd": "^7.27.1",
|
|
92
92
|
"@babel/standalone": "^7.29.1",
|
|
93
|
-
"@backtest-kit/graph": "^9.
|
|
94
|
-
"@backtest-kit/ollama": "^9.
|
|
95
|
-
"@backtest-kit/pinets": "^9.
|
|
96
|
-
"@backtest-kit/signals": "^9.
|
|
97
|
-
"@backtest-kit/ui": "^9.
|
|
98
|
-
"backtest-kit": "^9.
|
|
93
|
+
"@backtest-kit/graph": "^9.4.0",
|
|
94
|
+
"@backtest-kit/ollama": "^9.4.0",
|
|
95
|
+
"@backtest-kit/pinets": "^9.4.0",
|
|
96
|
+
"@backtest-kit/signals": "^9.4.0",
|
|
97
|
+
"@backtest-kit/ui": "^9.4.0",
|
|
98
|
+
"backtest-kit": "^9.4.0",
|
|
99
99
|
"markdown-it": "^14.1.1",
|
|
100
100
|
"typescript": "^5.0.0"
|
|
101
101
|
},
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"type": "commonjs",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@backtest-kit/cli": "^9.
|
|
17
|
-
"@backtest-kit/graph": "^9.
|
|
18
|
-
"@backtest-kit/pinets": "^9.
|
|
19
|
-
"@backtest-kit/ui": "^9.
|
|
16
|
+
"@backtest-kit/cli": "^9.4.0",
|
|
17
|
+
"@backtest-kit/graph": "^9.4.0",
|
|
18
|
+
"@backtest-kit/pinets": "^9.4.0",
|
|
19
|
+
"@backtest-kit/ui": "^9.4.0",
|
|
20
20
|
"agent-swarm-kit": "^2.6.0",
|
|
21
|
-
"backtest-kit": "^9.
|
|
21
|
+
"backtest-kit": "^9.4.0",
|
|
22
22
|
"functools-kit": "^2.3.0",
|
|
23
23
|
"garch": "^1.2.3",
|
|
24
24
|
"get-moment-stamp": "^1.1.2",
|
package/types.d.ts
CHANGED
|
@@ -249,7 +249,8 @@ declare class ConfigConnectionService {
|
|
|
249
249
|
readonly loggerService: LoggerService;
|
|
250
250
|
readonly resolveService: ResolveService;
|
|
251
251
|
readonly loaderService: LoaderService;
|
|
252
|
-
|
|
252
|
+
hasConfig: (fileName: string) => boolean;
|
|
253
|
+
loadConfig: ((fileName: string) => Promise<ModuleExports>) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, Promise<ModuleExports>>;
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
declare class FrontendProviderService {
|
|
@@ -381,7 +382,8 @@ declare class ModuleConnectionService {
|
|
|
381
382
|
readonly loggerService: LoggerService;
|
|
382
383
|
readonly resolveService: ResolveService;
|
|
383
384
|
readonly loaderService: LoaderService;
|
|
384
|
-
|
|
385
|
+
hasModule: (fileName: string) => boolean;
|
|
386
|
+
loadModule: ((fileName: string) => Promise<boolean>) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, Promise<boolean>>;
|
|
385
387
|
}
|
|
386
388
|
|
|
387
389
|
declare class ConfigService {
|
|
@@ -420,6 +422,7 @@ declare const cli: {
|
|
|
420
422
|
declare class SetupUtils {
|
|
421
423
|
enable: (() => void) & functools_kit.ISingleshotClearable<() => void>;
|
|
422
424
|
clear: () => void;
|
|
425
|
+
update: () => void;
|
|
423
426
|
}
|
|
424
427
|
declare const Setup: SetupUtils;
|
|
425
428
|
|