@tradejs/cli 3.1.3 → 3.1.5
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 +98 -228
- package/dist/scripts/backtest.js +4 -20
- package/dist/scripts/runtimeConfig.js +50 -143
- 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/cli.js
CHANGED
|
@@ -13668,8 +13668,7 @@ var init_runnerCore = __esm({
|
|
|
13668
13668
|
};
|
|
13669
13669
|
validateBacktestRuntimeDeployment = ({
|
|
13670
13670
|
deployment,
|
|
13671
|
-
deploymentId
|
|
13672
|
-
requestedInterval
|
|
13671
|
+
deploymentId
|
|
13673
13672
|
}) => {
|
|
13674
13673
|
if (deploymentId && !deployment) {
|
|
13675
13674
|
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
@@ -13677,18 +13676,12 @@ var init_runnerCore = __esm({
|
|
|
13677
13676
|
if (deployment && !deployment.enabled) {
|
|
13678
13677
|
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
13679
13678
|
}
|
|
13680
|
-
if (deployment && String(deployment.interval) !== String(requestedInterval)) {
|
|
13681
|
-
throw new Error(
|
|
13682
|
-
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedInterval}`
|
|
13683
|
-
);
|
|
13684
|
-
}
|
|
13685
13679
|
return deployment;
|
|
13686
13680
|
};
|
|
13687
13681
|
prepareRunEnvironment2 = async () => {
|
|
13688
13682
|
const deployment = validateBacktestRuntimeDeployment({
|
|
13689
13683
|
deployment: flags5.deployment ? await (0, import_runtimeDeployments.getRuntimeDeployment)(userName, String(flags5.deployment)) : null,
|
|
13690
|
-
deploymentId: typeof flags5.deployment === "string" ? flags5.deployment : void 0
|
|
13691
|
-
requestedInterval: interval
|
|
13684
|
+
deploymentId: typeof flags5.deployment === "string" ? flags5.deployment : void 0
|
|
13692
13685
|
});
|
|
13693
13686
|
const preparedRun = await prepareRunEnvironment({
|
|
13694
13687
|
connector: deployment?.connectorName ?? flags5.connector,
|
|
@@ -13703,7 +13696,7 @@ var init_runnerCore = __esm({
|
|
|
13703
13696
|
cacheOnly: flags5.cacheOnly,
|
|
13704
13697
|
interval,
|
|
13705
13698
|
projectRoot: projectRoot3,
|
|
13706
|
-
universe:
|
|
13699
|
+
universe: marketUniverse,
|
|
13707
13700
|
accountId: deployment?.accountId ?? flags5.account,
|
|
13708
13701
|
deploymentId: deployment?.id,
|
|
13709
13702
|
assetClasses: deployment?.assetClasses,
|
|
@@ -14409,15 +14402,7 @@ var init_backtest = __esm({
|
|
|
14409
14402
|
preparedRun.connectorName,
|
|
14410
14403
|
interval
|
|
14411
14404
|
).map((test) => {
|
|
14412
|
-
const
|
|
14413
|
-
({ strategyName }) => strategyName === config2.strategyName
|
|
14414
|
-
);
|
|
14415
|
-
if (deploymentStrategy?.enabled === false) {
|
|
14416
|
-
throw new Error(
|
|
14417
|
-
`Strategy ${config2.strategyName} is disabled in deployment ${preparedRun.deployment?.id}`
|
|
14418
|
-
);
|
|
14419
|
-
}
|
|
14420
|
-
const policyProfileId = (typeof flags5.policyProfile === "string" && flags5.policyProfile.trim() ? flags5.policyProfile.trim() : deploymentStrategy?.policyProfileId) || void 0;
|
|
14405
|
+
const policyProfileId = (typeof flags5.policyProfile === "string" && flags5.policyProfile.trim() ? flags5.policyProfile.trim() : void 0) || void 0;
|
|
14421
14406
|
return {
|
|
14422
14407
|
...test,
|
|
14423
14408
|
instrument: preparedRun.instrumentsBySymbol.get(
|
|
@@ -14429,7 +14414,6 @@ var init_backtest = __esm({
|
|
|
14429
14414
|
policyProfileId,
|
|
14430
14415
|
strategyConfig: {
|
|
14431
14416
|
...test.strategyConfig,
|
|
14432
|
-
...deploymentStrategy?.config,
|
|
14433
14417
|
...policyProfileId ? { POLICY_PROFILE_ID: policyProfileId } : {}
|
|
14434
14418
|
}
|
|
14435
14419
|
};
|
|
@@ -28101,13 +28085,14 @@ var init_runtimeScorecard2 = __esm({
|
|
|
28101
28085
|
// src/scripts/runtimeConfig.ts
|
|
28102
28086
|
var runtimeConfig_exports = {};
|
|
28103
28087
|
__export(runtimeConfig_exports, {
|
|
28104
|
-
|
|
28088
|
+
RUNTIME_CONFIG_ACTIONS: () => RUNTIME_CONFIG_ACTIONS,
|
|
28089
|
+
buildProvisionedRuntimeDeployment: () => buildProvisionedRuntimeDeployment,
|
|
28105
28090
|
isEquivalentRuntimeStrategyRelease: () => isEquivalentRuntimeStrategyRelease,
|
|
28106
28091
|
main: () => main37,
|
|
28107
28092
|
pointRuntimeDeploymentAtRelease: () => pointRuntimeDeploymentAtRelease,
|
|
28108
28093
|
runtimeConfig: () => runtimeConfig
|
|
28109
28094
|
});
|
|
28110
|
-
var import_config9, import_promises28, import_node_path23, import_node_util2, import_runtimeDeployments2,
|
|
28095
|
+
var import_config9, import_promises28, import_node_path23, import_node_util2, import_runtimeDeployments2, import_runtimeStrategyReleases, import_runtimeStrategies, import_strategies11, argv, RUNTIME_CONFIG_ACTIONS, action, option, hasFlag, required2, projectRoot12, userName2, OPERATIONAL_CONFIG_KEYS, requireRuntimePackageIdentity, toReleaseConfig, publish, buildProvisionedRuntimeDeployment, isEquivalentRuntimeStrategyRelease, pointRuntimeDeploymentAtRelease, provision, rollout, updateControlState, rollback, verify, inspect, runtimeConfig, main37;
|
|
28111
28096
|
var init_runtimeConfig = __esm({
|
|
28112
28097
|
"src/scripts/runtimeConfig.ts"() {
|
|
28113
28098
|
"use strict";
|
|
@@ -28116,11 +28101,19 @@ var init_runtimeConfig = __esm({
|
|
|
28116
28101
|
import_node_path23 = __toESM(require("path"));
|
|
28117
28102
|
import_node_util2 = require("util");
|
|
28118
28103
|
import_runtimeDeployments2 = require("@tradejs/infra/runtimeDeployments");
|
|
28119
|
-
import_runtimeStrategyConfigs2 = require("@tradejs/infra/runtimeStrategyConfigs");
|
|
28120
28104
|
import_runtimeStrategyReleases = require("@tradejs/infra/runtimeStrategyReleases");
|
|
28121
28105
|
import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
|
|
28122
28106
|
import_strategies11 = require("@tradejs/node/strategies");
|
|
28123
28107
|
argv = process.argv.slice(2);
|
|
28108
|
+
RUNTIME_CONFIG_ACTIONS = [
|
|
28109
|
+
"inspect",
|
|
28110
|
+
"verify",
|
|
28111
|
+
"provision",
|
|
28112
|
+
"rollout",
|
|
28113
|
+
"pause",
|
|
28114
|
+
"resume",
|
|
28115
|
+
"rollback"
|
|
28116
|
+
];
|
|
28124
28117
|
action = argv[0] ?? "inspect";
|
|
28125
28118
|
option = (name) => {
|
|
28126
28119
|
const index = argv.indexOf(`--${name}`);
|
|
@@ -28141,28 +28134,26 @@ var init_runtimeConfig = __esm({
|
|
|
28141
28134
|
"ENABLE",
|
|
28142
28135
|
"ENV",
|
|
28143
28136
|
"MAKE_ORDERS",
|
|
28144
|
-
"RECORD_RUNTIME_TRADES"
|
|
28145
|
-
"configId"
|
|
28137
|
+
"RECORD_RUNTIME_TRADES"
|
|
28146
28138
|
];
|
|
28139
|
+
requireRuntimePackageIdentity = (strategyName, metadata) => {
|
|
28140
|
+
if (!metadata.strategyPackage || !metadata.strategyPackageVersion || !metadata.runtimePackageVersion) {
|
|
28141
|
+
throw new Error(
|
|
28142
|
+
`Runtime package manifest is incomplete for ${strategyName}`
|
|
28143
|
+
);
|
|
28144
|
+
}
|
|
28145
|
+
return {
|
|
28146
|
+
strategyPackage: metadata.strategyPackage,
|
|
28147
|
+
strategyPackageVersion: metadata.strategyPackageVersion,
|
|
28148
|
+
runtimePackageVersion: metadata.runtimePackageVersion
|
|
28149
|
+
};
|
|
28150
|
+
};
|
|
28147
28151
|
toReleaseConfig = async (strategyName, sourceConfig) => {
|
|
28148
28152
|
const defaults = await (0, import_strategies11.getStrategyDefaults)(strategyName, projectRoot12) ?? {};
|
|
28149
28153
|
const config2 = { ...defaults, ...sourceConfig };
|
|
28150
28154
|
for (const key of OPERATIONAL_CONFIG_KEYS) delete config2[key];
|
|
28151
28155
|
return config2;
|
|
28152
28156
|
};
|
|
28153
|
-
writeMigrationBackup = async (payload) => {
|
|
28154
|
-
const directory = import_node_path23.default.join(projectRoot12, "data", "runtime-config-backups");
|
|
28155
|
-
await (0, import_promises28.mkdir)(directory, { recursive: true });
|
|
28156
|
-
const backupPath = import_node_path23.default.join(
|
|
28157
|
-
directory,
|
|
28158
|
-
`${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.json`
|
|
28159
|
-
);
|
|
28160
|
-
await (0, import_promises28.writeFile)(backupPath, `${JSON.stringify(payload, null, 2)}
|
|
28161
|
-
`, {
|
|
28162
|
-
flag: "wx"
|
|
28163
|
-
});
|
|
28164
|
-
return backupPath;
|
|
28165
|
-
};
|
|
28166
28157
|
publish = async ({
|
|
28167
28158
|
strategyName,
|
|
28168
28159
|
sourceConfig
|
|
@@ -28172,31 +28163,29 @@ var init_runtimeConfig = __esm({
|
|
|
28172
28163
|
strategyName,
|
|
28173
28164
|
projectRoot: projectRoot12
|
|
28174
28165
|
});
|
|
28166
|
+
const packageIdentity = requireRuntimePackageIdentity(strategyName, metadata);
|
|
28175
28167
|
return (0, import_runtimeStrategyReleases.publishRuntimeStrategyRelease)({
|
|
28176
28168
|
userName: userName2,
|
|
28177
28169
|
strategyName,
|
|
28178
28170
|
config: config2,
|
|
28179
|
-
...
|
|
28171
|
+
...packageIdentity,
|
|
28180
28172
|
createdBy: `cli:${userName2}`
|
|
28181
28173
|
});
|
|
28182
28174
|
};
|
|
28183
|
-
|
|
28175
|
+
buildProvisionedRuntimeDeployment = ({
|
|
28184
28176
|
deploymentId,
|
|
28185
28177
|
label,
|
|
28186
28178
|
connectorName,
|
|
28187
28179
|
provider,
|
|
28188
28180
|
accountId,
|
|
28189
28181
|
strategyName,
|
|
28190
|
-
releaseVersion
|
|
28191
|
-
config: config2
|
|
28182
|
+
releaseVersion
|
|
28192
28183
|
}) => ({
|
|
28193
28184
|
id: deploymentId,
|
|
28194
28185
|
label,
|
|
28195
28186
|
connectorName,
|
|
28196
28187
|
provider,
|
|
28197
28188
|
accountId,
|
|
28198
|
-
universe: config2.UNIVERSE,
|
|
28199
|
-
interval: String(config2.INTERVAL),
|
|
28200
28189
|
enabled: true,
|
|
28201
28190
|
strategies: [
|
|
28202
28191
|
{
|
|
@@ -28213,7 +28202,7 @@ var init_runtimeConfig = __esm({
|
|
|
28213
28202
|
strategyPackageVersion,
|
|
28214
28203
|
runtimePackageVersion
|
|
28215
28204
|
}) => Boolean(
|
|
28216
|
-
release && (0, import_node_util2.isDeepStrictEqual)(release.config, config2) &&
|
|
28205
|
+
release && (0, import_node_util2.isDeepStrictEqual)(release.config, config2) && release.strategyPackage === strategyPackage && release.strategyPackageVersion === strategyPackageVersion && release.runtimePackageVersion === runtimePackageVersion
|
|
28217
28206
|
);
|
|
28218
28207
|
pointRuntimeDeploymentAtRelease = ({
|
|
28219
28208
|
deployment,
|
|
@@ -28229,7 +28218,7 @@ var init_runtimeConfig = __esm({
|
|
|
28229
28218
|
} : strategy
|
|
28230
28219
|
)
|
|
28231
28220
|
});
|
|
28232
|
-
|
|
28221
|
+
provision = async () => {
|
|
28233
28222
|
const strategyName = required2("strategy");
|
|
28234
28223
|
const deploymentId = required2("deployment");
|
|
28235
28224
|
const accountId = required2("account");
|
|
@@ -28247,15 +28236,14 @@ var init_runtimeConfig = __esm({
|
|
|
28247
28236
|
);
|
|
28248
28237
|
}
|
|
28249
28238
|
const releaseConfig = await toReleaseConfig(strategyName, sourceConfig);
|
|
28250
|
-
const previewDeployment =
|
|
28239
|
+
const previewDeployment = buildProvisionedRuntimeDeployment({
|
|
28251
28240
|
deploymentId,
|
|
28252
28241
|
label,
|
|
28253
28242
|
connectorName,
|
|
28254
28243
|
provider,
|
|
28255
28244
|
accountId,
|
|
28256
28245
|
strategyName,
|
|
28257
|
-
releaseVersion: 1
|
|
28258
|
-
config: releaseConfig
|
|
28246
|
+
releaseVersion: 1
|
|
28259
28247
|
});
|
|
28260
28248
|
if (!hasFlag("write")) {
|
|
28261
28249
|
console.log(
|
|
@@ -28277,93 +28265,21 @@ var init_runtimeConfig = __esm({
|
|
|
28277
28265
|
);
|
|
28278
28266
|
return;
|
|
28279
28267
|
}
|
|
28280
|
-
const backupPath = await writeMigrationBackup({
|
|
28281
|
-
userName: userName2,
|
|
28282
|
-
capturedAt: Date.now(),
|
|
28283
|
-
reason: "bootstrap",
|
|
28284
|
-
sourceConfig
|
|
28285
|
-
});
|
|
28286
28268
|
const release = await publish({ strategyName, sourceConfig });
|
|
28287
28269
|
const deployment = await (0, import_runtimeDeployments2.saveRuntimeDeployment)(
|
|
28288
28270
|
userName2,
|
|
28289
|
-
|
|
28271
|
+
buildProvisionedRuntimeDeployment({
|
|
28290
28272
|
deploymentId,
|
|
28291
28273
|
label,
|
|
28292
28274
|
connectorName,
|
|
28293
28275
|
provider,
|
|
28294
28276
|
accountId,
|
|
28295
28277
|
strategyName,
|
|
28296
|
-
releaseVersion: release.releaseVersion
|
|
28297
|
-
config: release.config
|
|
28278
|
+
releaseVersion: release.releaseVersion
|
|
28298
28279
|
})
|
|
28299
28280
|
);
|
|
28300
28281
|
console.log(
|
|
28301
|
-
JSON.stringify(
|
|
28302
|
-
{ bootstrapped: true, backupPath, release, deployment },
|
|
28303
|
-
null,
|
|
28304
|
-
2
|
|
28305
|
-
)
|
|
28306
|
-
);
|
|
28307
|
-
};
|
|
28308
|
-
migrate = async () => {
|
|
28309
|
-
const strategyName = required2("strategy");
|
|
28310
|
-
const configId = option("config") ?? "config";
|
|
28311
|
-
const deploymentId = required2("deployment");
|
|
28312
|
-
const [sourceConfig, deployment] = await Promise.all([
|
|
28313
|
-
(0, import_runtimeStrategyConfigs2.getRuntimeStrategyConfig)(userName2, strategyName, configId),
|
|
28314
|
-
(0, import_runtimeDeployments2.getRuntimeDeployment)(userName2, deploymentId)
|
|
28315
|
-
]);
|
|
28316
|
-
if (!sourceConfig) {
|
|
28317
|
-
throw new Error(`Legacy config not found: ${strategyName}:${configId}`);
|
|
28318
|
-
}
|
|
28319
|
-
if (!deployment) throw new Error(`Deployment not found: ${deploymentId}`);
|
|
28320
|
-
const reference = deployment.strategies.find(
|
|
28321
|
-
(strategy) => strategy.strategyName === strategyName
|
|
28322
|
-
);
|
|
28323
|
-
if (!reference) {
|
|
28324
|
-
throw new Error(`${strategyName} is not bound to ${deploymentId}`);
|
|
28325
|
-
}
|
|
28326
|
-
const preview = {
|
|
28327
|
-
source: { configId, config: sourceConfig },
|
|
28328
|
-
releaseConfig: await toReleaseConfig(strategyName, sourceConfig),
|
|
28329
|
-
deployment: {
|
|
28330
|
-
id: deployment.id,
|
|
28331
|
-
accountId: deployment.accountId,
|
|
28332
|
-
strategy: {
|
|
28333
|
-
strategyName,
|
|
28334
|
-
releaseVersion: "<allocated on write>",
|
|
28335
|
-
controlState: "entries_paused"
|
|
28336
|
-
}
|
|
28337
|
-
}
|
|
28338
|
-
};
|
|
28339
|
-
if (!hasFlag("write")) {
|
|
28340
|
-
console.log(JSON.stringify({ dryRun: true, ...preview }, null, 2));
|
|
28341
|
-
return;
|
|
28342
|
-
}
|
|
28343
|
-
const backupPath = await writeMigrationBackup({
|
|
28344
|
-
userName: userName2,
|
|
28345
|
-
capturedAt: Date.now(),
|
|
28346
|
-
deployment,
|
|
28347
|
-
legacyConfig: sourceConfig
|
|
28348
|
-
});
|
|
28349
|
-
const release = await publish({ strategyName, sourceConfig });
|
|
28350
|
-
const updatedDeployment = {
|
|
28351
|
-
...deployment,
|
|
28352
|
-
strategies: deployment.strategies.map(
|
|
28353
|
-
(strategy) => strategy.strategyName === strategyName ? {
|
|
28354
|
-
strategyName,
|
|
28355
|
-
releaseVersion: release.releaseVersion,
|
|
28356
|
-
controlState: "entries_paused"
|
|
28357
|
-
} : strategy
|
|
28358
|
-
)
|
|
28359
|
-
};
|
|
28360
|
-
await (0, import_runtimeDeployments2.saveRuntimeDeployment)(userName2, updatedDeployment);
|
|
28361
|
-
console.log(
|
|
28362
|
-
JSON.stringify(
|
|
28363
|
-
{ migrated: true, backupPath, release, deployment: updatedDeployment },
|
|
28364
|
-
null,
|
|
28365
|
-
2
|
|
28366
|
-
)
|
|
28282
|
+
JSON.stringify({ provisioned: true, release, deployment }, null, 2)
|
|
28367
28283
|
);
|
|
28368
28284
|
};
|
|
28369
28285
|
rollout = async () => {
|
|
@@ -28380,18 +28296,18 @@ var init_runtimeConfig = __esm({
|
|
|
28380
28296
|
const reference = deployment.strategies.find(
|
|
28381
28297
|
(strategy) => strategy.strategyName === strategyName
|
|
28382
28298
|
);
|
|
28383
|
-
if (!reference
|
|
28384
|
-
throw new Error(`${strategyName} is not
|
|
28385
|
-
}
|
|
28299
|
+
if (!reference)
|
|
28300
|
+
throw new Error(`${strategyName} is not bound to ${deploymentId}`);
|
|
28386
28301
|
const [config2, metadata, currentRelease] = await Promise.all([
|
|
28387
28302
|
toReleaseConfig(strategyName, sourceConfig),
|
|
28388
28303
|
(0, import_runtimeStrategies.getRuntimeStrategyPackageMetadata)({ strategyName, projectRoot: projectRoot12 }),
|
|
28389
28304
|
(0, import_runtimeStrategyReleases.getRuntimeStrategyRelease)(userName2, strategyName, reference.releaseVersion)
|
|
28390
28305
|
]);
|
|
28306
|
+
const packageIdentity = requireRuntimePackageIdentity(strategyName, metadata);
|
|
28391
28307
|
const unchanged = isEquivalentRuntimeStrategyRelease({
|
|
28392
28308
|
release: currentRelease,
|
|
28393
28309
|
config: config2,
|
|
28394
|
-
...
|
|
28310
|
+
...packageIdentity
|
|
28395
28311
|
});
|
|
28396
28312
|
const preview = {
|
|
28397
28313
|
deploymentId,
|
|
@@ -28400,7 +28316,7 @@ var init_runtimeConfig = __esm({
|
|
|
28400
28316
|
nextControlState: "entries_paused",
|
|
28401
28317
|
unchanged,
|
|
28402
28318
|
config: config2,
|
|
28403
|
-
...
|
|
28319
|
+
...packageIdentity
|
|
28404
28320
|
};
|
|
28405
28321
|
if (!hasFlag("write")) {
|
|
28406
28322
|
console.log(JSON.stringify({ dryRun: true, ...preview }, null, 2));
|
|
@@ -28421,19 +28337,11 @@ var init_runtimeConfig = __esm({
|
|
|
28421
28337
|
);
|
|
28422
28338
|
return;
|
|
28423
28339
|
}
|
|
28424
|
-
const backupPath = await writeMigrationBackup({
|
|
28425
|
-
userName: userName2,
|
|
28426
|
-
capturedAt: Date.now(),
|
|
28427
|
-
reason: "rollout",
|
|
28428
|
-
deployment,
|
|
28429
|
-
currentRelease,
|
|
28430
|
-
sourceConfig
|
|
28431
|
-
});
|
|
28432
28340
|
const release = await (0, import_runtimeStrategyReleases.publishRuntimeStrategyRelease)({
|
|
28433
28341
|
userName: userName2,
|
|
28434
28342
|
strategyName,
|
|
28435
28343
|
config: config2,
|
|
28436
|
-
...
|
|
28344
|
+
...packageIdentity,
|
|
28437
28345
|
createdBy: `cli:${userName2}`
|
|
28438
28346
|
});
|
|
28439
28347
|
const updatedDeployment = pointRuntimeDeploymentAtRelease({
|
|
@@ -28446,7 +28354,6 @@ var init_runtimeConfig = __esm({
|
|
|
28446
28354
|
JSON.stringify(
|
|
28447
28355
|
{
|
|
28448
28356
|
rolledOut: true,
|
|
28449
|
-
backupPath,
|
|
28450
28357
|
release,
|
|
28451
28358
|
deployment: updatedDeployment
|
|
28452
28359
|
},
|
|
@@ -28455,13 +28362,6 @@ var init_runtimeConfig = __esm({
|
|
|
28455
28362
|
)
|
|
28456
28363
|
);
|
|
28457
28364
|
};
|
|
28458
|
-
publishDraft = async () => {
|
|
28459
|
-
const strategyName = required2("strategy");
|
|
28460
|
-
const draft = await (0, import_runtimeStrategyReleases.getRuntimeStrategyDraft)(userName2, strategyName);
|
|
28461
|
-
if (!draft) throw new Error(`Draft not found: ${strategyName}`);
|
|
28462
|
-
const release = await publish({ strategyName, sourceConfig: draft.config });
|
|
28463
|
-
console.log(JSON.stringify({ release }, null, 2));
|
|
28464
|
-
};
|
|
28465
28365
|
updateControlState = async (nextState) => {
|
|
28466
28366
|
const strategyName = required2("strategy");
|
|
28467
28367
|
const deploymentId = required2("deployment");
|
|
@@ -28470,10 +28370,9 @@ var init_runtimeConfig = __esm({
|
|
|
28470
28370
|
const reference = deployment.strategies.find(
|
|
28471
28371
|
(strategy) => strategy.strategyName === strategyName
|
|
28472
28372
|
);
|
|
28473
|
-
if (!reference
|
|
28474
|
-
throw new Error(`${strategyName} is not
|
|
28475
|
-
|
|
28476
|
-
const previousState = reference.controlState ?? "active";
|
|
28373
|
+
if (!reference)
|
|
28374
|
+
throw new Error(`${strategyName} is not bound to ${deploymentId}`);
|
|
28375
|
+
const previousState = reference.controlState;
|
|
28477
28376
|
const updated = await (0, import_runtimeDeployments2.saveRuntimeDeployment)(userName2, {
|
|
28478
28377
|
...deployment,
|
|
28479
28378
|
strategies: deployment.strategies.map(
|
|
@@ -28503,12 +28402,6 @@ var init_runtimeConfig = __esm({
|
|
|
28503
28402
|
const release = (await (0, import_runtimeStrategyReleases.listRuntimeStrategyReleases)(userName2, strategyName)).find((candidate) => candidate.releaseVersion === releaseVersion);
|
|
28504
28403
|
if (!release)
|
|
28505
28404
|
throw new Error(`Release not found: ${strategyName} v${releaseVersion}`);
|
|
28506
|
-
const backupPath = await writeMigrationBackup({
|
|
28507
|
-
userName: userName2,
|
|
28508
|
-
capturedAt: Date.now(),
|
|
28509
|
-
deployment,
|
|
28510
|
-
reason: "rollback"
|
|
28511
|
-
});
|
|
28512
28405
|
const updated = await (0, import_runtimeDeployments2.saveRuntimeDeployment)(userName2, {
|
|
28513
28406
|
...deployment,
|
|
28514
28407
|
strategies: deployment.strategies.map(
|
|
@@ -28519,7 +28412,7 @@ var init_runtimeConfig = __esm({
|
|
|
28519
28412
|
} : strategy
|
|
28520
28413
|
)
|
|
28521
28414
|
});
|
|
28522
|
-
console.log(JSON.stringify({
|
|
28415
|
+
console.log(JSON.stringify({ deployment: updated }, null, 2));
|
|
28523
28416
|
};
|
|
28524
28417
|
verify = async () => {
|
|
28525
28418
|
const deployments = await (0, import_runtimeDeployments2.listRuntimeDeployments)(userName2);
|
|
@@ -28530,8 +28423,7 @@ var init_runtimeConfig = __esm({
|
|
|
28530
28423
|
const strategies = await (0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({
|
|
28531
28424
|
userName: userName2,
|
|
28532
28425
|
projectRoot: projectRoot12,
|
|
28533
|
-
deployment
|
|
28534
|
-
connectorName: deployment.connectorName
|
|
28426
|
+
deployment
|
|
28535
28427
|
});
|
|
28536
28428
|
results2.push({
|
|
28537
28429
|
deploymentId: deployment.id,
|
|
@@ -28563,17 +28455,15 @@ var init_runtimeConfig = __esm({
|
|
|
28563
28455
|
console.log(JSON.stringify({ userName: userName2, deployments, releases }, null, 2));
|
|
28564
28456
|
};
|
|
28565
28457
|
runtimeConfig = async () => {
|
|
28566
|
-
if (action === "
|
|
28567
|
-
if (action === "migrate") return migrate();
|
|
28458
|
+
if (action === "provision") return provision();
|
|
28568
28459
|
if (action === "rollout") return rollout();
|
|
28569
|
-
if (action === "publish-draft") return publishDraft();
|
|
28570
28460
|
if (action === "verify") return verify();
|
|
28571
28461
|
if (action === "pause") return updateControlState("entries_paused");
|
|
28572
28462
|
if (action === "resume") return updateControlState("active");
|
|
28573
28463
|
if (action === "rollback") return rollback();
|
|
28574
28464
|
if (action === "inspect") return inspect();
|
|
28575
28465
|
throw new Error(
|
|
28576
|
-
|
|
28466
|
+
`Usage: tradejs runtime-config ${RUNTIME_CONFIG_ACTIONS.join("|")}`
|
|
28577
28467
|
);
|
|
28578
28468
|
};
|
|
28579
28469
|
main37 = runtimeConfig;
|
|
@@ -32173,18 +32063,15 @@ var init_tickerEvaluator = __esm({
|
|
|
32173
32063
|
for (const runtimeStrategy of runtimeStrategies) {
|
|
32174
32064
|
const {
|
|
32175
32065
|
strategyName,
|
|
32176
|
-
configId,
|
|
32177
32066
|
releaseVersion,
|
|
32178
32067
|
controlState,
|
|
32179
32068
|
strategyPackageVersion,
|
|
32180
32069
|
runtimePackageVersion,
|
|
32181
32070
|
strategyCreator,
|
|
32182
32071
|
sourceStrategyConfig,
|
|
32183
|
-
strategyConfig
|
|
32184
|
-
strategyResults
|
|
32072
|
+
strategyConfig
|
|
32185
32073
|
} = runtimeStrategy;
|
|
32186
|
-
const runtimeIdentity =
|
|
32187
|
-
const symbolResultConfig = strategyResults?.[symbol]?.config ?? null;
|
|
32074
|
+
const runtimeIdentity = `v${releaseVersion}`;
|
|
32188
32075
|
const runtimeConfig2 = buildRuntimeModeStrategyConfig({
|
|
32189
32076
|
strategyConfig,
|
|
32190
32077
|
env: "CRON",
|
|
@@ -32197,7 +32084,7 @@ var init_tickerEvaluator = __esm({
|
|
|
32197
32084
|
releaseVersion,
|
|
32198
32085
|
strategyPackageVersion,
|
|
32199
32086
|
runtimePackageVersion,
|
|
32200
|
-
config: {
|
|
32087
|
+
config: { strategyConfig },
|
|
32201
32088
|
runContext: {
|
|
32202
32089
|
connectorName: connectorName.toLowerCase(),
|
|
32203
32090
|
interval: String(interval4),
|
|
@@ -32225,7 +32112,7 @@ var init_tickerEvaluator = __esm({
|
|
|
32225
32112
|
evaluation = await lifecycle.evaluate({
|
|
32226
32113
|
key: lifecycleKey,
|
|
32227
32114
|
timestamp: lastCandle.timestamp,
|
|
32228
|
-
config: { runtimeConfig: runtimeConfig2, sourceStrategyConfig
|
|
32115
|
+
config: { runtimeConfig: runtimeConfig2, sourceStrategyConfig },
|
|
32229
32116
|
btcBinanceData,
|
|
32230
32117
|
btcCoinbaseData,
|
|
32231
32118
|
onRuntimeClose: (event) => runtimeCloseNotifications.push(event),
|
|
@@ -32236,13 +32123,12 @@ var init_tickerEvaluator = __esm({
|
|
|
32236
32123
|
}) => strategyCreator({
|
|
32237
32124
|
userName: userName3,
|
|
32238
32125
|
connectorName,
|
|
32239
|
-
runtimeConfigId:
|
|
32126
|
+
runtimeConfigId: runtimeIdentity,
|
|
32240
32127
|
runtimeReleaseVersion: releaseVersion,
|
|
32241
32128
|
entriesPaused: controlState === "entries_paused",
|
|
32242
32129
|
runtimeLineage,
|
|
32243
32130
|
runtimeConfigSnapshot: {
|
|
32244
|
-
userConfig: sourceStrategyConfig
|
|
32245
|
-
symbolResultConfig
|
|
32131
|
+
userConfig: sourceStrategyConfig
|
|
32246
32132
|
},
|
|
32247
32133
|
connector,
|
|
32248
32134
|
symbol,
|
|
@@ -32292,12 +32178,12 @@ var init_tickerEvaluator = __esm({
|
|
|
32292
32178
|
strategyName,
|
|
32293
32179
|
symbol,
|
|
32294
32180
|
timestamp: lastCandle.timestamp,
|
|
32295
|
-
runtimeConfigId:
|
|
32181
|
+
runtimeConfigId: runtimeIdentity,
|
|
32296
32182
|
runtimeReleaseVersion: releaseVersion
|
|
32297
32183
|
}),
|
|
32298
32184
|
userName: userName3,
|
|
32299
32185
|
strategy: strategyName,
|
|
32300
|
-
runtimeConfigId:
|
|
32186
|
+
runtimeConfigId: runtimeIdentity,
|
|
32301
32187
|
runtimeReleaseVersion: releaseVersion,
|
|
32302
32188
|
runtimeLineage,
|
|
32303
32189
|
symbol,
|
|
@@ -32315,12 +32201,9 @@ var init_tickerEvaluator = __esm({
|
|
|
32315
32201
|
continue;
|
|
32316
32202
|
}
|
|
32317
32203
|
if (stats) stats.signals += 1;
|
|
32318
|
-
signal.runtimeConfigId =
|
|
32204
|
+
signal.runtimeConfigId = runtimeIdentity;
|
|
32319
32205
|
signal.runtimeReleaseVersion = releaseVersion;
|
|
32320
32206
|
signal.runtimeLineage = runtimeLineage;
|
|
32321
|
-
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
32322
|
-
signal.signalId = `${signal.signalId}:${configId}`;
|
|
32323
|
-
}
|
|
32324
32207
|
if (releaseVersion && !signal.signalId.endsWith(`:v${releaseVersion}`)) {
|
|
32325
32208
|
signal.signalId = `${signal.signalId}:v${releaseVersion}`;
|
|
32326
32209
|
}
|
|
@@ -32340,12 +32223,12 @@ var init_tickerEvaluator = __esm({
|
|
|
32340
32223
|
strategyName,
|
|
32341
32224
|
symbol,
|
|
32342
32225
|
timestamp: lastCandle.timestamp,
|
|
32343
|
-
runtimeConfigId:
|
|
32226
|
+
runtimeConfigId: runtimeIdentity,
|
|
32344
32227
|
runtimeReleaseVersion: releaseVersion
|
|
32345
32228
|
}),
|
|
32346
32229
|
userName: userName3,
|
|
32347
32230
|
strategy: strategyName,
|
|
32348
|
-
runtimeConfigId:
|
|
32231
|
+
runtimeConfigId: runtimeIdentity,
|
|
32349
32232
|
runtimeReleaseVersion: releaseVersion,
|
|
32350
32233
|
runtimeLineage,
|
|
32351
32234
|
symbol,
|
|
@@ -32454,15 +32337,12 @@ var init_runner = __esm({
|
|
|
32454
32337
|
].join("\n");
|
|
32455
32338
|
const resolveSignalsConnectorName = async (value) => {
|
|
32456
32339
|
const connectorName = await (0, import_connectors16.resolveConnectorName)(value, projectRoot15);
|
|
32457
|
-
if (connectorName) {
|
|
32458
|
-
|
|
32340
|
+
if (!connectorName) {
|
|
32341
|
+
throw new Error(
|
|
32342
|
+
`Unknown runtime connector: ${String(value || "").trim() || String(value)}`
|
|
32343
|
+
);
|
|
32459
32344
|
}
|
|
32460
|
-
|
|
32461
|
-
'Unknown connector "%s". Fallback to %s.',
|
|
32462
|
-
String(value || "").trim() || String(value),
|
|
32463
|
-
import_connectors16.DEFAULT_CONNECTOR_NAME
|
|
32464
|
-
);
|
|
32465
|
-
return import_connectors16.DEFAULT_CONNECTOR_NAME;
|
|
32345
|
+
return connectorName;
|
|
32466
32346
|
};
|
|
32467
32347
|
const createSignalsSession2 = async (lifecycle, scope = {}) => {
|
|
32468
32348
|
const deployment = config2.deploymentId ? await (0, import_runtimeDeployments3.getRuntimeDeployment)(config2.userName, config2.deploymentId) : null;
|
|
@@ -32473,25 +32353,15 @@ var init_runner = __esm({
|
|
|
32473
32353
|
throw new Error(`Runtime deployment is disabled: ${deployment.id}`);
|
|
32474
32354
|
}
|
|
32475
32355
|
const requestedRuntimeInterval = scope.interval ?? interval4;
|
|
32476
|
-
const
|
|
32477
|
-
deployment?.strategies.some(
|
|
32478
|
-
(strategy) => strategy.releaseVersion != null
|
|
32479
|
-
)
|
|
32480
|
-
);
|
|
32481
|
-
const runtimeInterval = versionedDeployment ? requestedRuntimeInterval : deployment?.interval ?? requestedRuntimeInterval;
|
|
32356
|
+
const runtimeInterval = requestedRuntimeInterval;
|
|
32482
32357
|
const runtimeIntervalMs = Number(runtimeInterval) * 6e4;
|
|
32483
32358
|
if (!Number.isFinite(runtimeIntervalMs) || runtimeIntervalMs <= 0) {
|
|
32484
32359
|
throw new Error(`Invalid runtime timeframe: ${runtimeInterval}`);
|
|
32485
32360
|
}
|
|
32486
|
-
if (deployment && !versionedDeployment && String(deployment.interval) !== String(requestedRuntimeInterval)) {
|
|
32487
|
-
throw new Error(
|
|
32488
|
-
`Deployment ${deployment.id} requires timeframe ${deployment.interval}; received ${requestedRuntimeInterval}`
|
|
32489
|
-
);
|
|
32490
|
-
}
|
|
32491
32361
|
const connectorName = await resolveSignalsConnectorName(
|
|
32492
32362
|
deployment?.connectorName ?? scope.connectorName ?? config2.connectorName
|
|
32493
32363
|
);
|
|
32494
|
-
const universe =
|
|
32364
|
+
const universe = scope.universe ?? config2.universe;
|
|
32495
32365
|
const requestedAccountId = deployment?.accountId ?? scope.accountId ?? config2.accountId;
|
|
32496
32366
|
const connectorFactory = await (0, import_connectors16.getConnectorCreatorByName)(
|
|
32497
32367
|
connectorName,
|
|
@@ -32703,7 +32573,6 @@ var init_runner = __esm({
|
|
|
32703
32573
|
userName: config2.userName,
|
|
32704
32574
|
projectRoot: projectRoot15,
|
|
32705
32575
|
deployment,
|
|
32706
|
-
connectorName,
|
|
32707
32576
|
universe,
|
|
32708
32577
|
accountId,
|
|
32709
32578
|
interval: interval5
|
|
@@ -32711,8 +32580,8 @@ var init_runner = __esm({
|
|
|
32711
32580
|
if (!runtimeStrategies.length) {
|
|
32712
32581
|
lifecycle.clear();
|
|
32713
32582
|
import_logger10.logger.warn(
|
|
32714
|
-
"No strategy
|
|
32715
|
-
|
|
32583
|
+
"No strategy releases are bound to deployment %s",
|
|
32584
|
+
deployment?.id
|
|
32716
32585
|
);
|
|
32717
32586
|
return;
|
|
32718
32587
|
}
|
|
@@ -32720,7 +32589,7 @@ var init_runner = __esm({
|
|
|
32720
32589
|
new Set(
|
|
32721
32590
|
tickers.flatMap(
|
|
32722
32591
|
(symbol) => runtimeStrategies.map(
|
|
32723
|
-
({ strategyName,
|
|
32592
|
+
({ strategyName, releaseVersion }) => buildSignalsStrategyLifecycleKey({
|
|
32724
32593
|
connectorName,
|
|
32725
32594
|
universe: sessionUniverse,
|
|
32726
32595
|
accountId,
|
|
@@ -32728,7 +32597,7 @@ var init_runner = __esm({
|
|
|
32728
32597
|
symbol,
|
|
32729
32598
|
interval: interval5,
|
|
32730
32599
|
strategyName,
|
|
32731
|
-
configId:
|
|
32600
|
+
configId: `v${releaseVersion}`
|
|
32732
32601
|
})
|
|
32733
32602
|
)
|
|
32734
32603
|
)
|
|
@@ -32917,11 +32786,10 @@ var init_runner = __esm({
|
|
|
32917
32786
|
const configuredStrategies = await (0, import_runtimeStrategies2.loadResolvedRuntimeStrategies)({
|
|
32918
32787
|
userName: config2.userName,
|
|
32919
32788
|
projectRoot: projectRoot15,
|
|
32920
|
-
deployment
|
|
32921
|
-
connectorName: config2.connectorName
|
|
32789
|
+
deployment
|
|
32922
32790
|
});
|
|
32923
32791
|
const connectorName = await resolveSignalsConnectorName(
|
|
32924
|
-
deployment
|
|
32792
|
+
deployment.connectorName
|
|
32925
32793
|
);
|
|
32926
32794
|
const scopes = /* @__PURE__ */ new Map();
|
|
32927
32795
|
for (const strategy of configuredStrategies) {
|
|
@@ -32940,13 +32808,18 @@ var init_runner = __esm({
|
|
|
32940
32808
|
}
|
|
32941
32809
|
return scopes;
|
|
32942
32810
|
};
|
|
32943
|
-
const hasExplicitSignalsScope = () => Boolean(config2.hasExplicitScope);
|
|
32944
32811
|
const signalsConfiguredScopesOnce2 = async () => {
|
|
32945
|
-
if (config2.updateOnly || config2.showTickersList
|
|
32812
|
+
if (config2.updateOnly || config2.showTickersList) {
|
|
32946
32813
|
return signals2();
|
|
32947
32814
|
}
|
|
32948
|
-
|
|
32949
|
-
|
|
32815
|
+
if (!config2.deploymentId) {
|
|
32816
|
+
throw new Error("Runtime deployment id is required");
|
|
32817
|
+
}
|
|
32818
|
+
const configuredDeployment = await (0, import_runtimeDeployments3.getRuntimeDeployment)(
|
|
32819
|
+
config2.userName,
|
|
32820
|
+
config2.deploymentId
|
|
32821
|
+
);
|
|
32822
|
+
if (!configuredDeployment) {
|
|
32950
32823
|
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
32951
32824
|
}
|
|
32952
32825
|
const scopes = await loadConfiguredSignalsScopes(configuredDeployment);
|
|
@@ -32971,8 +32844,14 @@ var init_runner = __esm({
|
|
|
32971
32844
|
);
|
|
32972
32845
|
}
|
|
32973
32846
|
const abortController = new AbortController();
|
|
32974
|
-
|
|
32975
|
-
|
|
32847
|
+
if (!config2.deploymentId) {
|
|
32848
|
+
throw new Error("Runtime deployment id is required");
|
|
32849
|
+
}
|
|
32850
|
+
const daemonDeployment = await (0, import_runtimeDeployments3.getRuntimeDeployment)(
|
|
32851
|
+
config2.userName,
|
|
32852
|
+
config2.deploymentId
|
|
32853
|
+
);
|
|
32854
|
+
if (!daemonDeployment) {
|
|
32976
32855
|
throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
|
|
32977
32856
|
}
|
|
32978
32857
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -32985,10 +32864,7 @@ var init_runner = __esm({
|
|
|
32985
32864
|
const stopOnSigterm = () => stop("SIGTERM");
|
|
32986
32865
|
process.once("SIGINT", stopOnSigint);
|
|
32987
32866
|
process.once("SIGTERM", stopOnSigterm);
|
|
32988
|
-
import_logger10.logger.info(
|
|
32989
|
-
"signals daemon started (config-driven scopes, fallback interval=%s)",
|
|
32990
|
-
interval4
|
|
32991
|
-
);
|
|
32867
|
+
import_logger10.logger.info("signals daemon started (deployment-driven scopes)");
|
|
32992
32868
|
try {
|
|
32993
32869
|
await runSignalsDaemon({
|
|
32994
32870
|
intervalMs: 6e4,
|
|
@@ -33101,7 +32977,7 @@ __export(signals_exports, {
|
|
|
33101
32977
|
signalsConfiguredScopesOnce: () => signalsConfiguredScopesOnce,
|
|
33102
32978
|
signalsDaemon: () => signalsDaemon
|
|
33103
32979
|
});
|
|
33104
|
-
var import_config12, import_args31, flags29,
|
|
32980
|
+
var import_config12, import_args31, flags29, config, runner, createSignalsSession, signals, signalsConfiguredScopesOnce, signalsDaemon, main41;
|
|
33105
32981
|
var init_signals = __esm({
|
|
33106
32982
|
"src/scripts/signals.ts"() {
|
|
33107
32983
|
"use strict";
|
|
@@ -33145,11 +33021,6 @@ var init_signals = __esm({
|
|
|
33145
33021
|
import_args31.default.option(["A", "account"], "Trading account id");
|
|
33146
33022
|
import_args31.default.option(["D", "deployment"], "Runtime deployment id");
|
|
33147
33023
|
flags29 = import_args31.default.parse(process.argv);
|
|
33148
|
-
hasExplicitScope = process.argv.some(
|
|
33149
|
-
(argument) => ["-f", "--timeframe", "-V", "--universe", "-A", "--account"].some(
|
|
33150
|
-
(option2) => argument === option2 || argument.startsWith(`${option2}=`)
|
|
33151
|
-
)
|
|
33152
|
-
);
|
|
33153
33024
|
config = {
|
|
33154
33025
|
projectRoot: String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd(),
|
|
33155
33026
|
userName: String(flags29.user || "root"),
|
|
@@ -33171,8 +33042,7 @@ var init_signals = __esm({
|
|
|
33171
33042
|
showSkipStats: Boolean(flags29.showSkipStats),
|
|
33172
33043
|
parallel: flags29.parallel,
|
|
33173
33044
|
watch: Boolean(flags29.watch),
|
|
33174
|
-
settleDelayMs: flags29.settleDelayMs
|
|
33175
|
-
hasExplicitScope
|
|
33045
|
+
settleDelayMs: flags29.settleDelayMs
|
|
33176
33046
|
};
|
|
33177
33047
|
runner = createSignalsRunner(config);
|
|
33178
33048
|
createSignalsSession = runner.createSession;
|
|
@@ -37250,7 +37120,7 @@ var init_signalsSummary = __esm({
|
|
|
37250
37120
|
for (const trade of trades) {
|
|
37251
37121
|
const deployment = trade.deploymentId ? deploymentById.get(trade.deploymentId) : void 0;
|
|
37252
37122
|
const connectorName = deployment?.connectorName ?? fallbackConnectorName;
|
|
37253
|
-
const universe = trade.universe ??
|
|
37123
|
+
const universe = trade.universe ?? "crypto";
|
|
37254
37124
|
const accountId = trade.accountId ?? deployment?.accountId;
|
|
37255
37125
|
const deploymentId = trade.deploymentId;
|
|
37256
37126
|
const scopeKey = JSON.stringify([
|