@tradejs/cli 3.1.29-beta.286 → 3.1.29-beta.288

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.
@@ -2369,6 +2369,10 @@ var validateStrategyResearchSpec = (value) => {
2369
2369
  };
2370
2370
  if (!spec.budget || !spec.selection || !spec.diagnostics)
2371
2371
  throw new Error("Missing research budgets or criteria");
2372
+ if (spec.featurePaths !== void 0 && (!Array.isArray(spec.featurePaths) || !spec.featurePaths.length || spec.featurePaths.length > 64 || new Set(spec.featurePaths).size !== spec.featurePaths.length || spec.featurePaths.some(
2373
+ (path17) => typeof path17 !== "string" || !/^additionalIndicators\.[a-zA-Z0-9_.]+$/.test(path17) || classifyAiPocketFeaturePath(path17.split(".")) !== "eligible"
2374
+ )))
2375
+ throw new Error("Feature paths must be unique causal market features");
2372
2376
  positive(spec.budget.maxVariants, "maxVariants", 12);
2373
2377
  if (!Number.isInteger(spec.minQuality) || spec.minQuality < 1 || spec.minQuality > 5)
2374
2378
  throw new Error("minQuality must be 1 through 5");
@@ -4397,6 +4401,7 @@ var runStrategyResearch = async (parameters) => {
4397
4401
  parentSpec.selection,
4398
4402
  parentSpec.portfolio,
4399
4403
  parentSpec.minQuality,
4404
+ parentSpec.featurePaths,
4400
4405
  parentSpec.diagnostics
4401
4406
  ]) !== sha256Json([
4402
4407
  spec.core.variants.map((item) => item.resolvedConfig),
@@ -4405,6 +4410,7 @@ var runStrategyResearch = async (parameters) => {
4405
4410
  spec.selection,
4406
4411
  spec.portfolio,
4407
4412
  spec.minQuality,
4413
+ spec.featurePaths,
4408
4414
  spec.diagnostics
4409
4415
  ]) || parentState.lineage.runtimeSha256 !== state.lineage.runtimeSha256 || parentState.lineage.contextEnvironmentSha256 !== state.lineage.contextEnvironmentSha256)
