@backtest-kit/cli 9.8.4 → 10.1.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/build/index.cjs +205 -57
- package/build/index.mjs +207 -59
- package/docker/package.json +6 -6
- package/package.json +13 -13
- package/template/project/package.mustache +5 -5
- package/types.d.ts +0 -1
package/build/index.cjs
CHANGED
|
@@ -12,6 +12,7 @@ var diKit = require('di-kit');
|
|
|
12
12
|
var url = require('url');
|
|
13
13
|
var ccxt = require('ccxt');
|
|
14
14
|
var util = require('util');
|
|
15
|
+
var child_process = require('child_process');
|
|
15
16
|
var BacktestKitUi = require('@backtest-kit/ui');
|
|
16
17
|
var QuickChart = require('quickchart-js');
|
|
17
18
|
var telegraf = require('telegraf');
|
|
@@ -30,7 +31,6 @@ var BacktestKitOllama = require('@backtest-kit/ollama');
|
|
|
30
31
|
var BacktestKitPinets = require('@backtest-kit/pinets');
|
|
31
32
|
var BacktestKitSignals = require('@backtest-kit/signals');
|
|
32
33
|
var open = require('open');
|
|
33
|
-
var child_process = require('child_process');
|
|
34
34
|
|
|
35
35
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
36
36
|
function _interopNamespaceDefault(e) {
|
|
@@ -279,6 +279,9 @@ class SetupUtils {
|
|
|
279
279
|
const config = cli.configService.getNotificationConfig();
|
|
280
280
|
BacktestKit.Notification.enable(config);
|
|
281
281
|
}
|
|
282
|
+
{
|
|
283
|
+
BacktestKit.Cron.enable();
|
|
284
|
+
}
|
|
282
285
|
{
|
|
283
286
|
BacktestKit.Recent.enable();
|
|
284
287
|
BacktestKit.Storage.enable();
|
|
@@ -300,6 +303,9 @@ class SetupUtils {
|
|
|
300
303
|
return;
|
|
301
304
|
}
|
|
302
305
|
this.enable.clear();
|
|
306
|
+
{
|
|
307
|
+
BacktestKit.Cron.disable();
|
|
308
|
+
}
|
|
303
309
|
{
|
|
304
310
|
BacktestKit.Recent.disable();
|
|
305
311
|
BacktestKit.Storage.disable();
|
|
@@ -856,6 +862,129 @@ const notifyVerbose = functoolsKit.singleshot(() => {
|
|
|
856
862
|
|
|
857
863
|
const entrySubject = new functoolsKit.BehaviorSubject();
|
|
858
864
|
|
|
865
|
+
function killPid(pid, signal) {
|
|
866
|
+
try {
|
|
867
|
+
process.kill(pid, signal);
|
|
868
|
+
}
|
|
869
|
+
catch (err) {
|
|
870
|
+
if (err.code !== "ESRCH")
|
|
871
|
+
throw err;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
function killAll(tree, signal, callback) {
|
|
875
|
+
const killed = {};
|
|
876
|
+
try {
|
|
877
|
+
for (const pid of Object.keys(tree).map(Number)) {
|
|
878
|
+
for (const child of tree[pid]) {
|
|
879
|
+
if (!killed[child]) {
|
|
880
|
+
killPid(child, signal);
|
|
881
|
+
killed[child] = true;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
if (!killed[pid]) {
|
|
885
|
+
killPid(pid, signal);
|
|
886
|
+
killed[pid] = true;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
catch (err) {
|
|
891
|
+
if (callback)
|
|
892
|
+
return callback(err);
|
|
893
|
+
throw err;
|
|
894
|
+
}
|
|
895
|
+
callback?.();
|
|
896
|
+
}
|
|
897
|
+
function buildProcessTree(parentPid, tree, pidsToProcess, spawnList, cb) {
|
|
898
|
+
const ps = spawnList(parentPid);
|
|
899
|
+
let allData = "";
|
|
900
|
+
ps.stdout.on("data", (data) => {
|
|
901
|
+
allData += data.toString("ascii");
|
|
902
|
+
});
|
|
903
|
+
ps.on("close", (code) => {
|
|
904
|
+
delete pidsToProcess[parentPid];
|
|
905
|
+
if (code !== 0) {
|
|
906
|
+
if (Object.keys(pidsToProcess).length === 0)
|
|
907
|
+
cb();
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
const matches = allData.match(/\d+/g);
|
|
911
|
+
if (matches) {
|
|
912
|
+
for (const pidStr of matches) {
|
|
913
|
+
const pid = parseInt(pidStr, 10);
|
|
914
|
+
tree[parentPid].push(pid);
|
|
915
|
+
tree[pid] = [];
|
|
916
|
+
pidsToProcess[pid] = 1;
|
|
917
|
+
buildProcessTree(pid, tree, pidsToProcess, spawnList, cb);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
function treeKill(pid, signalOrCallback, callback) {
|
|
923
|
+
let signal;
|
|
924
|
+
if (typeof signalOrCallback === "function") {
|
|
925
|
+
callback = signalOrCallback;
|
|
926
|
+
signal = undefined;
|
|
927
|
+
}
|
|
928
|
+
else {
|
|
929
|
+
signal = signalOrCallback;
|
|
930
|
+
}
|
|
931
|
+
pid = parseInt(pid, 10);
|
|
932
|
+
if (Number.isNaN(pid)) {
|
|
933
|
+
const err = new Error("pid must be a number");
|
|
934
|
+
if (callback)
|
|
935
|
+
return callback(err);
|
|
936
|
+
throw err;
|
|
937
|
+
}
|
|
938
|
+
const tree = { [pid]: [] };
|
|
939
|
+
const pidsToProcess = { [pid]: 1 };
|
|
940
|
+
switch (process.platform) {
|
|
941
|
+
case "win32":
|
|
942
|
+
child_process.exec(`taskkill /pid ${pid} /T /F`, (err) => callback?.(err ?? undefined));
|
|
943
|
+
break;
|
|
944
|
+
case "darwin":
|
|
945
|
+
buildProcessTree(pid, tree, pidsToProcess, (parentPid) => child_process.spawn("pgrep", ["-P", String(parentPid)]), () => killAll(tree, signal, callback));
|
|
946
|
+
break;
|
|
947
|
+
default: // Linux
|
|
948
|
+
buildProcessTree(pid, tree, pidsToProcess, (parentPid) => child_process.spawn("ps", ["-o", "pid", "--no-headers", "--ppid", String(parentPid)]), () => killAll(tree, signal, callback));
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
const DRAIN_MAX_AWAIT = 250;
|
|
954
|
+
const drainStream = (stream) => new Promise((resolve) => {
|
|
955
|
+
if (stream.writableLength === 0) {
|
|
956
|
+
stream.write("", () => resolve());
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
stream.once("drain", () => {
|
|
960
|
+
stream.write("", () => resolve());
|
|
961
|
+
});
|
|
962
|
+
});
|
|
963
|
+
const flushStream = (stream) => {
|
|
964
|
+
const handle = stream._handle;
|
|
965
|
+
if (handle && typeof handle.setBlocking === "function") {
|
|
966
|
+
handle.setBlocking(true);
|
|
967
|
+
return new Promise((resolve) => stream.write("", () => resolve()));
|
|
968
|
+
}
|
|
969
|
+
return drainStream(stream);
|
|
970
|
+
};
|
|
971
|
+
const kill = functoolsKit.singleshot(async (code = -1) => {
|
|
972
|
+
await Promise.race([
|
|
973
|
+
Promise.all([
|
|
974
|
+
flushStream(process.stdout),
|
|
975
|
+
flushStream(process.stderr)
|
|
976
|
+
]),
|
|
977
|
+
functoolsKit.sleep(DRAIN_MAX_AWAIT),
|
|
978
|
+
]);
|
|
979
|
+
treeKill(process.pid, "SIGKILL", () => {
|
|
980
|
+
process.exit(code);
|
|
981
|
+
});
|
|
982
|
+
});
|
|
983
|
+
const notifyKill = functoolsKit.singleshot(() => {
|
|
984
|
+
console.log("Press Ctrl+C again to force quit.");
|
|
985
|
+
process.on("SIGINT", () => kill());
|
|
986
|
+
});
|
|
987
|
+
|
|
859
988
|
const DEFAULT_CACHE_LIST$1 = ["1m", "15m", "30m", "1h", "4h"];
|
|
860
989
|
const GET_CACHE_INTERVAL_LIST_FN$1 = () => {
|
|
861
990
|
const { values } = getArgs();
|
|
@@ -883,6 +1012,10 @@ class BacktestMainService {
|
|
|
883
1012
|
this.loggerService.log("backtestMainService run", {
|
|
884
1013
|
payload,
|
|
885
1014
|
});
|
|
1015
|
+
{
|
|
1016
|
+
const cwd = process.cwd();
|
|
1017
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1018
|
+
}
|
|
886
1019
|
await this.configConnectionService.loadConfig("setup.config");
|
|
887
1020
|
{
|
|
888
1021
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -896,7 +1029,8 @@ class BacktestMainService {
|
|
|
896
1029
|
}
|
|
897
1030
|
catch (error) {
|
|
898
1031
|
console.error("Module loader failed", error);
|
|
899
|
-
|
|
1032
|
+
kill(-1);
|
|
1033
|
+
return;
|
|
900
1034
|
}
|
|
901
1035
|
}
|
|
902
1036
|
{
|
|
@@ -907,10 +1041,6 @@ class BacktestMainService {
|
|
|
907
1041
|
this.frontendProviderService.connect();
|
|
908
1042
|
this.telegramProviderService.connect();
|
|
909
1043
|
}
|
|
910
|
-
{
|
|
911
|
-
const cwd = process.cwd();
|
|
912
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
913
|
-
}
|
|
914
1044
|
let absolutePath;
|
|
915
1045
|
{
|
|
916
1046
|
absolutePath = await this.resolveService.attachJavascript(payload.entryPoint);
|
|
@@ -1019,6 +1149,10 @@ class WalkerMainService {
|
|
|
1019
1149
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
1020
1150
|
this.run = functoolsKit.singleshot(async (payload) => {
|
|
1021
1151
|
this.loggerService.log("walkerMainService run", { payload });
|
|
1152
|
+
{
|
|
1153
|
+
const cwd = process.cwd();
|
|
1154
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1155
|
+
}
|
|
1022
1156
|
await this.configConnectionService.loadConfig("setup.config");
|
|
1023
1157
|
{
|
|
1024
1158
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -1032,7 +1166,8 @@ class WalkerMainService {
|
|
|
1032
1166
|
}
|
|
1033
1167
|
catch (error) {
|
|
1034
1168
|
console.error("Module loader failed", error);
|
|
1035
|
-
|
|
1169
|
+
kill(-1);
|
|
1170
|
+
return;
|
|
1036
1171
|
}
|
|
1037
1172
|
}
|
|
1038
1173
|
{
|
|
@@ -1068,10 +1203,6 @@ class WalkerMainService {
|
|
|
1068
1203
|
BacktestKit.Cache.resetCounter();
|
|
1069
1204
|
BacktestKit.Interval.resetCounter();
|
|
1070
1205
|
}
|
|
1071
|
-
{
|
|
1072
|
-
const cwd = process.cwd();
|
|
1073
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1074
|
-
}
|
|
1075
1206
|
await this.moduleConnectionService.loadModule("walker.module");
|
|
1076
1207
|
{
|
|
1077
1208
|
this.exchangeSchemaService.addSchema();
|
|
@@ -1200,7 +1331,7 @@ class WalkerMainService {
|
|
|
1200
1331
|
await fs$1.mkdir(dumpDir, { recursive: true });
|
|
1201
1332
|
await fs$1.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
1202
1333
|
console.log(`Saved: ${filePath}`);
|
|
1203
|
-
|
|
1334
|
+
kill(0);
|
|
1204
1335
|
return;
|
|
1205
1336
|
}
|
|
1206
1337
|
if (payload.markdown) {
|
|
@@ -1209,12 +1340,13 @@ class WalkerMainService {
|
|
|
1209
1340
|
await fs$1.mkdir(dumpDir, { recursive: true });
|
|
1210
1341
|
await fs$1.writeFile(filePath, report, "utf-8");
|
|
1211
1342
|
console.log(`Saved: ${filePath}`);
|
|
1212
|
-
|
|
1343
|
+
kill(0);
|
|
1213
1344
|
return;
|
|
1214
1345
|
}
|
|
1215
1346
|
const report = await BacktestKit.Walker.getReport(symbol, { walkerName: WalkerName$1.DefaultWalker });
|
|
1216
1347
|
console.log(report);
|
|
1217
|
-
|
|
1348
|
+
kill(0);
|
|
1349
|
+
return;
|
|
1218
1350
|
});
|
|
1219
1351
|
this.connect = functoolsKit.singleshot(async () => {
|
|
1220
1352
|
this.loggerService.log("walkerMainService connect");
|
|
@@ -1259,6 +1391,10 @@ class LiveMainService {
|
|
|
1259
1391
|
this.loggerService.log("liveMainService run", {
|
|
1260
1392
|
payload,
|
|
1261
1393
|
});
|
|
1394
|
+
{
|
|
1395
|
+
const cwd = process.cwd();
|
|
1396
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1397
|
+
}
|
|
1262
1398
|
await this.configConnectionService.loadConfig("setup.config");
|
|
1263
1399
|
{
|
|
1264
1400
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -1272,7 +1408,8 @@ class LiveMainService {
|
|
|
1272
1408
|
}
|
|
1273
1409
|
catch (error) {
|
|
1274
1410
|
console.error("Module loader failed", error);
|
|
1275
|
-
|
|
1411
|
+
kill(-1);
|
|
1412
|
+
return;
|
|
1276
1413
|
}
|
|
1277
1414
|
}
|
|
1278
1415
|
{
|
|
@@ -1283,10 +1420,6 @@ class LiveMainService {
|
|
|
1283
1420
|
this.frontendProviderService.connect();
|
|
1284
1421
|
this.telegramProviderService.connect();
|
|
1285
1422
|
}
|
|
1286
|
-
{
|
|
1287
|
-
const cwd = process.cwd();
|
|
1288
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1289
|
-
}
|
|
1290
1423
|
let absolutePath;
|
|
1291
1424
|
{
|
|
1292
1425
|
absolutePath = await this.resolveService.attachJavascript(payload.entryPoint);
|
|
@@ -1362,6 +1495,10 @@ class PaperMainService {
|
|
|
1362
1495
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
1363
1496
|
this.run = functoolsKit.singleshot(async (payload) => {
|
|
1364
1497
|
this.loggerService.log("paperMainService init");
|
|
1498
|
+
{
|
|
1499
|
+
const cwd = process.cwd();
|
|
1500
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1501
|
+
}
|
|
1365
1502
|
await this.configConnectionService.loadConfig("setup.config");
|
|
1366
1503
|
{
|
|
1367
1504
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -1375,7 +1512,8 @@ class PaperMainService {
|
|
|
1375
1512
|
}
|
|
1376
1513
|
catch (error) {
|
|
1377
1514
|
console.error("Module loader failed", error);
|
|
1378
|
-
|
|
1515
|
+
kill(-1);
|
|
1516
|
+
return;
|
|
1379
1517
|
}
|
|
1380
1518
|
}
|
|
1381
1519
|
{
|
|
@@ -1386,10 +1524,6 @@ class PaperMainService {
|
|
|
1386
1524
|
this.frontendProviderService.connect();
|
|
1387
1525
|
this.telegramProviderService.connect();
|
|
1388
1526
|
}
|
|
1389
|
-
{
|
|
1390
|
-
const cwd = process.cwd();
|
|
1391
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1392
|
-
}
|
|
1393
1527
|
let absolutePath;
|
|
1394
1528
|
{
|
|
1395
1529
|
absolutePath = await this.resolveService.attachJavascript(payload.entryPoint);
|
|
@@ -1857,7 +1991,7 @@ class TelegramApiService {
|
|
|
1857
1991
|
console.error("Telegram publish failure", {
|
|
1858
1992
|
error,
|
|
1859
1993
|
});
|
|
1860
|
-
setTimeout(() =>
|
|
1994
|
+
setTimeout(() => kill(-1), 5000);
|
|
1861
1995
|
});
|
|
1862
1996
|
const result = await Promise.race([
|
|
1863
1997
|
waitForResult,
|
|
@@ -1871,7 +2005,7 @@ class TelegramApiService {
|
|
|
1871
2005
|
return "Message scheduled for publication";
|
|
1872
2006
|
}
|
|
1873
2007
|
if (TIMEOUT_COUNTER > MAX_TIMEOUT_COUNT) {
|
|
1874
|
-
setTimeout(() =>
|
|
2008
|
+
setTimeout(() => kill(-1), 5000);
|
|
1875
2009
|
}
|
|
1876
2010
|
return "Message published successfully";
|
|
1877
2011
|
};
|
|
@@ -2584,7 +2718,8 @@ const LOAD_MODULE_MODULE_FN = async (fileName, self) => {
|
|
|
2584
2718
|
}
|
|
2585
2719
|
catch {
|
|
2586
2720
|
console.warn(`Module module import failed filePath=${filePath} baseDir=${baseDir}`);
|
|
2587
|
-
|
|
2721
|
+
kill(-1);
|
|
2722
|
+
return false;
|
|
2588
2723
|
}
|
|
2589
2724
|
}
|
|
2590
2725
|
return false;
|
|
@@ -2704,7 +2839,8 @@ const TRANSPILE_FN = functoolsKit.memoize(([path]) => `${path}`, (path, code, se
|
|
|
2704
2839
|
}
|
|
2705
2840
|
catch (error) {
|
|
2706
2841
|
console.log(`Error during transpilation error=\`${functoolsKit.getErrorMessage(error)}\` path=\`${path}\` __filename=\`${__filename}\` __dirname=\`${__dirname}\``);
|
|
2707
|
-
|
|
2842
|
+
kill(-1);
|
|
2843
|
+
return;
|
|
2708
2844
|
}
|
|
2709
2845
|
return {
|
|
2710
2846
|
require,
|
|
@@ -2968,7 +3104,7 @@ const GET_ALIAS_EXPORTS_FN = (self) => {
|
|
|
2968
3104
|
}
|
|
2969
3105
|
return null;
|
|
2970
3106
|
};
|
|
2971
|
-
const INIT_ALIAS_FN = (self) => {
|
|
3107
|
+
const INIT_ALIAS_FN = functoolsKit.singleshot((self) => {
|
|
2972
3108
|
const alias = GET_ALIAS_EXPORTS_FN(self);
|
|
2973
3109
|
if (!alias) {
|
|
2974
3110
|
return;
|
|
@@ -2980,18 +3116,21 @@ const INIT_ALIAS_FN = (self) => {
|
|
|
2980
3116
|
Object.entries(alias).forEach(([name, module]) => overrideModule(name, module));
|
|
2981
3117
|
Object.assign(IMPORT_ALIAS, alias);
|
|
2982
3118
|
}
|
|
2983
|
-
};
|
|
3119
|
+
});
|
|
2984
3120
|
class LoaderService {
|
|
2985
3121
|
constructor() {
|
|
2986
3122
|
this.babelService = inject(TYPES.babelService);
|
|
2987
3123
|
this.loggerService = inject(TYPES.loggerService);
|
|
2988
3124
|
this.resolveService = inject(TYPES.resolveService);
|
|
2989
|
-
this.getInstance = functoolsKit.memoize(([basePath]) => `${basePath}`, (basePath) =>
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
3125
|
+
this.getInstance = functoolsKit.memoize(([basePath]) => `${basePath}`, (basePath) => {
|
|
3126
|
+
INIT_ALIAS_FN(this);
|
|
3127
|
+
return new ClientLoader({
|
|
3128
|
+
babel: this.babelService,
|
|
3129
|
+
logger: this.loggerService,
|
|
3130
|
+
resolve: this.resolveService,
|
|
3131
|
+
path: basePath,
|
|
3132
|
+
});
|
|
3133
|
+
});
|
|
2995
3134
|
this.import = (filePath, basePath = process.cwd()) => {
|
|
2996
3135
|
this.loggerService.log("loaderService import", {
|
|
2997
3136
|
filePath,
|
|
@@ -3008,10 +3147,6 @@ class LoaderService {
|
|
|
3008
3147
|
const instance = this.getInstance(basePath);
|
|
3009
3148
|
return instance.check(filePath);
|
|
3010
3149
|
};
|
|
3011
|
-
this.init = functoolsKit.singleshot(() => {
|
|
3012
|
-
this.loggerService.log("loaderService init");
|
|
3013
|
-
INIT_ALIAS_FN(this);
|
|
3014
|
-
});
|
|
3015
3150
|
}
|
|
3016
3151
|
}
|
|
3017
3152
|
|
|
@@ -3040,7 +3175,8 @@ const LOAD_CONFIG_CONFIG_FN = async (fileName, self) => {
|
|
|
3040
3175
|
}
|
|
3041
3176
|
catch {
|
|
3042
3177
|
console.warn(`Module module import failed filePath=${filePath} baseDir=${baseDir}`);
|
|
3043
|
-
|
|
3178
|
+
kill(-1);
|
|
3179
|
+
return;
|
|
3044
3180
|
}
|
|
3045
3181
|
}
|
|
3046
3182
|
return null;
|
|
@@ -3225,7 +3361,7 @@ const main$g = async () => {
|
|
|
3225
3361
|
if (MODES.some((mode) => values[mode])) {
|
|
3226
3362
|
return;
|
|
3227
3363
|
}
|
|
3228
|
-
process.stdout.write(`@backtest-kit/cli ${"
|
|
3364
|
+
process.stdout.write(`@backtest-kit/cli ${"10.1.0"}\n`);
|
|
3229
3365
|
process.stdout.write("\n");
|
|
3230
3366
|
process.stdout.write(`Run with --help to see available commands.\n`);
|
|
3231
3367
|
process.stdout.write("\n");
|
|
@@ -3235,7 +3371,7 @@ const main$g = async () => {
|
|
|
3235
3371
|
main$g();
|
|
3236
3372
|
|
|
3237
3373
|
const notifyShutdown = functoolsKit.singleshot(async () => {
|
|
3238
|
-
console.log("Graceful shutdown initiated.
|
|
3374
|
+
console.log("Graceful shutdown initiated.");
|
|
3239
3375
|
});
|
|
3240
3376
|
|
|
3241
3377
|
const FLUSH_DIRS = ["report", "log", "markdown", "agent"];
|
|
@@ -3274,6 +3410,7 @@ const BEFORE_EXIT_FN$5 = functoolsKit.singleshot(async () => {
|
|
|
3274
3410
|
return;
|
|
3275
3411
|
}
|
|
3276
3412
|
notifyShutdown();
|
|
3413
|
+
notifyKill();
|
|
3277
3414
|
const { exchangeName, frameName, strategyName, symbol, status } = running;
|
|
3278
3415
|
if (status === "fulfilled") {
|
|
3279
3416
|
return;
|
|
@@ -3314,6 +3451,7 @@ const BEFORE_EXIT_FN$4 = functoolsKit.singleshot(async () => {
|
|
|
3314
3451
|
return;
|
|
3315
3452
|
}
|
|
3316
3453
|
notifyShutdown();
|
|
3454
|
+
notifyKill();
|
|
3317
3455
|
const { walkerName, symbol, status } = running;
|
|
3318
3456
|
if (status === "fulfilled") {
|
|
3319
3457
|
return;
|
|
@@ -3351,6 +3489,7 @@ const BEFORE_EXIT_FN$3 = functoolsKit.singleshot(async () => {
|
|
|
3351
3489
|
return;
|
|
3352
3490
|
}
|
|
3353
3491
|
notifyShutdown();
|
|
3492
|
+
notifyKill();
|
|
3354
3493
|
const { exchangeName, strategyName, symbol, status } = running;
|
|
3355
3494
|
if (status === "fulfilled") {
|
|
3356
3495
|
return;
|
|
@@ -3386,6 +3525,7 @@ const BEFORE_EXIT_FN$2 = functoolsKit.singleshot(async () => {
|
|
|
3386
3525
|
return;
|
|
3387
3526
|
}
|
|
3388
3527
|
notifyShutdown();
|
|
3528
|
+
notifyKill();
|
|
3389
3529
|
const { exchangeName, strategyName, symbol, status } = running;
|
|
3390
3530
|
if (status === "fulfilled") {
|
|
3391
3531
|
return;
|
|
@@ -3486,6 +3626,7 @@ const createGracefulShutdown = (mode) => {
|
|
|
3486
3626
|
const handler = functoolsKit.singleshot(async () => {
|
|
3487
3627
|
process.off("SIGINT", handler);
|
|
3488
3628
|
notifyShutdown();
|
|
3629
|
+
notifyKill();
|
|
3489
3630
|
await stop();
|
|
3490
3631
|
});
|
|
3491
3632
|
return functoolsKit.singleshot(() => {
|
|
@@ -3503,13 +3644,17 @@ const main$a = async () => {
|
|
|
3503
3644
|
const mode = resolveMode(values);
|
|
3504
3645
|
if (!mode) {
|
|
3505
3646
|
console.error("--entry requires exactly one of --backtest, --live, --paper, --walker");
|
|
3506
|
-
|
|
3647
|
+
kill(1);
|
|
3507
3648
|
return;
|
|
3508
3649
|
}
|
|
3509
3650
|
const entryPoints = getPositionals();
|
|
3510
3651
|
if (!entryPoints.length) {
|
|
3511
3652
|
throw new Error("At least one entry point is required");
|
|
3512
3653
|
}
|
|
3654
|
+
{
|
|
3655
|
+
const cwd = process.cwd();
|
|
3656
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3657
|
+
}
|
|
3513
3658
|
await cli.configConnectionService.loadConfig("setup.config");
|
|
3514
3659
|
{
|
|
3515
3660
|
const loader = await cli.configConnectionService.loadConfig("loader.config");
|
|
@@ -3523,7 +3668,8 @@ const main$a = async () => {
|
|
|
3523
3668
|
}
|
|
3524
3669
|
catch (error) {
|
|
3525
3670
|
console.error("Module loader failed", error);
|
|
3526
|
-
|
|
3671
|
+
kill(-1);
|
|
3672
|
+
return;
|
|
3527
3673
|
}
|
|
3528
3674
|
}
|
|
3529
3675
|
{
|
|
@@ -3533,9 +3679,6 @@ const main$a = async () => {
|
|
|
3533
3679
|
cli.frontendProviderService.connect();
|
|
3534
3680
|
cli.telegramProviderService.connect();
|
|
3535
3681
|
const cwd = process.cwd();
|
|
3536
|
-
{
|
|
3537
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3538
|
-
}
|
|
3539
3682
|
if (entryPoints.length === 1) {
|
|
3540
3683
|
const absolutePath = path.resolve(entryPoints[0]);
|
|
3541
3684
|
const moduleRoot = path.dirname(absolutePath);
|
|
@@ -3565,6 +3708,7 @@ main$a();
|
|
|
3565
3708
|
const BEFORE_EXIT_FN$1 = functoolsKit.singleshot(async () => {
|
|
3566
3709
|
process.off("SIGINT", BEFORE_EXIT_FN$1);
|
|
3567
3710
|
notifyShutdown();
|
|
3711
|
+
notifyKill();
|
|
3568
3712
|
cli.frontendProviderService.disable();
|
|
3569
3713
|
});
|
|
3570
3714
|
const listenGracefulShutdown$1 = functoolsKit.singleshot(() => {
|
|
@@ -3585,6 +3729,7 @@ main$9();
|
|
|
3585
3729
|
const BEFORE_EXIT_FN = functoolsKit.singleshot(async () => {
|
|
3586
3730
|
process.off("SIGINT", BEFORE_EXIT_FN);
|
|
3587
3731
|
notifyShutdown();
|
|
3732
|
+
notifyKill();
|
|
3588
3733
|
cli.telegramProviderService.disable();
|
|
3589
3734
|
});
|
|
3590
3735
|
const listenGracefulShutdown = functoolsKit.singleshot(() => {
|
|
@@ -3734,7 +3879,12 @@ const main$6 = async () => {
|
|
|
3734
3879
|
}
|
|
3735
3880
|
if (values.pine) {
|
|
3736
3881
|
console.warn("--editor and --pine are mutually exclusive. Use one at a time.");
|
|
3737
|
-
|
|
3882
|
+
kill(1);
|
|
3883
|
+
return;
|
|
3884
|
+
}
|
|
3885
|
+
{
|
|
3886
|
+
const cwd = process.cwd();
|
|
3887
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3738
3888
|
}
|
|
3739
3889
|
await cli.configConnectionService.loadConfig("setup.config");
|
|
3740
3890
|
{
|
|
@@ -3749,17 +3899,14 @@ const main$6 = async () => {
|
|
|
3749
3899
|
}
|
|
3750
3900
|
catch (error) {
|
|
3751
3901
|
console.error("Module loader failed", error);
|
|
3752
|
-
|
|
3902
|
+
kill(-1);
|
|
3903
|
+
return;
|
|
3753
3904
|
}
|
|
3754
3905
|
}
|
|
3755
3906
|
{
|
|
3756
3907
|
await cli.configService.waitForInit();
|
|
3757
3908
|
Setup.enable();
|
|
3758
3909
|
}
|
|
3759
|
-
{
|
|
3760
|
-
const cwd = process.cwd();
|
|
3761
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3762
|
-
}
|
|
3763
3910
|
await cli.moduleConnectionService.loadModule("editor.module");
|
|
3764
3911
|
{
|
|
3765
3912
|
await cli.exchangeSchemaService.addSchema();
|
|
@@ -3779,7 +3926,8 @@ const main$6 = async () => {
|
|
|
3779
3926
|
const beforeExit = () => {
|
|
3780
3927
|
process.off("SIGINT", beforeExit);
|
|
3781
3928
|
unServer();
|
|
3782
|
-
|
|
3929
|
+
kill(0);
|
|
3930
|
+
return;
|
|
3783
3931
|
};
|
|
3784
3932
|
process.on("SIGINT", beforeExit);
|
|
3785
3933
|
};
|
|
@@ -4350,7 +4498,7 @@ const main$1 = async () => {
|
|
|
4350
4498
|
if (!values.help) {
|
|
4351
4499
|
return;
|
|
4352
4500
|
}
|
|
4353
|
-
process.stdout.write(`@backtest-kit/cli ${"
|
|
4501
|
+
process.stdout.write(`@backtest-kit/cli ${"10.1.0"}\n\n`);
|
|
4354
4502
|
process.stdout.write(HELP_TEXT);
|
|
4355
4503
|
process.exit(0);
|
|
4356
4504
|
};
|
|
@@ -4364,7 +4512,7 @@ const main = async () => {
|
|
|
4364
4512
|
if (!values.version) {
|
|
4365
4513
|
return;
|
|
4366
4514
|
}
|
|
4367
|
-
process.stdout.write(`@backtest-kit/cli ${"
|
|
4515
|
+
process.stdout.write(`@backtest-kit/cli ${"10.1.0"}\n`);
|
|
4368
4516
|
process.exit(0);
|
|
4369
4517
|
};
|
|
4370
4518
|
main();
|
package/build/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as BacktestKit from 'backtest-kit';
|
|
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, Broker, 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
|
-
import { getErrorMessage, errorData, singleshot, str, compose, BehaviorSubject, createAwaiter, execpool, queued,
|
|
3
|
+
import { setConfig, Notification, Cron, 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, Broker, 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
|
+
import { getErrorMessage, errorData, singleshot, str, compose, BehaviorSubject, sleep, createAwaiter, execpool, queued, 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';
|
|
7
7
|
import path, { join, resolve, dirname, basename, extname } from 'path';
|
|
@@ -11,6 +11,7 @@ import { createActivator } from 'di-kit';
|
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
import ccxt from 'ccxt';
|
|
13
13
|
import { parseArgs } from 'util';
|
|
14
|
+
import { exec, spawn } from 'child_process';
|
|
14
15
|
import * as BacktestKitUi from '@backtest-kit/ui';
|
|
15
16
|
import { lib, serve } from '@backtest-kit/ui';
|
|
16
17
|
import QuickChart from 'quickchart-js';
|
|
@@ -31,7 +32,6 @@ import * as BacktestKitPinets from '@backtest-kit/pinets';
|
|
|
31
32
|
import { run as run$1, Code, toMarkdown } from '@backtest-kit/pinets';
|
|
32
33
|
import * as BacktestKitSignals from '@backtest-kit/signals';
|
|
33
34
|
import open from 'open';
|
|
34
|
-
import { spawn } from 'child_process';
|
|
35
35
|
|
|
36
36
|
setConfig({
|
|
37
37
|
CC_MAX_NOTIFICATIONS: 5000,
|
|
@@ -254,6 +254,9 @@ class SetupUtils {
|
|
|
254
254
|
const config = cli.configService.getNotificationConfig();
|
|
255
255
|
Notification.enable(config);
|
|
256
256
|
}
|
|
257
|
+
{
|
|
258
|
+
Cron.enable();
|
|
259
|
+
}
|
|
257
260
|
{
|
|
258
261
|
Recent.enable();
|
|
259
262
|
Storage.enable();
|
|
@@ -275,6 +278,9 @@ class SetupUtils {
|
|
|
275
278
|
return;
|
|
276
279
|
}
|
|
277
280
|
this.enable.clear();
|
|
281
|
+
{
|
|
282
|
+
Cron.disable();
|
|
283
|
+
}
|
|
278
284
|
{
|
|
279
285
|
Recent.disable();
|
|
280
286
|
Storage.disable();
|
|
@@ -831,6 +837,129 @@ const notifyVerbose = singleshot(() => {
|
|
|
831
837
|
|
|
832
838
|
const entrySubject = new BehaviorSubject();
|
|
833
839
|
|
|
840
|
+
function killPid(pid, signal) {
|
|
841
|
+
try {
|
|
842
|
+
process.kill(pid, signal);
|
|
843
|
+
}
|
|
844
|
+
catch (err) {
|
|
845
|
+
if (err.code !== "ESRCH")
|
|
846
|
+
throw err;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
function killAll(tree, signal, callback) {
|
|
850
|
+
const killed = {};
|
|
851
|
+
try {
|
|
852
|
+
for (const pid of Object.keys(tree).map(Number)) {
|
|
853
|
+
for (const child of tree[pid]) {
|
|
854
|
+
if (!killed[child]) {
|
|
855
|
+
killPid(child, signal);
|
|
856
|
+
killed[child] = true;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
if (!killed[pid]) {
|
|
860
|
+
killPid(pid, signal);
|
|
861
|
+
killed[pid] = true;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
catch (err) {
|
|
866
|
+
if (callback)
|
|
867
|
+
return callback(err);
|
|
868
|
+
throw err;
|
|
869
|
+
}
|
|
870
|
+
callback?.();
|
|
871
|
+
}
|
|
872
|
+
function buildProcessTree(parentPid, tree, pidsToProcess, spawnList, cb) {
|
|
873
|
+
const ps = spawnList(parentPid);
|
|
874
|
+
let allData = "";
|
|
875
|
+
ps.stdout.on("data", (data) => {
|
|
876
|
+
allData += data.toString("ascii");
|
|
877
|
+
});
|
|
878
|
+
ps.on("close", (code) => {
|
|
879
|
+
delete pidsToProcess[parentPid];
|
|
880
|
+
if (code !== 0) {
|
|
881
|
+
if (Object.keys(pidsToProcess).length === 0)
|
|
882
|
+
cb();
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
const matches = allData.match(/\d+/g);
|
|
886
|
+
if (matches) {
|
|
887
|
+
for (const pidStr of matches) {
|
|
888
|
+
const pid = parseInt(pidStr, 10);
|
|
889
|
+
tree[parentPid].push(pid);
|
|
890
|
+
tree[pid] = [];
|
|
891
|
+
pidsToProcess[pid] = 1;
|
|
892
|
+
buildProcessTree(pid, tree, pidsToProcess, spawnList, cb);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
function treeKill(pid, signalOrCallback, callback) {
|
|
898
|
+
let signal;
|
|
899
|
+
if (typeof signalOrCallback === "function") {
|
|
900
|
+
callback = signalOrCallback;
|
|
901
|
+
signal = undefined;
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
signal = signalOrCallback;
|
|
905
|
+
}
|
|
906
|
+
pid = parseInt(pid, 10);
|
|
907
|
+
if (Number.isNaN(pid)) {
|
|
908
|
+
const err = new Error("pid must be a number");
|
|
909
|
+
if (callback)
|
|
910
|
+
return callback(err);
|
|
911
|
+
throw err;
|
|
912
|
+
}
|
|
913
|
+
const tree = { [pid]: [] };
|
|
914
|
+
const pidsToProcess = { [pid]: 1 };
|
|
915
|
+
switch (process.platform) {
|
|
916
|
+
case "win32":
|
|
917
|
+
exec(`taskkill /pid ${pid} /T /F`, (err) => callback?.(err ?? undefined));
|
|
918
|
+
break;
|
|
919
|
+
case "darwin":
|
|
920
|
+
buildProcessTree(pid, tree, pidsToProcess, (parentPid) => spawn("pgrep", ["-P", String(parentPid)]), () => killAll(tree, signal, callback));
|
|
921
|
+
break;
|
|
922
|
+
default: // Linux
|
|
923
|
+
buildProcessTree(pid, tree, pidsToProcess, (parentPid) => spawn("ps", ["-o", "pid", "--no-headers", "--ppid", String(parentPid)]), () => killAll(tree, signal, callback));
|
|
924
|
+
break;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
const DRAIN_MAX_AWAIT = 250;
|
|
929
|
+
const drainStream = (stream) => new Promise((resolve) => {
|
|
930
|
+
if (stream.writableLength === 0) {
|
|
931
|
+
stream.write("", () => resolve());
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
stream.once("drain", () => {
|
|
935
|
+
stream.write("", () => resolve());
|
|
936
|
+
});
|
|
937
|
+
});
|
|
938
|
+
const flushStream = (stream) => {
|
|
939
|
+
const handle = stream._handle;
|
|
940
|
+
if (handle && typeof handle.setBlocking === "function") {
|
|
941
|
+
handle.setBlocking(true);
|
|
942
|
+
return new Promise((resolve) => stream.write("", () => resolve()));
|
|
943
|
+
}
|
|
944
|
+
return drainStream(stream);
|
|
945
|
+
};
|
|
946
|
+
const kill = singleshot(async (code = -1) => {
|
|
947
|
+
await Promise.race([
|
|
948
|
+
Promise.all([
|
|
949
|
+
flushStream(process.stdout),
|
|
950
|
+
flushStream(process.stderr)
|
|
951
|
+
]),
|
|
952
|
+
sleep(DRAIN_MAX_AWAIT),
|
|
953
|
+
]);
|
|
954
|
+
treeKill(process.pid, "SIGKILL", () => {
|
|
955
|
+
process.exit(code);
|
|
956
|
+
});
|
|
957
|
+
});
|
|
958
|
+
const notifyKill = singleshot(() => {
|
|
959
|
+
console.log("Press Ctrl+C again to force quit.");
|
|
960
|
+
process.on("SIGINT", () => kill());
|
|
961
|
+
});
|
|
962
|
+
|
|
834
963
|
const DEFAULT_CACHE_LIST$1 = ["1m", "15m", "30m", "1h", "4h"];
|
|
835
964
|
const GET_CACHE_INTERVAL_LIST_FN$1 = () => {
|
|
836
965
|
const { values } = getArgs();
|
|
@@ -858,6 +987,10 @@ class BacktestMainService {
|
|
|
858
987
|
this.loggerService.log("backtestMainService run", {
|
|
859
988
|
payload,
|
|
860
989
|
});
|
|
990
|
+
{
|
|
991
|
+
const cwd = process.cwd();
|
|
992
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
993
|
+
}
|
|
861
994
|
await this.configConnectionService.loadConfig("setup.config");
|
|
862
995
|
{
|
|
863
996
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -871,7 +1004,8 @@ class BacktestMainService {
|
|
|
871
1004
|
}
|
|
872
1005
|
catch (error) {
|
|
873
1006
|
console.error("Module loader failed", error);
|
|
874
|
-
|
|
1007
|
+
kill(-1);
|
|
1008
|
+
return;
|
|
875
1009
|
}
|
|
876
1010
|
}
|
|
877
1011
|
{
|
|
@@ -882,10 +1016,6 @@ class BacktestMainService {
|
|
|
882
1016
|
this.frontendProviderService.connect();
|
|
883
1017
|
this.telegramProviderService.connect();
|
|
884
1018
|
}
|
|
885
|
-
{
|
|
886
|
-
const cwd = process.cwd();
|
|
887
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
888
|
-
}
|
|
889
1019
|
let absolutePath;
|
|
890
1020
|
{
|
|
891
1021
|
absolutePath = await this.resolveService.attachJavascript(payload.entryPoint);
|
|
@@ -994,6 +1124,10 @@ class WalkerMainService {
|
|
|
994
1124
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
995
1125
|
this.run = singleshot(async (payload) => {
|
|
996
1126
|
this.loggerService.log("walkerMainService run", { payload });
|
|
1127
|
+
{
|
|
1128
|
+
const cwd = process.cwd();
|
|
1129
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1130
|
+
}
|
|
997
1131
|
await this.configConnectionService.loadConfig("setup.config");
|
|
998
1132
|
{
|
|
999
1133
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -1007,7 +1141,8 @@ class WalkerMainService {
|
|
|
1007
1141
|
}
|
|
1008
1142
|
catch (error) {
|
|
1009
1143
|
console.error("Module loader failed", error);
|
|
1010
|
-
|
|
1144
|
+
kill(-1);
|
|
1145
|
+
return;
|
|
1011
1146
|
}
|
|
1012
1147
|
}
|
|
1013
1148
|
{
|
|
@@ -1043,10 +1178,6 @@ class WalkerMainService {
|
|
|
1043
1178
|
Cache.resetCounter();
|
|
1044
1179
|
Interval.resetCounter();
|
|
1045
1180
|
}
|
|
1046
|
-
{
|
|
1047
|
-
const cwd = process.cwd();
|
|
1048
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1049
|
-
}
|
|
1050
1181
|
await this.moduleConnectionService.loadModule("walker.module");
|
|
1051
1182
|
{
|
|
1052
1183
|
this.exchangeSchemaService.addSchema();
|
|
@@ -1175,7 +1306,7 @@ class WalkerMainService {
|
|
|
1175
1306
|
await mkdir(dumpDir, { recursive: true });
|
|
1176
1307
|
await writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
1177
1308
|
console.log(`Saved: ${filePath}`);
|
|
1178
|
-
|
|
1309
|
+
kill(0);
|
|
1179
1310
|
return;
|
|
1180
1311
|
}
|
|
1181
1312
|
if (payload.markdown) {
|
|
@@ -1184,12 +1315,13 @@ class WalkerMainService {
|
|
|
1184
1315
|
await mkdir(dumpDir, { recursive: true });
|
|
1185
1316
|
await writeFile(filePath, report, "utf-8");
|
|
1186
1317
|
console.log(`Saved: ${filePath}`);
|
|
1187
|
-
|
|
1318
|
+
kill(0);
|
|
1188
1319
|
return;
|
|
1189
1320
|
}
|
|
1190
1321
|
const report = await Walker.getReport(symbol, { walkerName: WalkerName$1.DefaultWalker });
|
|
1191
1322
|
console.log(report);
|
|
1192
|
-
|
|
1323
|
+
kill(0);
|
|
1324
|
+
return;
|
|
1193
1325
|
});
|
|
1194
1326
|
this.connect = singleshot(async () => {
|
|
1195
1327
|
this.loggerService.log("walkerMainService connect");
|
|
@@ -1234,6 +1366,10 @@ class LiveMainService {
|
|
|
1234
1366
|
this.loggerService.log("liveMainService run", {
|
|
1235
1367
|
payload,
|
|
1236
1368
|
});
|
|
1369
|
+
{
|
|
1370
|
+
const cwd = process.cwd();
|
|
1371
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1372
|
+
}
|
|
1237
1373
|
await this.configConnectionService.loadConfig("setup.config");
|
|
1238
1374
|
{
|
|
1239
1375
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -1247,7 +1383,8 @@ class LiveMainService {
|
|
|
1247
1383
|
}
|
|
1248
1384
|
catch (error) {
|
|
1249
1385
|
console.error("Module loader failed", error);
|
|
1250
|
-
|
|
1386
|
+
kill(-1);
|
|
1387
|
+
return;
|
|
1251
1388
|
}
|
|
1252
1389
|
}
|
|
1253
1390
|
{
|
|
@@ -1258,10 +1395,6 @@ class LiveMainService {
|
|
|
1258
1395
|
this.frontendProviderService.connect();
|
|
1259
1396
|
this.telegramProviderService.connect();
|
|
1260
1397
|
}
|
|
1261
|
-
{
|
|
1262
|
-
const cwd = process.cwd();
|
|
1263
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1264
|
-
}
|
|
1265
1398
|
let absolutePath;
|
|
1266
1399
|
{
|
|
1267
1400
|
absolutePath = await this.resolveService.attachJavascript(payload.entryPoint);
|
|
@@ -1337,6 +1470,10 @@ class PaperMainService {
|
|
|
1337
1470
|
this.configConnectionService = inject(TYPES.configConnectionService);
|
|
1338
1471
|
this.run = singleshot(async (payload) => {
|
|
1339
1472
|
this.loggerService.log("paperMainService init");
|
|
1473
|
+
{
|
|
1474
|
+
const cwd = process.cwd();
|
|
1475
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1476
|
+
}
|
|
1340
1477
|
await this.configConnectionService.loadConfig("setup.config");
|
|
1341
1478
|
{
|
|
1342
1479
|
const loader = await this.configConnectionService.loadConfig("loader.config");
|
|
@@ -1350,7 +1487,8 @@ class PaperMainService {
|
|
|
1350
1487
|
}
|
|
1351
1488
|
catch (error) {
|
|
1352
1489
|
console.error("Module loader failed", error);
|
|
1353
|
-
|
|
1490
|
+
kill(-1);
|
|
1491
|
+
return;
|
|
1354
1492
|
}
|
|
1355
1493
|
}
|
|
1356
1494
|
{
|
|
@@ -1361,10 +1499,6 @@ class PaperMainService {
|
|
|
1361
1499
|
this.frontendProviderService.connect();
|
|
1362
1500
|
this.telegramProviderService.connect();
|
|
1363
1501
|
}
|
|
1364
|
-
{
|
|
1365
|
-
const cwd = process.cwd();
|
|
1366
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
1367
|
-
}
|
|
1368
1502
|
let absolutePath;
|
|
1369
1503
|
{
|
|
1370
1504
|
absolutePath = await this.resolveService.attachJavascript(payload.entryPoint);
|
|
@@ -1832,7 +1966,7 @@ class TelegramApiService {
|
|
|
1832
1966
|
console.error("Telegram publish failure", {
|
|
1833
1967
|
error,
|
|
1834
1968
|
});
|
|
1835
|
-
setTimeout(() =>
|
|
1969
|
+
setTimeout(() => kill(-1), 5000);
|
|
1836
1970
|
});
|
|
1837
1971
|
const result = await Promise.race([
|
|
1838
1972
|
waitForResult,
|
|
@@ -1846,7 +1980,7 @@ class TelegramApiService {
|
|
|
1846
1980
|
return "Message scheduled for publication";
|
|
1847
1981
|
}
|
|
1848
1982
|
if (TIMEOUT_COUNTER > MAX_TIMEOUT_COUNT) {
|
|
1849
|
-
setTimeout(() =>
|
|
1983
|
+
setTimeout(() => kill(-1), 5000);
|
|
1850
1984
|
}
|
|
1851
1985
|
return "Message published successfully";
|
|
1852
1986
|
};
|
|
@@ -2559,7 +2693,8 @@ const LOAD_MODULE_MODULE_FN = async (fileName, self) => {
|
|
|
2559
2693
|
}
|
|
2560
2694
|
catch {
|
|
2561
2695
|
console.warn(`Module module import failed filePath=${filePath} baseDir=${baseDir}`);
|
|
2562
|
-
|
|
2696
|
+
kill(-1);
|
|
2697
|
+
return false;
|
|
2563
2698
|
}
|
|
2564
2699
|
}
|
|
2565
2700
|
return false;
|
|
@@ -2679,7 +2814,8 @@ const TRANSPILE_FN = memoize(([path]) => `${path}`, (path, code, self, require)
|
|
|
2679
2814
|
}
|
|
2680
2815
|
catch (error) {
|
|
2681
2816
|
console.log(`Error during transpilation error=\`${getErrorMessage(error)}\` path=\`${path}\` __filename=\`${__filename}\` __dirname=\`${__dirname}\``);
|
|
2682
|
-
|
|
2817
|
+
kill(-1);
|
|
2818
|
+
return;
|
|
2683
2819
|
}
|
|
2684
2820
|
return {
|
|
2685
2821
|
require,
|
|
@@ -2939,7 +3075,7 @@ const GET_ALIAS_EXPORTS_FN = (self) => {
|
|
|
2939
3075
|
}
|
|
2940
3076
|
return null;
|
|
2941
3077
|
};
|
|
2942
|
-
const INIT_ALIAS_FN = (self) => {
|
|
3078
|
+
const INIT_ALIAS_FN = singleshot((self) => {
|
|
2943
3079
|
const alias = GET_ALIAS_EXPORTS_FN(self);
|
|
2944
3080
|
if (!alias) {
|
|
2945
3081
|
return;
|
|
@@ -2951,18 +3087,21 @@ const INIT_ALIAS_FN = (self) => {
|
|
|
2951
3087
|
Object.entries(alias).forEach(([name, module]) => overrideModule(name, module));
|
|
2952
3088
|
Object.assign(IMPORT_ALIAS, alias);
|
|
2953
3089
|
}
|
|
2954
|
-
};
|
|
3090
|
+
});
|
|
2955
3091
|
class LoaderService {
|
|
2956
3092
|
constructor() {
|
|
2957
3093
|
this.babelService = inject(TYPES.babelService);
|
|
2958
3094
|
this.loggerService = inject(TYPES.loggerService);
|
|
2959
3095
|
this.resolveService = inject(TYPES.resolveService);
|
|
2960
|
-
this.getInstance = memoize(([basePath]) => `${basePath}`, (basePath) =>
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
3096
|
+
this.getInstance = memoize(([basePath]) => `${basePath}`, (basePath) => {
|
|
3097
|
+
INIT_ALIAS_FN(this);
|
|
3098
|
+
return new ClientLoader({
|
|
3099
|
+
babel: this.babelService,
|
|
3100
|
+
logger: this.loggerService,
|
|
3101
|
+
resolve: this.resolveService,
|
|
3102
|
+
path: basePath,
|
|
3103
|
+
});
|
|
3104
|
+
});
|
|
2966
3105
|
this.import = (filePath, basePath = process.cwd()) => {
|
|
2967
3106
|
this.loggerService.log("loaderService import", {
|
|
2968
3107
|
filePath,
|
|
@@ -2979,10 +3118,6 @@ class LoaderService {
|
|
|
2979
3118
|
const instance = this.getInstance(basePath);
|
|
2980
3119
|
return instance.check(filePath);
|
|
2981
3120
|
};
|
|
2982
|
-
this.init = singleshot(() => {
|
|
2983
|
-
this.loggerService.log("loaderService init");
|
|
2984
|
-
INIT_ALIAS_FN(this);
|
|
2985
|
-
});
|
|
2986
3121
|
}
|
|
2987
3122
|
}
|
|
2988
3123
|
|
|
@@ -3011,7 +3146,8 @@ const LOAD_CONFIG_CONFIG_FN = async (fileName, self) => {
|
|
|
3011
3146
|
}
|
|
3012
3147
|
catch {
|
|
3013
3148
|
console.warn(`Module module import failed filePath=${filePath} baseDir=${baseDir}`);
|
|
3014
|
-
|
|
3149
|
+
kill(-1);
|
|
3150
|
+
return;
|
|
3015
3151
|
}
|
|
3016
3152
|
}
|
|
3017
3153
|
return null;
|
|
@@ -3196,7 +3332,7 @@ const main$g = async () => {
|
|
|
3196
3332
|
if (MODES.some((mode) => values[mode])) {
|
|
3197
3333
|
return;
|
|
3198
3334
|
}
|
|
3199
|
-
process.stdout.write(`@backtest-kit/cli ${"
|
|
3335
|
+
process.stdout.write(`@backtest-kit/cli ${"10.1.0"}\n`);
|
|
3200
3336
|
process.stdout.write("\n");
|
|
3201
3337
|
process.stdout.write(`Run with --help to see available commands.\n`);
|
|
3202
3338
|
process.stdout.write("\n");
|
|
@@ -3206,7 +3342,7 @@ const main$g = async () => {
|
|
|
3206
3342
|
main$g();
|
|
3207
3343
|
|
|
3208
3344
|
const notifyShutdown = singleshot(async () => {
|
|
3209
|
-
console.log("Graceful shutdown initiated.
|
|
3345
|
+
console.log("Graceful shutdown initiated.");
|
|
3210
3346
|
});
|
|
3211
3347
|
|
|
3212
3348
|
const FLUSH_DIRS = ["report", "log", "markdown", "agent"];
|
|
@@ -3245,6 +3381,7 @@ const BEFORE_EXIT_FN$5 = singleshot(async () => {
|
|
|
3245
3381
|
return;
|
|
3246
3382
|
}
|
|
3247
3383
|
notifyShutdown();
|
|
3384
|
+
notifyKill();
|
|
3248
3385
|
const { exchangeName, frameName, strategyName, symbol, status } = running;
|
|
3249
3386
|
if (status === "fulfilled") {
|
|
3250
3387
|
return;
|
|
@@ -3285,6 +3422,7 @@ const BEFORE_EXIT_FN$4 = singleshot(async () => {
|
|
|
3285
3422
|
return;
|
|
3286
3423
|
}
|
|
3287
3424
|
notifyShutdown();
|
|
3425
|
+
notifyKill();
|
|
3288
3426
|
const { walkerName, symbol, status } = running;
|
|
3289
3427
|
if (status === "fulfilled") {
|
|
3290
3428
|
return;
|
|
@@ -3322,6 +3460,7 @@ const BEFORE_EXIT_FN$3 = singleshot(async () => {
|
|
|
3322
3460
|
return;
|
|
3323
3461
|
}
|
|
3324
3462
|
notifyShutdown();
|
|
3463
|
+
notifyKill();
|
|
3325
3464
|
const { exchangeName, strategyName, symbol, status } = running;
|
|
3326
3465
|
if (status === "fulfilled") {
|
|
3327
3466
|
return;
|
|
@@ -3357,6 +3496,7 @@ const BEFORE_EXIT_FN$2 = singleshot(async () => {
|
|
|
3357
3496
|
return;
|
|
3358
3497
|
}
|
|
3359
3498
|
notifyShutdown();
|
|
3499
|
+
notifyKill();
|
|
3360
3500
|
const { exchangeName, strategyName, symbol, status } = running;
|
|
3361
3501
|
if (status === "fulfilled") {
|
|
3362
3502
|
return;
|
|
@@ -3457,6 +3597,7 @@ const createGracefulShutdown = (mode) => {
|
|
|
3457
3597
|
const handler = singleshot(async () => {
|
|
3458
3598
|
process.off("SIGINT", handler);
|
|
3459
3599
|
notifyShutdown();
|
|
3600
|
+
notifyKill();
|
|
3460
3601
|
await stop();
|
|
3461
3602
|
});
|
|
3462
3603
|
return singleshot(() => {
|
|
@@ -3474,13 +3615,17 @@ const main$a = async () => {
|
|
|
3474
3615
|
const mode = resolveMode(values);
|
|
3475
3616
|
if (!mode) {
|
|
3476
3617
|
console.error("--entry requires exactly one of --backtest, --live, --paper, --walker");
|
|
3477
|
-
|
|
3618
|
+
kill(1);
|
|
3478
3619
|
return;
|
|
3479
3620
|
}
|
|
3480
3621
|
const entryPoints = getPositionals();
|
|
3481
3622
|
if (!entryPoints.length) {
|
|
3482
3623
|
throw new Error("At least one entry point is required");
|
|
3483
3624
|
}
|
|
3625
|
+
{
|
|
3626
|
+
const cwd = process.cwd();
|
|
3627
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3628
|
+
}
|
|
3484
3629
|
await cli.configConnectionService.loadConfig("setup.config");
|
|
3485
3630
|
{
|
|
3486
3631
|
const loader = await cli.configConnectionService.loadConfig("loader.config");
|
|
@@ -3494,7 +3639,8 @@ const main$a = async () => {
|
|
|
3494
3639
|
}
|
|
3495
3640
|
catch (error) {
|
|
3496
3641
|
console.error("Module loader failed", error);
|
|
3497
|
-
|
|
3642
|
+
kill(-1);
|
|
3643
|
+
return;
|
|
3498
3644
|
}
|
|
3499
3645
|
}
|
|
3500
3646
|
{
|
|
@@ -3504,9 +3650,6 @@ const main$a = async () => {
|
|
|
3504
3650
|
cli.frontendProviderService.connect();
|
|
3505
3651
|
cli.telegramProviderService.connect();
|
|
3506
3652
|
const cwd = process.cwd();
|
|
3507
|
-
{
|
|
3508
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3509
|
-
}
|
|
3510
3653
|
if (entryPoints.length === 1) {
|
|
3511
3654
|
const absolutePath = path.resolve(entryPoints[0]);
|
|
3512
3655
|
const moduleRoot = path.dirname(absolutePath);
|
|
@@ -3536,6 +3679,7 @@ main$a();
|
|
|
3536
3679
|
const BEFORE_EXIT_FN$1 = singleshot(async () => {
|
|
3537
3680
|
process.off("SIGINT", BEFORE_EXIT_FN$1);
|
|
3538
3681
|
notifyShutdown();
|
|
3682
|
+
notifyKill();
|
|
3539
3683
|
cli.frontendProviderService.disable();
|
|
3540
3684
|
});
|
|
3541
3685
|
const listenGracefulShutdown$1 = singleshot(() => {
|
|
@@ -3556,6 +3700,7 @@ main$9();
|
|
|
3556
3700
|
const BEFORE_EXIT_FN = singleshot(async () => {
|
|
3557
3701
|
process.off("SIGINT", BEFORE_EXIT_FN);
|
|
3558
3702
|
notifyShutdown();
|
|
3703
|
+
notifyKill();
|
|
3559
3704
|
cli.telegramProviderService.disable();
|
|
3560
3705
|
});
|
|
3561
3706
|
const listenGracefulShutdown = singleshot(() => {
|
|
@@ -3705,7 +3850,12 @@ const main$6 = async () => {
|
|
|
3705
3850
|
}
|
|
3706
3851
|
if (values.pine) {
|
|
3707
3852
|
console.warn("--editor and --pine are mutually exclusive. Use one at a time.");
|
|
3708
|
-
|
|
3853
|
+
kill(1);
|
|
3854
|
+
return;
|
|
3855
|
+
}
|
|
3856
|
+
{
|
|
3857
|
+
const cwd = process.cwd();
|
|
3858
|
+
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3709
3859
|
}
|
|
3710
3860
|
await cli.configConnectionService.loadConfig("setup.config");
|
|
3711
3861
|
{
|
|
@@ -3720,17 +3870,14 @@ const main$6 = async () => {
|
|
|
3720
3870
|
}
|
|
3721
3871
|
catch (error) {
|
|
3722
3872
|
console.error("Module loader failed", error);
|
|
3723
|
-
|
|
3873
|
+
kill(-1);
|
|
3874
|
+
return;
|
|
3724
3875
|
}
|
|
3725
3876
|
}
|
|
3726
3877
|
{
|
|
3727
3878
|
await cli.configService.waitForInit();
|
|
3728
3879
|
Setup.enable();
|
|
3729
3880
|
}
|
|
3730
|
-
{
|
|
3731
|
-
const cwd = process.cwd();
|
|
3732
|
-
dotenv.config({ path: path.join(cwd, '.env'), override: true, quiet: true });
|
|
3733
|
-
}
|
|
3734
3881
|
await cli.moduleConnectionService.loadModule("editor.module");
|
|
3735
3882
|
{
|
|
3736
3883
|
await cli.exchangeSchemaService.addSchema();
|
|
@@ -3750,7 +3897,8 @@ const main$6 = async () => {
|
|
|
3750
3897
|
const beforeExit = () => {
|
|
3751
3898
|
process.off("SIGINT", beforeExit);
|
|
3752
3899
|
unServer();
|
|
3753
|
-
|
|
3900
|
+
kill(0);
|
|
3901
|
+
return;
|
|
3754
3902
|
};
|
|
3755
3903
|
process.on("SIGINT", beforeExit);
|
|
3756
3904
|
};
|
|
@@ -4321,7 +4469,7 @@ const main$1 = async () => {
|
|
|
4321
4469
|
if (!values.help) {
|
|
4322
4470
|
return;
|
|
4323
4471
|
}
|
|
4324
|
-
process.stdout.write(`@backtest-kit/cli ${"
|
|
4472
|
+
process.stdout.write(`@backtest-kit/cli ${"10.1.0"}\n\n`);
|
|
4325
4473
|
process.stdout.write(HELP_TEXT);
|
|
4326
4474
|
process.exit(0);
|
|
4327
4475
|
};
|
|
@@ -4335,7 +4483,7 @@ const main = async () => {
|
|
|
4335
4483
|
if (!values.version) {
|
|
4336
4484
|
return;
|
|
4337
4485
|
}
|
|
4338
|
-
process.stdout.write(`@backtest-kit/cli ${"
|
|
4486
|
+
process.stdout.write(`@backtest-kit/cli ${"10.1.0"}\n`);
|
|
4339
4487
|
process.exit(0);
|
|
4340
4488
|
};
|
|
4341
4489
|
main();
|
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": "
|
|
19
|
-
"@backtest-kit/graph": "
|
|
20
|
-
"@backtest-kit/pinets": "
|
|
21
|
-
"@backtest-kit/signals": "
|
|
22
|
-
"@backtest-kit/ui": "
|
|
18
|
+
"@backtest-kit/cli": "10.1.0",
|
|
19
|
+
"@backtest-kit/graph": "10.1.0",
|
|
20
|
+
"@backtest-kit/pinets": "10.1.0",
|
|
21
|
+
"@backtest-kit/signals": "10.1.0",
|
|
22
|
+
"@backtest-kit/ui": "10.1.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.7.0",
|
|
28
|
-
"backtest-kit": "
|
|
28
|
+
"backtest-kit": "10.1.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": "
|
|
3
|
+
"version": "10.1.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": "
|
|
67
|
-
"@backtest-kit/ollama": "
|
|
68
|
-
"@backtest-kit/pinets": "
|
|
69
|
-
"@backtest-kit/signals": "
|
|
70
|
-
"@backtest-kit/ui": "
|
|
66
|
+
"@backtest-kit/graph": "10.1.0",
|
|
67
|
+
"@backtest-kit/ollama": "10.1.0",
|
|
68
|
+
"@backtest-kit/pinets": "10.1.0",
|
|
69
|
+
"@backtest-kit/signals": "10.1.0",
|
|
70
|
+
"@backtest-kit/ui": "10.1.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": "
|
|
78
|
+
"backtest-kit": "10.1.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": "^
|
|
94
|
-
"@backtest-kit/ollama": "^
|
|
95
|
-
"@backtest-kit/pinets": "^
|
|
96
|
-
"@backtest-kit/signals": "^
|
|
97
|
-
"@backtest-kit/ui": "^
|
|
98
|
-
"backtest-kit": "^
|
|
93
|
+
"@backtest-kit/graph": "^10.1.0",
|
|
94
|
+
"@backtest-kit/ollama": "^10.1.0",
|
|
95
|
+
"@backtest-kit/pinets": "^10.1.0",
|
|
96
|
+
"@backtest-kit/signals": "^10.1.0",
|
|
97
|
+
"@backtest-kit/ui": "^10.1.0",
|
|
98
|
+
"backtest-kit": "^10.1.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": "^
|
|
17
|
-
"@backtest-kit/graph": "^
|
|
18
|
-
"@backtest-kit/pinets": "^
|
|
19
|
-
"@backtest-kit/ui": "^
|
|
16
|
+
"@backtest-kit/cli": "^10.1.0",
|
|
17
|
+
"@backtest-kit/graph": "^10.1.0",
|
|
18
|
+
"@backtest-kit/pinets": "^10.1.0",
|
|
19
|
+
"@backtest-kit/ui": "^10.1.0",
|
|
20
20
|
"agent-swarm-kit": "^2.7.0",
|
|
21
|
-
"backtest-kit": "^
|
|
21
|
+
"backtest-kit": "^10.1.0",
|
|
22
22
|
"functools-kit": "^2.3.0",
|
|
23
23
|
"garch": "^1.2.3",
|
|
24
24
|
"get-moment-stamp": "^2.0.0",
|
package/types.d.ts
CHANGED
|
@@ -209,7 +209,6 @@ declare class LoaderService {
|
|
|
209
209
|
getInstance: ((basePath: string) => ClientLoader) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, ClientLoader>;
|
|
210
210
|
import: (filePath: string, basePath?: string) => any;
|
|
211
211
|
check: (filePath: string, basePath?: string) => Promise<boolean>;
|
|
212
|
-
init: (() => void) & functools_kit.ISingleshotClearable<() => void>;
|
|
213
212
|
}
|
|
214
213
|
|
|
215
214
|
declare class ResolveService implements IResolve {
|