@tradejs/cli 3.1.2 → 3.1.4
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/dist/cli.js +173 -187
- package/dist/scripts/backtest.js +4 -20
- package/dist/scripts/runtimeConfig.js +127 -102
- package/dist/scripts/signals.js +43 -63
- package/dist/scripts/signalsDaemon.js +43 -63
- package/dist/scripts/signalsSummary.js +1 -1
- package/package.json +7 -7
package/dist/scripts/signals.js
CHANGED
|
@@ -4803,18 +4803,15 @@ var createSignalsTickerEvaluator = ({
|
|
|
4803
4803
|
for (const runtimeStrategy of runtimeStrategies) {
|
|
4804
4804
|
const {
|
|
4805
4805
|
strategyName,
|
|
4806
|
-
configId,
|
|
4807
4806
|
releaseVersion,
|
|
4808
4807
|
controlState,
|
|
4809
4808
|
strategyPackageVersion,
|
|
4810
4809
|
runtimePackageVersion,
|
|
4811
4810
|
strategyCreator,
|
|
4812
4811
|
sourceStrategyConfig,
|
|
4813
|
-
strategyConfig
|
|
4814
|
-
strategyResults
|
|
4812
|
+
strategyConfig
|
|
4815
4813
|
} = runtimeStrategy;
|
|
4816
|
-
const runtimeIdentity =
|
|
4817
|
-
const symbolResultConfig = strategyResults?.[symbol]?.config ?? null;
|
|
4814
|
+
const runtimeIdentity = `v${releaseVersion}`;
|
|
4818
4815
|
const runtimeConfig = buildRuntimeModeStrategyConfig({
|
|
4819
4816
|
strategyConfig,
|
|
4820
4817
|
env: "CRON",
|
|
@@ -4827,7 +4824,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
4827
4824
|
releaseVersion,
|
|
4828
4825
|
strategyPackageVersion,
|
|
4829
4826
|
runtimePackageVersion,
|
|
4830
|
-
config: {
|
|
4827
|
+
config: { strategyConfig },
|
|
4831
4828
|
runContext: {
|
|
4832
4829
|
connectorName: connectorName.toLowerCase(),
|
|
4833
4830
|
interval: String(interval),
|
|
@@ -4855,7 +4852,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
4855
4852
|
evaluation = await lifecycle.evaluate({
|
|
4856
4853
|
key: lifecycleKey,
|
|
4857
4854
|
timestamp: lastCandle.timestamp,
|
|
4858
|
-
config: { runtimeConfig, sourceStrategyConfig
|
|
4855
|
+
config: { runtimeConfig, sourceStrategyConfig },
|
|
4859
4856
|
btcBinanceData,
|
|
4860
4857
|
btcCoinbaseData,
|
|
4861
4858
|
onRuntimeClose: (event) => runtimeCloseNotifications.push(event),
|
|
@@ -4866,13 +4863,12 @@ var createSignalsTickerEvaluator = ({
|
|
|
4866
4863
|
}) => strategyCreator({
|
|
4867
4864
|
userName,
|
|
4868
4865
|
connectorName,
|
|
4869
|
-
runtimeConfigId:
|
|
4866
|
+
runtimeConfigId: runtimeIdentity,
|
|
4870
4867
|
runtimeReleaseVersion: releaseVersion,
|
|
4871
4868
|
entriesPaused: controlState === "entries_paused",
|
|
4872
4869
|
runtimeLineage,
|
|
4873
4870
|
runtimeConfigSnapshot: {
|
|
4874
|
-
userConfig: sourceStrategyConfig
|
|
4875
|
-
symbolResultConfig
|
|
4871
|
+
userConfig: sourceStrategyConfig
|
|
4876
4872
|
},
|
|
4877
4873
|
connector,
|
|
4878
4874
|
symbol,
|
|
@@ -4922,12 +4918,12 @@ var createSignalsTickerEvaluator = ({
|
|
|
4922
4918
|
strategyName,
|
|
4923
4919
|
symbol,
|
|
4924
4920
|
timestamp: lastCandle.timestamp,
|
|
4925
|
-
runtimeConfigId:
|
|
4921
|
+
runtimeConfigId: runtimeIdentity,
|
|
4926
4922
|
runtimeReleaseVersion: releaseVersion
|
|
4927
4923
|
}),
|
|
4928
4924
|
userName,
|
|
4929
4925
|
strategy: strategyName,
|
|
4930
|
-
runtimeConfigId:
|
|
4926
|
+
runtimeConfigId: runtimeIdentity,
|
|
4931
4927
|
runtimeReleaseVersion: releaseVersion,
|
|
4932
4928
|
runtimeLineage,
|
|
4933
4929
|
symbol,
|
|
@@ -4945,12 +4941,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4945
4941
|
continue;
|
|
4946
4942
|
}
|
|
4947
4943
|
if (stats) stats.signals += 1;
|
|
4948
|
-
signal.runtimeConfigId =
|
|
4944
|
+
signal.runtimeConfigId = runtimeIdentity;
|
|
4949
4945
|
signal.runtimeReleaseVersion = releaseVersion;
|
|
4950
4946
|
signal.runtimeLineage = runtimeLineage;
|
|
4951
|
-
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
4952
|
-
signal.signalId = `${signal.signalId}:${configId}`;
|
|
4953
|
-
}
|
|
4954
4947
|
if (releaseVersion && !signal.signalId.endsWith(`:v${releaseVersion}`)) {
|
|
4955
4948
|
signal.signalId = `${signal.signalId}:v${releaseVersion}`;
|
|
4956
4949
|
}
|
|
@@ -4970,12 +4963,12 @@ var createSignalsTickerEvaluator = ({
|
|
|
4970
4963
|
strategyName,
|
|
4971
4964
|
symbol,
|
|
4972
4965
|
timestamp: lastCandle.timestamp,
|
|
4973
|
-
runtimeConfigId:
|
|
4966
|
+
runtimeConfigId: runtimeIdentity,
|
|
4974
4967
|
runtimeReleaseVersion: releaseVersion
|
|
4975
4968
|
}),
|
|
4976
4969
|
userName,
|
|
4977
4970
|
strategy: strategyName,
|
|
4978
|
-
runtimeConfigId:
|
|
4971
|
+
runtimeConfigId: runtimeIdentity,
|
|
4979
4972
|
runtimeReleaseVersion: releaseVersion,
|
|
4980
4973
|
runtimeLineage,
|
|
4981
4974
|
symbol,
|
|
@@ -5055,15 +5048,12 @@ var createSignalsRunner = (config2) => {
|
|
|
5055
5048
|
].join("\n");
|
|
5056
5049
|
const resolveSignalsConnectorName = async (value) => {
|
|
5057
5050
|
const connectorName = await (0, import_connectors6.resolveConnectorName)(value, projectRoot);
|
|
5058
|
-
if (connectorName) {
|
|
5059
|
-
|
|
5051
|
+
if (!connectorName) {
|
|
5052
|
+
throw new Error(
|
|
5053
|
+
`Unknown runtime connector: ${String(value || "").trim() || String(value)}`
|
|
5054
|
+
);
|
|
5060
5055
|
}
|
|
5061
|
-
|
|
5062
|
-
'Unknown connector "%s". Fallback to %s.',
|
|
5063
|
-
String(value || "").trim() || String(value),
|
|
5064
|
-
import_connectors6.DEFAULT_CONNECTOR_NAME
|
|
5065
|
-
);
|
|
5066
|
-
return import_connectors6.DEFAULT_CONNECTOR_NAME;
|
|
5056
|
+
return connectorName;
|
|
5067
5057
|
};
|
|
5068
5058
|
const createSignalsSession2 = async (lifecycle, scope = {}) => {
|
|
5069
5059
|
const deployment = config2.deploymentId ? await (0, import_runtimeDeployments.getRuntimeDeployment)(config2.userName, config2.deploymentId) : null;
|
|
@@ -5074,25 +5064,15 @@ var createSignalsRunner = (config2) => {
|
|
|
5074
5064
|
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
5075
5065
|
}
|
|
5076
5066
|
const requestedRuntimeInterval = scope.interval ?? interval;
|
|
5077
|
-
const
|
|
5078
|
-
deployment?.strategies.some(
|
|
5079
|
-
(strategy) => strategy.releaseVersion != null
|
|
5080
|
-
)
|
|
5081
|
-
);
|
|
5082
|
-
const runtimeInterval = versionedDeployment ? requestedRuntimeInterval : deployment?.interval ?? requestedRuntimeInterval;
|
|
5067
|
+
const runtimeInterval = requestedRuntimeInterval;
|
|
5083
5068
|
const runtimeIntervalMs = Number(runtimeInterval) * 6e4;
|
|
5084
5069
|
if (!Number.isFinite(runtimeIntervalMs) || runtimeIntervalMs <= 0) {
|
|
5085
5070
|
throw new Error(`Invalid runtime timeframe: ${runtimeInterval}`);
|
|
5086
5071
|
}
|
|
5087
|
-
if (deployment && !versionedDeployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
5088
|
-
throw new Error(
|
|
5089
|
-
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedRuntimeInterval}`
|
|
5090
|
-
);
|
|
5091
|
-
}
|
|
5092
5072
|
const connectorName = await resolveSignalsConnectorName(
|
|
5093
5073
|
deployment?.connectorName ?? scope.connectorName ?? config2.connectorName
|
|
5094
5074
|
);
|
|
5095
|
-
const universe =
|
|
5075
|
+
const universe = scope.universe ?? config2.universe;
|
|
5096
5076
|
const requestedAccountId = deployment?.accountId ?? scope.accountId ?? config2.accountId;
|
|
5097
5077
|
const connectorFactory = await (0, import_connectors6.getConnectorCreatorByName)(
|
|
5098
5078
|
connectorName,
|
|
@@ -5304,7 +5284,6 @@ var createSignalsRunner = (config2) => {
|
|
|
5304
5284
|
userName: config2.userName,
|
|
5305
5285
|
projectRoot,
|
|
5306
5286
|
deployment,
|
|
5307
|
-
connectorName,
|
|
5308
5287
|
universe,
|
|
5309
5288
|
accountId,
|
|
5310
5289
|
interval: interval2
|
|
@@ -5312,8 +5291,8 @@ var createSignalsRunner = (config2) => {
|
|
|
5312
5291
|
if (!runtimeStrategies.length) {
|
|
5313
5292
|
lifecycle.clear();
|
|
5314
5293
|
import_logger4.logger.warn(
|
|
5315
|
-
"No strategy
|
|
5316
|
-
|
|
5294
|
+
"No strategy releases are bound to deployment %s",
|
|
5295
|
+
deployment?.id
|
|
5317
5296
|
);
|
|
5318
5297
|
return;
|
|
5319
5298
|
}
|
|
@@ -5321,7 +5300,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5321
5300
|
new Set(
|
|
5322
5301
|
tickers.flatMap(
|
|
5323
5302
|
(symbol) => runtimeStrategies.map(
|
|
5324
|
-
({ strategyName,
|
|
5303
|
+
({ strategyName, releaseVersion }) => buildSignalsStrategyLifecycleKey({
|
|
5325
5304
|
connectorName,
|
|
5326
5305
|
universe: sessionUniverse,
|
|
5327
5306
|
accountId,
|
|
@@ -5329,7 +5308,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5329
5308
|
symbol,
|
|
5330
5309
|
interval: interval2,
|
|
5331
5310
|
strategyName,
|
|
5332
|
-
configId:
|
|
5311
|
+
configId: `v${releaseVersion}`
|
|
5333
5312
|
})
|
|
5334
5313
|
)
|
|
5335
5314
|
)
|
|
@@ -5518,11 +5497,10 @@ var createSignalsRunner = (config2) => {
|
|
|
5518
5497
|
const configuredStrategies = await (0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({
|
|
5519
5498
|
userName: config2.userName,
|
|
5520
5499
|
projectRoot,
|
|
5521
|
-
deployment
|
|
5522
|
-
connectorName: config2.connectorName
|
|
5500
|
+
deployment
|
|
5523
5501
|
});
|
|
5524
5502
|
const connectorName = await resolveSignalsConnectorName(
|
|
5525
|
-
deployment
|
|
5503
|
+
deployment.connectorName
|
|
5526
5504
|
);
|
|
5527
5505
|
const scopes = /* @__PURE__ */ new Map();
|
|
5528
5506
|
for (const strategy of configuredStrategies) {
|
|
@@ -5541,13 +5519,18 @@ var createSignalsRunner = (config2) => {
|
|
|
5541
5519
|
}
|
|
5542
5520
|
return scopes;
|
|
5543
5521
|
};
|
|
5544
|
-
const hasExplicitSignalsScope = () => Boolean(config2.hasExplicitScope);
|
|
5545
5522
|
const signalsConfiguredScopesOnce2 = async () => {
|
|
5546
|
-
if (config2.updateOnly || config2.showTickersList
|
|
5523
|
+
if (config2.updateOnly || config2.showTickersList) {
|
|
5547
5524
|
return signals2();
|
|
5548
5525
|
}
|
|
5549
|
-
|
|
5550
|
-
|
|
5526
|
+
if (!config2.deploymentId) {
|
|
5527
|
+
throw new Error("Runtime deployment id is required");
|
|
5528
|
+
}
|
|
5529
|
+
const configuredDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
|
|
5530
|
+
config2.userName,
|
|
5531
|
+
config2.deploymentId
|
|
5532
|
+
);
|
|
5533
|
+
if (!configuredDeployment) {
|
|
5551
5534
|
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5552
5535
|
}
|
|
5553
5536
|
const scopes = await loadConfiguredSignalsScopes(configuredDeployment);
|
|
@@ -5572,8 +5555,14 @@ var createSignalsRunner = (config2) => {
|
|
|
5572
5555
|
);
|
|
5573
5556
|
}
|
|
5574
5557
|
const abortController = new AbortController();
|
|
5575
|
-
|
|
5576
|
-
|
|
5558
|
+
if (!config2.deploymentId) {
|
|
5559
|
+
throw new Error("Runtime deployment id is required");
|
|
5560
|
+
}
|
|
5561
|
+
const daemonDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
|
|
5562
|
+
config2.userName,
|
|
5563
|
+
config2.deploymentId
|
|
5564
|
+
);
|
|
5565
|
+
if (!daemonDeployment) {
|
|
5577
5566
|
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5578
5567
|
}
|
|
5579
5568
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -5586,10 +5575,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5586
5575
|
const stopOnSigterm = () => stop("SIGTERM");
|
|
5587
5576
|
process.once("SIGINT", stopOnSigint);
|
|
5588
5577
|
process.once("SIGTERM", stopOnSigterm);
|
|
5589
|
-
import_logger4.logger.info(
|
|
5590
|
-
"signals daemon started (config-driven scopes, fallback interval=%s)",
|
|
5591
|
-
interval
|
|
5592
|
-
);
|
|
5578
|
+
import_logger4.logger.info("signals daemon started (deployment-driven scopes)");
|
|
5593
5579
|
try {
|
|
5594
5580
|
await runSignalsDaemon({
|
|
5595
5581
|
intervalMs: 6e4,
|
|
@@ -5729,11 +5715,6 @@ import_args.default.option(["V", "universe"], "Market universe (crypto or tradfi
|
|
|
5729
5715
|
import_args.default.option(["A", "account"], "Trading account id");
|
|
5730
5716
|
import_args.default.option(["D", "deployment"], "Runtime deployment id");
|
|
5731
5717
|
var flags = import_args.default.parse(process.argv);
|
|
5732
|
-
var hasExplicitScope = process.argv.some(
|
|
5733
|
-
(argument) => ["-f", "--timeframe", "-V", "--universe", "-A", "--account"].some(
|
|
5734
|
-
(option) => argument === option || argument.startsWith(`${option}=`)
|
|
5735
|
-
)
|
|
5736
|
-
);
|
|
5737
5718
|
var config = {
|
|
5738
5719
|
projectRoot: String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd(),
|
|
5739
5720
|
userName: String(flags.user || "root"),
|
|
@@ -5755,8 +5736,7 @@ var config = {
|
|
|
5755
5736
|
showSkipStats: Boolean(flags.showSkipStats),
|
|
5756
5737
|
parallel: flags.parallel,
|
|
5757
5738
|
watch: Boolean(flags.watch),
|
|
5758
|
-
settleDelayMs: flags.settleDelayMs
|
|
5759
|
-
hasExplicitScope
|
|
5739
|
+
settleDelayMs: flags.settleDelayMs
|
|
5760
5740
|
};
|
|
5761
5741
|
var runner = createSignalsRunner(config);
|
|
5762
5742
|
var createSignalsSession = runner.createSession;
|
|
@@ -4801,18 +4801,15 @@ var createSignalsTickerEvaluator = ({
|
|
|
4801
4801
|
for (const runtimeStrategy of runtimeStrategies) {
|
|
4802
4802
|
const {
|
|
4803
4803
|
strategyName,
|
|
4804
|
-
configId,
|
|
4805
4804
|
releaseVersion,
|
|
4806
4805
|
controlState,
|
|
4807
4806
|
strategyPackageVersion,
|
|
4808
4807
|
runtimePackageVersion,
|
|
4809
4808
|
strategyCreator,
|
|
4810
4809
|
sourceStrategyConfig,
|
|
4811
|
-
strategyConfig
|
|
4812
|
-
strategyResults
|
|
4810
|
+
strategyConfig
|
|
4813
4811
|
} = runtimeStrategy;
|
|
4814
|
-
const runtimeIdentity =
|
|
4815
|
-
const symbolResultConfig = strategyResults?.[symbol]?.config ?? null;
|
|
4812
|
+
const runtimeIdentity = `v${releaseVersion}`;
|
|
4816
4813
|
const runtimeConfig = buildRuntimeModeStrategyConfig({
|
|
4817
4814
|
strategyConfig,
|
|
4818
4815
|
env: "CRON",
|
|
@@ -4825,7 +4822,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
4825
4822
|
releaseVersion,
|
|
4826
4823
|
strategyPackageVersion,
|
|
4827
4824
|
runtimePackageVersion,
|
|
4828
|
-
config: {
|
|
4825
|
+
config: { strategyConfig },
|
|
4829
4826
|
runContext: {
|
|
4830
4827
|
connectorName: connectorName.toLowerCase(),
|
|
4831
4828
|
interval: String(interval),
|
|
@@ -4853,7 +4850,7 @@ var createSignalsTickerEvaluator = ({
|
|
|
4853
4850
|
evaluation = await lifecycle.evaluate({
|
|
4854
4851
|
key: lifecycleKey,
|
|
4855
4852
|
timestamp: lastCandle.timestamp,
|
|
4856
|
-
config: { runtimeConfig, sourceStrategyConfig
|
|
4853
|
+
config: { runtimeConfig, sourceStrategyConfig },
|
|
4857
4854
|
btcBinanceData,
|
|
4858
4855
|
btcCoinbaseData,
|
|
4859
4856
|
onRuntimeClose: (event) => runtimeCloseNotifications.push(event),
|
|
@@ -4864,13 +4861,12 @@ var createSignalsTickerEvaluator = ({
|
|
|
4864
4861
|
}) => strategyCreator({
|
|
4865
4862
|
userName,
|
|
4866
4863
|
connectorName,
|
|
4867
|
-
runtimeConfigId:
|
|
4864
|
+
runtimeConfigId: runtimeIdentity,
|
|
4868
4865
|
runtimeReleaseVersion: releaseVersion,
|
|
4869
4866
|
entriesPaused: controlState === "entries_paused",
|
|
4870
4867
|
runtimeLineage,
|
|
4871
4868
|
runtimeConfigSnapshot: {
|
|
4872
|
-
userConfig: sourceStrategyConfig
|
|
4873
|
-
symbolResultConfig
|
|
4869
|
+
userConfig: sourceStrategyConfig
|
|
4874
4870
|
},
|
|
4875
4871
|
connector,
|
|
4876
4872
|
symbol,
|
|
@@ -4920,12 +4916,12 @@ var createSignalsTickerEvaluator = ({
|
|
|
4920
4916
|
strategyName,
|
|
4921
4917
|
symbol,
|
|
4922
4918
|
timestamp: lastCandle.timestamp,
|
|
4923
|
-
runtimeConfigId:
|
|
4919
|
+
runtimeConfigId: runtimeIdentity,
|
|
4924
4920
|
runtimeReleaseVersion: releaseVersion
|
|
4925
4921
|
}),
|
|
4926
4922
|
userName,
|
|
4927
4923
|
strategy: strategyName,
|
|
4928
|
-
runtimeConfigId:
|
|
4924
|
+
runtimeConfigId: runtimeIdentity,
|
|
4929
4925
|
runtimeReleaseVersion: releaseVersion,
|
|
4930
4926
|
runtimeLineage,
|
|
4931
4927
|
symbol,
|
|
@@ -4943,12 +4939,9 @@ var createSignalsTickerEvaluator = ({
|
|
|
4943
4939
|
continue;
|
|
4944
4940
|
}
|
|
4945
4941
|
if (stats) stats.signals += 1;
|
|
4946
|
-
signal.runtimeConfigId =
|
|
4942
|
+
signal.runtimeConfigId = runtimeIdentity;
|
|
4947
4943
|
signal.runtimeReleaseVersion = releaseVersion;
|
|
4948
4944
|
signal.runtimeLineage = runtimeLineage;
|
|
4949
|
-
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
4950
|
-
signal.signalId = `${signal.signalId}:${configId}`;
|
|
4951
|
-
}
|
|
4952
4945
|
if (releaseVersion && !signal.signalId.endsWith(`:v${releaseVersion}`)) {
|
|
4953
4946
|
signal.signalId = `${signal.signalId}:v${releaseVersion}`;
|
|
4954
4947
|
}
|
|
@@ -4968,12 +4961,12 @@ var createSignalsTickerEvaluator = ({
|
|
|
4968
4961
|
strategyName,
|
|
4969
4962
|
symbol,
|
|
4970
4963
|
timestamp: lastCandle.timestamp,
|
|
4971
|
-
runtimeConfigId:
|
|
4964
|
+
runtimeConfigId: runtimeIdentity,
|
|
4972
4965
|
runtimeReleaseVersion: releaseVersion
|
|
4973
4966
|
}),
|
|
4974
4967
|
userName,
|
|
4975
4968
|
strategy: strategyName,
|
|
4976
|
-
runtimeConfigId:
|
|
4969
|
+
runtimeConfigId: runtimeIdentity,
|
|
4977
4970
|
runtimeReleaseVersion: releaseVersion,
|
|
4978
4971
|
runtimeLineage,
|
|
4979
4972
|
symbol,
|
|
@@ -5053,15 +5046,12 @@ var createSignalsRunner = (config2) => {
|
|
|
5053
5046
|
].join("\n");
|
|
5054
5047
|
const resolveSignalsConnectorName = async (value) => {
|
|
5055
5048
|
const connectorName = await (0, import_connectors6.resolveConnectorName)(value, projectRoot);
|
|
5056
|
-
if (connectorName) {
|
|
5057
|
-
|
|
5049
|
+
if (!connectorName) {
|
|
5050
|
+
throw new Error(
|
|
5051
|
+
`Unknown runtime connector: ${String(value || "").trim() || String(value)}`
|
|
5052
|
+
);
|
|
5058
5053
|
}
|
|
5059
|
-
|
|
5060
|
-
'Unknown connector "%s". Fallback to %s.',
|
|
5061
|
-
String(value || "").trim() || String(value),
|
|
5062
|
-
import_connectors6.DEFAULT_CONNECTOR_NAME
|
|
5063
|
-
);
|
|
5064
|
-
return import_connectors6.DEFAULT_CONNECTOR_NAME;
|
|
5054
|
+
return connectorName;
|
|
5065
5055
|
};
|
|
5066
5056
|
const createSignalsSession2 = async (lifecycle, scope = {}) => {
|
|
5067
5057
|
const deployment = config2.deploymentId ? await (0, import_runtimeDeployments.getRuntimeDeployment)(config2.userName, config2.deploymentId) : null;
|
|
@@ -5072,25 +5062,15 @@ var createSignalsRunner = (config2) => {
|
|
|
5072
5062
|
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
5073
5063
|
}
|
|
5074
5064
|
const requestedRuntimeInterval = scope.interval ?? interval;
|
|
5075
|
-
const
|
|
5076
|
-
deployment?.strategies.some(
|
|
5077
|
-
(strategy) => strategy.releaseVersion != null
|
|
5078
|
-
)
|
|
5079
|
-
);
|
|
5080
|
-
const runtimeInterval = versionedDeployment ? requestedRuntimeInterval : deployment?.interval ?? requestedRuntimeInterval;
|
|
5065
|
+
const runtimeInterval = requestedRuntimeInterval;
|
|
5081
5066
|
const runtimeIntervalMs = Number(runtimeInterval) * 6e4;
|
|
5082
5067
|
if (!Number.isFinite(runtimeIntervalMs) || runtimeIntervalMs <= 0) {
|
|
5083
5068
|
throw new Error(`Invalid runtime timeframe: ${runtimeInterval}`);
|
|
5084
5069
|
}
|
|
5085
|
-
if (deployment && !versionedDeployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
5086
|
-
throw new Error(
|
|
5087
|
-
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedRuntimeInterval}`
|
|
5088
|
-
);
|
|
5089
|
-
}
|
|
5090
5070
|
const connectorName = await resolveSignalsConnectorName(
|
|
5091
5071
|
deployment?.connectorName ?? scope.connectorName ?? config2.connectorName
|
|
5092
5072
|
);
|
|
5093
|
-
const universe =
|
|
5073
|
+
const universe = scope.universe ?? config2.universe;
|
|
5094
5074
|
const requestedAccountId = deployment?.accountId ?? scope.accountId ?? config2.accountId;
|
|
5095
5075
|
const connectorFactory = await (0, import_connectors6.getConnectorCreatorByName)(
|
|
5096
5076
|
connectorName,
|
|
@@ -5302,7 +5282,6 @@ var createSignalsRunner = (config2) => {
|
|
|
5302
5282
|
userName: config2.userName,
|
|
5303
5283
|
projectRoot,
|
|
5304
5284
|
deployment,
|
|
5305
|
-
connectorName,
|
|
5306
5285
|
universe,
|
|
5307
5286
|
accountId,
|
|
5308
5287
|
interval: interval2
|
|
@@ -5310,8 +5289,8 @@ var createSignalsRunner = (config2) => {
|
|
|
5310
5289
|
if (!runtimeStrategies.length) {
|
|
5311
5290
|
lifecycle.clear();
|
|
5312
5291
|
import_logger4.logger.warn(
|
|
5313
|
-
"No strategy
|
|
5314
|
-
|
|
5292
|
+
"No strategy releases are bound to deployment %s",
|
|
5293
|
+
deployment?.id
|
|
5315
5294
|
);
|
|
5316
5295
|
return;
|
|
5317
5296
|
}
|
|
@@ -5319,7 +5298,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5319
5298
|
new Set(
|
|
5320
5299
|
tickers.flatMap(
|
|
5321
5300
|
(symbol) => runtimeStrategies.map(
|
|
5322
|
-
({ strategyName,
|
|
5301
|
+
({ strategyName, releaseVersion }) => buildSignalsStrategyLifecycleKey({
|
|
5323
5302
|
connectorName,
|
|
5324
5303
|
universe: sessionUniverse,
|
|
5325
5304
|
accountId,
|
|
@@ -5327,7 +5306,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5327
5306
|
symbol,
|
|
5328
5307
|
interval: interval2,
|
|
5329
5308
|
strategyName,
|
|
5330
|
-
configId:
|
|
5309
|
+
configId: `v${releaseVersion}`
|
|
5331
5310
|
})
|
|
5332
5311
|
)
|
|
5333
5312
|
)
|
|
@@ -5516,11 +5495,10 @@ var createSignalsRunner = (config2) => {
|
|
|
5516
5495
|
const configuredStrategies = await (0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({
|
|
5517
5496
|
userName: config2.userName,
|
|
5518
5497
|
projectRoot,
|
|
5519
|
-
deployment
|
|
5520
|
-
connectorName: config2.connectorName
|
|
5498
|
+
deployment
|
|
5521
5499
|
});
|
|
5522
5500
|
const connectorName = await resolveSignalsConnectorName(
|
|
5523
|
-
deployment
|
|
5501
|
+
deployment.connectorName
|
|
5524
5502
|
);
|
|
5525
5503
|
const scopes = /* @__PURE__ */ new Map();
|
|
5526
5504
|
for (const strategy of configuredStrategies) {
|
|
@@ -5539,13 +5517,18 @@ var createSignalsRunner = (config2) => {
|
|
|
5539
5517
|
}
|
|
5540
5518
|
return scopes;
|
|
5541
5519
|
};
|
|
5542
|
-
const hasExplicitSignalsScope = () => Boolean(config2.hasExplicitScope);
|
|
5543
5520
|
const signalsConfiguredScopesOnce2 = async () => {
|
|
5544
|
-
if (config2.updateOnly || config2.showTickersList
|
|
5521
|
+
if (config2.updateOnly || config2.showTickersList) {
|
|
5545
5522
|
return signals2();
|
|
5546
5523
|
}
|
|
5547
|
-
|
|
5548
|
-
|
|
5524
|
+
if (!config2.deploymentId) {
|
|
5525
|
+
throw new Error("Runtime deployment id is required");
|
|
5526
|
+
}
|
|
5527
|
+
const configuredDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
|
|
5528
|
+
config2.userName,
|
|
5529
|
+
config2.deploymentId
|
|
5530
|
+
);
|
|
5531
|
+
if (!configuredDeployment) {
|
|
5549
5532
|
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5550
5533
|
}
|
|
5551
5534
|
const scopes = await loadConfiguredSignalsScopes(configuredDeployment);
|
|
@@ -5570,8 +5553,14 @@ var createSignalsRunner = (config2) => {
|
|
|
5570
5553
|
);
|
|
5571
5554
|
}
|
|
5572
5555
|
const abortController = new AbortController();
|
|
5573
|
-
|
|
5574
|
-
|
|
5556
|
+
if (!config2.deploymentId) {
|
|
5557
|
+
throw new Error("Runtime deployment id is required");
|
|
5558
|
+
}
|
|
5559
|
+
const daemonDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
|
|
5560
|
+
config2.userName,
|
|
5561
|
+
config2.deploymentId
|
|
5562
|
+
);
|
|
5563
|
+
if (!daemonDeployment) {
|
|
5575
5564
|
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
5576
5565
|
}
|
|
5577
5566
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -5584,10 +5573,7 @@ var createSignalsRunner = (config2) => {
|
|
|
5584
5573
|
const stopOnSigterm = () => stop("SIGTERM");
|
|
5585
5574
|
process.once("SIGINT", stopOnSigint);
|
|
5586
5575
|
process.once("SIGTERM", stopOnSigterm);
|
|
5587
|
-
import_logger4.logger.info(
|
|
5588
|
-
"signals daemon started (config-driven scopes, fallback interval=%s)",
|
|
5589
|
-
interval
|
|
5590
|
-
);
|
|
5576
|
+
import_logger4.logger.info("signals daemon started (deployment-driven scopes)");
|
|
5591
5577
|
try {
|
|
5592
5578
|
await runSignalsDaemon({
|
|
5593
5579
|
intervalMs: 6e4,
|
|
@@ -5727,11 +5713,6 @@ import_args.default.option(["V", "universe"], "Market universe (crypto or tradfi
|
|
|
5727
5713
|
import_args.default.option(["A", "account"], "Trading account id");
|
|
5728
5714
|
import_args.default.option(["D", "deployment"], "Runtime deployment id");
|
|
5729
5715
|
var flags = import_args.default.parse(process.argv);
|
|
5730
|
-
var hasExplicitScope = process.argv.some(
|
|
5731
|
-
(argument) => ["-f", "--timeframe", "-V", "--universe", "-A", "--account"].some(
|
|
5732
|
-
(option) => argument === option || argument.startsWith(`${option}=`)
|
|
5733
|
-
)
|
|
5734
|
-
);
|
|
5735
5716
|
var config = {
|
|
5736
5717
|
projectRoot: String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd(),
|
|
5737
5718
|
userName: String(flags.user || "root"),
|
|
@@ -5753,8 +5734,7 @@ var config = {
|
|
|
5753
5734
|
showSkipStats: Boolean(flags.showSkipStats),
|
|
5754
5735
|
parallel: flags.parallel,
|
|
5755
5736
|
watch: Boolean(flags.watch),
|
|
5756
|
-
settleDelayMs: flags.settleDelayMs
|
|
5757
|
-
hasExplicitScope
|
|
5737
|
+
settleDelayMs: flags.settleDelayMs
|
|
5758
5738
|
};
|
|
5759
5739
|
var runner = createSignalsRunner(config);
|
|
5760
5740
|
var createSignalsSession = runner.createSession;
|
|
@@ -893,7 +893,7 @@ var groupRuntimeTradesByConnectorScope = ({
|
|
|
893
893
|
for (const trade of trades) {
|
|
894
894
|
const deployment = trade.deploymentId ? deploymentById.get(trade.deploymentId) : void 0;
|
|
895
895
|
const connectorName = deployment?.connectorName ?? fallbackConnectorName;
|
|
896
|
-
const universe = trade.universe ??
|
|
896
|
+
const universe = trade.universe ?? "crypto";
|
|
897
897
|
const accountId = trade.accountId ?? deployment?.accountId;
|
|
898
898
|
const deploymentId = trade.deploymentId;
|
|
899
899
|
const scopeKey = JSON.stringify([
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/cli",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.4",
|
|
4
4
|
"description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"tradejs": "dist/cli.js"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@tradejs/connectors": "^3.1.
|
|
36
|
-
"@tradejs/core": "^3.1.
|
|
37
|
-
"@tradejs/indicators": "^3.1.
|
|
38
|
-
"@tradejs/infra": "^3.1.
|
|
39
|
-
"@tradejs/node": "^3.1.
|
|
35
|
+
"@tradejs/connectors": "^3.1.4",
|
|
36
|
+
"@tradejs/core": "^3.1.4",
|
|
37
|
+
"@tradejs/indicators": "^3.1.4",
|
|
38
|
+
"@tradejs/infra": "^3.1.4",
|
|
39
|
+
"@tradejs/node": "^3.1.4",
|
|
40
40
|
"@tradejs/strategy-kit": "^3.0.0",
|
|
41
|
-
"@tradejs/types": "^3.1.
|
|
41
|
+
"@tradejs/types": "^3.1.4",
|
|
42
42
|
"args": "^5.0.3",
|
|
43
43
|
"bcryptjs": "^2.4.3",
|
|
44
44
|
"chalk": "4.1.2",
|