@backtest-kit/cli 12.4.0 → 12.6.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 +1888 -1854
- package/build/index.cjs +413 -227
- package/build/index.mjs +413 -227
- package/config/notification.config.mjs +13 -13
- package/config/symbol.config.mjs +460 -460
- package/docker/.env.example +2 -2
- package/docker/content/feb_2026/feb_2026.strategy.ts +11 -11
- package/docker/content/feb_2026/modules/backtest.module.ts +83 -83
- package/docker/docker-compose.yaml +46 -46
- package/docker/package.json +39 -38
- package/docker/tsconfig.json +36 -36
- package/package.json +126 -126
- package/template/average-buy.mustache +22 -22
- package/template/breakeven.mustache +21 -21
- package/template/cancel-scheduled.mustache +14 -14
- package/template/cancelled.mustache +21 -21
- package/template/close-pending.mustache +16 -16
- package/template/closed.mustache +23 -23
- package/template/opened.mustache +22 -22
- package/template/partial-loss.mustache +22 -22
- package/template/partial-profit.mustache +22 -22
- package/template/project/config/symbol.config.ts +460 -460
- package/template/project/package.mustache +28 -28
- package/template/risk.mustache +19 -19
- package/template/scheduled.mustache +22 -22
- package/template/signal-close.mustache +22 -22
- package/template/signal-info.mustache +20 -20
- package/template/signal-open.mustache +22 -22
- package/template/source/CLAUDE.md +160 -160
- package/template/trailing-stop.mustache +21 -21
- package/template/trailing-take.mustache +21 -21
package/build/index.cjs
CHANGED
|
@@ -98,11 +98,11 @@ const getEntrySubject = functoolsKit.singleshot(() => {
|
|
|
98
98
|
return new functoolsKit.BehaviorSubject();
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
const main$
|
|
101
|
+
const main$i = () => {
|
|
102
102
|
const entrySubject = getEntrySubject();
|
|
103
103
|
entrySubject.subscribe((path) => console.log("Running", path));
|
|
104
104
|
};
|
|
105
|
-
main$
|
|
105
|
+
main$i();
|
|
106
106
|
|
|
107
107
|
const ERROR_HANDLER_INSTALLED = Symbol.for("error-handler-installed");
|
|
108
108
|
function dumpStackTrace() {
|
|
@@ -663,6 +663,10 @@ const getArgs = functoolsKit.singleshot(() => {
|
|
|
663
663
|
type: "boolean",
|
|
664
664
|
default: false,
|
|
665
665
|
},
|
|
666
|
+
main: {
|
|
667
|
+
type: "boolean",
|
|
668
|
+
default: false,
|
|
669
|
+
},
|
|
666
670
|
cacheInterval: {
|
|
667
671
|
type: "string",
|
|
668
672
|
default: "1m, 15m, 30m, 4h",
|
|
@@ -1611,6 +1615,8 @@ const getEnv = functoolsKit.singleshot(() => {
|
|
|
1611
1615
|
};
|
|
1612
1616
|
});
|
|
1613
1617
|
|
|
1618
|
+
const READY_SUBJECT = new functoolsKit.BehaviorSubject();
|
|
1619
|
+
const MAX_WAIT_TIME = 5000;
|
|
1614
1620
|
const GET_SYMBOL_EXPORTS_FN = async (self) => {
|
|
1615
1621
|
const exports = await self.configConnectionService.loadConfig("symbol.config");
|
|
1616
1622
|
if (!exports) {
|
|
@@ -1655,6 +1661,17 @@ const MAP_SYMBOL_CONFIG_FN = (config) => {
|
|
|
1655
1661
|
symbolList.sort(({ priority: a_p, index: a_x }, { priority: b_p, index: b_x }) => b_p - a_p || a_x - b_x);
|
|
1656
1662
|
return symbolList;
|
|
1657
1663
|
};
|
|
1664
|
+
const CREATE_LISTEN_FN = (self) => async () => {
|
|
1665
|
+
const promise = READY_SUBJECT.toPromise();
|
|
1666
|
+
self.enable();
|
|
1667
|
+
if (READY_SUBJECT.data) {
|
|
1668
|
+
return;
|
|
1669
|
+
}
|
|
1670
|
+
await Promise.race([
|
|
1671
|
+
promise,
|
|
1672
|
+
functoolsKit.sleep(MAX_WAIT_TIME),
|
|
1673
|
+
]);
|
|
1674
|
+
};
|
|
1658
1675
|
class FrontendProviderService {
|
|
1659
1676
|
constructor() {
|
|
1660
1677
|
this.loggerService = inject(TYPES.loggerService);
|
|
@@ -1672,7 +1689,7 @@ class FrontendProviderService {
|
|
|
1672
1689
|
BacktestKitUi.lib.symbolConnectionService.getSymbolList.setValue(Promise.resolve(symbolList));
|
|
1673
1690
|
}
|
|
1674
1691
|
}
|
|
1675
|
-
unServer = BacktestKitUi.serve(CC_WWWROOT_HOST, CC_WWWROOT_PORT, this.resolveService.PROJECT_ROOT_DIR);
|
|
1692
|
+
unServer = BacktestKitUi.serve(CC_WWWROOT_HOST, CC_WWWROOT_PORT, this.resolveService.PROJECT_ROOT_DIR, () => READY_SUBJECT.next(true));
|
|
1676
1693
|
};
|
|
1677
1694
|
init();
|
|
1678
1695
|
return () => {
|
|
@@ -1692,7 +1709,7 @@ class FrontendProviderService {
|
|
|
1692
1709
|
if (!getArgs().values.ui) {
|
|
1693
1710
|
return;
|
|
1694
1711
|
}
|
|
1695
|
-
return getEntrySubject().subscribe(this
|
|
1712
|
+
return getEntrySubject().subscribe(CREATE_LISTEN_FN(this));
|
|
1696
1713
|
});
|
|
1697
1714
|
}
|
|
1698
1715
|
}
|
|
@@ -3358,14 +3375,14 @@ const cli = {
|
|
|
3358
3375
|
};
|
|
3359
3376
|
init();
|
|
3360
3377
|
|
|
3361
|
-
const MODES = ["backtest", "walker", "paper", "live", "pine", "editor", "dump", "pnldebug", "brokerdebug", "flush", "init", "docker", "help", "version"];
|
|
3378
|
+
const MODES = ["backtest", "walker", "paper", "live", "main", "pine", "editor", "dump", "pnldebug", "brokerdebug", "flush", "init", "docker", "help", "version"];
|
|
3362
3379
|
const ENTRY_PATH$1 = "./node_modules/@backtest-kit/cli/build/index.mjs";
|
|
3363
|
-
const HELP_TEXT$1 = `
|
|
3364
|
-
Example:
|
|
3365
|
-
|
|
3366
|
-
node ${ENTRY_PATH$1} --help
|
|
3380
|
+
const HELP_TEXT$1 = `
|
|
3381
|
+
Example:
|
|
3382
|
+
|
|
3383
|
+
node ${ENTRY_PATH$1} --help
|
|
3367
3384
|
`.trimStart();
|
|
3368
|
-
const main$
|
|
3385
|
+
const main$h = async () => {
|
|
3369
3386
|
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
3370
3387
|
return;
|
|
3371
3388
|
}
|
|
@@ -3373,14 +3390,14 @@ const main$g = async () => {
|
|
|
3373
3390
|
if (MODES.some((mode) => values[mode])) {
|
|
3374
3391
|
return;
|
|
3375
3392
|
}
|
|
3376
|
-
process.stdout.write(`@backtest-kit/cli ${"12.
|
|
3393
|
+
process.stdout.write(`@backtest-kit/cli ${"12.6.0"}\n`);
|
|
3377
3394
|
process.stdout.write("\n");
|
|
3378
3395
|
process.stdout.write(`Run with --help to see available commands.\n`);
|
|
3379
3396
|
process.stdout.write("\n");
|
|
3380
3397
|
process.stdout.write(HELP_TEXT$1);
|
|
3381
3398
|
process.exit(0);
|
|
3382
3399
|
};
|
|
3383
|
-
main$
|
|
3400
|
+
main$h();
|
|
3384
3401
|
|
|
3385
3402
|
const notifyShutdown = functoolsKit.singleshot(async () => {
|
|
3386
3403
|
console.log("Graceful shutdown initiated.");
|
|
@@ -3396,7 +3413,7 @@ const flush = async (entryPoint) => {
|
|
|
3396
3413
|
console.log(`Removed: ${target}`);
|
|
3397
3414
|
}
|
|
3398
3415
|
};
|
|
3399
|
-
const main$
|
|
3416
|
+
const main$g = async () => {
|
|
3400
3417
|
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
3401
3418
|
return;
|
|
3402
3419
|
}
|
|
@@ -3413,10 +3430,10 @@ const main$f = async () => {
|
|
|
3413
3430
|
}
|
|
3414
3431
|
process.exit(0);
|
|
3415
3432
|
};
|
|
3416
|
-
main$
|
|
3433
|
+
main$g();
|
|
3417
3434
|
|
|
3418
|
-
const BEFORE_EXIT_FN$
|
|
3419
|
-
process.off("SIGINT", BEFORE_EXIT_FN$
|
|
3435
|
+
const BEFORE_EXIT_FN$6 = functoolsKit.singleshot(async () => {
|
|
3436
|
+
process.off("SIGINT", BEFORE_EXIT_FN$6);
|
|
3420
3437
|
const [running = null] = await BacktestKit.Backtest.list();
|
|
3421
3438
|
if (!running) {
|
|
3422
3439
|
return;
|
|
@@ -3433,10 +3450,10 @@ const BEFORE_EXIT_FN$5 = functoolsKit.singleshot(async () => {
|
|
|
3433
3450
|
frameName,
|
|
3434
3451
|
});
|
|
3435
3452
|
});
|
|
3436
|
-
const listenGracefulShutdown$
|
|
3437
|
-
process.on("SIGINT", BEFORE_EXIT_FN$
|
|
3453
|
+
const listenGracefulShutdown$6 = functoolsKit.singleshot(() => {
|
|
3454
|
+
process.on("SIGINT", BEFORE_EXIT_FN$6);
|
|
3438
3455
|
});
|
|
3439
|
-
const main$
|
|
3456
|
+
const main$f = async () => {
|
|
3440
3457
|
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
3441
3458
|
return;
|
|
3442
3459
|
}
|
|
@@ -3452,12 +3469,12 @@ const main$e = async () => {
|
|
|
3452
3469
|
entryPoint && await flush(entryPoint);
|
|
3453
3470
|
}
|
|
3454
3471
|
await cli.backtestMainService.connect();
|
|
3455
|
-
listenGracefulShutdown$
|
|
3472
|
+
listenGracefulShutdown$6();
|
|
3456
3473
|
};
|
|
3457
|
-
main$
|
|
3474
|
+
main$f();
|
|
3458
3475
|
|
|
3459
|
-
const BEFORE_EXIT_FN$
|
|
3460
|
-
process.off("SIGINT", BEFORE_EXIT_FN$
|
|
3476
|
+
const BEFORE_EXIT_FN$5 = functoolsKit.singleshot(async () => {
|
|
3477
|
+
process.off("SIGINT", BEFORE_EXIT_FN$5);
|
|
3461
3478
|
const [running = null] = await BacktestKit.Walker.list();
|
|
3462
3479
|
if (!running) {
|
|
3463
3480
|
return;
|
|
@@ -3470,10 +3487,10 @@ const BEFORE_EXIT_FN$4 = functoolsKit.singleshot(async () => {
|
|
|
3470
3487
|
}
|
|
3471
3488
|
BacktestKit.Walker.stop(symbol, { walkerName });
|
|
3472
3489
|
});
|
|
3473
|
-
const listenGracefulShutdown$
|
|
3474
|
-
process.on("SIGINT", BEFORE_EXIT_FN$
|
|
3490
|
+
const listenGracefulShutdown$5 = functoolsKit.singleshot(() => {
|
|
3491
|
+
process.on("SIGINT", BEFORE_EXIT_FN$5);
|
|
3475
3492
|
});
|
|
3476
|
-
const main$
|
|
3493
|
+
const main$e = async () => {
|
|
3477
3494
|
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
3478
3495
|
return;
|
|
3479
3496
|
}
|
|
@@ -3489,13 +3506,13 @@ const main$d = async () => {
|
|
|
3489
3506
|
await flush(entryPoint);
|
|
3490
3507
|
}
|
|
3491
3508
|
}
|
|
3492
|
-
listenGracefulShutdown$
|
|
3509
|
+
listenGracefulShutdown$5();
|
|
3493
3510
|
await cli.walkerMainService.connect();
|
|
3494
3511
|
};
|
|
3495
|
-
main$
|
|
3512
|
+
main$e();
|
|
3496
3513
|
|
|
3497
|
-
const BEFORE_EXIT_FN$
|
|
3498
|
-
process.off("SIGINT", BEFORE_EXIT_FN$
|
|
3514
|
+
const BEFORE_EXIT_FN$4 = functoolsKit.singleshot(async () => {
|
|
3515
|
+
process.off("SIGINT", BEFORE_EXIT_FN$4);
|
|
3499
3516
|
const [running = null] = await BacktestKit.Live.list();
|
|
3500
3517
|
if (!running) {
|
|
3501
3518
|
return;
|
|
@@ -3511,10 +3528,10 @@ const BEFORE_EXIT_FN$3 = functoolsKit.singleshot(async () => {
|
|
|
3511
3528
|
strategyName,
|
|
3512
3529
|
});
|
|
3513
3530
|
});
|
|
3514
|
-
const listenGracefulShutdown$
|
|
3515
|
-
process.on("SIGINT", BEFORE_EXIT_FN$
|
|
3531
|
+
const listenGracefulShutdown$4 = functoolsKit.singleshot(() => {
|
|
3532
|
+
process.on("SIGINT", BEFORE_EXIT_FN$4);
|
|
3516
3533
|
});
|
|
3517
|
-
const main$
|
|
3534
|
+
const main$d = async () => {
|
|
3518
3535
|
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
3519
3536
|
return;
|
|
3520
3537
|
}
|
|
@@ -3526,12 +3543,12 @@ const main$c = async () => {
|
|
|
3526
3543
|
return;
|
|
3527
3544
|
}
|
|
3528
3545
|
cli.paperMainService.connect();
|
|
3529
|
-
listenGracefulShutdown$
|
|
3546
|
+
listenGracefulShutdown$4();
|
|
3530
3547
|
};
|
|
3531
|
-
main$
|
|
3548
|
+
main$d();
|
|
3532
3549
|
|
|
3533
|
-
const BEFORE_EXIT_FN$
|
|
3534
|
-
process.off("SIGINT", BEFORE_EXIT_FN$
|
|
3550
|
+
const BEFORE_EXIT_FN$3 = functoolsKit.singleshot(async () => {
|
|
3551
|
+
process.off("SIGINT", BEFORE_EXIT_FN$3);
|
|
3535
3552
|
const [running = null] = await BacktestKit.Live.list();
|
|
3536
3553
|
if (!running) {
|
|
3537
3554
|
return;
|
|
@@ -3547,6 +3564,84 @@ const BEFORE_EXIT_FN$2 = functoolsKit.singleshot(async () => {
|
|
|
3547
3564
|
strategyName,
|
|
3548
3565
|
});
|
|
3549
3566
|
});
|
|
3567
|
+
const listenGracefulShutdown$3 = functoolsKit.singleshot(() => {
|
|
3568
|
+
process.on("SIGINT", BEFORE_EXIT_FN$3);
|
|
3569
|
+
});
|
|
3570
|
+
const main$c = async () => {
|
|
3571
|
+
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
3572
|
+
return;
|
|
3573
|
+
}
|
|
3574
|
+
const { values } = getArgs();
|
|
3575
|
+
if (!values.live) {
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
if (values.entry) {
|
|
3579
|
+
return;
|
|
3580
|
+
}
|
|
3581
|
+
await cli.liveMainService.connect();
|
|
3582
|
+
listenGracefulShutdown$3();
|
|
3583
|
+
};
|
|
3584
|
+
main$c();
|
|
3585
|
+
|
|
3586
|
+
const stopBacktestList$1 = async () => {
|
|
3587
|
+
for (const item of await BacktestKit.Backtest.list()) {
|
|
3588
|
+
if (item.status === "fulfilled") {
|
|
3589
|
+
continue;
|
|
3590
|
+
}
|
|
3591
|
+
BacktestKit.Backtest.stop(item.symbol, {
|
|
3592
|
+
exchangeName: item.exchangeName,
|
|
3593
|
+
strategyName: item.strategyName,
|
|
3594
|
+
frameName: item.frameName,
|
|
3595
|
+
});
|
|
3596
|
+
}
|
|
3597
|
+
};
|
|
3598
|
+
const stopLiveList$1 = async () => {
|
|
3599
|
+
for (const item of await BacktestKit.Live.list()) {
|
|
3600
|
+
if (item.status === "fulfilled") {
|
|
3601
|
+
continue;
|
|
3602
|
+
}
|
|
3603
|
+
BacktestKit.Live.stop(item.symbol, {
|
|
3604
|
+
exchangeName: item.exchangeName,
|
|
3605
|
+
strategyName: item.strategyName,
|
|
3606
|
+
});
|
|
3607
|
+
}
|
|
3608
|
+
};
|
|
3609
|
+
const stopWalkerList$1 = async () => {
|
|
3610
|
+
for (const item of await BacktestKit.Walker.list()) {
|
|
3611
|
+
if (item.status === "fulfilled") {
|
|
3612
|
+
continue;
|
|
3613
|
+
}
|
|
3614
|
+
BacktestKit.Walker.stop(item.symbol, { walkerName: item.walkerName });
|
|
3615
|
+
}
|
|
3616
|
+
};
|
|
3617
|
+
const stopMain$1 = async () => {
|
|
3618
|
+
await stopBacktestList$1();
|
|
3619
|
+
await stopLiveList$1();
|
|
3620
|
+
await stopWalkerList$1();
|
|
3621
|
+
};
|
|
3622
|
+
const listenFinish$1 = functoolsKit.singleshot(() => {
|
|
3623
|
+
let disposeRef;
|
|
3624
|
+
const unBacktest = BacktestKit.listenDoneBacktest(() => {
|
|
3625
|
+
console.log("Backtest trading finished");
|
|
3626
|
+
disposeRef && disposeRef();
|
|
3627
|
+
});
|
|
3628
|
+
const unLive = BacktestKit.listenDoneLive(() => {
|
|
3629
|
+
console.log("Live trading finished");
|
|
3630
|
+
disposeRef && disposeRef();
|
|
3631
|
+
});
|
|
3632
|
+
const unWalker = BacktestKit.listenDoneWalker(() => {
|
|
3633
|
+
console.log("Walker comparison finished");
|
|
3634
|
+
disposeRef && disposeRef();
|
|
3635
|
+
});
|
|
3636
|
+
disposeRef = functoolsKit.compose(() => unBacktest(), () => unLive(), () => unWalker());
|
|
3637
|
+
BacktestKit.shutdown();
|
|
3638
|
+
});
|
|
3639
|
+
const BEFORE_EXIT_FN$2 = functoolsKit.singleshot(async () => {
|
|
3640
|
+
process.off("SIGINT", BEFORE_EXIT_FN$2);
|
|
3641
|
+
notifyShutdown();
|
|
3642
|
+
notifyKill();
|
|
3643
|
+
await stopMain$1();
|
|
3644
|
+
});
|
|
3550
3645
|
const listenGracefulShutdown$2 = functoolsKit.singleshot(() => {
|
|
3551
3646
|
process.on("SIGINT", BEFORE_EXIT_FN$2);
|
|
3552
3647
|
});
|
|
@@ -3555,14 +3650,56 @@ const main$b = async () => {
|
|
|
3555
3650
|
return;
|
|
3556
3651
|
}
|
|
3557
3652
|
const { values } = getArgs();
|
|
3558
|
-
if (!values.
|
|
3653
|
+
if (!values.main) {
|
|
3559
3654
|
return;
|
|
3560
3655
|
}
|
|
3561
3656
|
if (values.entry) {
|
|
3562
3657
|
return;
|
|
3563
3658
|
}
|
|
3564
|
-
|
|
3659
|
+
const [entryPoint = null] = getPositionals();
|
|
3660
|
+
if (!entryPoint) {
|
|
3661
|
+
throw new Error("Entry point is required");
|
|
3662
|
+
}
|
|
3663
|
+
{
|
|
3664
|
+
const cwd = process.cwd();
|
|
3665
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3666
|
+
}
|
|
3667
|
+
await cli.configConnectionService.loadConfig("setup.config");
|
|
3668
|
+
{
|
|
3669
|
+
const loader = await cli.configConnectionService.loadConfig("loader.config");
|
|
3670
|
+
try {
|
|
3671
|
+
if (typeof loader === "function") {
|
|
3672
|
+
await loader();
|
|
3673
|
+
}
|
|
3674
|
+
if (typeof loader?.loader === "function") {
|
|
3675
|
+
await loader.loader();
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
catch (error) {
|
|
3679
|
+
console.error("Module loader failed", error);
|
|
3680
|
+
kill(-1);
|
|
3681
|
+
return;
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
{
|
|
3685
|
+
await cli.configService.waitForInit();
|
|
3686
|
+
Setup.enable();
|
|
3687
|
+
}
|
|
3688
|
+
const cwd = process.cwd();
|
|
3689
|
+
{
|
|
3690
|
+
const absolutePath = path.resolve(entryPoint);
|
|
3691
|
+
const moduleRoot = path.dirname(absolutePath);
|
|
3692
|
+
process.chdir(moduleRoot);
|
|
3693
|
+
cwd !== moduleRoot && Setup.update();
|
|
3694
|
+
dotenv.config({ path: path.join(moduleRoot, '.env'), override: true, quiet: true });
|
|
3695
|
+
}
|
|
3696
|
+
if (!values.noFlush) {
|
|
3697
|
+
await flush(path.resolve(cwd, entryPoint));
|
|
3698
|
+
}
|
|
3699
|
+
await cli.moduleConnectionService.loadModule("main.module");
|
|
3700
|
+
listenFinish$1();
|
|
3565
3701
|
listenGracefulShutdown$2();
|
|
3702
|
+
await cli.resolveService.attachEntry(path.resolve(cwd, entryPoint));
|
|
3566
3703
|
};
|
|
3567
3704
|
main$b();
|
|
3568
3705
|
|
|
@@ -3571,13 +3708,29 @@ const MODE_MODULE = {
|
|
|
3571
3708
|
live: "live.module",
|
|
3572
3709
|
paper: "paper.module",
|
|
3573
3710
|
walker: "walker.module",
|
|
3711
|
+
main: "main.module",
|
|
3574
3712
|
};
|
|
3713
|
+
const MODE_LIST = ["backtest", "live", "paper", "walker", "main"];
|
|
3575
3714
|
const resolveMode = (values) => {
|
|
3576
|
-
|
|
3577
|
-
if (enabled.length !== 1) {
|
|
3715
|
+
if (MODE_LIST.filter((mode) => values[mode]).length > 1) {
|
|
3578
3716
|
return null;
|
|
3579
3717
|
}
|
|
3580
|
-
|
|
3718
|
+
if (values.main) {
|
|
3719
|
+
return "main";
|
|
3720
|
+
}
|
|
3721
|
+
if (values.backtest) {
|
|
3722
|
+
return "backtest";
|
|
3723
|
+
}
|
|
3724
|
+
if (values.live) {
|
|
3725
|
+
return "live";
|
|
3726
|
+
}
|
|
3727
|
+
if (values.paper) {
|
|
3728
|
+
return "paper";
|
|
3729
|
+
}
|
|
3730
|
+
if (values.walker) {
|
|
3731
|
+
return "walker";
|
|
3732
|
+
}
|
|
3733
|
+
return null;
|
|
3581
3734
|
};
|
|
3582
3735
|
const stopBacktestList = async () => {
|
|
3583
3736
|
for (const item of await BacktestKit.Backtest.list()) {
|
|
@@ -3610,11 +3763,17 @@ const stopWalkerList = async () => {
|
|
|
3610
3763
|
BacktestKit.Walker.stop(item.symbol, { walkerName: item.walkerName });
|
|
3611
3764
|
}
|
|
3612
3765
|
};
|
|
3766
|
+
const stopMain = async () => {
|
|
3767
|
+
await stopBacktestList();
|
|
3768
|
+
await stopLiveList();
|
|
3769
|
+
await stopWalkerList();
|
|
3770
|
+
};
|
|
3613
3771
|
const MODE_STOP = {
|
|
3614
3772
|
backtest: stopBacktestList,
|
|
3615
3773
|
live: stopLiveList,
|
|
3616
3774
|
paper: stopLiveList,
|
|
3617
3775
|
walker: stopWalkerList,
|
|
3776
|
+
main: stopMain,
|
|
3618
3777
|
};
|
|
3619
3778
|
const listenFinish = functoolsKit.singleshot(() => {
|
|
3620
3779
|
let disposeRef;
|
|
@@ -3655,12 +3814,12 @@ const main$a = async () => {
|
|
|
3655
3814
|
}
|
|
3656
3815
|
const mode = resolveMode(values);
|
|
3657
3816
|
if (!mode) {
|
|
3658
|
-
console.error("--entry requires exactly one of --backtest, --live, --paper, --walker");
|
|
3817
|
+
console.error("--entry requires exactly one of --backtest, --live, --paper, --walker, --main");
|
|
3659
3818
|
kill(1);
|
|
3660
3819
|
return;
|
|
3661
3820
|
}
|
|
3662
3821
|
const entryPoints = getPositionals();
|
|
3663
|
-
if (!entryPoints.length) {
|
|
3822
|
+
if (mode !== "main" && !entryPoints.length) {
|
|
3664
3823
|
throw new Error("At least one entry point is required");
|
|
3665
3824
|
}
|
|
3666
3825
|
{
|
|
@@ -3707,12 +3866,18 @@ const main$a = async () => {
|
|
|
3707
3866
|
}
|
|
3708
3867
|
await cli.moduleConnectionService.loadModule(MODE_MODULE[mode]);
|
|
3709
3868
|
listenFinish();
|
|
3710
|
-
|
|
3869
|
+
{
|
|
3870
|
+
const listenShutdown = createGracefulShutdown(mode);
|
|
3871
|
+
listenShutdown();
|
|
3872
|
+
}
|
|
3711
3873
|
let absolutePath;
|
|
3712
3874
|
for (const entryPoint of entryPoints) {
|
|
3713
3875
|
absolutePath = path.resolve(cwd, entryPoint);
|
|
3714
3876
|
await cli.resolveService.attachEntry(absolutePath);
|
|
3715
3877
|
}
|
|
3878
|
+
if (mode === "main") {
|
|
3879
|
+
return;
|
|
3880
|
+
}
|
|
3716
3881
|
await getEntrySubject().next(absolutePath);
|
|
3717
3882
|
};
|
|
3718
3883
|
main$a();
|
|
@@ -4324,183 +4489,204 @@ const main$2 = async () => {
|
|
|
4324
4489
|
main$2();
|
|
4325
4490
|
|
|
4326
4491
|
const ENTRY_PATH = "./node_modules/@backtest-kit/cli/build/index.mjs";
|
|
4327
|
-
const HELP_TEXT = `
|
|
4328
|
-
Usage:
|
|
4329
|
-
node index.mjs --<mode> [flags] [entry-point]
|
|
4330
|
-
|
|
4331
|
-
Modes:
|
|
4332
|
-
|
|
4333
|
-
--backtest <entry> Run strategy against historical candle data
|
|
4334
|
-
--walker <entry...> Run Walker A/B strategy comparison across multiple strategies
|
|
4335
|
-
--paper <entry> Paper trading (live prices, no real orders)
|
|
4336
|
-
--live <entry> Live trading with real orders
|
|
4337
|
-
--
|
|
4338
|
-
--
|
|
4339
|
-
--
|
|
4340
|
-
--
|
|
4341
|
-
--
|
|
4342
|
-
--
|
|
4343
|
-
--
|
|
4344
|
-
--
|
|
4345
|
-
--
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
--
|
|
4351
|
-
--
|
|
4352
|
-
--
|
|
4353
|
-
--
|
|
4354
|
-
--
|
|
4355
|
-
--
|
|
4356
|
-
--
|
|
4357
|
-
--
|
|
4358
|
-
--
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
--
|
|
4364
|
-
--
|
|
4365
|
-
--
|
|
4366
|
-
--
|
|
4367
|
-
--
|
|
4368
|
-
--
|
|
4369
|
-
--
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
--
|
|
4382
|
-
--
|
|
4383
|
-
--
|
|
4384
|
-
--
|
|
4385
|
-
--
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
--
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
--
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
--
|
|
4409
|
-
--
|
|
4410
|
-
--
|
|
4411
|
-
--
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
--
|
|
4424
|
-
--
|
|
4425
|
-
--
|
|
4426
|
-
--
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4492
|
+
const HELP_TEXT = `
|
|
4493
|
+
Usage:
|
|
4494
|
+
node index.mjs --<mode> [flags] [entry-point]
|
|
4495
|
+
|
|
4496
|
+
Modes:
|
|
4497
|
+
|
|
4498
|
+
--backtest <entry> Run strategy against historical candle data
|
|
4499
|
+
--walker <entry...> Run Walker A/B strategy comparison across multiple strategies
|
|
4500
|
+
--paper <entry> Paper trading (live prices, no real orders)
|
|
4501
|
+
--live <entry> Live trading with real orders
|
|
4502
|
+
--main <entry> Run an entry point with prepared environment, no trading harness
|
|
4503
|
+
--pine <entry> Execute a local .pine indicator file
|
|
4504
|
+
--editor Open the Pine Script visual editor in the browser
|
|
4505
|
+
--dump Fetch and save raw OHLCV candles
|
|
4506
|
+
--pnldebug Simulate PnL per minute for a given entry price and direction
|
|
4507
|
+
--brokerdebug Fire a single broker commit against the live broker adapter
|
|
4508
|
+
--flush <entry...> Delete report/log/markdown/agent folders from strategy dump dir
|
|
4509
|
+
--init Scaffold a new project in the current directory
|
|
4510
|
+
--docker Scaffold a Docker workspace for running strategies in a container
|
|
4511
|
+
--help Print this help message
|
|
4512
|
+
|
|
4513
|
+
Backtest flags:
|
|
4514
|
+
|
|
4515
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4516
|
+
--strategy <string> Strategy name from addStrategySchema (default: first registered)
|
|
4517
|
+
--exchange <string> Exchange name from addExchangeSchema (default: first registered)
|
|
4518
|
+
--frame <string> Frame name from addFrameSchema (default: first registered)
|
|
4519
|
+
--cacheInterval <string> Comma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
|
|
4520
|
+
--noCache Skip candle cache warming before the run
|
|
4521
|
+
--noFlush Skip removing report/log/markdown/agent folders before backtest run
|
|
4522
|
+
--verbose Log every candle fetch to stdout
|
|
4523
|
+
--ui Start web dashboard at http://localhost:60050
|
|
4524
|
+
--telegram Send trade notifications to Telegram
|
|
4525
|
+
|
|
4526
|
+
Walker flags (--walker):
|
|
4527
|
+
|
|
4528
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4529
|
+
--cacheInterval <string> Comma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
|
|
4530
|
+
--noCache Skip candle cache warming before the run
|
|
4531
|
+
--noFlush Skip removing report/log/markdown/agent folders before walker run
|
|
4532
|
+
--verbose Log every candle fetch to stdout
|
|
4533
|
+
--output <string> Output file base name (default: walker_{SYMBOL}_{TIMESTAMP})
|
|
4534
|
+
--json Save results as JSON to ./dump/<output>.json
|
|
4535
|
+
--markdown Save report as Markdown to ./dump/<output>.md
|
|
4536
|
+
|
|
4537
|
+
Each positional argument is a strategy entry point. All strategy files are loaded without
|
|
4538
|
+
changing process.cwd() — .env is read from the working directory only.
|
|
4539
|
+
addWalkerSchema is called automatically using the registered exchange and frame.
|
|
4540
|
+
After comparison completes the report is printed to stdout (or saved if --json/--markdown).
|
|
4541
|
+
|
|
4542
|
+
Module file ./modules/walker.module is loaded automatically if it exists.
|
|
4543
|
+
|
|
4544
|
+
Paper / Live flags:
|
|
4545
|
+
|
|
4546
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4547
|
+
--strategy <string> Strategy name (default: first registered)
|
|
4548
|
+
--exchange <string> Exchange name (default: first registered)
|
|
4549
|
+
--verbose Log every candle fetch to stdout
|
|
4550
|
+
--ui Start web dashboard
|
|
4551
|
+
--telegram Send Telegram notifications
|
|
4552
|
+
|
|
4553
|
+
Main flags (--main):
|
|
4554
|
+
|
|
4555
|
+
--noFlush Skip removing report/log/markdown/agent folders before the run
|
|
4556
|
+
|
|
4557
|
+
Prepares the runtime environment (loads .env, setup.config, loader.config and
|
|
4558
|
+
modules/main.module) and runs the single positional entry point — but does NOT
|
|
4559
|
+
start any trading harness. Unlike --backtest/--live/--walker, the CLI never calls
|
|
4560
|
+
Backtest/Live/Walker.background; the entry point decides what to run.
|
|
4561
|
+
|
|
4562
|
+
Exactly one positional entry point is required. process.cwd() is changed to the
|
|
4563
|
+
entry point directory and its local .env is loaded.
|
|
4564
|
+
|
|
4565
|
+
Backtest, Live and Walker runs started from userspace are still tracked: the run
|
|
4566
|
+
finishes automatically when one of them completes, Ctrl+C stops any active run,
|
|
4567
|
+
and a second Ctrl+C force-quits.
|
|
4568
|
+
|
|
4569
|
+
Module file ./modules/main.module is loaded automatically if it exists.
|
|
4570
|
+
|
|
4571
|
+
PineScript flags (--pine):
|
|
4572
|
+
|
|
4573
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4574
|
+
--timeframe <string> Candle interval (default: 15m)
|
|
4575
|
+
--limit <string> Number of candles to fetch (default: 250)
|
|
4576
|
+
--when <string> End date — ISO 8601 or Unix ms (default: now)
|
|
4577
|
+
--exchange <string> Exchange name (default: first registered)
|
|
4578
|
+
--output <string> Output file base name without extension
|
|
4579
|
+
--json Save output as JSON array to <pine-dir>/dump/<output>.json
|
|
4580
|
+
--jsonl Save output as JSONL to <pine-dir>/dump/<output>.jsonl
|
|
4581
|
+
--markdown Save output as Markdown table to <pine-dir>/dump/<output>.md
|
|
4582
|
+
|
|
4583
|
+
Only plot() calls with display=display.data_window produce output columns.
|
|
4584
|
+
Module file ./modules/pine.module is loaded automatically if it exists.
|
|
4585
|
+
|
|
4586
|
+
Candle dump flags (--dump):
|
|
4587
|
+
|
|
4588
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4589
|
+
--timeframe <string> Candle interval (default: 15m)
|
|
4590
|
+
--limit <string> Number of candles (default: 250)
|
|
4591
|
+
--when <string> End date — ISO 8601 or Unix ms (default: now)
|
|
4592
|
+
--exchange <string> Exchange name (default: first registered)
|
|
4593
|
+
--output <string> Output file base name (default: {SYMBOL}_{LIMIT}_{TIMEFRAME}_{TIMESTAMP})
|
|
4594
|
+
--json Save as JSON array to ./dump/<output>.json
|
|
4595
|
+
--jsonl Save as JSONL to ./dump/<output>.jsonl
|
|
4596
|
+
|
|
4597
|
+
Module file ./modules/dump.module is loaded automatically if it exists.
|
|
4598
|
+
|
|
4599
|
+
PnL debug flags (--pnldebug):
|
|
4600
|
+
|
|
4601
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4602
|
+
--priceopen <number> Entry price (required)
|
|
4603
|
+
--direction <string> Position direction: long or short (default: long)
|
|
4604
|
+
--when <string> Start timestamp — ISO 8601 or Unix ms (default: now)
|
|
4605
|
+
--minutes <string> Number of 1m candles to simulate (default: 60)
|
|
4606
|
+
--exchange <string> Exchange name (default: first registered)
|
|
4607
|
+
--output <string> Output file base name (default: {SYMBOL}_{DIRECTION}_{PRICEOPEN}_{TIMESTAMP})
|
|
4608
|
+
--json Save as JSON array to ./dump/<output>.json
|
|
4609
|
+
--jsonl Save as JSONL to ./dump/<output>.jsonl
|
|
4610
|
+
--markdown Save as Markdown table to ./dump/<output>.md
|
|
4611
|
+
|
|
4612
|
+
Module file ./modules/pnldebug.module is loaded automatically if it exists.
|
|
4613
|
+
|
|
4614
|
+
Broker debug flags (--brokerdebug):
|
|
4615
|
+
|
|
4616
|
+
--symbol <string> Trading pair (default: BTCUSDT)
|
|
4617
|
+
--exchange <string> Exchange name (default: first registered)
|
|
4618
|
+
--commit <string> Commit type to fire: signal-open, signal-close, partial-profit,
|
|
4619
|
+
partial-loss, average-buy, trailing-stop, trailing-take, breakeven
|
|
4620
|
+
(default: signal-open)
|
|
4621
|
+
|
|
4622
|
+
Loads ./live.module, fetches the last candle for --symbol/--timeframe, and calls
|
|
4623
|
+
the selected broker commit with synthetic payload values derived from current price.
|
|
4624
|
+
|
|
4625
|
+
Flush flags (--flush):
|
|
4626
|
+
|
|
4627
|
+
One or more positional entry points. For each entry point the following
|
|
4628
|
+
subdirectories are removed from <entry-dir>/dump/:
|
|
4629
|
+
|
|
4630
|
+
report log markdown agent
|
|
4631
|
+
|
|
4632
|
+
Init flags (--init):
|
|
4633
|
+
|
|
4634
|
+
--output <string> Target directory name (default: backtest-kit-project)
|
|
4635
|
+
|
|
4636
|
+
Scaffolds a project and runs scripts/fetch_docs.mjs to download library docs.
|
|
4637
|
+
|
|
4638
|
+
Docker flags (--docker):
|
|
4639
|
+
|
|
4640
|
+
--output <string> Target directory name (default: backtest-kit-docker)
|
|
4641
|
+
|
|
4642
|
+
Scaffolds a Docker workspace: docker-compose.yaml, .env.example, package.json,
|
|
4643
|
+
tsconfig.json, and a sample strategy under content/. Run npm install then
|
|
4644
|
+
docker compose up to start the container.
|
|
4645
|
+
|
|
4646
|
+
Module hooks (loaded automatically by each mode):
|
|
4647
|
+
|
|
4648
|
+
modules/backtest.module --backtest Broker adapter for backtest
|
|
4649
|
+
modules/walker.module --walker Broker adapter for walker comparison
|
|
4650
|
+
modules/paper.module --paper Broker adapter for paper trading
|
|
4651
|
+
modules/live.module --live Broker adapter for live trading
|
|
4652
|
+
modules/main.module --main Environment setup for a custom entry point
|
|
4653
|
+
modules/pine.module --pine Exchange schema for PineScript runs
|
|
4654
|
+
modules/editor.module --editor Exchange schema for the visual Pine editor
|
|
4655
|
+
modules/dump.module --dump Exchange schema for candle dumps
|
|
4656
|
+
modules/pnldebug.module --pnldebug Exchange schema for PnL debug runs
|
|
4657
|
+
modules/brokerdebug.module --brokerdebug Broker adapter used for broker commit testing
|
|
4658
|
+
|
|
4659
|
+
--flush has no associated module. It only removes dump subdirectories.
|
|
4660
|
+
|
|
4661
|
+
Extensions .ts, .mjs, .cjs are tried automatically. Missing module = soft warning.
|
|
4662
|
+
|
|
4663
|
+
Environment variables:
|
|
4664
|
+
|
|
4665
|
+
CC_TELEGRAM_TOKEN Telegram bot token (required for --telegram)
|
|
4666
|
+
CC_TELEGRAM_CHANNEL Telegram channel or chat ID (required for --telegram)
|
|
4667
|
+
CC_WWWROOT_HOST UI server bind address (default: 0.0.0.0)
|
|
4668
|
+
CC_WWWROOT_PORT UI server port (default: 60050)
|
|
4669
|
+
|
|
4670
|
+
Examples:
|
|
4671
|
+
|
|
4672
|
+
node ${ENTRY_PATH} --backtest ./content/feb_2026.strategy.ts
|
|
4673
|
+
node ${ENTRY_PATH} --backtest --symbol BTCUSDT --noCache --noFlush --ui ./content/feb_2026.strategy.ts
|
|
4674
|
+
node ${ENTRY_PATH} --walker ./content/feb_2026_v1.strategy.ts ./content/feb_2026_v2.strategy.ts ./content/feb_2026_v3.strategy.ts
|
|
4675
|
+
node ${ENTRY_PATH} --walker --symbol BTCUSDT --noCache --noFlush --markdown ./content/feb_2026_v1.ts ./content/feb_2026_v2.ts
|
|
4676
|
+
node ${ENTRY_PATH} --paper --symbol ETHUSDT ./content/feb_2026.strategy.ts
|
|
4677
|
+
node ${ENTRY_PATH} --live --ui --telegram ./content/feb_2026.strategy.ts
|
|
4678
|
+
node ${ENTRY_PATH} --main ./tools/fetch_fear_and_greed.ts
|
|
4679
|
+
node ${ENTRY_PATH} --pine ./math/feb_2026.pine --timeframe 15m --limit 500 --jsonl
|
|
4680
|
+
node ${ENTRY_PATH} --editor
|
|
4681
|
+
node ${ENTRY_PATH} --dump --symbol BTCUSDT --timeframe 15m --limit 500 --jsonl
|
|
4682
|
+
node ${ENTRY_PATH} --pnldebug --symbol BTCUSDT --priceopen 64069.50 --direction short --when "2025-02-25" --minutes 120
|
|
4683
|
+
node ${ENTRY_PATH} --pnldebug --priceopen 67956.73 --direction long --when 1772064000000 --minutes 60 --markdown
|
|
4684
|
+
node ${ENTRY_PATH} --brokerdebug --commit signal-open --symbol BTCUSDT
|
|
4685
|
+
node ${ENTRY_PATH} --brokerdebug --commit partial-profit --symbol ETHUSDT
|
|
4686
|
+
node ${ENTRY_PATH} --flush ./content/feb_2026.strategy/feb_2026.strategy.ts
|
|
4687
|
+
node ${ENTRY_PATH} --flush ./content/feb_2026.strategy/feb_2026.strategy.ts ./content/feb_2026.strategy/feb_2026.test.ts
|
|
4688
|
+
node ${ENTRY_PATH} --init --output my-trading-bot
|
|
4689
|
+
node ${ENTRY_PATH} --docker --output my-docker-workspace
|
|
4504
4690
|
`.trimStart();
|
|
4505
4691
|
const main$1 = async () => {
|
|
4506
4692
|
if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
|
|
@@ -4510,7 +4696,7 @@ const main$1 = async () => {
|
|
|
4510
4696
|
if (!values.help) {
|
|
4511
4697
|
return;
|
|
4512
4698
|
}
|
|
4513
|
-
process.stdout.write(`@backtest-kit/cli ${"12.
|
|
4699
|
+
process.stdout.write(`@backtest-kit/cli ${"12.6.0"}\n\n`);
|
|
4514
4700
|
process.stdout.write(HELP_TEXT);
|
|
4515
4701
|
process.exit(0);
|
|
4516
4702
|
};
|
|
@@ -4524,7 +4710,7 @@ const main = async () => {
|
|
|
4524
4710
|
if (!values.version) {
|
|
4525
4711
|
return;
|
|
4526
4712
|
}
|
|
4527
|
-
process.stdout.write(`@backtest-kit/cli ${"12.
|
|
4713
|
+
process.stdout.write(`@backtest-kit/cli ${"12.6.0"}\n`);
|
|
4528
4714
|
process.exit(0);
|
|
4529
4715
|
};
|
|
4530
4716
|
main();
|
|
@@ -4546,17 +4732,17 @@ async function run(mode, args) {
|
|
|
4546
4732
|
}
|
|
4547
4733
|
if (mode === "backtest") {
|
|
4548
4734
|
await cli.backtestMainService.run(args);
|
|
4549
|
-
listenGracefulShutdown$
|
|
4735
|
+
listenGracefulShutdown$6();
|
|
4550
4736
|
return;
|
|
4551
4737
|
}
|
|
4552
4738
|
if (mode === "paper") {
|
|
4553
4739
|
await cli.paperMainService.run(args);
|
|
4554
|
-
listenGracefulShutdown$
|
|
4740
|
+
listenGracefulShutdown$4();
|
|
4555
4741
|
return;
|
|
4556
4742
|
}
|
|
4557
4743
|
if (mode === "live") {
|
|
4558
4744
|
await cli.liveMainService.run(args);
|
|
4559
|
-
listenGracefulShutdown$
|
|
4745
|
+
listenGracefulShutdown$3();
|
|
4560
4746
|
return;
|
|
4561
4747
|
}
|
|
4562
4748
|
throw new Error(`Invalid mode: ${mode}`);
|