@tradejs/cli 3.0.1 → 3.1.1

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.
@@ -752,8 +752,113 @@ ${reactions}
752
752
  var import_node_crypto2 = require("crypto");
753
753
  var import_promises3 = __toESM(require("fs/promises"));
754
754
  var import_node_path3 = __toESM(require("path"));
755
- var import_types = require("@tradejs/types");
755
+ var import_types2 = require("@tradejs/types");
756
756
  var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
757
+
758
+ // src/lib/strategyRelease/liveDiagnosis.ts
759
+ var import_types = require("@tradejs/types");
760
+ var buildStrategyLiveDiagnosis = (input) => {
761
+ const minimumClosedTrades = input.minimumClosedTrades ?? 20;
762
+ const minimumParityRatio = input.minimumParityRatio ?? 0.95;
763
+ const maximumOrderFailureRate = input.maximumOrderFailureRate ?? 0.05;
764
+ const minimumRegimeCoverage = input.minimumRegimeCoverage ?? 0.5;
765
+ const hasExplicitRiskScale = input.riskScaleComparable != null;
766
+ const comparisonObservedDrawdown = hasExplicitRiskScale ? input.riskScaleComparable ? input.normalizedObservedDrawdown ?? null : null : input.observedDrawdown;
767
+ const runtimeDivergence = !input.lineageComparable || input.parityRatio != null && input.parityRatio < minimumParityRatio || input.orderFailureRate != null && input.orderFailureRate > maximumOrderFailureRate;
768
+ const insufficient = input.closedTrades < minimumClosedTrades || input.parityRatio == null || comparisonObservedDrawdown == null || input.historicalDrawdownP95 == null;
769
+ const expected = !runtimeDivergence && !insufficient && comparisonObservedDrawdown <= input.historicalDrawdownP95;
770
+ const verdict = runtimeDivergence ? "RUNTIME_DIVERGENCE" : insufficient ? "INSUFFICIENT_EVIDENCE" : expected ? "EXPECTED_DRAWDOWN" : "GENERALIZATION_FAILURE";
771
+ const attributionIncomplete = input.rawCoreExpectancyDelta == null || input.aiGateAddedValue == null || input.regimeCoverage == null;
772
+ const attributedVerdict = verdict === "GENERALIZATION_FAILURE" && attributionIncomplete ? "INSUFFICIENT_EVIDENCE" : verdict;
773
+ const subtype = attributedVerdict !== "GENERALIZATION_FAILURE" ? null : input.rawCoreExpectancyDelta < 0 && input.aiGateAddedValue >= 0 ? "RAW_CORE_DECAY" : input.aiGateAddedValue < 0 ? "AI_GATE_FAILURE" : input.regimeCoverage < minimumRegimeCoverage ? "REGIME_SHIFT" : (input.overfitProbability ?? 0) >= 0.5 ? "SUSPECTED_HISTORICAL_OVERFIT" : "RAW_CORE_DECAY";
774
+ const explanation = attributedVerdict === "RUNTIME_DIVERGENCE" ? "Runtime cannot be compared economically until lineage, replay parity, and order execution agree with the frozen composition." : attributedVerdict === "EXPECTED_DRAWDOWN" ? "The observed drawdown is within the preregistered equal-length historical drawdown envelope." : attributedVerdict === "GENERALIZATION_FAILURE" ? `Runtime is comparable, but the observed drawdown exceeds the historical envelope (${subtype}).` : attributionIncomplete && verdict === "GENERALIZATION_FAILURE" ? "The drawdown breaches its historical envelope, but matched shadow raw-core, deterministic-gate, or causal regime evidence is missing for attribution." : "There are not enough comparable closed trades and historical drawdown observations for attribution.";
775
+ const recommendations = attributedVerdict === "RUNTIME_DIVERGENCE" ? [
776
+ "Resolve lineage and replay parity mismatches before evaluating strategy economics.",
777
+ "Inspect order failures and execution residuals against the frozen execution model."
778
+ ] : attributedVerdict === "EXPECTED_DRAWDOWN" ? [
779
+ "Keep the frozen composition unchanged and continue prospective evidence collection."
780
+ ] : attributedVerdict === "GENERALIZATION_FAILURE" ? [
781
+ "Do not retune the live cohort; open a new immutable research lineage.",
782
+ "Compare raw-core decay, AI-gate added value, and causal regime coverage."
783
+ ] : [
784
+ attributionIncomplete && verdict === "GENERALIZATION_FAILURE" ? "Collect matched shadow raw-core, deterministic-gate, and causal regime evidence without changing the composition." : "Collect more verified prospective outcomes without changing the composition."
785
+ ];
786
+ return {
787
+ schema: import_types.STRATEGY_LIVE_DIAGNOSIS_SCHEMA,
788
+ strategy: input.strategy,
789
+ compositionId: input.compositionId,
790
+ createdAt: input.createdAt,
791
+ verdict: attributedVerdict,
792
+ subtype,
793
+ confidence: runtimeDivergence || input.closedTrades >= 50 ? "high" : input.closedTrades >= 20 ? "medium" : "low",
794
+ evidence: {
795
+ lineageComparable: input.lineageComparable,
796
+ riskScaleComparable: input.riskScaleComparable ?? false,
797
+ releaseMaxLossValue: input.releaseMaxLossValue ?? null,
798
+ runtimeMaxLossValue: input.runtimeMaxLossValue ?? null,
799
+ riskScaleRatio: input.riskScaleRatio ?? null,
800
+ parityRatio: input.parityRatio,
801
+ orderFailureRate: input.orderFailureRate,
802
+ observedDrawdown: input.observedDrawdown,
803
+ normalizedObservedDrawdown: input.normalizedObservedDrawdown ?? null,
804
+ historicalDrawdownP95: input.historicalDrawdownP95,
805
+ historicalDrawdownMaximum: input.historicalDrawdownMaximum,
806
+ closedTrades: input.closedTrades,
807
+ rawCoreExpectancyDelta: input.rawCoreExpectancyDelta,
808
+ aiGateAddedValue: input.aiGateAddedValue,
809
+ regimeCoverage: input.regimeCoverage,
810
+ overfitProbability: input.overfitProbability
811
+ },
812
+ explanation,
813
+ recommendations
814
+ };
815
+ };
816
+ var buildStrategyLiveDiagnosisFromScorecard = ({
817
+ manifest,
818
+ scorecard,
819
+ days
820
+ }) => {
821
+ const rolling = scorecard.rolling.find((entry) => entry.days === days);
822
+ const envelope = manifest.monitoring.drawdownEnvelopes.find(
823
+ (entry) => entry.days === days
824
+ );
825
+ const orderFailureRate = scorecard.funnel.orderAttempts ? scorecard.funnel.orderFailures / scorecard.funnel.orderAttempts : null;
826
+ const lineage = scorecard.lineage;
827
+ const lineageComparable = scorecard.parity.lineageReason == null && lineage?.complete === true && lineage.conflicts === false && lineage.compositionId === manifest.composition.compositionId && lineage.gitDirty === false && lineage.gitSha === manifest.composition.gitSha && lineage.configFingerprint === manifest.composition.runtimeConfigFingerprint && lineage.gateFingerprint === manifest.composition.gateFingerprint && lineage.contextFingerprint === manifest.composition.runtimeContextFingerprint;
828
+ const releaseMaxLossValue = manifest.composition.maxLossValue;
829
+ const runtimeMaxLossValue = lineage?.maxLossValue ?? null;
830
+ const riskScaleComparable = Number.isFinite(releaseMaxLossValue) && releaseMaxLossValue > 0 && runtimeMaxLossValue != null && Number.isFinite(runtimeMaxLossValue) && runtimeMaxLossValue > 0;
831
+ const riskScaleRatio = riskScaleComparable ? runtimeMaxLossValue / releaseMaxLossValue : null;
832
+ const normalizedObservedDrawdown = rolling != null && riskScaleRatio != null ? rolling.maxDrawdown / riskScaleRatio : null;
833
+ const normalizeRuntimeEconomics = (value) => value != null && riskScaleRatio != null ? value / riskScaleRatio : null;
834
+ return buildStrategyLiveDiagnosis({
835
+ strategy: manifest.strategy,
836
+ compositionId: manifest.composition.compositionId,
837
+ createdAt: scorecard.generatedAt,
838
+ lineageComparable,
839
+ riskScaleComparable,
840
+ releaseMaxLossValue,
841
+ runtimeMaxLossValue,
842
+ riskScaleRatio,
843
+ parityRatio: scorecard.parity.ratio,
844
+ orderFailureRate,
845
+ observedDrawdown: rolling?.maxDrawdown ?? null,
846
+ normalizedObservedDrawdown,
847
+ historicalDrawdownP95: envelope?.p95 ?? null,
848
+ historicalDrawdownMaximum: envelope?.maximum ?? null,
849
+ closedTrades: rolling?.closedTrades ?? 0,
850
+ rawCoreExpectancyDelta: scorecard.prospective?.rawCoreExpectancy != null && manifest.monitoring.rawCoreExpectancy != null ? normalizeRuntimeEconomics(scorecard.prospective.rawCoreExpectancy) - manifest.monitoring.rawCoreExpectancy : null,
851
+ aiGateAddedValue: scorecard.prospective?.rawCoreExpectancy != null && scorecard.prospective.aiGateExpectancy != null ? normalizeRuntimeEconomics(scorecard.prospective.aiGateExpectancy) - normalizeRuntimeEconomics(scorecard.prospective.rawCoreExpectancy) : null,
852
+ regimeCoverage: scorecard.prospective?.regimeCoverage ?? null,
853
+ overfitProbability: manifest.monitoring.overfitProbability,
854
+ minimumClosedTrades: manifest.monitoring.minimumProspectiveClosedTrades,
855
+ minimumParityRatio: manifest.monitoring.minimumParityRatio,
856
+ maximumOrderFailureRate: manifest.monitoring.maximumOrderFailureRate,
857
+ minimumRegimeCoverage: manifest.monitoring.minimumRegimeCoverage
858
+ });
859
+ };
860
+
861
+ // src/lib/strategyRelease.ts
757
862
  var SHA256_RE = /^[a-f0-9]{64}$/;
