@tradejs/cli 3.1.6 → 3.1.7

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
@@ -6611,13 +6611,13 @@ var init_aiTrainCharts = __esm({
6611
6611
  if (!evaluations.length) {
6612
6612
  return [];
6613
6613
  }
6614
- const sorted = [...evaluations].sort(
6614
+ const sorted2 = [...evaluations].sort(
6615
6615
  (left, right) => (left.timestamp ?? 0) - (right.timestamp ?? 0) || left.symbol.localeCompare(right.symbol) || left.signalId.localeCompare(right.signalId)
6616
6616
  );
6617
6617
  let amount = 100;
6618
- const firstTimestamp = sorted[0]?.timestamp ?? Date.now();
6618
+ const firstTimestamp = sorted2[0]?.timestamp ?? Date.now();
6619
6619
  const orderLog = [[firstTimestamp, amount]];
6620
- for (const evaluation of sorted) {
6620
+ for (const evaluation of sorted2) {
6621
6621
  amount += evaluation.profit;
6622
6622
  orderLog.push([
6623
6623
  evaluation.timestamp ?? firstTimestamp,
@@ -16388,12 +16388,12 @@ var init_executionCalibration = __esm({
16388
16388
  if (!values.length) {
16389
16389
  return null;
16390
16390
  }
16391
- const sorted = [...values].sort((left, right) => left - right);
16392
- const index = (sorted.length - 1) * probability;
16391
+ const sorted2 = [...values].sort((left, right) => left - right);
16392
+ const index = (sorted2.length - 1) * probability;
16393
16393
  const lowerIndex = Math.floor(index);
16394
16394
  const upperIndex = Math.ceil(index);
16395
- const lower = sorted[lowerIndex];
16396
- const upper = sorted[upperIndex];
16395
+ const lower = sorted2[lowerIndex];
16396
+ const upper = sorted2[upperIndex];
16397
16397
  if (lower == null || upper == null) {
16398
16398
  return null;
16399
16399
  }
@@ -17905,9 +17905,9 @@ var init_hyperliquidWhaleSelection = __esm({
17905
17905
  };
17906
17906
  median = (values) => {
17907
17907
  if (!values.length) return 0;
17908
- const sorted = [...values].sort((left, right) => left - right);
17909
- const middle = Math.floor(sorted.length / 2);
17910
- return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
17908
+ const sorted2 = [...values].sort((left, right) => left - right);
17909
+ const middle = Math.floor(sorted2.length / 2);
17910
+ return sorted2.length % 2 ? sorted2[middle] : (sorted2[middle - 1] + sorted2[middle]) / 2;
17911
17911
  };
17912
17912
  evaluateHyperliquidWhaleStructure = (params) => {
17913
17913
  const fills = params.fills.filter((fill) => {
@@ -18387,14 +18387,14 @@ var init_mlInspect = __esm({
18387
18387
  }
18388
18388
  return sample;
18389
18389
  };
18390
- quantileSorted = (sorted, q) => {
18391
- if (!sorted.length) return 0;
18392
- if (sorted.length === 1) return sorted[0];
18393
- const pos = (sorted.length - 1) * q;
18390
+ quantileSorted = (sorted2, q) => {
18391
+ if (!sorted2.length) return 0;
18392
+ if (sorted2.length === 1) return sorted2[0];
18393
+ const pos = (sorted2.length - 1) * q;
18394
18394
  const base = Math.floor(pos);
18395
18395
  const rest = pos - base;
18396
- const left = sorted[base];
18397
- const right = sorted[Math.min(base + 1, sorted.length - 1)];
18396
+ const left = sorted2[base];
18397
+ const right = sorted2[Math.min(base + 1, sorted2.length - 1)];
18398
18398
  return left + (right - left) * rest;
18399
18399
  };
18400
18400
  mean2 = (values) => {
@@ -18469,12 +18469,12 @@ var init_mlInspect = __esm({
18469
18469
  if (values.length < minFieldValues) {
18470
18470
  continue;
18471
18471
  }
18472
- const sorted = [...values].sort((a, b) => a - b);
18473
- const q1 = quantileSorted(sorted, 0.25);
18474
- const median2 = quantileSorted(sorted, 0.5);
18475
- const q3 = quantileSorted(sorted, 0.75);
18476
- const p95 = quantileSorted(sorted, 0.95);
18477
- const p99 = quantileSorted(sorted, 0.99);
18472
+ const sorted2 = [...values].sort((a, b) => a - b);
18473
+ const q1 = quantileSorted(sorted2, 0.25);
18474
+ const median2 = quantileSorted(sorted2, 0.5);
18475
+ const q3 = quantileSorted(sorted2, 0.75);
18476
+ const p95 = quantileSorted(sorted2, 0.95);
18477
+ const p99 = quantileSorted(sorted2, 0.99);
18478
18478
  const valuesMean = mean2(values);
18479
18479
  const valuesStd = std(values, valuesMean);
18480
18480
  const iqr = q3 - q1;
@@ -18490,8 +18490,8 @@ var init_mlInspect = __esm({
18490
18490
  nonFiniteRate: nonFinite / Math.max(present, 1),
18491
18491
  zeroRate: zeros / Math.max(values.length, 1),
18492
18492
  uniqueCount,
18493
- min: sorted[0],
18494
- max: sorted[sorted.length - 1],
18493
+ min: sorted2[0],
18494
+ max: sorted2[sorted2.length - 1],
18495
18495
  mean: valuesMean,
18496
18496
  std: valuesStd,
18497
18497
  median: median2,
@@ -21339,14 +21339,14 @@ var init_metrics = __esm({
21339
21339
  "SHORT"
21340
21340
  ];
21341
21341
  selectCohort = (trades, cohort) => cohort === "ALL" ? trades : trades.filter((trade) => trade.direction === cohort);
21342
- quantile2 = (sorted, probability) => {
21343
- if (!sorted.length) return null;
21344
- const position = (sorted.length - 1) * probability;
21342
+ quantile2 = (sorted2, probability) => {
21343
+ if (!sorted2.length) return null;
21344
+ const position = (sorted2.length - 1) * probability;
21345
21345
  const lower = Math.floor(position);
21346
21346
  const upper = Math.ceil(position);
21347
- if (lower === upper) return sorted[lower];
21347
+ if (lower === upper) return sorted2[lower];
21348
21348
  const weight = position - lower;
21349
- return sorted[lower] * (1 - weight) + sorted[upper] * weight;
21349
+ return sorted2[lower] * (1 - weight) + sorted2[upper] * weight;
21350
21350
  };
21351
21351
  compareChronologicalTrades = (left, right) => left.exitTimestamp - right.exitTimestamp || (left.signalId < right.signalId ? -1 : left.signalId > right.signalId ? 1 : 0);
21352
21352
  orderCoreResearchTrades = (trades) => {
@@ -21358,7 +21358,7 @@ var init_metrics = __esm({
21358
21358
  return trades;
21359
21359
  };
21360
21360
  summarizeCoreResearchTrades = (trades, periodDays) => {
21361
- const sorted = orderCoreResearchTrades(trades);
21361
+ const sorted2 = orderCoreResearchTrades(trades);
21362
21362
  let pnl = 0;
21363
21363
  let grossProfit = 0;
21364
21364
  let grossLoss = 0;
@@ -21370,7 +21370,7 @@ var init_metrics = __esm({
21370
21370
  let realizedMaxDrawdown = 0;
21371
21371
  let consecutiveLosses = 0;
21372
21372
  let maximumConsecutiveLosses = 0;
21373
- for (const trade of sorted) {
21373
+ for (const trade of sorted2) {
21374
21374
  pnl += trade.netProfit;
21375
21375
  if (trade.netProfit > 0) {
21376
21376
  wins += 1;
@@ -21392,9 +21392,9 @@ var init_metrics = __esm({
21392
21392
  peak = Math.max(peak, equity);
21393
21393
  realizedMaxDrawdown = Math.max(realizedMaxDrawdown, peak - equity);
21394
21394
  }
21395
- const count = sorted.length;
21396
- const pnlDistribution = sorted.map((trade) => trade.netProfit).sort((left, right) => left - right);
21397
- const holdingHours = sorted.map((trade) => (trade.exitTimestamp - trade.entryTimestamp) / 36e5).sort((left, right) => left - right);
21395
+ const count = sorted2.length;
21396
+ const pnlDistribution = sorted2.map((trade) => trade.netProfit).sort((left, right) => left - right);
21397
+ const holdingHours = sorted2.map((trade) => (trade.exitTimestamp - trade.entryTimestamp) / 36e5).sort((left, right) => left - right);
21398
21398
  const averageWin = wins > 0 ? grossProfit / wins : null;
21399
21399
  const strictLosses = losses - breakeven;
21400
21400
  const averageLoss = strictLosses > 0 ? grossLoss / strictLosses : null;
@@ -21567,13 +21567,13 @@ var init_statistics = __esm({
21567
21567
  return (state >>> 0) / 4294967296;
21568
21568
  };
21569
21569
  };
21570
- percentile = (sorted, probability) => {
21571
- if (!sorted.length) return Number.NaN;
21570
+ percentile = (sorted2, probability) => {
21571
+ if (!sorted2.length) return Number.NaN;
21572
21572
  const index = Math.min(
21573
- sorted.length - 1,
21574
- Math.max(0, Math.floor(probability * sorted.length))
21573
+ sorted2.length - 1,
21574
+ Math.max(0, Math.floor(probability * sorted2.length))
21575
21575
  );
21576
- return sorted[index];
21576
+ return sorted2[index];
21577
21577
  };
21578
21578
  calendarClusterBootstrap = (params) => {
21579
21579
  const clusterMs = params.clusterDays * DAY_MS11;
@@ -21787,8 +21787,8 @@ var init_statistics = __esm({
21787
21787
  const outScores = performanceByVariant.map(
21788
21788
  (performance) => outSample.reduce((sum3, index) => sum3 + performance[index], 0)
21789
21789
  );
21790
- const sorted = [...outScores].sort((left, right) => left - right);
21791
- const rankAscending = sorted.indexOf(outScores[selected]);
21790
+ const sorted2 = [...outScores].sort((left, right) => left - right);
21791
+ const rankAscending = sorted2.indexOf(outScores[selected]);
21792
21792
  const omega = (rankAscending + 1) / (outScores.length + 1);
21793
21793
  if (Math.log(omega / (1 - omega)) < 0) belowMedian += 1;
21794
21794
  }
@@ -26584,12 +26584,12 @@ var init_monitoringProfile = __esm({
26584
26584
  return left;
26585
26585
  };
26586
26586
  percentile2 = (values, probability) => {
26587
- const sorted = [...values].sort((left, right) => left - right);
26588
- const position = (sorted.length - 1) * probability;
26587
+ const sorted2 = [...values].sort((left, right) => left - right);
26588
+ const position = (sorted2.length - 1) * probability;
26589
26589
  const lower = Math.floor(position);
26590
26590
  const upper = Math.ceil(position);
26591
- if (lower === upper) return sorted[lower];
26592
- return sorted[lower] * (upper - position) + sorted[upper] * (position - lower);
26591
+ if (lower === upper) return sorted2[lower];
26592
+ return sorted2[lower] * (upper - position) + sorted2[upper] * (position - lower);
26593
26593
  };
26594
26594
  buildStrategyMonitoringProfile = ({
26595
26595
  trades,
@@ -32262,6 +32262,58 @@ var init_tickerEvaluator = __esm({
32262
32262
  }
32263
32263
  });
32264
32264
 
32265
+ // src/lib/signals/configuredScopes.ts
32266
+ var sorted, buildConfiguredSignalsScopes;
32267
+ var init_configuredScopes = __esm({
32268
+ "src/lib/signals/configuredScopes.ts"() {
32269
+ "use strict";
32270
+ sorted = (values) => values ? [...values].sort() : [];
32271
+ buildConfiguredSignalsScopes = ({
32272
+ connectorName,
32273
+ deployment,
32274
+ strategies
32275
+ }) => {
32276
+ const deploymentIdentity = JSON.stringify({
32277
+ id: deployment.id,
32278
+ enabled: deployment.enabled,
32279
+ connectorName: deployment.connectorName,
32280
+ provider: deployment.provider,
32281
+ accountId: deployment.accountId,
32282
+ tickers: sorted(deployment.tickers),
32283
+ assetClasses: sorted(deployment.assetClasses)
32284
+ });
32285
+ const groups = /* @__PURE__ */ new Map();
32286
+ for (const strategy of strategies) {
32287
+ const baseKey = [
32288
+ connectorName,
32289
+ strategy.universe,
32290
+ strategy.accountId ?? "default",
32291
+ strategy.interval
32292
+ ].join(":");
32293
+ const group = groups.get(baseKey) ?? {
32294
+ scope: {
32295
+ connectorName,
32296
+ universe: strategy.universe,
32297
+ accountId: strategy.accountId,
32298
+ interval: strategy.interval
32299
+ },
32300
+ strategyIdentities: []
32301
+ };
32302
+ group.strategyIdentities.push(
32303
+ `${strategy.strategyName}@${strategy.releaseVersion}:${strategy.controlState}`
32304
+ );
32305
+ groups.set(baseKey, group);
32306
+ }
32307
+ return [...groups.entries()].map(([baseKey, group]) => ({
32308
+ key: [baseKey, deploymentIdentity, ...group.strategyIdentities.sort()].join(
32309
+ ":"
32310
+ ),
32311
+ scope: group.scope
32312
+ }));
32313
+ };
32314
+ }
32315
+ });
32316
+
32265
32317
  // src/lib/signals/runner.ts
32266
32318
  var import_progress11, import_chalk45, import_connectors16, import_cli12, import_async5, import_strategies13, import_constants16, import_time8, import_logger10, import_runtimeDeployments3, SLOW_SIGNALS_WARNING_MS, formatDuration3, resolvePositiveInteger2, resolveNonNegativeInteger, createSignalsRunner;
32267
32319
  var init_runner = __esm({
@@ -32290,6 +32342,7 @@ var init_runner = __esm({
32290
32342
  init_daemon();
32291
32343
  init_klineFeed();
32292
32344
  init_tickerEvaluator();
32345
+ init_configuredScopes();
32293
32346
  SLOW_SIGNALS_WARNING_MS = 10 * 6e4;
32294
32347
  formatDuration3 = (durationMs) => `${(durationMs / 1e3).toFixed(1)}s`;
32295
32348
  resolvePositiveInteger2 = (value, fallback) => {
@@ -32797,22 +32850,13 @@ var init_runner = __esm({
32797
32850
  const connectorName = await resolveSignalsConnectorName(
32798
32851
  deployment.connectorName
32799
32852
  );
32800
- const scopes = /* @__PURE__ */ new Map();
32801
- for (const strategy of configuredStrategies) {
32802
- const key = [
32853
+ return new Map(
32854
+ buildConfiguredSignalsScopes({
32803
32855
  connectorName,
32804
- strategy.universe,
32805
- strategy.accountId ?? "default",
32806
- strategy.interval
32807
- ].join(":");
32808
- scopes.set(key, {
32809
- connectorName,
32810
- universe: strategy.universe,
32811
- accountId: strategy.accountId,
32812
- interval: strategy.interval
32813
- });
32814
- }
32815
- return scopes;
32856
+ deployment,
32857
+ strategies: configuredStrategies
32858
+ }).map(({ key, scope }) => [key, scope])
32859
+ );
32816
32860
  };
32817
32861
  const signalsConfiguredScopesOnce2 = async () => {
32818
32862
  if (config2.updateOnly || config2.showTickersList) {
@@ -32853,12 +32897,13 @@ var init_runner = __esm({
32853
32897
  if (!config2.deploymentId) {
32854
32898
  throw new Error("Runtime deployment id is required");
32855
32899
  }
32856
- const daemonDeployment = await (0, import_runtimeDeployments3.getRuntimeDeployment)(
32900
+ const deploymentId = config2.deploymentId;
32901
+ const initialDeployment = await (0, import_runtimeDeployments3.getRuntimeDeployment)(
32857
32902
  config2.userName,
32858
- config2.deploymentId
32903
+ deploymentId
32859
32904
  );
32860
- if (!daemonDeployment) {
32861
- throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
32905
+ if (!initialDeployment) {
32906
+ throw new Error(`Runtime deployment not found: ${deploymentId}`);
32862
32907
  }
32863
32908
  const sessions = /* @__PURE__ */ new Map();
32864
32909
  const lastBoundaryByScope = /* @__PURE__ */ new Map();
@@ -32877,7 +32922,14 @@ var init_runner = __esm({
32877
32922
  settleDelayMs: resolveNonNegativeInteger(config2.settleDelayMs, 5e3),
32878
32923
  signal: abortController.signal,
32879
32924
  runCycle: async () => {
32880
- const scopes = await loadConfiguredSignalsScopes(daemonDeployment);
32925
+ const currentDeployment = await (0, import_runtimeDeployments3.getRuntimeDeployment)(
32926
+ config2.userName,
32927
+ deploymentId
32928
+ );
32929
+ if (!currentDeployment) {
32930
+ throw new Error(`Runtime deployment not found: ${deploymentId}`);
32931
+ }
32932
+ const scopes = await loadConfiguredSignalsScopes(currentDeployment);
32881
32933
  for (const [key, staleSession] of sessions) {
32882
32934
  if (scopes.has(key)) continue;
32883
32935
  await staleSession.klineFeed?.close();
@@ -36599,8 +36651,8 @@ var init_outputReport = __esm({
36599
36651
  grouped.set(record.strategy, existing);
36600
36652
  }
36601
36653
  const formatSet = (values) => {
36602
- const sorted = [...values].sort();
36603
- return sorted.length <= 3 ? sorted.join(", ") : `${sorted.slice(0, 3).join(", ")} \u2026 (+${sorted.length - 3})`;
36654
+ const sorted2 = [...values].sort();
36655
+ return sorted2.length <= 3 ? sorted2.join(", ") : `${sorted2.slice(0, 3).join(", ")} \u2026 (+${sorted2.length - 3})`;
36604
36656
  };
36605
36657
  return grouped.size ? createMarkdownTable2(
36606
36658
  [
@@ -4994,6 +4994,52 @@ var createSignalsTickerEvaluator = ({
4994
4994
  return strategySignals;
4995
4995
  };
4996
4996
 
4997
+ // src/lib/signals/configuredScopes.ts
4998
+ var sorted = (values) => values ? [...values].sort() : [];
4999
+ var buildConfiguredSignalsScopes = ({
5000
+ connectorName,
5001
+ deployment,
5002
+ strategies
5003
+ }) => {
5004
+ const deploymentIdentity = JSON.stringify({
5005
+ id: deployment.id,
5006
+ enabled: deployment.enabled,
5007
+ connectorName: deployment.connectorName,
5008
+ provider: deployment.provider,
5009
+ accountId: deployment.accountId,
5010
+ tickers: sorted(deployment.tickers),
5011
+ assetClasses: sorted(deployment.assetClasses)
5012
+ });
5013
+ const groups = /* @__PURE__ */ new Map();
5014
+ for (const strategy of strategies) {
5015
+ const baseKey = [
5016
+ connectorName,
5017
+ strategy.universe,
5018
+ strategy.accountId ?? "default",
5019
+ strategy.interval
5020
+ ].join(":");
5021
+ const group = groups.get(baseKey) ?? {
5022
+ scope: {
5023
+ connectorName,
5024
+ universe: strategy.universe,
5025
+ accountId: strategy.accountId,
5026
+ interval: strategy.interval
5027
+ },
5028
+ strategyIdentities: []
5029
+ };
5030
+ group.strategyIdentities.push(
5031
+ `${strategy.strategyName}@${strategy.releaseVersion}:${strategy.controlState}`
5032
+ );
5033
+ groups.set(baseKey, group);
5034
+ }
5035
+ return [...groups.entries()].map(([baseKey, group]) => ({
5036
+ key: [baseKey, deploymentIdentity, ...group.strategyIdentities.sort()].join(
5037
+ ":"
5038
+ ),
5039
+ scope: group.scope
5040
+ }));
5041
+ };
5042
+
4997
5043
  // src/lib/signals/runner.ts
4998
5044
  var SLOW_SIGNALS_WARNING_MS = 10 * 6e4;
4999
5045
  var formatDuration2 = (durationMs) => `${(durationMs / 1e3).toFixed(1)}s`;
@@ -5502,22 +5548,13 @@ var createSignalsRunner = (config2) => {
5502
5548
  const connectorName = await resolveSignalsConnectorName(
5503
5549
  deployment.connectorName
5504
5550
  );
5505
- const scopes = /* @__PURE__ */ new Map();
5506
- for (const strategy of configuredStrategies) {
5507
- const key = [
5508
- connectorName,
5509
- strategy.universe,
5510
- strategy.accountId ?? "default",
5511
- strategy.interval
5512
- ].join(":");
5513
- scopes.set(key, {
5551
+ return new Map(
5552
+ buildConfiguredSignalsScopes({
5514
5553
  connectorName,
5515
- universe: strategy.universe,
5516
- accountId: strategy.accountId,
5517
- interval: strategy.interval
5518
- });
5519
- }
5520
- return scopes;
5554
+ deployment,
5555
+ strategies: configuredStrategies
5556
+ }).map(({ key, scope }) => [key, scope])
5557
+ );
5521
5558
  };
5522
5559
  const signalsConfiguredScopesOnce2 = async () => {
5523
5560
  if (config2.updateOnly || config2.showTickersList) {
@@ -5558,12 +5595,13 @@ var createSignalsRunner = (config2) => {
5558
5595
  if (!config2.deploymentId) {
5559
5596
  throw new Error("Runtime deployment id is required");
5560
5597
  }
5561
- const daemonDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
5598
+ const deploymentId = config2.deploymentId;
5599
+ const initialDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
5562
5600
  config2.userName,
5563
- config2.deploymentId
5601
+ deploymentId
5564
5602
  );
5565
- if (!daemonDeployment) {
5566
- throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
5603
+ if (!initialDeployment) {
5604
+ throw new Error(`Runtime deployment not found: ${deploymentId}`);
5567
5605
  }
5568
5606
  const sessions = /* @__PURE__ */ new Map();
5569
5607
  const lastBoundaryByScope = /* @__PURE__ */ new Map();
@@ -5582,7 +5620,14 @@ var createSignalsRunner = (config2) => {
5582
5620
  settleDelayMs: resolveNonNegativeInteger(config2.settleDelayMs, 5e3),
5583
5621
  signal: abortController.signal,
5584
5622
  runCycle: async () => {
5585
- const scopes = await loadConfiguredSignalsScopes(daemonDeployment);
5623
+ const currentDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
5624
+ config2.userName,
5625
+ deploymentId
5626
+ );
5627
+ if (!currentDeployment) {
5628
+ throw new Error(`Runtime deployment not found: ${deploymentId}`);
5629
+ }
5630
+ const scopes = await loadConfiguredSignalsScopes(currentDeployment);
5586
5631
  for (const [key, staleSession] of sessions) {
5587
5632
  if (scopes.has(key)) continue;
5588
5633
  await staleSession.klineFeed?.close();
@@ -4992,6 +4992,52 @@ var createSignalsTickerEvaluator = ({
4992
4992
  return strategySignals;
4993
4993
  };
4994
4994
 
4995
+ // src/lib/signals/configuredScopes.ts
4996
+ var sorted = (values) => values ? [...values].sort() : [];
4997
+ var buildConfiguredSignalsScopes = ({
4998
+ connectorName,
4999
+ deployment,
5000
+ strategies
5001
+ }) => {
5002
+ const deploymentIdentity = JSON.stringify({
5003
+ id: deployment.id,
5004
+ enabled: deployment.enabled,
5005
+ connectorName: deployment.connectorName,
5006
+ provider: deployment.provider,
5007
+ accountId: deployment.accountId,
5008
+ tickers: sorted(deployment.tickers),
5009
+ assetClasses: sorted(deployment.assetClasses)
5010
+ });
5011
+ const groups = /* @__PURE__ */ new Map();
5012
+ for (const strategy of strategies) {
5013
+ const baseKey = [
5014
+ connectorName,
5015
+ strategy.universe,
5016
+ strategy.accountId ?? "default",
5017
+ strategy.interval
5018
+ ].join(":");
5019
+ const group = groups.get(baseKey) ?? {
5020
+ scope: {
5021
+ connectorName,
5022
+ universe: strategy.universe,
5023
+ accountId: strategy.accountId,
5024
+ interval: strategy.interval
5025
+ },
5026
+ strategyIdentities: []
5027
+ };
5028
+ group.strategyIdentities.push(
5029
+ `${strategy.strategyName}@${strategy.releaseVersion}:${strategy.controlState}`
5030
+ );
5031
+ groups.set(baseKey, group);
5032
+ }
5033
+ return [...groups.entries()].map(([baseKey, group]) => ({
5034
+ key: [baseKey, deploymentIdentity, ...group.strategyIdentities.sort()].join(
5035
+ ":"
5036
+ ),
5037
+ scope: group.scope
5038
+ }));
5039
+ };
5040
+
4995
5041
  // src/lib/signals/runner.ts
4996
5042
  var SLOW_SIGNALS_WARNING_MS = 10 * 6e4;
4997
5043
  var formatDuration2 = (durationMs) => `${(durationMs / 1e3).toFixed(1)}s`;
@@ -5500,22 +5546,13 @@ var createSignalsRunner = (config2) => {
5500
5546
  const connectorName = await resolveSignalsConnectorName(
5501
5547
  deployment.connectorName
5502
5548
  );
5503
- const scopes = /* @__PURE__ */ new Map();
5504
- for (const strategy of configuredStrategies) {
5505
- const key = [
5506
- connectorName,
5507
- strategy.universe,
5508
- strategy.accountId ?? "default",
5509
- strategy.interval
5510
- ].join(":");
5511
- scopes.set(key, {
5549
+ return new Map(
5550
+ buildConfiguredSignalsScopes({
5512
5551
  connectorName,
5513
- universe: strategy.universe,
5514
- accountId: strategy.accountId,
5515
- interval: strategy.interval
5516
- });
5517
- }
5518
- return scopes;
5552
+ deployment,
5553
+ strategies: configuredStrategies
5554
+ }).map(({ key, scope }) => [key, scope])
5555
+ );
5519
5556
  };
5520
5557
  const signalsConfiguredScopesOnce2 = async () => {
5521
5558
  if (config2.updateOnly || config2.showTickersList) {
@@ -5556,12 +5593,13 @@ var createSignalsRunner = (config2) => {
5556
5593
  if (!config2.deploymentId) {
5557
5594
  throw new Error("Runtime deployment id is required");
5558
5595
  }
5559
- const daemonDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
5596
+ const deploymentId = config2.deploymentId;
5597
+ const initialDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
5560
5598
  config2.userName,
5561
- config2.deploymentId
5599
+ deploymentId
5562
5600
  );
5563
- if (!daemonDeployment) {
5564
- throw new Error(`Runtime deployment not found: ${config2.deploymentId}`);
5601
+ if (!initialDeployment) {
5602
+ throw new Error(`Runtime deployment not found: ${deploymentId}`);
5565
5603
  }
5566
5604
  const sessions = /* @__PURE__ */ new Map();
5567
5605
  const lastBoundaryByScope = /* @__PURE__ */ new Map();
@@ -5580,7 +5618,14 @@ var createSignalsRunner = (config2) => {
5580
5618
  settleDelayMs: resolveNonNegativeInteger(config2.settleDelayMs, 5e3),
5581
5619
  signal: abortController.signal,
5582
5620
  runCycle: async () => {
5583
- const scopes = await loadConfiguredSignalsScopes(daemonDeployment);
5621
+ const currentDeployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(
5622
+ config2.userName,
5623
+ deploymentId
5624
+ );
5625
+ if (!currentDeployment) {
5626
+ throw new Error(`Runtime deployment not found: ${deploymentId}`);
5627
+ }
5628
+ const scopes = await loadConfiguredSignalsScopes(currentDeployment);
5584
5629
  for (const [key, staleSession] of sessions) {
5585
5630
  if (scopes.has(key)) continue;
5586
5631
  await staleSession.klineFeed?.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/cli",
3
- "version": "3.1.6",
3
+ "version": "3.1.7",
4
4
  "description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -32,13 +32,13 @@
32
32
  "tradejs": "dist/cli.js"
33
33
  },
34
34
  "dependencies": {
35
- "@tradejs/connectors": "^3.1.6",
36
- "@tradejs/core": "^3.1.6",
37
- "@tradejs/indicators": "^3.1.6",
38
- "@tradejs/infra": "^3.1.6",
39
- "@tradejs/node": "^3.1.6",
35
+ "@tradejs/connectors": "^3.1.7",
36
+ "@tradejs/core": "^3.1.7",
37
+ "@tradejs/indicators": "^3.1.7",
38
+ "@tradejs/infra": "^3.1.7",
39
+ "@tradejs/node": "^3.1.7",
40
40
  "@tradejs/strategy-kit": "^3.0.0",
41
- "@tradejs/types": "^3.1.6",
41
+ "@tradejs/types": "^3.1.7",
42
42
  "args": "^5.0.3",
43
43
  "bcryptjs": "^2.4.3",
44
44
  "chalk": "4.1.2",