4410
4416
  throw new Error(
@@ -5784,9 +5790,10 @@ var createNativeStrategyResearchBackend = (parameters) => {
5784
5790
  throw new Error(
5785
5791
  "Tester workers are already active; research will resume when the host is free"
5786
5792
  );
5787
- if (import_node_os2.default.freemem() < spec.budget.minimumFreeMemoryMb * 1024 * 1024)
5793
+ const availableBytes = import_node_os2.default.platform() === "darwin" ? process.availableMemory() : import_node_os2.default.freemem();
5794
+ if (!Number.isFinite(availableBytes) || availableBytes < spec.budget.minimumFreeMemoryMb * 1024 * 1024)
5788
5795
  throw new Error(
5789
- "Insufficient free host memory for the frozen research budget"
5796
+ "Insufficient available host memory for the frozen research budget"
5790
5797
  );
5791
5798
  };
5792
5799
  return {
@@ -6239,9 +6246,14 @@ var createNativeStrategyResearchBackend = (parameters) => {
6239
6246
  throw new Error(
6240
6247
  `Native/export reconciliation is ${reconciliation.status}: ${reconciliation.reasons.join("; ")}`
6241
6248
  );
6249
+ const researchSignalId = (symbol, signalId) => JSON.stringify([symbol, signalId]);
6242
6250
  const trades = loaded.trades.filter(
6243
6251
  (trade) => trade.signalTimestamp >= spec.core.window.start && trade.signalTimestamp < spec.core.window.end && trade.exitTimestamp < spec.core.window.end
6244
- );
6252
+ ).map((trade) => ({
6253
+ ...trade,
6254
+ // Strategy-generated signal IDs need not be unique across symbols.
6255
+ signalId: researchSignalId(trade.symbol, trade.signalId)
6256
+ }));
6245
6257
  const tradeBySignal = new Map(
6246
6258
  trades.map((trade) => [trade.signalId, trade])
6247
6259
  );
@@ -6265,9 +6277,10 @@ var createNativeStrategyResearchBackend = (parameters) => {
6265
6277
  for await (const line of lines) {
6266
6278
  if (!line.trim()) continue;
6267
6279
  const row = JSON.parse(line);
6268
- const trade = tradeBySignal.get(row.signalId);
6269
- if (!trade || seen.has(row.signalId)) continue;
6270
- seen.add(row.signalId);
6280
+ const signalId = researchSignalId(row.symbol, row.signalId);
6281
+ const trade = tradeBySignal.get(signalId);
6282
+ if (!trade || seen.has(signalId)) continue;
6283
+ seen.add(signalId);
6271
6284
  if (discoveryOnly && (row.timestamp >= spec.testSince || trade.exitTimestamp >= spec.testSince)) {
6272
6285
  if (row.timestamp < spec.testSince) purgedLabels++;
6273
6286
  continue;
@@ -6305,7 +6318,7 @@ var createNativeStrategyResearchBackend = (parameters) => {
6305
6318
  featureProfile: "all"
6306
6319
  });
6307
6320
  for (const key of Object.keys(features))
6308
- if (!key.startsWith("additionalIndicators.") || features[key] == null)
6321
+ if (!key.startsWith("additionalIndicators.") || features[key] == null || spec.featurePaths && !spec.featurePaths.includes(key))
6309
6322
  delete features[key];
6310
6323
  featureValues += Object.keys(features).length;
6311
6324
  if (featureValues > 5e6)
@@ -6324,7 +6337,7 @@ var createNativeStrategyResearchBackend = (parameters) => {
6324
6337
  pathCoverage[key]++;
6325
6338
  }
6326
6339
  rows.push({
6327
- signalId: row.signalId,
6340
+ signalId,
6328
6341
  symbol: row.symbol,
6329
6342
  strategy: row.strategyName,
6330
6343
  timestamp: row.timestamp,
@@ -6339,7 +6352,7 @@ var createNativeStrategyResearchBackend = (parameters) => {
6339
6352
  });
6340
6353
  if (discoveryOnly) {
6341
6354
  eventInputs.push({
6342
- signalId: row.signalId,
6355
+ signalId,
6343
6356
  timestamp: row.timestamp,
6344
6357
  symbol: row.symbol,
6345
6358
  direction: row.direction,
@@ -6350,8 +6363,8 @@ var createNativeStrategyResearchBackend = (parameters) => {
6350
6363
  });
6351
6364
  const key = `${row.direction}:${trade.netProfit > 0}`;
6352
6365
  const bucket = sampleBuckets.get(key) ?? [];
6353
- bucket.push(row.signalId);
6354
- sampleInputs.set(row.signalId, row);
6366
+ bucket.push(signalId);
6367
+ sampleInputs.set(signalId, row);
6355
6368
  bucket.sort((a, b) => sha256Json(a).localeCompare(sha256Json(b)));
6356
6369
  while (bucket.length > spec.diagnostics.samplePerSideAndOutcome)
6357
6370
  sampleInputs.delete(bucket.pop());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/cli",
3
- "version": "3.1.29-beta.286",
3
+ "version": "3.1.29-beta.288",
4
4
  "description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -37,13 +37,13 @@
37
37
  "tradejs": "dist/cli.js"
38
38
  },
39
39
  "dependencies": {
40
- "@tradejs/connectors": "^3.1.29-beta.286",
41
- "@tradejs/core": "^3.1.29-beta.286",
42
- "@tradejs/indicators": "^3.1.29-beta.286",
43
- "@tradejs/infra": "^3.1.29-beta.286",
44
- "@tradejs/node": "^3.1.29-beta.286",
40
+ "@tradejs/connectors": "^3.1.29-beta.288",
41
+ "@tradejs/core": "^3.1.29-beta.288",
42
+ "@tradejs/indicators": "^3.1.29-beta.288",
43
+ "@tradejs/infra": "^3.1.29-beta.288",
44
+ "@tradejs/node": "^3.1.29-beta.288",
45
45
  "@tradejs/strategy-kit": "3.0.6",
46
- "@tradejs/types": "^3.1.29-beta.286",
46
+ "@tradejs/types": "^3.1.29-beta.288",
47
47
  "args": "^5.0.3",
48
48
  "bcryptjs": "^2.4.3",
49
49
  "chalk": "4.1.2",