758
863
  var LINEAGE_FINGERPRINT_RE = /^[a-f0-9]{16}$/;
759
864
  var safeSegment2 = import_strategyReleaseEvidence.safeStrategyEvidenceSegment;
@@ -1128,7 +1233,7 @@ var createStrategyReleaseManifest = (input) => {
1128
1233
  verdict
1129
1234
  };
1130
1235
  return {
1131
- schema: import_types.STRATEGY_RELEASE_SCHEMA,
1236
+ schema: import_types2.STRATEGY_RELEASE_SCHEMA,
1132
1237
  releaseId: `${safeSegment2(input.strategy, "strategy")}_${compactTimestamp(input.createdAt)}_${strategyReleaseSha256(releaseIdentity).slice(0, 16)}`,
1133
1238
  strategy: input.strategy,
1134
1239
  createdAt: input.createdAt,
@@ -1163,7 +1268,7 @@ var verifyStrategyReleaseEnvelope = async (valueOrPath) => {
1163
1268
  );
1164
1269
  const manifest = envelope.manifest;
1165
1270
  assert(
1166
- manifest.schema === import_types.STRATEGY_RELEASE_SCHEMA,
1271
+ manifest.schema === import_types2.STRATEGY_RELEASE_SCHEMA,
1167
1272
  "manifest schema mismatch"
1168
1273
  );
1169
1274
  const rebuilt = createStrategyReleaseManifest({
@@ -1212,106 +1317,6 @@ var writeJsonAtomic = async (filePath, value) => {
1212
1317
  );
1213
1318
  await import_promises3.default.rename(temporaryPath, filePath);
1214
1319
  };
1215
- var buildStrategyLiveDiagnosis = (input) => {
1216
- const minimumClosedTrades = input.minimumClosedTrades ?? 20;
1217
- const minimumParityRatio = input.minimumParityRatio ?? 0.95;
1218
- const maximumOrderFailureRate = input.maximumOrderFailureRate ?? 0.05;
1219
- const minimumRegimeCoverage = input.minimumRegimeCoverage ?? 0.5;
1220
- const hasExplicitRiskScale = input.riskScaleComparable != null;
1221
- const comparisonObservedDrawdown = hasExplicitRiskScale ? input.riskScaleComparable ? input.normalizedObservedDrawdown ?? null : null : input.observedDrawdown;
1222
- const runtimeDivergence = !input.lineageComparable || input.parityRatio != null && input.parityRatio < minimumParityRatio || input.orderFailureRate != null && input.orderFailureRate > maximumOrderFailureRate;
1223
- const insufficient = input.closedTrades < minimumClosedTrades || input.parityRatio == null || comparisonObservedDrawdown == null || input.historicalDrawdownP95 == null;
1224
- const expected = !runtimeDivergence && !insufficient && comparisonObservedDrawdown <= input.historicalDrawdownP95;
1225
- const verdict = runtimeDivergence ? "RUNTIME_DIVERGENCE" : insufficient ? "INSUFFICIENT_EVIDENCE" : expected ? "EXPECTED_DRAWDOWN" : "GENERALIZATION_FAILURE";
1226
- const attributionIncomplete = input.rawCoreExpectancyDelta == null || input.aiGateAddedValue == null || input.regimeCoverage == null;
1227
- const attributedVerdict = verdict === "GENERALIZATION_FAILURE" && attributionIncomplete ? "INSUFFICIENT_EVIDENCE" : verdict;
1228
- const subtype = attributedVerdict !== "GENERALIZATION_FAILURE" ? null : input.rawCoreExpectancyDelta < 0 && input.aiGateAddedValue >= 0 ? "RAW_CORE_DECAY" : input.aiGateAddedValue < 0 ? "AI_GATE_FAILURE" : input.regimeCoverage < minimumRegimeCoverage ? "REGIME_SHIFT" : (input.overfitProbability ?? 0) >= 0.5 ? "SUSPECTED_HISTORICAL_OVERFIT" : "RAW_CORE_DECAY";
1229
- const explanation = attributedVerdict === "RUNTIME_DIVERGENCE" ? "Runtime cannot be compared economically until lineage, replay parity, and order execution agree with the frozen composition." : attributedVerdict === "EXPECTED_DRAWDOWN" ? "The observed drawdown is within the preregistered equal-length historical drawdown envelope." : attributedVerdict === "GENERALIZATION_FAILURE" ? `Runtime is comparable, but the observed drawdown exceeds the historical envelope (${subtype}).` : attributionIncomplete && verdict === "GENERALIZATION_FAILURE" ? "The drawdown breaches its historical envelope, but matched shadow raw-core, deterministic-gate, or causal regime evidence is missing for attribution." : "There are not enough comparable closed trades and historical drawdown observations for attribution.";
1230
- const recommendations = attributedVerdict === "RUNTIME_DIVERGENCE" ? [
1231
- "Resolve lineage and replay parity mismatches before evaluating strategy economics.",
1232
- "Inspect order failures and execution residuals against the frozen execution model."
1233
- ] : attributedVerdict === "EXPECTED_DRAWDOWN" ? [
1234
- "Keep the frozen composition unchanged and continue prospective evidence collection."
1235
- ] : attributedVerdict === "GENERALIZATION_FAILURE" ? [
1236
- "Do not retune the live cohort; open a new immutable research lineage.",
1237
- "Compare raw-core decay, AI-gate added value, and causal regime coverage."
1238
- ] : [
1239
- attributionIncomplete && verdict === "GENERALIZATION_FAILURE" ? "Collect matched shadow raw-core, deterministic-gate, and causal regime evidence without changing the composition." : "Collect more verified prospective outcomes without changing the composition."
1240
- ];
1241
- return {
1242
- schema: import_types.STRATEGY_LIVE_DIAGNOSIS_SCHEMA,
1243
- strategy: input.strategy,
1244
- compositionId: input.compositionId,
1245
- createdAt: input.createdAt,
1246
- verdict: attributedVerdict,
1247
- subtype,
1248
- confidence: runtimeDivergence || input.closedTrades >= 50 ? "high" : input.closedTrades >= 20 ? "medium" : "low",
1249
- evidence: {
1250
- lineageComparable: input.lineageComparable,
1251
- riskScaleComparable: input.riskScaleComparable ?? false,
1252
- releaseMaxLossValue: input.releaseMaxLossValue ?? null,
1253
- runtimeMaxLossValue: input.runtimeMaxLossValue ?? null,
1254
- riskScaleRatio: input.riskScaleRatio ?? null,
1255
- parityRatio: input.parityRatio,
1256
- orderFailureRate: input.orderFailureRate,
1257
- observedDrawdown: input.observedDrawdown,
1258
- normalizedObservedDrawdown: input.normalizedObservedDrawdown ?? null,
1259
- historicalDrawdownP95: input.historicalDrawdownP95,
1260
- historicalDrawdownMaximum: input.historicalDrawdownMaximum,
1261
- closedTrades: input.closedTrades,
1262
- rawCoreExpectancyDelta: input.rawCoreExpectancyDelta,
1263
- aiGateAddedValue: input.aiGateAddedValue,
1264
- regimeCoverage: input.regimeCoverage,
1265
- overfitProbability: input.overfitProbability
1266
- },
1267
- explanation,
1268
- recommendations
1269
- };
1270
- };
1271
- var buildStrategyLiveDiagnosisFromScorecard = ({
1272
- manifest,
1273
- scorecard,
1274
- days
1275
- }) => {
1276
- const rolling = scorecard.rolling.find((entry) => entry.days === days);
1277
- const envelope = manifest.monitoring.drawdownEnvelopes.find(
1278
- (entry) => entry.days === days
1279
- );
1280
- const orderFailureRate = scorecard.funnel.orderAttempts ? scorecard.funnel.orderFailures / scorecard.funnel.orderAttempts : null;
1281
- const lineage = scorecard.lineage;
1282
- const lineageComparable = scorecard.parity.lineageReason == null && lineage?.complete === true && lineage.conflicts === false && lineage.compositionId === manifest.composition.compositionId && lineage.gitDirty === false && lineage.gitSha === manifest.composition.gitSha && lineage.configFingerprint === manifest.composition.runtimeConfigFingerprint && lineage.gateFingerprint === manifest.composition.gateFingerprint && lineage.contextFingerprint === manifest.composition.runtimeContextFingerprint;
1283
- const releaseMaxLossValue = manifest.composition.maxLossValue;
1284
- const runtimeMaxLossValue = lineage?.maxLossValue ?? null;
1285
- const riskScaleComparable = Number.isFinite(releaseMaxLossValue) && releaseMaxLossValue > 0 && runtimeMaxLossValue != null && Number.isFinite(runtimeMaxLossValue) && runtimeMaxLossValue > 0;
1286
- const riskScaleRatio = riskScaleComparable ? runtimeMaxLossValue / releaseMaxLossValue : null;
1287
- const normalizedObservedDrawdown = rolling != null && riskScaleRatio != null ? rolling.maxDrawdown / riskScaleRatio : null;
1288
- const normalizeRuntimeEconomics = (value) => value != null && riskScaleRatio != null ? value / riskScaleRatio : null;
1289
- return buildStrategyLiveDiagnosis({
1290
- strategy: manifest.strategy,
1291
- compositionId: manifest.composition.compositionId,
1292
- createdAt: scorecard.generatedAt,
1293
- lineageComparable,
1294
- riskScaleComparable,
1295
- releaseMaxLossValue,
1296
- runtimeMaxLossValue,
1297
- riskScaleRatio,
1298
- parityRatio: scorecard.parity.ratio,
1299
- orderFailureRate,
1300
- observedDrawdown: rolling?.maxDrawdown ?? null,
1301
- normalizedObservedDrawdown,
1302
- historicalDrawdownP95: envelope?.p95 ?? null,
1303
- historicalDrawdownMaximum: envelope?.maximum ?? null,
1304
- closedTrades: rolling?.closedTrades ?? 0,
1305
- rawCoreExpectancyDelta: scorecard.prospective?.rawCoreExpectancy != null && manifest.monitoring.rawCoreExpectancy != null ? normalizeRuntimeEconomics(scorecard.prospective.rawCoreExpectancy) - manifest.monitoring.rawCoreExpectancy : null,
1306
- aiGateAddedValue: scorecard.prospective?.rawCoreExpectancy != null && scorecard.prospective.aiGateExpectancy != null ? normalizeRuntimeEconomics(scorecard.prospective.aiGateExpectancy) - normalizeRuntimeEconomics(scorecard.prospective.rawCoreExpectancy) : null,
1307
- regimeCoverage: scorecard.prospective?.regimeCoverage ?? null,
1308
- overfitProbability: manifest.monitoring.overfitProbability,
1309
- minimumClosedTrades: manifest.monitoring.minimumProspectiveClosedTrades,
1310
- minimumParityRatio: manifest.monitoring.minimumParityRatio,
1311
- maximumOrderFailureRate: manifest.monitoring.maximumOrderFailureRate,
1312
- minimumRegimeCoverage: manifest.monitoring.minimumRegimeCoverage
1313
- });
1314
- };
1315
1320
  var publishStrategyLiveDiagnosis = async ({
1316
1321
  rootDir,
1317
1322
  diagnosis,