@tradejs/cli 3.1.10 → 3.1.11-beta.216

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 CHANGED
@@ -12182,7 +12182,7 @@ var init_marketContextPrepare = __esm({
12182
12182
  });
12183
12183
 
12184
12184
  // src/lib/runtimeRedis.ts
12185
- var import_redis4, import_time, import_runtimeStrategyConfigs, isRuntimeStrategyEnabled, isRuntimeTradeRecord, loadRuntimeTrades, loadRuntimeClosedTrades, loadRuntimeActiveTradeOrderIds, loadStrategyResultSymbols;
12185
+ var import_redis4, import_time, import_runtimeStrategyConfigs, isRuntimeStrategyEnabled, isRuntimeTradeRecord, loadRuntimeTrades, loadRuntimeClosedTrades, loadRuntimeActiveTradeOrderIds, loadRuntimeActiveTrades, loadStrategyResultSymbols;
12186
12186
  var init_runtimeRedis = __esm({
12187
12187
  "src/lib/runtimeRedis.ts"() {
12188
12188
  "use strict";
@@ -12267,6 +12267,17 @@ var init_runtimeRedis = __esm({
12267
12267
  ).filter((orderId) => orderId != null)
12268
12268
  );
12269
12269
  };
12270
+ loadRuntimeActiveTrades = async (userName3) => {
12271
+ const orderIds = await loadRuntimeActiveTradeOrderIds(userName3);
12272
+ const trades = await Promise.all(
12273
+ [...orderIds].map(
12274
+ (orderId) => (0, import_redis4.getData)(import_redis4.redisKeys.runtimeTrade(userName3, orderId), null)
12275
+ )
12276
+ );
12277
+ return trades.filter(
12278
+ (trade) => isRuntimeTradeRecord(trade) && trade.status === "active"
12279
+ );
12280
+ };
12270
12281
  loadStrategyResultSymbols = async ({
12271
12282
  userName: userName3,
12272
12283
  strategy
@@ -12689,7 +12700,7 @@ var init_tickerUniverseCache = __esm({
12689
12700
  });
12690
12701
 
12691
12702
  // src/lib/runEnvironment.ts
12692
- var import_chalk12, import_connectors5, import_cli4, import_constants6, import_time2, import_runtimeStrategies, timeOperation2, resolveBacktestExecutionPreloadInterval, resolveRunConnectorName, loadDeploymentReplayStrategies, prepareRunEnvironment;
12703
+ var import_chalk12, import_connectors5, import_cli4, import_constants6, import_time2, import_runtimeStrategies, timeOperation2, resolveBacktestExecutionPreloadInterval, resolveRunConnectorName, mergeRuntimeStrategySelections, loadDeploymentReplayStrategies, prepareRunEnvironment;
12693
12704
  var init_runEnvironment = __esm({
12694
12705
  "src/lib/runEnvironment.ts"() {
12695
12706
  "use strict";
@@ -12734,6 +12745,18 @@ var init_runEnvironment = __esm({
12734
12745
  );
12735
12746
  return import_connectors5.DEFAULT_CONNECTOR_NAME;
12736
12747
  };
12748
+ mergeRuntimeStrategySelections = (strategies) => {
12749
+ if (strategies.some((strategy) => !strategy.selection?.tickers)) {
12750
+ return void 0;
12751
+ }
12752
+ return {
12753
+ tickers: [
12754
+ ...new Set(
12755
+ strategies.flatMap((strategy) => strategy.selection?.tickers ?? [])
12756
+ )
12757
+ ]
12758
+ };
12759
+ };
12737
12760
  loadDeploymentReplayStrategies = async ({
12738
12761
  userName: userName3,
12739
12762
  projectRoot: projectRoot15,
@@ -12753,14 +12776,16 @@ var init_runEnvironment = __esm({
12753
12776
  strategyPackage,
12754
12777
  strategyPackageVersion,
12755
12778
  runtimePackageVersion,
12756
- sourceStrategyConfig
12779
+ sourceStrategyConfig,
12780
+ selection
12757
12781
  }) => ({
12758
12782
  strategyName,
12759
12783
  version,
12760
12784
  strategyPackage,
12761
12785
  strategyPackageVersion,
12762
12786
  runtimePackageVersion,
12763
- strategyConfig: sourceStrategyConfig
12787
+ strategyConfig: sourceStrategyConfig,
12788
+ ...selection ? { selection } : {}
12764
12789
  })
12765
12790
  ) : [];
12766
12791
  if (!strategies.length) {
@@ -13705,7 +13730,7 @@ var init_runnerCore = __esm({
13705
13730
  }
13706
13731
  return deployment;
13707
13732
  };
13708
- prepareRunEnvironment2 = async () => {
13733
+ prepareRunEnvironment2 = async (strategyName) => {
13709
13734
  const deployment = validateBacktestRuntimeDeployment({
13710
13735
  deployment: flags5.deployment ? await (0, import_runtimeStrategies2.getRuntimeDeployment)({
13711
13736
  userName,
@@ -13714,10 +13739,13 @@ var init_runnerCore = __esm({
13714
13739
  }) : null,
13715
13740
  deploymentId: typeof flags5.deployment === "string" ? flags5.deployment : void 0
13716
13741
  });
13742
+ const runtimeStrategy = strategyName ? deployment?.strategies.find(
13743
+ (strategy) => strategy.strategyName === strategyName
13744
+ ) : void 0;
13717
13745
  const preparedRun = await prepareRunEnvironment({
13718
13746
  connector: deployment?.connectorName ?? flags5.connector,
13719
13747
  userName,
13720
- tickers: flags5.tickers || deployment?.tickers?.join(","),
13748
+ tickers: flags5.tickers || runtimeStrategy?.selection?.tickers?.join(",") || deployment?.tickers?.join(","),
13721
13749
  exclude: flags5.exclude,
13722
13750
  tickersLimit: flags5.tickersLimit,
13723
13751
  showTickersList: flags5.showTickersList,
@@ -14420,7 +14448,7 @@ var init_backtest = __esm({
14420
14448
  });
14421
14449
  return;
14422
14450
  }
14423
- const preparedRun = await prepareRunEnvironment2();
14451
+ const preparedRun = await prepareRunEnvironment2(config2.strategyName);
14424
14452
  if (!preparedRun || flags5.updateOnly) {
14425
14453
  return;
14426
14454
  }
@@ -25539,7 +25567,7 @@ var init_runtimeLineage = __esm({
25539
25567
  });
25540
25568
 
25541
25569
  // src/lib/runtimeEvidenceDeployment.ts
25542
- var import_runtimeStrategies3, isRecord, isNonEmptyString, INTERVALS, UNIVERSES, parseRuntimeEvidenceDeploymentSnapshot, activeRuntimeEvidenceStrategies, runtimeDeploymentFromEvidence, resolveRuntimeEvidenceDeploymentSnapshot;
25570
+ var import_runtimeStrategies3, isRecord, isNonEmptyString, INTERVALS, UNIVERSES, isRuntimeStrategySelection, parseRuntimeEvidenceDeploymentSnapshot, activeRuntimeEvidenceStrategies, runtimeDeploymentFromEvidence, resolveRuntimeEvidenceDeploymentSnapshot;
25543
25571
  var init_runtimeEvidenceDeployment = __esm({
25544
25572
  "src/lib/runtimeEvidenceDeployment.ts"() {
25545
25573
  "use strict";
@@ -25562,6 +25590,7 @@ var init_runtimeEvidenceDeployment = __esm({
25562
25590
  "M"
25563
25591
  ]);
25564
25592
  UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
25593
+ isRuntimeStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => key === "tickers") && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every((ticker) => isNonEmptyString(ticker));
25565
25594
  parseRuntimeEvidenceDeploymentSnapshot = (value) => {
25566
25595
  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)) {
25567
25596
  throw new Error(
@@ -25569,7 +25598,7 @@ var init_runtimeEvidenceDeployment = __esm({
25569
25598
  );
25570
25599
  }
25571
25600
  const strategies = value.strategies.map((candidate) => {
25572
- 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)) {
25601
+ 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) || !isRuntimeStrategySelection(candidate.selection)) {
25573
25602
  throw new Error(
25574
25603
  "Runtime evidence deployment strategy snapshot is invalid"
25575
25604
  );
@@ -25609,11 +25638,12 @@ var init_runtimeEvidenceDeployment = __esm({
25609
25638
  accountId: deployment.accountId,
25610
25639
  enabled: deployment.enabled,
25611
25640
  strategies: deployment.strategies.map(
25612
- ({ strategyName, version, enabled, controlState }) => ({
25641
+ ({ strategyName, version, enabled, controlState, selection }) => ({
25613
25642
  strategyName,
25614
25643
  version,
25615
25644
  enabled,
25616
- controlState
25645
+ controlState,
25646
+ ...selection ? { selection } : {}
25617
25647
  })
25618
25648
  ),
25619
25649
  ...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
@@ -25651,7 +25681,8 @@ var init_runtimeEvidenceDeployment = __esm({
25651
25681
  strategyPackage,
25652
25682
  strategyPackageVersion,
25653
25683
  runtimePackageVersion,
25654
- sourceStrategyConfig
25684
+ sourceStrategyConfig,
25685
+ selection
25655
25686
  }) => ({
25656
25687
  strategyName,
25657
25688
  version,
@@ -25663,7 +25694,8 @@ var init_runtimeEvidenceDeployment = __esm({
25663
25694
  strategyPackage,
25664
25695
  strategyPackageVersion,
25665
25696
  runtimePackageVersion,
25666
- strategyConfig: sourceStrategyConfig
25697
+ strategyConfig: sourceStrategyConfig,
25698
+ ...selection ? { selection } : {}
25667
25699
  })
25668
25700
  ),
25669
25701
  ...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
@@ -32352,12 +32384,29 @@ var init_tickerEvaluator = __esm({
32352
32384
  });
32353
32385
 
32354
32386
  // src/lib/signals/configuredScopes.ts
32355
- var sorted, formatConfiguredStrategyIdentity, buildConfiguredSignalsScopes;
32387
+ var sorted, formatConfiguredStrategyIdentity, getConfiguredScopeActiveSymbols, buildConfiguredSignalsScopes;
32356
32388
  var init_configuredScopes = __esm({
32357
32389
  "src/lib/signals/configuredScopes.ts"() {
32358
32390
  "use strict";
32359
32391
  sorted = (values) => values ? [...values].sort() : [];
32360
32392
  formatConfiguredStrategyIdentity = (strategy) => `${strategy.strategyName}@v${strategy.version}[${strategy.controlState}]`;
32393
+ getConfiguredScopeActiveSymbols = ({
32394
+ trades,
32395
+ deploymentId,
32396
+ strategyNames,
32397
+ universe,
32398
+ accountId,
32399
+ interval: interval4
32400
+ }) => {
32401
+ const strategyNameSet = new Set(strategyNames);
32402
+ return [
32403
+ ...new Set(
32404
+ trades.filter(
32405
+ (trade) => trade.status === "active" && trade.deploymentId === deploymentId && strategyNameSet.has(trade.strategy) && (trade.universe ?? "crypto") === universe && (!trade.accountId || trade.accountId === accountId) && (!trade.interval || String(trade.interval) === String(interval4))
32406
+ ).map(({ symbol }) => symbol)
32407
+ )
32408
+ ].sort();
32409
+ };
32361
32410
  buildConfiguredSignalsScopes = ({
32362
32411
  connectorName,
32363
32412
  deployment,
@@ -32374,21 +32423,30 @@ var init_configuredScopes = __esm({
32374
32423
  });
32375
32424
  const groups = /* @__PURE__ */ new Map();
32376
32425
  for (const strategy of strategies) {
32426
+ const selectionIdentity = JSON.stringify({
32427
+ tickers: sorted(strategy.selection?.tickers)
32428
+ });
32377
32429
  const baseKey = [
32378
32430
  connectorName,
32379
32431
  strategy.universe,
32380
32432
  strategy.accountId ?? "default",
32381
- strategy.interval
32433
+ strategy.interval,
32434
+ selectionIdentity
32382
32435
  ].join(":");
32383
32436
  const group = groups.get(baseKey) ?? {
32384
32437
  scope: {
32385
32438
  connectorName,
32386
32439
  universe: strategy.universe,
32387
32440
  accountId: strategy.accountId,
32388
- interval: strategy.interval
32441
+ interval: strategy.interval,
32442
+ strategyNames: [],
32443
+ ...strategy.selection ? {
32444
+ selection: { tickers: [...strategy.selection.tickers] }
32445
+ } : {}
32389
32446
  },
32390
32447
  strategyIdentities: []
32391
32448
  };
32449
+ group.scope.strategyNames.push(strategy.strategyName);
32392
32450
  group.strategyIdentities.push(formatConfiguredStrategyIdentity(strategy));
32393
32451
  groups.set(baseKey, group);
32394
32452
  }
@@ -32396,7 +32454,10 @@ var init_configuredScopes = __esm({
32396
32454
  key: [baseKey, deploymentIdentity, ...group.strategyIdentities.sort()].join(
32397
32455
  ":"
32398
32456
  ),
32399
- scope: group.scope
32457
+ scope: {
32458
+ ...group.scope,
32459
+ strategyNames: [...group.scope.strategyNames].sort()
32460
+ }
32400
32461
  }));
32401
32462
  };
32402
32463
  }
@@ -32419,6 +32480,7 @@ var init_runner = __esm({
32419
32480
  import_runtimeHeartbeats = require("@tradejs/infra/runtimeHeartbeats");
32420
32481
  import_runtimeStrategies6 = require("@tradejs/node/runtimeStrategies");
32421
32482
  init_windows();
32483
+ init_runtimeRedis();
32422
32484
  init_runFormatting();
32423
32485
  init_hooks();
32424
32486
  init_marketContextPrepare();
@@ -32540,6 +32602,10 @@ var init_runner = __esm({
32540
32602
  interval: runtimeInterval,
32541
32603
  intervalMs: runtimeIntervalMs,
32542
32604
  deployment,
32605
+ ...scope.strategyNames ? { strategyNames: [...scope.strategyNames] } : {},
32606
+ ...scope.selection ? {
32607
+ selection: { tickers: [...scope.selection.tickers] }
32608
+ } : {},
32543
32609
  startedAt: Date.now(),
32544
32610
  marketConnector,
32545
32611
  btcReferences,
@@ -32569,13 +32635,31 @@ var init_runner = __esm({
32569
32635
  btcReferences,
32570
32636
  lifecycle,
32571
32637
  interval: interval5,
32572
- intervalMs
32638
+ intervalMs,
32639
+ strategyNames,
32640
+ selection
32573
32641
  } = session;
32574
32642
  const universe = sessionUniverse ?? marketConnector.universe ?? "crypto";
32643
+ const selectedActiveSymbols = !config2.tickers && selection?.tickers?.length && strategyNames?.length ? getConfiguredScopeActiveSymbols({
32644
+ trades: await loadRuntimeActiveTrades(config2.userName),
32645
+ deploymentId: deployment?.id ?? "",
32646
+ strategyNames,
32647
+ universe,
32648
+ accountId,
32649
+ interval: interval5
32650
+ }) : [];
32651
+ const selectedTickers = selection?.tickers ? [.../* @__PURE__ */ new Set([...selection.tickers, ...selectedActiveSymbols])] : void 0;
32652
+ if (selectedActiveSymbols.length) {
32653
+ import_logger10.logger.info(
32654
+ import_chalk45.default.gray(
32655
+ `strategy selection retained active symbols: ${selectedActiveSymbols.join(", ")}`
32656
+ )
32657
+ );
32658
+ }
32575
32659
  const tickers = await timeOperation3("tickers load", () => {
32576
32660
  const baseArgs = [
32577
32661
  marketConnector,
32578
- config2.tickers || deployment?.tickers?.join(","),
32662
+ config2.tickers || selectedTickers?.join(",") || deployment?.tickers?.join(","),
32579
32663
  config2.exclude,
32580
32664
  config2.tickersLimit,
32581
32665
  config2.chunk
@@ -32718,7 +32802,7 @@ var init_runner = __esm({
32718
32802
  const primaryEthByTimestamp = new Map(
32719
32803
  primaryEthClosedData.map((candle) => [candle.timestamp, candle])
32720
32804
  );
32721
- const runtimeStrategies = await (0, import_runtimeStrategies5.loadResolvedRuntimeStrategies)({
32805
+ const configuredRuntimeStrategies = await (0, import_runtimeStrategies5.loadResolvedRuntimeStrategies)({
32722
32806
  userName: config2.userName,
32723
32807
  projectRoot: projectRoot15,
32724
32808
  deploymentId: deployment?.id ?? "",
@@ -32726,6 +32810,10 @@ var init_runner = __esm({
32726
32810
  accountId,
32727
32811
  interval: interval5
32728
32812
  });
32813
+ const selectedStrategyNames = strategyNames?.length ? new Set(strategyNames) : null;
32814
+ const runtimeStrategies = selectedStrategyNames ? configuredRuntimeStrategies.filter(
32815
+ ({ strategyName }) => selectedStrategyNames.has(strategyName)
32816
+ ) : configuredRuntimeStrategies;
32729
32817
  if (!runtimeStrategies.length) {
32730
32818
  lifecycle.clear();
32731
32819
  import_logger10.logger.warn(
@@ -33911,7 +33999,7 @@ var init_portfolioReplayConnector = __esm({
33911
33999
  });
33912
34000
 
33913
34001
  // src/lib/replay/historicalSignalsReplay.ts
33914
- var import_chalk46, import_progress12, import_backtest4, import_strategies13, import_time9, import_logger11, import_redis19, import_connectors17, import_cli13, import_strategies14, import_runtimeStrategies8, loadRuntimeStrategies, loadReferenceConnector, buildPreparedData, buildAfterSignalsContext, buildSymbolSharedReplayKey, runHistoricalSignalsReplay;
34002
+ var import_chalk46, import_progress12, import_backtest4, import_strategies13, import_time9, import_logger11, import_redis19, import_connectors17, import_cli13, import_strategies14, import_runtimeStrategies8, loadRuntimeStrategies, loadReferenceConnector, buildPreparedData, buildAfterSignalsContext, strategyIncludesSymbol, buildSymbolSharedReplayKey, runHistoricalSignalsReplay;
33915
34003
  var init_historicalSignalsReplay = __esm({
33916
34004
  "src/lib/replay/historicalSignalsReplay.ts"() {
33917
34005
  "use strict";
@@ -33941,7 +34029,8 @@ var init_historicalSignalsReplay = __esm({
33941
34029
  strategyPackage,
33942
34030
  strategyPackageVersion,
33943
34031
  runtimePackageVersion,
33944
- strategyConfig
34032
+ strategyConfig,
34033
+ selection
33945
34034
  } = runtimeStrategy;
33946
34035
  const strategyCreator = await (0, import_strategies14.getStrategyCreator)(
33947
34036
  strategyName,
@@ -33971,7 +34060,8 @@ var init_historicalSignalsReplay = __esm({
33971
34060
  runtimePackageVersion,
33972
34061
  strategyCreator,
33973
34062
  strategyConfig,
33974
- strategyResults
34063
+ strategyResults,
34064
+ ...selection ? { selection } : {}
33975
34065
  };
33976
34066
  })
33977
34067
  );
@@ -34056,6 +34146,14 @@ var init_historicalSignalsReplay = __esm({
34056
34146
  })
34057
34147
  )
34058
34148
  });
34149
+ strategyIncludesSymbol = (strategy, symbol) => {
34150
+ const tickers = strategy.selection?.tickers;
34151
+ if (!tickers) return true;
34152
+ const normalizedSymbol = symbol.trim().toUpperCase();
34153
+ return tickers.some(
34154
+ (ticker) => ticker.trim().toUpperCase() === normalizedSymbol
34155
+ );
34156
+ };
34059
34157
  buildSymbolSharedReplayKey = ({
34060
34158
  connectorName,
34061
34159
  interval: interval4,
@@ -34159,7 +34257,7 @@ var init_historicalSignalsReplay = __esm({
34159
34257
  });
34160
34258
  sharedReplayKeyPrefixes.push(sharedIndicatorsReplayKey);
34161
34259
  const strategiesForSymbol = await Promise.all(
34162
- loadedStrategies.map(
34260
+ loadedStrategies.filter((strategy) => strategyIncludesSymbol(strategy, symbol)).map(
34163
34261
  async ({
34164
34262
  strategyName,
34165
34263
  version,
@@ -37207,14 +37305,16 @@ var init_replayRunner = __esm({
37207
37305
  strategyPackage,
37208
37306
  strategyPackageVersion,
37209
37307
  runtimePackageVersion,
37210
- strategyConfig
37308
+ strategyConfig,
37309
+ selection
37211
37310
  }) => ({
37212
37311
  strategyName,
37213
37312
  version,
37214
37313
  strategyPackage,
37215
37314
  strategyPackageVersion,
37216
37315
  runtimePackageVersion,
37217
- strategyConfig
37316
+ strategyConfig,
37317
+ ...selection ? { selection } : {}
37218
37318
  })
37219
37319
  )
37220
37320
  } : await loadDeploymentReplayStrategies({
@@ -37246,10 +37346,11 @@ var init_replayRunner = __esm({
37246
37346
  `Replay requires one deployment universe: ${[...strategyUniverses].join(",")}`
37247
37347
  );
37248
37348
  }
37349
+ const replaySelection = mergeRuntimeStrategySelections(replayStrategies);
37249
37350
  const preparedRun = await prepareRunEnvironment({
37250
37351
  connector: deployment.connectorName,
37251
37352
  userName: replayUserName,
37252
- tickers: replayFlags.tickers ?? deployment.tickers,
37353
+ tickers: replayFlags.tickers ?? replaySelection?.tickers?.join(",") ?? deployment.tickers?.join(","),
37253
37354
  exclude: replayFlags.exclude,
37254
37355
  tickersLimit: replayFlags.tickersLimit,
37255
37356
  showTickersList: replayFlags.showTickersList,
@@ -37297,7 +37398,9 @@ var init_replayRunner = __esm({
37297
37398
  const replayResult = await runHistoricalSignalsReplay({
37298
37399
  preparedRun,
37299
37400
  interval: replayInterval,
37300
- runtimeStrategies: replayStrategies
37401
+ runtimeStrategies: replayFlags.tickers ? replayStrategies.map(
37402
+ ({ selection: _selection, ...strategy }) => strategy
37403
+ ) : replayStrategies
37301
37404
  });
37302
37405
  for (const _strategy of replayResult.strategies) {
37303
37406
  incrementSuccessTests();
@@ -32,6 +32,7 @@ var runEnvironment_exports = {};
32
32
  __export(runEnvironment_exports, {
33
33
  loadDeploymentReplayStrategies: () => loadDeploymentReplayStrategies,
34
34
  loadReplayStrategies: () => loadReplayStrategies,
35
+ mergeRuntimeStrategySelections: () => mergeRuntimeStrategySelections,
35
36
  prepareRunEnvironment: () => prepareRunEnvironment,
36
37
  resolveBacktestExecutionPreloadInterval: () => resolveBacktestExecutionPreloadInterval
37
38
  });
@@ -484,6 +485,18 @@ var resolveRunConnectorName = async ({
484
485
  );
485
486
  return import_connectors3.DEFAULT_CONNECTOR_NAME;
486
487
  };
488
+ var mergeRuntimeStrategySelections = (strategies) => {
489
+ if (strategies.some((strategy) => !strategy.selection?.tickers)) {
490
+ return void 0;
491
+ }
492
+ return {
493
+ tickers: [
494
+ ...new Set(
495
+ strategies.flatMap((strategy) => strategy.selection?.tickers ?? [])
496
+ )
497
+ ]
498
+ };
499
+ };
487
500
  var loadReplayStrategies = async (userName) => {
488
501
  const runtimeStrategies = await loadRuntimeStrategyBacktestConfigs(userName);
489
502
  if (!runtimeStrategies.length) {
@@ -514,14 +527,16 @@ var loadDeploymentReplayStrategies = async ({
514
527
  strategyPackage,
515
528
  strategyPackageVersion,
516
529
  runtimePackageVersion,
517
- sourceStrategyConfig
530
+ sourceStrategyConfig,
531
+ selection
518
532
  }) => ({
519
533
  strategyName,
520
534
  version,
521
535
  strategyPackage,
522
536
  strategyPackageVersion,
523
537
  runtimePackageVersion,
524
- strategyConfig: sourceStrategyConfig
538
+ strategyConfig: sourceStrategyConfig,
539
+ ...selection ? { selection } : {}
525
540
  })
526
541
  ) : [];
527
542
  if (!strategies.length) {
@@ -679,6 +694,7 @@ var prepareRunEnvironment = async ({
679
694
  0 && (module.exports = {
680
695
  loadDeploymentReplayStrategies,
681
696
  loadReplayStrategies,
697
+ mergeRuntimeStrategySelections,
682
698
  prepareRunEnvironment,
683
699
  resolveBacktestExecutionPreloadInterval
684
700
  });
@@ -45,6 +45,7 @@ var INTERVALS = /* @__PURE__ */ new Set([
45
45
  "M"
46
46
  ]);
47
47
  var UNIVERSES = /* @__PURE__ */ new Set(["crypto", "tradfi"]);
48
+ var isRuntimeStrategySelection = (value) => value === void 0 || isRecord(value) && Object.keys(value).length === 1 && Object.keys(value).every((key) => key === "tickers") && Array.isArray(value.tickers) && value.tickers.length > 0 && value.tickers.every((ticker) => isNonEmptyString(ticker));
48
49
  var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
49
50
  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
51
  throw new Error(
@@ -52,7 +53,7 @@ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
52
53
  );
53
54
  }
54
55
  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
+ 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) || !isRuntimeStrategySelection(candidate.selection)) {
56
57
  throw new Error(
57
58
  "Runtime evidence deployment strategy snapshot is invalid"
58
59
  );
@@ -92,11 +93,12 @@ var runtimeDeploymentFromEvidence = (deployment) => ({
92
93
  accountId: deployment.accountId,
93
94
  enabled: deployment.enabled,
94
95
  strategies: deployment.strategies.map(
95
- ({ strategyName, version, enabled, controlState }) => ({
96
+ ({ strategyName, version, enabled, controlState, selection }) => ({
96
97
  strategyName,
97
98
  version,
98
99
  enabled,
99
- controlState
100
+ controlState,
101
+ ...selection ? { selection } : {}
100
102
  })
101
103
  ),
102
104
  ...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
@@ -134,7 +136,8 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
134
136
  strategyPackage,
135
137
  strategyPackageVersion,
136
138
  runtimePackageVersion,
137
- sourceStrategyConfig
139
+ sourceStrategyConfig,
140
+ selection
138
141
  }) => ({
139
142
  strategyName,
140
143
  version,
@@ -146,7 +149,8 @@ var resolveRuntimeEvidenceDeploymentSnapshot = async ({
146
149
  strategyPackage,
147
150
  strategyPackageVersion,
148
151
  runtimePackageVersion,
149
- strategyConfig: sourceStrategyConfig
152
+ strategyConfig: sourceStrategyConfig,
153
+ ...selection ? { selection } : {}
150
154
  })
151
155
  ),
152
156
  ...deployment.assetClasses ? { assetClasses: [...deployment.assetClasses] } : {},
@@ -24,6 +24,7 @@ __export(runtimeRedis_exports, {
24
24
  isRuntimeStrategyEnabled: () => isRuntimeStrategyEnabled,
25
25
  isRuntimeTradeRecord: () => isRuntimeTradeRecord,
26
26
  loadRuntimeActiveTradeOrderIds: () => loadRuntimeActiveTradeOrderIds,
27
+ loadRuntimeActiveTrades: () => loadRuntimeActiveTrades,
27
28
  loadRuntimeClosedTrades: () => loadRuntimeClosedTrades,
28
29
  loadRuntimeStrategyConfigs: () => import_runtimeStrategyConfigs.loadRuntimeStrategyConfigs,
29
30
  loadRuntimeStrategyNames: () => import_runtimeStrategyConfigs.loadRuntimeStrategyNames,
@@ -114,6 +115,17 @@ var loadRuntimeActiveTradeOrderIds = async (userName) => {
114
115
  ).filter((orderId) => orderId != null)
115
116
  );
116
117
  };
118
+ var loadRuntimeActiveTrades = async (userName) => {
119
+ const orderIds = await loadRuntimeActiveTradeOrderIds(userName);
120
+ const trades = await Promise.all(
121
+ [...orderIds].map(
122
+ (orderId) => (0, import_redis.getData)(import_redis.redisKeys.runtimeTrade(userName, orderId), null)
123
+ )
124
+ );
125
+ return trades.filter(
126
+ (trade) => isRuntimeTradeRecord(trade) && trade.status === "active"
127
+ );
128
+ };
117
129
  var loadStrategyResultSymbols = async ({
118
130
  userName,
119
131
  strategy
@@ -132,6 +144,7 @@ var loadStrategyResultSymbols = async ({
132
144
  isRuntimeStrategyEnabled,
133
145
  isRuntimeTradeRecord,
134
146
  loadRuntimeActiveTradeOrderIds,
147
+ loadRuntimeActiveTrades,
135
148
  loadRuntimeClosedTrades,
136
149
  loadRuntimeStrategyConfigs,
137
150
  loadRuntimeStrategyNames,
@@ -5024,7 +5024,7 @@ var validateBacktestRuntimeDeployment = ({
5024
5024
  }
5025
5025
  return deployment;
5026
5026
  };
5027
- var prepareRunEnvironment2 = async () => {
5027
+ var prepareRunEnvironment2 = async (strategyName) => {
5028
5028
  const deployment = validateBacktestRuntimeDeployment({
5029
5029
  deployment: flags.deployment ? await (0, import_runtimeStrategies2.getRuntimeDeployment)({
5030
5030
  userName,
@@ -5033,10 +5033,13 @@ var prepareRunEnvironment2 = async () => {
5033
5033
  }) : null,
5034
5034
  deploymentId: typeof flags.deployment === "string" ? flags.deployment : void 0
5035
5035
  });
5036
+ const runtimeStrategy = strategyName ? deployment?.strategies.find(
5037
+ (strategy) => strategy.strategyName === strategyName
5038
+ ) : void 0;
5036
5039
  const preparedRun = await prepareRunEnvironment({
5037
5040
  connector: deployment?.connectorName ?? flags.connector,
5038
5041
  userName,
5039
- tickers: flags.tickers || deployment?.tickers?.join(","),
5042
+ tickers: flags.tickers || runtimeStrategy?.selection?.tickers?.join(",") || deployment?.tickers?.join(","),
5040
5043
  exclude: flags.exclude,
5041
5044
  tickersLimit: flags.tickersLimit,
5042
5045
  showTickersList: flags.showTickersList,
@@ -5693,7 +5696,7 @@ var backtest = async () => {
5693
5696
  });
5694
5697
  return;
5695
5698
  }
5696
- const preparedRun = await prepareRunEnvironment2();
5699
+ const preparedRun = await prepareRunEnvironment2(config.strategyName);
5697
5700
  if (!preparedRun || flags.updateOnly) {
5698
5701
  return;
5699
5702
  }