@tradejs/cli 3.1.8-beta.213 → 3.1.9-beta.214
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 +856 -334
- package/dist/lib/runEnvironment.js +88 -48
- package/dist/lib/runtimeDebugEvidence.js +48 -12
- package/dist/lib/runtimeEvidenceDeployment.js +162 -0
- package/dist/lib/runtimeLineage.js +9 -1
- package/dist/lib/runtimeScorecard.js +119 -8
- package/dist/lib/runtimeSignalsLoader.js +8 -4
- package/dist/scripts/backtest.js +50 -49
- package/dist/scripts/replay.js +921 -648
- package/dist/scripts/replayRunner.js +921 -648
- package/dist/scripts/replayRuntimeEvidence.js +50 -13
- package/dist/scripts/runtimeEvidence.js +136 -18
- package/dist/scripts/runtimeScorecard.js +143 -44
- package/dist/scripts/signals.js +47 -8
- package/dist/scripts/signalsDaemon.js +47 -8
- package/dist/scripts/signalsSummary.js +12 -5
- package/package.json +7 -7
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/lib/runEnvironment.ts
|
|
31
31
|
var runEnvironment_exports = {};
|
|
32
32
|
__export(runEnvironment_exports, {
|
|
33
|
+
loadDeploymentReplayStrategies: () => loadDeploymentReplayStrategies,
|
|
33
34
|
loadReplayStrategies: () => loadReplayStrategies,
|
|
34
35
|
prepareRunEnvironment: () => prepareRunEnvironment,
|
|
35
36
|
resolveBacktestExecutionPreloadInterval: () => resolveBacktestExecutionPreloadInterval
|
|
@@ -40,6 +41,54 @@ var import_connectors3 = require("@tradejs/node/connectors");
|
|
|
40
41
|
var import_cli3 = require("@tradejs/node/cli");
|
|
41
42
|
var import_constants = require("@tradejs/core/constants");
|
|
42
43
|
var import_time2 = require("@tradejs/core/time");
|
|
44
|
+
var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
|
|
45
|
+
|
|
46
|
+
// src/lib/runtimeStrategyBacktest.ts
|
|
47
|
+
var import_chalk = __toESM(require("chalk"));
|
|
48
|
+
|
|
49
|
+
// src/lib/runtimeRedis.ts
|
|
50
|
+
var import_redis = require("@tradejs/infra/redis");
|
|
51
|
+
var import_time = require("@tradejs/core/time");
|
|
52
|
+
var import_runtimeStrategyConfigs = require("@tradejs/infra/runtimeStrategyConfigs");
|
|
53
|
+
var isRuntimeStrategyEnabled = (strategyConfig) => {
|
|
54
|
+
const enabled = strategyConfig.ENABLE;
|
|
55
|
+
return enabled !== false;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/lib/runtimeStrategyBacktest.ts
|
|
59
|
+
var BACKTEST_CLI_RUNTIME_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
60
|
+
"ENV",
|
|
61
|
+
"INTERVAL",
|
|
62
|
+
"MAKE_ORDERS",
|
|
63
|
+
"CLOSE_OPPOSITE_POSITIONS",
|
|
64
|
+
"BACKTEST_PRICE_MODE",
|
|
65
|
+
"BACKTEST_ENTRY_DELAY_BARS"
|
|
66
|
+
]);
|
|
67
|
+
var toStrategyConfigGrid = (strategyConfig) => Object.fromEntries(
|
|
68
|
+
Object.entries(strategyConfig).filter(([key]) => !BACKTEST_CLI_RUNTIME_CONFIG_KEYS.has(key)).map(([key, value]) => [key, [value]])
|
|
69
|
+
);
|
|
70
|
+
var loadRuntimeStrategyBacktestConfigs = async (userName) => {
|
|
71
|
+
const configs = await (0, import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs)(userName, {
|
|
72
|
+
onInvalidConfig: (key) => {
|
|
73
|
+
console.log(import_chalk.default.yellow(`Skip invalid runtime strategy config: ${key}`));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return configs.filter(({ configId }) => configId === "config").filter(({ strategyName, strategyConfig }) => {
|
|
77
|
+
const enabled = isRuntimeStrategyEnabled(strategyConfig);
|
|
78
|
+
if (!enabled) {
|
|
79
|
+
console.log(
|
|
80
|
+
import_chalk.default.yellow(
|
|
81
|
+
`Skip inactive runtime strategy config by ENABLE=false: ${strategyName}`
|
|
82
|
+
)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return enabled;
|
|
86
|
+
}).map(({ strategyName, strategyConfig }) => ({
|
|
87
|
+
strategyName,
|
|
88
|
+
strategyConfig,
|
|
89
|
+
backtestConfig: toStrategyConfigGrid(strategyConfig)
|
|
90
|
+
}));
|
|
91
|
+
};
|
|
43
92
|
|
|
44
93
|
// src/lib/timeWindow.ts
|
|
45
94
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -143,53 +192,6 @@ var resolveTimeWindow = ({
|
|
|
143
192
|
);
|
|
144
193
|
};
|
|
145
194
|
|
|
146
|
-
// src/lib/runtimeStrategyBacktest.ts
|
|
147
|
-
var import_chalk = __toESM(require("chalk"));
|
|
148
|
-
|
|
149
|
-
// src/lib/runtimeRedis.ts
|
|
150
|
-
var import_redis = require("@tradejs/infra/redis");
|
|
151
|
-
var import_time = require("@tradejs/core/time");
|
|
152
|
-
var import_runtimeStrategyConfigs = require("@tradejs/infra/runtimeStrategyConfigs");
|
|
153
|
-
var isRuntimeStrategyEnabled = (strategyConfig) => {
|
|
154
|
-
const enabled = strategyConfig.ENABLE;
|
|
155
|
-
return enabled !== false;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
// src/lib/runtimeStrategyBacktest.ts
|
|
159
|
-
var BACKTEST_CLI_RUNTIME_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
160
|
-
"ENV",
|
|
161
|
-
"INTERVAL",
|
|
162
|
-
"MAKE_ORDERS",
|
|
163
|
-
"CLOSE_OPPOSITE_POSITIONS",
|
|
164
|
-
"BACKTEST_PRICE_MODE",
|
|
165
|
-
"BACKTEST_ENTRY_DELAY_BARS"
|
|
166
|
-
]);
|
|
167
|
-
var toStrategyConfigGrid = (strategyConfig) => Object.fromEntries(
|
|
168
|
-
Object.entries(strategyConfig).filter(([key]) => !BACKTEST_CLI_RUNTIME_CONFIG_KEYS.has(key)).map(([key, value]) => [key, [value]])
|
|
169
|
-
);
|
|
170
|
-
var loadRuntimeStrategyBacktestConfigs = async (userName) => {
|
|
171
|
-
const configs = await (0, import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs)(userName, {
|
|
172
|
-
onInvalidConfig: (key) => {
|
|
173
|
-
console.log(import_chalk.default.yellow(`Skip invalid runtime strategy config: ${key}`));
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
return configs.filter(({ configId }) => configId === "config").filter(({ strategyName, strategyConfig }) => {
|
|
177
|
-
const enabled = isRuntimeStrategyEnabled(strategyConfig);
|
|
178
|
-
if (!enabled) {
|
|
179
|
-
console.log(
|
|
180
|
-
import_chalk.default.yellow(
|
|
181
|
-
`Skip inactive runtime strategy config by ENABLE=false: ${strategyName}`
|
|
182
|
-
)
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
return enabled;
|
|
186
|
-
}).map(({ strategyName, strategyConfig }) => ({
|
|
187
|
-
strategyName,
|
|
188
|
-
strategyConfig,
|
|
189
|
-
backtestConfig: toStrategyConfigGrid(strategyConfig)
|
|
190
|
-
}));
|
|
191
|
-
};
|
|
192
|
-
|
|
193
195
|
// src/lib/runFormatting.ts
|
|
194
196
|
var import_date_fns = require("date-fns");
|
|
195
197
|
var ListIt = require("list-it");
|
|
@@ -490,10 +492,47 @@ var loadReplayStrategies = async (userName) => {
|
|
|
490
492
|
`No active runtime strategy configs found by users:${userName}:strategies:*:config`
|
|
491
493
|
)
|
|
492
494
|
);
|
|
493
|
-
return [];
|
|
494
495
|
}
|
|
495
496
|
return runtimeStrategies;
|
|
496
497
|
};
|
|
498
|
+
var loadDeploymentReplayStrategies = async ({
|
|
499
|
+
userName,
|
|
500
|
+
projectRoot,
|
|
501
|
+
deploymentId
|
|
502
|
+
}) => {
|
|
503
|
+
const [deployment, runtimeStrategies] = await Promise.all([
|
|
504
|
+
(0, import_runtimeStrategies.getRuntimeDeployment)({ userName, projectRoot, deploymentId }),
|
|
505
|
+
(0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({ userName, projectRoot, deploymentId })
|
|
506
|
+
]);
|
|
507
|
+
if (!deployment) {
|
|
508
|
+
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
509
|
+
}
|
|
510
|
+
const strategies = deployment.enabled ? runtimeStrategies.filter((strategy) => strategy.enabled).map(
|
|
511
|
+
({
|
|
512
|
+
strategyName,
|
|
513
|
+
version,
|
|
514
|
+
strategyPackage,
|
|
515
|
+
strategyPackageVersion,
|
|
516
|
+
runtimePackageVersion,
|
|
517
|
+
sourceStrategyConfig
|
|
518
|
+
}) => ({
|
|
519
|
+
strategyName,
|
|
520
|
+
version,
|
|
521
|
+
strategyPackage,
|
|
522
|
+
strategyPackageVersion,
|
|
523
|
+
runtimePackageVersion,
|
|
524
|
+
strategyConfig: sourceStrategyConfig
|
|
525
|
+
})
|
|
526
|
+
) : [];
|
|
527
|
+
if (!strategies.length) {
|
|
528
|
+
console.log(
|
|
529
|
+
import_chalk3.default.yellow(
|
|
530
|
+
`No enabled strategies found in runtime deployment ${deploymentId}`
|
|
531
|
+
)
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
return { deployment, strategies };
|
|
535
|
+
};
|
|
497
536
|
var prepareRunEnvironment = async ({
|
|
498
537
|
connector,
|
|
499
538
|
userName,
|
|
@@ -638,6 +677,7 @@ var prepareRunEnvironment = async ({
|
|
|
638
677
|
};
|
|
639
678
|
// Annotate the CommonJS export names for ESM import in node:
|
|
640
679
|
0 && (module.exports = {
|
|
680
|
+
loadDeploymentReplayStrategies,
|
|
641
681
|
loadReplayStrategies,
|
|
642
682
|
prepareRunEnvironment,
|
|
643
683
|
resolveBacktestExecutionPreloadInterval
|
|
@@ -220,18 +220,39 @@ var loadRuntimeSignalEvaluations = async (userName, {
|
|
|
220
220
|
}
|
|
221
221
|
return sortByTimestamp([...deduped.values()]);
|
|
222
222
|
};
|
|
223
|
+
var loadRuntimeLineageScopes = async (userName, {
|
|
224
|
+
startTime,
|
|
225
|
+
endTime
|
|
226
|
+
}) => {
|
|
227
|
+
const records = (await Promise.all(
|
|
228
|
+
(0, import_time2.getRuntimeStorageDayKeys)(startTime, endTime).map(
|
|
229
|
+
(dayKey) => (0, import_redis2.getHashJsonValues)(
|
|
230
|
+
import_redis2.redisKeys.runtimeLineageScopeBucket(userName, dayKey)
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
)).flat().filter(
|
|
234
|
+
(record) => record != null && typeof record.strategy === "string" && typeof record.symbol === "string" && typeof record.firstTimestamp === "number" && typeof record.lastTimestamp === "number" && record.lineage != null
|
|
235
|
+
);
|
|
236
|
+
return records.sort(
|
|
237
|
+
(left, right) => left.firstTimestamp - right.firstTimestamp || left.strategy.localeCompare(right.strategy) || left.symbol.localeCompare(right.symbol)
|
|
238
|
+
);
|
|
239
|
+
};
|
|
223
240
|
var parseBucketKey = (prefix, key) => {
|
|
224
241
|
if (!key.startsWith(prefix)) {
|
|
225
242
|
return null;
|
|
226
243
|
}
|
|
227
244
|
const suffix = key.slice(prefix.length);
|
|
228
|
-
const
|
|
229
|
-
if (
|
|
245
|
+
const parts = suffix.split(":");
|
|
246
|
+
if (parts.length < 2 || parts.some((part) => !part)) {
|
|
230
247
|
return null;
|
|
231
248
|
}
|
|
249
|
+
const [dayKey, ...scopeParts] = parts;
|
|
250
|
+
const strategy = scopeParts.at(-1);
|
|
251
|
+
if (!dayKey || !strategy) return null;
|
|
232
252
|
return {
|
|
233
|
-
dayKey
|
|
234
|
-
|
|
253
|
+
dayKey,
|
|
254
|
+
...scopeParts.length > 1 ? { deploymentId: scopeParts.slice(0, -1).join(":") } : {},
|
|
255
|
+
strategy
|
|
235
256
|
};
|
|
236
257
|
};
|
|
237
258
|
var loadRuntimeSignalEvaluationStatsBuckets = async (userName) => {
|
|
@@ -293,7 +314,8 @@ var collectRuntimeDebugEvidence = async ({
|
|
|
293
314
|
userName,
|
|
294
315
|
startTime,
|
|
295
316
|
endTime,
|
|
296
|
-
strategies
|
|
317
|
+
strategies,
|
|
318
|
+
deploymentId
|
|
297
319
|
}) => {
|
|
298
320
|
const dayKeys = (0, import_time2.getRuntimeStorageDayKeys)(startTime, endTime);
|
|
299
321
|
const dayKeySet = new Set(dayKeys);
|
|
@@ -303,6 +325,7 @@ var collectRuntimeDebugEvidence = async ({
|
|
|
303
325
|
signals,
|
|
304
326
|
evaluations,
|
|
305
327
|
evaluationStatsBuckets,
|
|
328
|
+
lineageScopes,
|
|
306
329
|
configs
|
|
307
330
|
] = await Promise.all([
|
|
308
331
|
loadRuntimeTrades(userName, { startTime, endTime }),
|
|
@@ -310,6 +333,7 @@ var collectRuntimeDebugEvidence = async ({
|
|
|
310
333
|
loadRuntimeSignals(userName, { startTime, endTime }),
|
|
311
334
|
loadRuntimeSignalEvaluations(userName, { startTime, endTime }),
|
|
312
335
|
loadRuntimeSignalEvaluationStatsBuckets(userName),
|
|
336
|
+
loadRuntimeLineageScopes(userName, { startTime, endTime }),
|
|
313
337
|
(0, import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs)(userName)
|
|
314
338
|
]);
|
|
315
339
|
const tradesByOrderId = new Map(
|
|
@@ -322,15 +346,21 @@ var collectRuntimeDebugEvidence = async ({
|
|
|
322
346
|
(left, right) => left.entryTimestamp - right.entryTimestamp
|
|
323
347
|
);
|
|
324
348
|
const filteredStats = evaluationStatsBuckets.filter(
|
|
325
|
-
(entry) => dayKeySet.has(entry.dayKey) && (!strategies?.length || strategies.includes(entry.strategy))
|
|
349
|
+
(entry) => dayKeySet.has(entry.dayKey) && (!deploymentId || entry.deploymentId === deploymentId) && (!strategies?.length || strategies.includes(entry.strategy))
|
|
326
350
|
);
|
|
351
|
+
const matchesDeployment = (value) => !deploymentId || value.deploymentId === deploymentId;
|
|
327
352
|
return {
|
|
328
353
|
dayKeys,
|
|
329
|
-
trades: filterByStrategies(trades, strategies),
|
|
330
|
-
signals: filterByStrategies(signals, strategies),
|
|
331
|
-
evaluations: filterByStrategies(evaluations, strategies)
|
|
354
|
+
trades: filterByStrategies(trades, strategies).filter(matchesDeployment),
|
|
355
|
+
signals: filterByStrategies(signals, strategies).filter(matchesDeployment),
|
|
356
|
+
evaluations: filterByStrategies(evaluations, strategies).filter(
|
|
357
|
+
matchesDeployment
|
|
358
|
+
),
|
|
332
359
|
evaluationStatsBuckets: filteredStats,
|
|
333
|
-
|
|
360
|
+
lineageScopes: lineageScopes.filter(matchesDeployment).filter(
|
|
361
|
+
(scope) => !strategies?.length || strategies.includes(scope.strategy)
|
|
362
|
+
),
|
|
363
|
+
strategyConfigs: deploymentId ? [] : configs.filter(
|
|
334
364
|
(config) => !strategies?.length || strategies.includes(config.strategyName)
|
|
335
365
|
)
|
|
336
366
|
};
|
|
@@ -343,7 +373,8 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
343
373
|
evaluations,
|
|
344
374
|
trades,
|
|
345
375
|
strategyConfigs,
|
|
346
|
-
evaluationStatsBuckets
|
|
376
|
+
evaluationStatsBuckets,
|
|
377
|
+
lineageScopes
|
|
347
378
|
}) => {
|
|
348
379
|
const signalById = new Map(
|
|
349
380
|
signals.map((signal) => [signal.signalId, signal])
|
|
@@ -471,6 +502,7 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
471
502
|
signals: signals.length,
|
|
472
503
|
evaluations: reportEvaluations.length,
|
|
473
504
|
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
505
|
+
lineageScopes: lineageScopes?.length ?? 0,
|
|
474
506
|
strategyConfigs: strategyConfigs?.length ?? 0
|
|
475
507
|
},
|
|
476
508
|
trades: debugTrades,
|
|
@@ -494,6 +526,7 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
494
526
|
evaluation
|
|
495
527
|
})),
|
|
496
528
|
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
529
|
+
lineageScopes: lineageScopes ?? [],
|
|
497
530
|
strategyConfigs: strategyConfigs ?? []
|
|
498
531
|
};
|
|
499
532
|
};
|
|
@@ -505,7 +538,8 @@ var buildRuntimeEvidenceReportPayload = ({
|
|
|
505
538
|
evaluations,
|
|
506
539
|
trades,
|
|
507
540
|
strategyConfigs,
|
|
508
|
-
evaluationStatsBuckets
|
|
541
|
+
evaluationStatsBuckets,
|
|
542
|
+
lineageScopes
|
|
509
543
|
}) => ({
|
|
510
544
|
reportType: "runtime-daily-evidence",
|
|
511
545
|
generatedAt: Date.now(),
|
|
@@ -522,12 +556,14 @@ var buildRuntimeEvidenceReportPayload = ({
|
|
|
522
556
|
signals: signals.length,
|
|
523
557
|
evaluations: evaluations.length,
|
|
524
558
|
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
559
|
+
lineageScopes: lineageScopes?.length ?? 0,
|
|
525
560
|
strategyConfigs: strategyConfigs?.length ?? 0
|
|
526
561
|
},
|
|
527
562
|
trades: trades.map((trade) => ({ trade })),
|
|
528
563
|
signals: signals.map((signal) => ({ signal })),
|
|
529
564
|
evaluations: evaluations.map((evaluation) => ({ evaluation })),
|
|
530
565
|
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
566
|
+
lineageScopes: lineageScopes ?? [],
|
|
531
567
|
strategyConfigs: strategyConfigs ?? []
|
|
532
568
|
});
|
|
533
569
|
var buildRuntimeDebugReportAttachment = async (params) => {
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/runtimeEvidenceDeployment.ts
|
|
21
|
+
var runtimeEvidenceDeployment_exports = {};
|
|
22
|
+
__export(runtimeEvidenceDeployment_exports, {
|
|
23
|
+
activeRuntimeEvidenceStrategies: () => activeRuntimeEvidenceStrategies,
|
|
24
|
+
parseRuntimeEvidenceDeploymentSnapshot: () => parseRuntimeEvidenceDeploymentSnapshot,
|
|
25
|
+
resolveRuntimeEvidenceDeploymentSnapshot: () => resolveRuntimeEvidenceDeploymentSnapshot,
|
|
26
|
+
runtimeDeploymentFromEvidence: () => runtimeDeploymentFromEvidence
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(runtimeEvidenceDeployment_exports);
|
|
29
|
+
var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
|
|
30
|
+
var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
31
|
+
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
32
|
+
var INTERVALS = /* @__PURE__ */ new Set([
|
|
33
|
+
"1",
|
|
34
|
+
"3",
|
|
35
|
+
"5",
|
|
36
|
+
"15",
|
|
37
|
+
"30",
|
|
38
|
+
"60",
|
|
39
|
+
"120",
|
|
40
|
+
"240",
|
|
41
|
+
"360",
|
|
42
|
+
"720",
|
|
43
|
+
"D",
|
|
44
|
+
"W",
|
|
45
|
+
"M"
|
|
46
|
+
]);
|
|
47
|
+
var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
|
|
48
|
+
var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
49
|
+
if (!isRecord(value) || value.schemaVersion !== 1 || !isNonEmptyString(value.id) || !isNonEmptyString(value.label) || !isNonEmptyString(value.connectorName) || !isNonEmptyString(value.provider) || !isNonEmptyString(value.accountId) || typeof value.enabled !== "boolean" || !Array.isArray(value.strategies)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
"Runtime evidence deployment snapshot is missing or invalid"
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
const strategies = value.strategies.map((candidate) => {
|
|
55
|
+
if (!isRecord(candidate) || !isNonEmptyString(candidate.strategyName) || !Number.isSafeInteger(candidate.version) || Number(candidate.version) <= 0 || typeof candidate.enabled !== "boolean" || !["active", "entries_paused"].includes(String(candidate.controlState)) || !INTERVALS.has(String(candidate.interval)) || !UNIVERSES.has(String(candidate.universe)) || !isNonEmptyString(candidate.strategyPackage) || !isNonEmptyString(candidate.strategyPackageVersion) || !isNonEmptyString(candidate.runtimePackageVersion) || !isRecord(candidate.strategyConfig)) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
"Runtime evidence deployment strategy snapshot is invalid"
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (String(candidate.strategyConfig.INTERVAL) !== String(candidate.interval) || String(candidate.strategyConfig.UNIVERSE) !== String(candidate.universe)) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`Runtime evidence strategy config does not match its scope: ${candidate.strategyName}`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (candidate.accountId != null && (!isNonEmptyString(candidate.accountId) || candidate.accountId !== value.accountId)) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`Runtime evidence strategy account does not match deployment: ${candidate.strategyName}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return candidate;
|
|
71
|
+
});
|
|
72
|
+
const identities = /* @__PURE__ */ new Set();
|
|
73
|
+
for (const strategy of strategies) {
|
|
74
|
+
if (identities.has(strategy.strategyName)) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Duplicate runtime evidence strategy: ${strategy.strategyName}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
identities.add(strategy.strategyName);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
...value,
|
|
83
|
+
strategies
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
87
|
+
var runtimeDeploymentFromEvidence = (deployment) => ({
|
|
88
|
+
id: deployment.id,
|
|
89
|
+
label: deployment.label,
|
|
90
|
+
connectorName: deployment.connectorName,
|
|
91
|
+
provider: deployment.provider,
|
|
92
|
+
accountId: deployment.accountId,
|
|
93
|
+
enabled: deployment.enabled,
|
|
94
|
+
strategies: deployment.strategies.map(
|
|
95
|
+
({ strategyName, version, enabled, controlState }) => ({
|
|
96
|
+
strategyName,
|
|
97
|
+
version,
|
|
98
|
+
enabled,
|
|
99
|
+
controlState
|
|
100
|
+
})
|
|
101
|
+
),
|
|
102
|
+
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
103
|
+
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
104
|
+
});
|
|
105
|
+
var resolveRuntimeEvidenceDeploymentSnapshot = async ({
|
|
106
|
+
userName,
|
|
107
|
+
projectRoot,
|
|
108
|
+
deploymentId
|
|
109
|
+
}) => {
|
|
110
|
+
const [deployment, strategies] = await Promise.all([
|
|
111
|
+
(0, import_runtimeStrategies.getRuntimeDeployment)({ userName, projectRoot, deploymentId }),
|
|
112
|
+
(0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({ userName, projectRoot, deploymentId })
|
|
113
|
+
]);
|
|
114
|
+
if (!deployment) {
|
|
115
|
+
throw new Error(`Runtime deployment not found: ${deploymentId}`);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
schemaVersion: 1,
|
|
119
|
+
id: deployment.id,
|
|
120
|
+
label: deployment.label,
|
|
121
|
+
connectorName: deployment.connectorName,
|
|
122
|
+
provider: deployment.provider,
|
|
123
|
+
accountId: deployment.accountId,
|
|
124
|
+
enabled: deployment.enabled,
|
|
125
|
+
strategies: strategies.map(
|
|
126
|
+
({
|
|
127
|
+
strategyName,
|
|
128
|
+
version,
|
|
129
|
+
enabled,
|
|
130
|
+
controlState,
|
|
131
|
+
interval,
|
|
132
|
+
universe,
|
|
133
|
+
accountId,
|
|
134
|
+
strategyPackage,
|
|
135
|
+
strategyPackageVersion,
|
|
136
|
+
runtimePackageVersion,
|
|
137
|
+
sourceStrategyConfig
|
|
138
|
+
}) => ({
|
|
139
|
+
strategyName,
|
|
140
|
+
version,
|
|
141
|
+
enabled,
|
|
142
|
+
controlState,
|
|
143
|
+
interval,
|
|
144
|
+
universe,
|
|
145
|
+
...accountId ? { accountId } : {},
|
|
146
|
+
strategyPackage,
|
|
147
|
+
strategyPackageVersion,
|
|
148
|
+
runtimePackageVersion,
|
|
149
|
+
strategyConfig: sourceStrategyConfig
|
|
150
|
+
})
|
|
151
|
+
),
|
|
152
|
+
...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
|
|
153
|
+
...deployment.tickers ? { tickers: [...deployment.tickers] } : {}
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
157
|
+
0 && (module.exports = {
|
|
158
|
+
activeRuntimeEvidenceStrategies,
|
|
159
|
+
parseRuntimeEvidenceDeploymentSnapshot,
|
|
160
|
+
resolveRuntimeEvidenceDeploymentSnapshot,
|
|
161
|
+
runtimeDeploymentFromEvidence
|
|
162
|
+
});
|
|
@@ -34,6 +34,7 @@ __export(runtimeLineage_exports, {
|
|
|
34
34
|
fingerprintRuntimeValue: () => fingerprintRuntimeValue,
|
|
35
35
|
resetRuntimeLineageCachesForTests: () => resetRuntimeLineageCachesForTests,
|
|
36
36
|
runtimeLineageKey: () => runtimeLineageKey,
|
|
37
|
+
runtimeLineagesComparable: () => runtimeLineagesComparable,
|
|
37
38
|
runtimeLineagesMatch: () => runtimeLineagesMatch
|
|
38
39
|
});
|
|
39
40
|
module.exports = __toCommonJS(runtimeLineage_exports);
|
|
@@ -330,7 +331,12 @@ async function buildRuntimeLineage({
|
|
|
330
331
|
maxLossValue: resolveRuntimeMaxLossValue(config)
|
|
331
332
|
};
|
|
332
333
|
}
|
|
333
|
-
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
334
|
+
var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? [
|
|
335
|
+
"v2",
|
|
336
|
+
lineage.version,
|
|
337
|
+
lineage.strategyPackageVersion ?? "strategy:unknown",
|
|
338
|
+
lineage.runtimePackageVersion ?? "runtime:unknown"
|
|
339
|
+
].join(":") : [
|
|
334
340
|
lineage.schemaVersion,
|
|
335
341
|
lineage.compositionId ?? "unbound-composition",
|
|
336
342
|
lineage.gitSha ?? "unknown",
|
|
@@ -340,6 +346,7 @@ var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? ["v2", lineag
|
|
|
340
346
|
lineage.contextFingerprint
|
|
341
347
|
].join(":");
|
|
342
348
|
var runtimeLineagesMatch = (left, right) => left != null && right != null && runtimeLineageKey(left) === runtimeLineageKey(right);
|
|
349
|
+
var runtimeLineagesComparable = (left, right) => runtimeLineagesMatch(left, right) && typeof left?.maxLossValue === "number" && Number.isFinite(left.maxLossValue) && typeof right?.maxLossValue === "number" && Number.isFinite(right.maxLossValue) && left.maxLossValue === right.maxLossValue;
|
|
343
350
|
var resetRuntimeLineageCachesForTests = () => {
|
|
344
351
|
gitLineageCache.clear();
|
|
345
352
|
gateFingerprintCache.clear();
|
|
@@ -352,5 +359,6 @@ var resetRuntimeLineageCachesForTests = () => {
|
|
|
352
359
|
fingerprintRuntimeValue,
|
|
353
360
|
resetRuntimeLineageCachesForTests,
|
|
354
361
|
runtimeLineageKey,
|
|
362
|
+
runtimeLineagesComparable,
|
|
355
363
|
runtimeLineagesMatch
|
|
356
364
|
});
|