@tradejs/cli 3.1.27-beta.250 → 3.1.28-beta.251

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.
@@ -4614,6 +4614,7 @@ var createSignalsTickerEvaluator = ({
4614
4614
  primaryEthClosedData,
4615
4615
  primaryEthByTimestamp,
4616
4616
  runtimeStrategies,
4617
+ matchesStrategySymbol,
4617
4618
  strategyStats,
4618
4619
  runtimeCloseNotifications,
4619
4620
  lifecycle,
@@ -4654,6 +4655,9 @@ var createSignalsTickerEvaluator = ({
4654
4655
  );
4655
4656
  const strategySignals = [];
4656
4657
  for (const runtimeStrategy of runtimeStrategies) {
4658
+ if (matchesStrategySymbol && !matchesStrategySymbol(runtimeStrategy, symbol)) {
4659
+ continue;
4660
+ }
4657
4661
  const {
4658
4662
  strategyName,
4659
4663
  strategyRevision,
@@ -4858,6 +4862,28 @@ var createSignalsTickerEvaluator = ({
4858
4862
 
4859
4863
  // src/lib/signals/configuredScopes.ts
4860
4864
  var sorted = (values) => values ? [...values].sort() : [];
4865
+ var normalizeSymbol = (value) => value.trim().toUpperCase();
4866
+ var isActiveTradeInScope = ({
4867
+ trade,
4868
+ deploymentId,
4869
+ universe,
4870
+ accountId,
4871
+ interval
4872
+ }) => trade.status === "active" && trade.deploymentId === deploymentId && (trade.universe ?? "crypto") === universe && (!trade.accountId || trade.accountId === accountId) && (!trade.interval || String(trade.interval) === String(interval));
4873
+ var mergeConfiguredStrategySelections = (strategies) => {
4874
+ if (strategies.some(({ selection }) => !selection)) {
4875
+ return void 0;
4876
+ }
4877
+ return {
4878
+ tickers: [
4879
+ ...new Set(
4880
+ strategies.flatMap(
4881
+ ({ selection }) => (selection?.tickers ?? []).map(normalizeSymbol)
4882
+ )
4883
+ )
4884
+ ].sort()
4885
+ };
4886
+ };
4861
4887
  var formatConfiguredStrategyIdentity = (strategy) => `${strategy.strategyName}@${strategy.strategyRevision}[${strategy.controlState}]`;
4862
4888
  var getConfiguredScopeActiveSymbols = ({
4863
4889
  trades,
@@ -4871,11 +4897,47 @@ var getConfiguredScopeActiveSymbols = ({
4871
4897
  return [
4872
4898
  ...new Set(
4873
4899
  trades.filter(
4874
- (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(interval))
4875
- ).map(({ symbol }) => symbol)
4900
+ (trade) => isActiveTradeInScope({
4901
+ trade,
4902
+ deploymentId,
4903
+ universe,
4904
+ accountId,
4905
+ interval
4906
+ }) && strategyNameSet.has(trade.strategy) && Boolean(trade.symbol)
4907
+ ).map(({ symbol }) => normalizeSymbol(symbol))
4876
4908
  )
4877
4909
  ].sort();
4878
4910
  };
4911
+ var createConfiguredStrategySymbolMatcher = ({
4912
+ trades,
4913
+ deploymentId,
4914
+ universe,
4915
+ accountId,
4916
+ interval
4917
+ }) => {
4918
+ const activeStrategySymbols = new Set(
4919
+ trades.filter(
4920
+ (trade) => isActiveTradeInScope({
4921
+ trade,
4922
+ deploymentId,
4923
+ universe,
4924
+ accountId,
4925
+ interval
4926
+ })
4927
+ ).map(
4928
+ ({ strategy, symbol }) => `${strategy}\0${normalizeSymbol(symbol)}`
4929
+ )
4930
+ );
4931
+ return (strategy, symbol) => {
4932
+ if (!strategy.selection) return true;
4933
+ const normalizedSymbol = normalizeSymbol(symbol);
4934
+ return strategy.selection.tickers.some(
4935
+ (ticker) => normalizeSymbol(ticker) === normalizedSymbol
4936
+ ) || activeStrategySymbols.has(
4937
+ `${strategy.strategyName}\0${normalizedSymbol}`
4938
+ );
4939
+ };
4940
+ };
4879
4941
  var buildConfiguredSignalsScopes = ({
4880
4942
  connectorName,
4881
4943
  deployment,
@@ -4893,15 +4955,11 @@ var buildConfiguredSignalsScopes = ({
4893
4955
  });
4894
4956
  const groups = /* @__PURE__ */ new Map();
4895
4957
  for (const strategy of strategies) {
4896
- const selectionIdentity = JSON.stringify({
4897
- tickers: sorted(strategy.selection?.tickers)
4898
- });
4899
4958
  const baseKey = [
4900
4959
  connectorName,
4901
4960
  strategy.universe,
4902
4961
  strategy.accountId ?? "default",
4903
- strategy.interval,
4904
- selectionIdentity
4962
+ strategy.interval
4905
4963
  ].join(":");
4906
4964
  const group = groups.get(baseKey) ?? {
4907
4965
  scope: {
@@ -4909,26 +4967,31 @@ var buildConfiguredSignalsScopes = ({
4909
4967
  universe: strategy.universe,
4910
4968
  accountId: strategy.accountId,
4911
4969
  interval: strategy.interval,
4912
- strategyNames: [],
4913
- ...strategy.selection ? {
4914
- selection: { tickers: [...strategy.selection.tickers] }
4915
- } : {}
4970
+ strategyNames: []
4916
4971
  },
4917
- strategyIdentities: []
4972
+ strategyIdentities: [],
4973
+ strategies: []
4918
4974
  };
4919
4975
  group.scope.strategyNames.push(strategy.strategyName);
4920
4976
  group.strategyIdentities.push(formatConfiguredStrategyIdentity(strategy));
4977
+ group.strategies.push(strategy);
4921
4978
  groups.set(baseKey, group);
4922
4979
  }
4923
- return [...groups.entries()].map(([baseKey, group]) => ({
4924
- key: [baseKey, deploymentIdentity, ...group.strategyIdentities.sort()].join(
4925
- ":"
4926
- ),
4927
- scope: {
4928
- ...group.scope,
4929
- strategyNames: [...group.scope.strategyNames].sort()
4930
- }
4931
- }));
4980
+ return [...groups.entries()].map(([baseKey, group]) => {
4981
+ const selection = mergeConfiguredStrategySelections(group.strategies);
4982
+ return {
4983
+ key: [
4984
+ baseKey,
4985
+ deploymentIdentity,
4986
+ ...group.strategyIdentities.sort()
4987
+ ].join(":"),
4988
+ scope: {
4989
+ ...group.scope,
4990
+ strategyNames: [...group.scope.strategyNames].sort(),
4991
+ ...selection ? { selection } : {}
4992
+ }
4993
+ };
4994
+ });
4932
4995
  };
4933
4996
 
4934
4997
  // src/lib/runtimeEvidenceCompositionSnapshots.ts
@@ -5453,10 +5516,12 @@ var createSignalsRunner = (config2) => {
5453
5516
  selection
5454
5517
  } = session;
5455
5518
  const universe = sessionUniverse ?? marketConnector.universe ?? "crypto";
5456
- const selectedActiveSymbols = !config2.tickers && selection?.tickers?.length && strategyNames?.length ? getConfiguredScopeActiveSymbols({
5457
- trades: await loadRuntimeActiveTrades(config2.userName),
5519
+ const activeScopeStrategyNames = strategyNames?.length ? strategyNames : deployment?.strategies.filter(({ enabled }) => enabled).map(({ strategyName }) => strategyName) ?? [];
5520
+ const runtimeActiveTrades = deployment?.id && activeScopeStrategyNames.length ? await loadRuntimeActiveTrades(config2.userName) : [];
5521
+ const selectedActiveSymbols = !config2.tickers && activeScopeStrategyNames.length ? getConfiguredScopeActiveSymbols({
5522
+ trades: runtimeActiveTrades,
5458
5523
  deploymentId: deployment?.id ?? "",
5459
- strategyNames,
5524
+ strategyNames: activeScopeStrategyNames,
5460
5525
  universe,
5461
5526
  accountId,
5462
5527
  interval: interval2
@@ -5465,11 +5530,11 @@ var createSignalsRunner = (config2) => {
5465
5530
  if (selectedActiveSymbols.length) {
5466
5531
  import_logger4.logger.info(
5467
5532
  import_chalk7.default.gray(
5468
- `strategy selection retained active symbols: ${selectedActiveSymbols.join(", ")}`
5533
+ `runtime scope retained active symbols: ${selectedActiveSymbols.join(", ")}`
5469
5534
  )
5470
5535
  );
5471
5536
  }
5472
- const tickers = await timeOperation2("tickers load", () => {
5537
+ const loadedTickers = await timeOperation2("tickers load", () => {
5473
5538
  const baseArgs = [
5474
5539
  marketConnector,
5475
5540
  config2.tickers || selectedTickers?.join(",") || deployment?.tickers?.join(","),
@@ -5482,6 +5547,7 @@ var createSignalsRunner = (config2) => {
5482
5547
  assetClasses: deployment?.assetClasses
5483
5548
  }) : (0, import_cli2.getTickers)(...baseArgs);
5484
5549
  });
5550
+ const tickers = config2.tickers ? loadedTickers : [.../* @__PURE__ */ new Set([...loadedTickers, ...selectedActiveSymbols])];
5485
5551
  if (universe === "tradfi" && typeof marketConnector.listInstruments !== "function") {
5486
5552
  throw new Error("TradFi connector must implement listInstruments");
5487
5553
  }
@@ -5635,10 +5701,19 @@ var createSignalsRunner = (config2) => {
5635
5701
  );
5636
5702
  return;
5637
5703
  }
5704
+ const matchesStrategySymbol = createConfiguredStrategySymbolMatcher({
5705
+ trades: runtimeActiveTrades,
5706
+ deploymentId: deployment?.id ?? "",
5707
+ universe,
5708
+ accountId,
5709
+ interval: interval2
5710
+ });
5638
5711
  lifecycle.retain(
5639
5712
  new Set(
5640
5713
  tickers.flatMap(
5641
- (symbol) => runtimeStrategies.map(
5714
+ (symbol) => runtimeStrategies.filter(
5715
+ (runtimeStrategy) => matchesStrategySymbol(runtimeStrategy, symbol)
5716
+ ).map(
5642
5717
  ({ strategyName, strategyRevision }) => buildSignalsStrategyLifecycleKey({
5643
5718
  connectorName,
5644
5719
  universe: sessionUniverse,
@@ -5705,6 +5780,7 @@ var createSignalsRunner = (config2) => {
5705
5780
  primaryEthClosedData,
5706
5781
  primaryEthByTimestamp,
5707
5782
  runtimeStrategies,
5783
+ matchesStrategySymbol,
5708
5784
  strategyStats,
5709
5785
  runtimeCloseNotifications,
5710
5786
  lifecycle,
@@ -4612,6 +4612,7 @@ var createSignalsTickerEvaluator = ({
4612
4612
  primaryEthClosedData,
4613
4613
  primaryEthByTimestamp,
4614
4614
  runtimeStrategies,
4615
+ matchesStrategySymbol,
4615
4616
  strategyStats,
4616
4617
  runtimeCloseNotifications,
4617
4618
  lifecycle,
@@ -4652,6 +4653,9 @@ var createSignalsTickerEvaluator = ({
4652
4653
  );
4653
4654
  const strategySignals = [];
4654
4655
  for (const runtimeStrategy of runtimeStrategies) {
4656
+ if (matchesStrategySymbol && !matchesStrategySymbol(runtimeStrategy, symbol)) {
4657
+ continue;
4658
+ }
4655
4659
  const {
4656
4660
  strategyName,
4657
4661
  strategyRevision,
@@ -4856,6 +4860,28 @@ var createSignalsTickerEvaluator = ({
4856
4860
 
4857
4861
  // src/lib/signals/configuredScopes.ts
4858
4862
  var sorted = (values) => values ? [...values].sort() : [];
4863
+ var normalizeSymbol = (value) => value.trim().toUpperCase();
4864
+ var isActiveTradeInScope = ({
4865
+ trade,
4866
+ deploymentId,
4867
+ universe,
4868
+ accountId,
4869
+ interval
4870
+ }) => trade.status === "active" && trade.deploymentId === deploymentId && (trade.universe ?? "crypto") === universe && (!trade.accountId || trade.accountId === accountId) && (!trade.interval || String(trade.interval) === String(interval));
4871
+ var mergeConfiguredStrategySelections = (strategies) => {
4872
+ if (strategies.some(({ selection }) => !selection)) {
4873
+ return void 0;
4874
+ }
4875
+ return {
4876
+ tickers: [
4877
+ ...new Set(
4878
+ strategies.flatMap(
4879
+ ({ selection }) => (selection?.tickers ?? []).map(normalizeSymbol)
4880
+ )
4881
+ )
4882
+ ].sort()
4883
+ };
4884
+ };
4859
4885
  var formatConfiguredStrategyIdentity = (strategy) => `${strategy.strategyName}@${strategy.strategyRevision}[${strategy.controlState}]`;
4860
4886
  var getConfiguredScopeActiveSymbols = ({
4861
4887
  trades,
@@ -4869,11 +4895,47 @@ var getConfiguredScopeActiveSymbols = ({
4869
4895
  return [
4870
4896
  ...new Set(
4871
4897
  trades.filter(
4872
- (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(interval))
4873
- ).map(({ symbol }) => symbol)
4898
+ (trade) => isActiveTradeInScope({
4899
+ trade,
4900
+ deploymentId,
4901
+ universe,
4902
+ accountId,
4903
+ interval
4904
+ }) && strategyNameSet.has(trade.strategy) && Boolean(trade.symbol)
4905
+ ).map(({ symbol }) => normalizeSymbol(symbol))
4874
4906
  )
4875
4907
  ].sort();
4876
4908
  };
4909
+ var createConfiguredStrategySymbolMatcher = ({
4910
+ trades,
4911
+ deploymentId,
4912
+ universe,
4913
+ accountId,
4914
+ interval
4915
+ }) => {
4916
+ const activeStrategySymbols = new Set(
4917
+ trades.filter(
4918
+ (trade) => isActiveTradeInScope({
4919
+ trade,
4920
+ deploymentId,
4921
+ universe,
4922
+ accountId,
4923
+ interval
4924
+ })
4925
+ ).map(
4926
+ ({ strategy, symbol }) => `${strategy}\0${normalizeSymbol(symbol)}`
4927
+ )
4928
+ );
4929
+ return (strategy, symbol) => {
4930
+ if (!strategy.selection) return true;
4931
+ const normalizedSymbol = normalizeSymbol(symbol);
4932
+ return strategy.selection.tickers.some(
4933
+ (ticker) => normalizeSymbol(ticker) === normalizedSymbol
4934
+ ) || activeStrategySymbols.has(
4935
+ `${strategy.strategyName}\0${normalizedSymbol}`
4936
+ );
4937
+ };
4938
+ };
4877
4939
  var buildConfiguredSignalsScopes = ({
4878
4940
  connectorName,
4879
4941
  deployment,
@@ -4891,15 +4953,11 @@ var buildConfiguredSignalsScopes = ({
4891
4953
  });
4892
4954
  const groups = /* @__PURE__ */ new Map();
4893
4955
  for (const strategy of strategies) {
4894
- const selectionIdentity = JSON.stringify({
4895
- tickers: sorted(strategy.selection?.tickers)
4896
- });
4897
4956
  const baseKey = [
4898
4957
  connectorName,
4899
4958
  strategy.universe,
4900
4959
  strategy.accountId ?? "default",
4901
- strategy.interval,
4902
- selectionIdentity
4960
+ strategy.interval
4903
4961
  ].join(":");
4904
4962
  const group = groups.get(baseKey) ?? {
4905
4963
  scope: {
@@ -4907,26 +4965,31 @@ var buildConfiguredSignalsScopes = ({
4907
4965
  universe: strategy.universe,
4908
4966
  accountId: strategy.accountId,
4909
4967
  interval: strategy.interval,
4910
- strategyNames: [],
4911
- ...strategy.selection ? {
4912
- selection: { tickers: [...strategy.selection.tickers] }
4913
- } : {}
4968
+ strategyNames: []
4914
4969
  },
4915
- strategyIdentities: []
4970
+ strategyIdentities: [],
4971
+ strategies: []
4916
4972
  };
4917
4973
  group.scope.strategyNames.push(strategy.strategyName);
4918
4974
  group.strategyIdentities.push(formatConfiguredStrategyIdentity(strategy));
4975
+ group.strategies.push(strategy);
4919
4976
  groups.set(baseKey, group);
4920
4977
  }
4921
- return [...groups.entries()].map(([baseKey, group]) => ({
4922
- key: [baseKey, deploymentIdentity, ...group.strategyIdentities.sort()].join(
4923
- ":"
4924
- ),
4925
- scope: {
4926
- ...group.scope,
4927
- strategyNames: [...group.scope.strategyNames].sort()
4928
- }
4929
- }));
4978
+ return [...groups.entries()].map(([baseKey, group]) => {
4979
+ const selection = mergeConfiguredStrategySelections(group.strategies);
4980
+ return {
4981
+ key: [
4982
+ baseKey,
4983
+ deploymentIdentity,
4984
+ ...group.strategyIdentities.sort()
4985
+ ].join(":"),
4986
+ scope: {
4987
+ ...group.scope,
4988
+ strategyNames: [...group.scope.strategyNames].sort(),
4989
+ ...selection ? { selection } : {}
4990
+ }
4991
+ };
4992
+ });
4930
4993
  };
4931
4994
 
4932
4995
  // src/lib/runtimeEvidenceCompositionSnapshots.ts
@@ -5451,10 +5514,12 @@ var createSignalsRunner = (config2) => {
5451
5514
  selection
5452
5515
  } = session;
5453
5516
  const universe = sessionUniverse ?? marketConnector.universe ?? "crypto";
5454
- const selectedActiveSymbols = !config2.tickers && selection?.tickers?.length && strategyNames?.length ? getConfiguredScopeActiveSymbols({
5455
- trades: await loadRuntimeActiveTrades(config2.userName),
5517
+ const activeScopeStrategyNames = strategyNames?.length ? strategyNames : deployment?.strategies.filter(({ enabled }) => enabled).map(({ strategyName }) => strategyName) ?? [];
5518
+ const runtimeActiveTrades = deployment?.id && activeScopeStrategyNames.length ? await loadRuntimeActiveTrades(config2.userName) : [];
5519
+ const selectedActiveSymbols = !config2.tickers && activeScopeStrategyNames.length ? getConfiguredScopeActiveSymbols({
5520
+ trades: runtimeActiveTrades,
5456
5521
  deploymentId: deployment?.id ?? "",
5457
- strategyNames,
5522
+ strategyNames: activeScopeStrategyNames,
5458
5523
  universe,
5459
5524
  accountId,
5460
5525
  interval: interval2
@@ -5463,11 +5528,11 @@ var createSignalsRunner = (config2) => {
5463
5528
  if (selectedActiveSymbols.length) {
5464
5529
  import_logger4.logger.info(
5465
5530
  import_chalk7.default.gray(
5466
- `strategy selection retained active symbols: ${selectedActiveSymbols.join(", ")}`
5531
+ `runtime scope retained active symbols: ${selectedActiveSymbols.join(", ")}`
5467
5532
  )
5468
5533
  );
5469
5534
  }
5470
- const tickers = await timeOperation2("tickers load", () => {
5535
+ const loadedTickers = await timeOperation2("tickers load", () => {
5471
5536
  const baseArgs = [
5472
5537
  marketConnector,
5473
5538
  config2.tickers || selectedTickers?.join(",") || deployment?.tickers?.join(","),
@@ -5480,6 +5545,7 @@ var createSignalsRunner = (config2) => {
5480
5545
  assetClasses: deployment?.assetClasses
5481
5546
  }) : (0, import_cli2.getTickers)(...baseArgs);
5482
5547
  });
5548
+ const tickers = config2.tickers ? loadedTickers : [.../* @__PURE__ */ new Set([...loadedTickers, ...selectedActiveSymbols])];
5483
5549
  if (universe === "tradfi" && typeof marketConnector.listInstruments !== "function") {
5484
5550
  throw new Error("TradFi connector must implement listInstruments");
5485
5551
  }
@@ -5633,10 +5699,19 @@ var createSignalsRunner = (config2) => {
5633
5699
  );
5634
5700
  return;
5635
5701
  }
5702
+ const matchesStrategySymbol = createConfiguredStrategySymbolMatcher({
5703
+ trades: runtimeActiveTrades,
5704
+ deploymentId: deployment?.id ?? "",
5705
+ universe,
5706
+ accountId,
5707
+ interval: interval2
5708
+ });
5636
5709
  lifecycle.retain(
5637
5710
  new Set(
5638
5711
  tickers.flatMap(
5639
- (symbol) => runtimeStrategies.map(
5712
+ (symbol) => runtimeStrategies.filter(
5713
+ (runtimeStrategy) => matchesStrategySymbol(runtimeStrategy, symbol)
5714
+ ).map(
5640
5715
  ({ strategyName, strategyRevision }) => buildSignalsStrategyLifecycleKey({
5641
5716
  connectorName,
5642
5717
  universe: sessionUniverse,
@@ -5703,6 +5778,7 @@ var createSignalsRunner = (config2) => {
5703
5778
  primaryEthClosedData,
5704
5779
  primaryEthByTimestamp,
5705
5780
  runtimeStrategies,
5781
+ matchesStrategySymbol,
5706
5782
  strategyStats,
5707
5783
  runtimeCloseNotifications,
5708
5784
  lifecycle,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/cli",
3
- "version": "3.1.27-beta.250",
3
+ "version": "3.1.28-beta.251",
4
4
  "description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -36,13 +36,13 @@
36
36
  "tradejs": "dist/cli.js"
37
37
  },
38
38
  "dependencies": {
39
- "@tradejs/connectors": "^3.1.27-beta.250",
40
- "@tradejs/core": "^3.1.27-beta.250",
41
- "@tradejs/indicators": "^3.1.27-beta.250",
42
- "@tradejs/infra": "^3.1.27-beta.250",
43
- "@tradejs/node": "^3.1.27-beta.250",
39
+ "@tradejs/connectors": "^3.1.28-beta.251",
40
+ "@tradejs/core": "^3.1.28-beta.251",
41
+ "@tradejs/indicators": "^3.1.28-beta.251",
42
+ "@tradejs/infra": "^3.1.28-beta.251",
43
+ "@tradejs/node": "^3.1.28-beta.251",
44
44
  "@tradejs/strategy-kit": "3.0.4",
45
- "@tradejs/types": "^3.1.27-beta.250",
45
+ "@tradejs/types": "^3.1.28-beta.251",
46
46
  "args": "^5.0.3",
47
47
  "bcryptjs": "^2.4.3",
48
48
  "chalk": "4.1.2",