@tradejs/cli 3.1.27-beta.245 → 3.1.27-beta.247
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 +211 -19
- package/dist/lib/runtimeParityDetails.js +57 -2
- package/dist/scripts/replay.js +189 -16
- package/dist/scripts/replayRunner.js +189 -16
- package/dist/scripts/replayRuntimeEvidence.js +13 -1
- package/package.json +7 -7
|
@@ -40,7 +40,7 @@ __export(replayRunner_exports, {
|
|
|
40
40
|
module.exports = __toCommonJS(replayRunner_exports);
|
|
41
41
|
var import_chalk13 = __toESM(require("chalk"));
|
|
42
42
|
var import_constants6 = require("@tradejs/core/constants");
|
|
43
|
-
var
|
|
43
|
+
var import_data4 = require("@tradejs/core/data");
|
|
44
44
|
var import_time7 = require("@tradejs/core/time");
|
|
45
45
|
var import_redis6 = require("@tradejs/infra/redis");
|
|
46
46
|
|
|
@@ -5614,6 +5614,78 @@ var prepareHistoricalReplay = async (context, adapters) => {
|
|
|
5614
5614
|
};
|
|
5615
5615
|
};
|
|
5616
5616
|
|
|
5617
|
+
// src/lib/replay/historicalSignalsReplaySkipEvidence.ts
|
|
5618
|
+
var import_data = require("@tradejs/core/data");
|
|
5619
|
+
var replayScopeKey = (strategy, symbol) => `${strategy}::${symbol}`;
|
|
5620
|
+
var appendReplaySignalEvaluationRun = ({
|
|
5621
|
+
runs = [],
|
|
5622
|
+
reason,
|
|
5623
|
+
timestamp,
|
|
5624
|
+
interval
|
|
5625
|
+
}) => {
|
|
5626
|
+
const stepMs = (0, import_data.intervalToMs)(interval);
|
|
5627
|
+
const last = runs.at(-1);
|
|
5628
|
+
if (last?.reason === reason && last.stepMs === stepMs && timestamp === last.lastTimestamp + stepMs) {
|
|
5629
|
+
return [...runs.slice(0, -1), { ...last, lastTimestamp: timestamp }];
|
|
5630
|
+
}
|
|
5631
|
+
return [
|
|
5632
|
+
...runs,
|
|
5633
|
+
{
|
|
5634
|
+
status: "skip",
|
|
5635
|
+
reason,
|
|
5636
|
+
firstTimestamp: timestamp,
|
|
5637
|
+
lastTimestamp: timestamp,
|
|
5638
|
+
stepMs
|
|
5639
|
+
}
|
|
5640
|
+
];
|
|
5641
|
+
};
|
|
5642
|
+
var createHistoricalReplaySkipEvidence = (runtimeLineages) => {
|
|
5643
|
+
const lineageByStrategySymbol = new Map(
|
|
5644
|
+
runtimeLineages.map((record2) => [
|
|
5645
|
+
replayScopeKey(record2.strategy, record2.symbol),
|
|
5646
|
+
record2
|
|
5647
|
+
])
|
|
5648
|
+
);
|
|
5649
|
+
const scopes = /* @__PURE__ */ new Map();
|
|
5650
|
+
const record = ({
|
|
5651
|
+
strategyName,
|
|
5652
|
+
symbol,
|
|
5653
|
+
strategyConfig,
|
|
5654
|
+
runtimeLineage,
|
|
5655
|
+
timestamp,
|
|
5656
|
+
result
|
|
5657
|
+
}) => {
|
|
5658
|
+
const scopeKey = replayScopeKey(strategyName, symbol);
|
|
5659
|
+
const lineageRecord = lineageByStrategySymbol.get(scopeKey);
|
|
5660
|
+
if (!lineageRecord) return;
|
|
5661
|
+
const existing = scopes.get(scopeKey);
|
|
5662
|
+
const skipReason = typeof result === "string" ? result.trim() || "NO_SIGNAL" : result ? null : "NO_SIGNAL";
|
|
5663
|
+
scopes.set(scopeKey, {
|
|
5664
|
+
strategy: strategyName,
|
|
5665
|
+
symbol,
|
|
5666
|
+
...lineageRecord.deploymentId ? { deploymentId: lineageRecord.deploymentId } : {},
|
|
5667
|
+
...lineageRecord.accountId ? { accountId: lineageRecord.accountId } : {},
|
|
5668
|
+
strategyRevision: runtimeLineage.strategyRevision,
|
|
5669
|
+
lineage: runtimeLineage,
|
|
5670
|
+
firstTimestamp: Math.min(
|
|
5671
|
+
existing?.firstTimestamp ?? timestamp,
|
|
5672
|
+
timestamp
|
|
5673
|
+
),
|
|
5674
|
+
lastTimestamp: Math.max(existing?.lastTimestamp ?? timestamp, timestamp),
|
|
5675
|
+
evaluationRuns: skipReason ? appendReplaySignalEvaluationRun({
|
|
5676
|
+
runs: existing?.evaluationRuns,
|
|
5677
|
+
reason: skipReason,
|
|
5678
|
+
timestamp,
|
|
5679
|
+
interval: strategyConfig.INTERVAL ?? "15"
|
|
5680
|
+
}) : existing?.evaluationRuns
|
|
5681
|
+
});
|
|
5682
|
+
};
|
|
5683
|
+
const values = () => [...scopes.values()].sort(
|
|
5684
|
+
(left, right) => left.strategy.localeCompare(right.strategy) || left.symbol.localeCompare(right.symbol)
|
|
5685
|
+
);
|
|
5686
|
+
return { record, values };
|
|
5687
|
+
};
|
|
5688
|
+
|
|
5617
5689
|
// src/lib/replay/historicalSignalsReplayExecution.ts
|
|
5618
5690
|
var advanceCycleMarket = async (plan, connector, timestamp) => {
|
|
5619
5691
|
const cycleSymbols = plan.cycleSymbolsByTimestamp.get(timestamp) ?? [];
|
|
@@ -5639,6 +5711,9 @@ var advanceAbortedCycle = (cycleSymbols, timestamp) => {
|
|
|
5639
5711
|
var executeHistoricalReplay = async (context, adapters) => {
|
|
5640
5712
|
const signals = [];
|
|
5641
5713
|
let abortedCycles = 0;
|
|
5714
|
+
const skipEvidence = createHistoricalReplaySkipEvidence(
|
|
5715
|
+
context.plan.runtimeLineages
|
|
5716
|
+
);
|
|
5642
5717
|
try {
|
|
5643
5718
|
for (const timestamp of context.plan.orderedTimestamps) {
|
|
5644
5719
|
const cycleStartedAt = adapters.clock.now();
|
|
@@ -5681,6 +5756,14 @@ var executeHistoricalReplay = async (context, adapters) => {
|
|
|
5681
5756
|
btcCandle,
|
|
5682
5757
|
ethCandle?.timestamp === timestamp ? ethCandle : void 0
|
|
5683
5758
|
);
|
|
5759
|
+
skipEvidence.record({
|
|
5760
|
+
strategyName: strategyRuntime.strategyName,
|
|
5761
|
+
symbol: symbolRuntime.symbol,
|
|
5762
|
+
strategyConfig: strategyRuntime.strategyConfig,
|
|
5763
|
+
runtimeLineage: strategyRuntime.runtimeLineage,
|
|
5764
|
+
timestamp,
|
|
5765
|
+
result
|
|
5766
|
+
});
|
|
5684
5767
|
if (result && typeof result !== "string") {
|
|
5685
5768
|
result.runtimeLineage = strategyRuntime.runtimeLineage;
|
|
5686
5769
|
await adapters.enrichSignal(result);
|
|
@@ -5708,7 +5791,11 @@ var executeHistoricalReplay = async (context, adapters) => {
|
|
|
5708
5791
|
adapters.releaseReplayCache(keyPrefix);
|
|
5709
5792
|
}
|
|
5710
5793
|
}
|
|
5711
|
-
return {
|
|
5794
|
+
return {
|
|
5795
|
+
signals,
|
|
5796
|
+
abortedCycles,
|
|
5797
|
+
replayLineageScopes: skipEvidence.values()
|
|
5798
|
+
};
|
|
5712
5799
|
};
|
|
5713
5800
|
|
|
5714
5801
|
// src/lib/replay/historicalSignalsReplayResults.ts
|
|
@@ -5737,7 +5824,8 @@ var collectHistoricalReplayResult = (context) => ({
|
|
|
5737
5824
|
positionLog: context.artifacts.positionLog,
|
|
5738
5825
|
cycleCount: context.cycleCount,
|
|
5739
5826
|
abortedCycles: context.abortedCycles,
|
|
5740
|
-
runtimeLineages: context.runtimeLineages
|
|
5827
|
+
runtimeLineages: context.runtimeLineages,
|
|
5828
|
+
replayLineageScopes: context.replayLineageScopes
|
|
5741
5829
|
});
|
|
5742
5830
|
|
|
5743
5831
|
// src/lib/replay/historicalSignalsReplay.ts
|
|
@@ -5956,7 +6044,8 @@ var runHistoricalSignalsReplay = async ({
|
|
|
5956
6044
|
signals: execution.signals,
|
|
5957
6045
|
cycleCount: plan.orderedTimestamps.length,
|
|
5958
6046
|
abortedCycles: execution.abortedCycles,
|
|
5959
|
-
runtimeLineages: plan.runtimeLineages
|
|
6047
|
+
runtimeLineages: plan.runtimeLineages,
|
|
6048
|
+
replayLineageScopes: execution.replayLineageScopes
|
|
5960
6049
|
});
|
|
5961
6050
|
};
|
|
5962
6051
|
|
|
@@ -6443,7 +6532,7 @@ var import_redis4 = require("@tradejs/infra/redis");
|
|
|
6443
6532
|
|
|
6444
6533
|
// src/lib/runtimeSignalsStorage.ts
|
|
6445
6534
|
var import_constants4 = require("@tradejs/core/constants");
|
|
6446
|
-
var
|
|
6535
|
+
var import_data2 = require("@tradejs/core/data");
|
|
6447
6536
|
var import_time4 = require("@tradejs/core/time");
|
|
6448
6537
|
var isRuntimeSignalBucketRef = (value) => {
|
|
6449
6538
|
if (!value || typeof value !== "object") {
|
|
@@ -7026,6 +7115,46 @@ var findNearestRuntimeEvaluationOutcome = ({
|
|
|
7026
7115
|
}
|
|
7027
7116
|
return nearest;
|
|
7028
7117
|
};
|
|
7118
|
+
var findNearestReplayEvaluationOutcome = ({
|
|
7119
|
+
entry,
|
|
7120
|
+
lineageScopes,
|
|
7121
|
+
toleranceMs,
|
|
7122
|
+
timestampOffsetMs
|
|
7123
|
+
}) => {
|
|
7124
|
+
const strategy = getEntryStrategy(entry);
|
|
7125
|
+
if (!strategy) return null;
|
|
7126
|
+
let nearest = null;
|
|
7127
|
+
for (const scope of lineageScopes) {
|
|
7128
|
+
if (scope.strategy !== strategy || scope.symbol !== entry.symbol) {
|
|
7129
|
+
continue;
|
|
7130
|
+
}
|
|
7131
|
+
for (const run of scope.evaluationRuns ?? []) {
|
|
7132
|
+
if (run.stepMs <= 0) continue;
|
|
7133
|
+
const targetTimestamp = entry.timestamp - timestampOffsetMs;
|
|
7134
|
+
if (targetTimestamp < run.firstTimestamp - toleranceMs || targetTimestamp > run.lastTimestamp + toleranceMs) {
|
|
7135
|
+
continue;
|
|
7136
|
+
}
|
|
7137
|
+
const step = Math.round(
|
|
7138
|
+
(targetTimestamp - run.firstTimestamp) / run.stepMs
|
|
7139
|
+
);
|
|
7140
|
+
const candidateTimestamp = run.firstTimestamp + step * run.stepMs;
|
|
7141
|
+
const timestampDiffMs = Math.abs(
|
|
7142
|
+
candidateTimestamp + timestampOffsetMs - entry.timestamp
|
|
7143
|
+
);
|
|
7144
|
+
if (candidateTimestamp < run.firstTimestamp || candidateTimestamp > run.lastTimestamp || timestampDiffMs > toleranceMs || nearest && timestampDiffMs >= nearest.timestampDiffMs) {
|
|
7145
|
+
continue;
|
|
7146
|
+
}
|
|
7147
|
+
nearest = {
|
|
7148
|
+
status: run.status,
|
|
7149
|
+
reason: run.reason,
|
|
7150
|
+
timestamp: candidateTimestamp,
|
|
7151
|
+
timestampDiffMs,
|
|
7152
|
+
source: "replay_scope_compact"
|
|
7153
|
+
};
|
|
7154
|
+
}
|
|
7155
|
+
}
|
|
7156
|
+
return nearest;
|
|
7157
|
+
};
|
|
7029
7158
|
var hasRuntimeLineageCoverage = ({
|
|
7030
7159
|
entry,
|
|
7031
7160
|
lineageScopes
|
|
@@ -7280,6 +7409,7 @@ var buildReplayMismatchDrilldown = ({
|
|
|
7280
7409
|
runtimeSignalEvaluations = [],
|
|
7281
7410
|
replaySignals = [],
|
|
7282
7411
|
replaySignalEvaluations = [],
|
|
7412
|
+
replayLineageScopes = [],
|
|
7283
7413
|
runtimeLineageScopes = [],
|
|
7284
7414
|
toleranceMs,
|
|
7285
7415
|
backtestTimestampOffsetMs,
|
|
@@ -7306,7 +7436,16 @@ var buildReplayMismatchDrilldown = ({
|
|
|
7306
7436
|
toleranceMs,
|
|
7307
7437
|
timestampOffsetMs: backtestTimestampOffsetMs
|
|
7308
7438
|
});
|
|
7309
|
-
const
|
|
7439
|
+
const nearestReplayEvaluationOutcome = findNearestReplayEvaluationOutcome({
|
|
7440
|
+
entry,
|
|
7441
|
+
lineageScopes: replayLineageScopes,
|
|
7442
|
+
toleranceMs,
|
|
7443
|
+
timestampOffsetMs: backtestTimestampOffsetMs
|
|
7444
|
+
});
|
|
7445
|
+
const classification = nearestReplaySignal ? classifySignalDiagnostic(nearestReplaySignal.signal) : nearestReplayEvaluation ? classifyEvaluationDiagnostic(nearestReplayEvaluation.evaluation) : nearestReplayEvaluationOutcome ? {
|
|
7446
|
+
classification: "core_skipped",
|
|
7447
|
+
reason: nearestReplayEvaluationOutcome.reason
|
|
7448
|
+
} : nearestCandidate?.nearest ? {
|
|
7310
7449
|
classification: "timing_or_price_drift",
|
|
7311
7450
|
reason: nearestCandidate.reason
|
|
7312
7451
|
} : {
|
|
@@ -7330,7 +7469,8 @@ var buildReplayMismatchDrilldown = ({
|
|
|
7330
7469
|
timestampDiffMs: nearestReplayEvaluation.timestampDiffMs
|
|
7331
7470
|
}),
|
|
7332
7471
|
...includeArtifacts ? { replayEvaluationArtifact: nearestReplayEvaluation.evaluation } : {}
|
|
7333
|
-
} : {}
|
|
7472
|
+
} : {},
|
|
7473
|
+
...nearestReplayEvaluationOutcome ? { replayEvaluationOutcome: nearestReplayEvaluationOutcome } : {}
|
|
7334
7474
|
};
|
|
7335
7475
|
});
|
|
7336
7476
|
const backtestOnlyDiagnostics = backtestOnly.map((entry, index) => {
|
|
@@ -7440,6 +7580,7 @@ var buildReplayRuntimeComparisonDetails = ({
|
|
|
7440
7580
|
runtimeSignalEvaluations,
|
|
7441
7581
|
replaySignals,
|
|
7442
7582
|
replaySignalEvaluations,
|
|
7583
|
+
replayLineageScopes,
|
|
7443
7584
|
runtimeLineageScopes
|
|
7444
7585
|
}) => {
|
|
7445
7586
|
const runtimeDetails = runtimeEntries.map(toRuntimeParityDetail);
|
|
@@ -7499,6 +7640,7 @@ var buildReplayRuntimeComparisonDetails = ({
|
|
|
7499
7640
|
runtimeSignalEvaluations,
|
|
7500
7641
|
replaySignals,
|
|
7501
7642
|
replaySignalEvaluations,
|
|
7643
|
+
replayLineageScopes,
|
|
7502
7644
|
runtimeLineageScopes,
|
|
7503
7645
|
toleranceMs,
|
|
7504
7646
|
backtestTimestampOffsetMs,
|
|
@@ -7521,6 +7663,7 @@ var buildReplayExchangeComparisonDetails = ({
|
|
|
7521
7663
|
runtimeSignalEvaluations,
|
|
7522
7664
|
replaySignals,
|
|
7523
7665
|
replaySignalEvaluations,
|
|
7666
|
+
replayLineageScopes,
|
|
7524
7667
|
runtimeLineageScopes
|
|
7525
7668
|
}) => {
|
|
7526
7669
|
const toExchangeDetail = (entry) => toExchangeParityDetail({
|
|
@@ -7608,6 +7751,7 @@ var buildReplayExchangeComparisonDetails = ({
|
|
|
7608
7751
|
runtimeSignalEvaluations,
|
|
7609
7752
|
replaySignals,
|
|
7610
7753
|
replaySignalEvaluations,
|
|
7754
|
+
replayLineageScopes,
|
|
7611
7755
|
runtimeLineageScopes,
|
|
7612
7756
|
toleranceMs,
|
|
7613
7757
|
backtestTimestampOffsetMs,
|
|
@@ -7731,14 +7875,35 @@ var filterReplayComparisonByLineage = ({
|
|
|
7731
7875
|
lineageScopeKey(record)
|
|
7732
7876
|
])
|
|
7733
7877
|
);
|
|
7734
|
-
const comparableBacktestEntries =
|
|
7878
|
+
const comparableBacktestEntries = [];
|
|
7879
|
+
const excludedBacktestEntryDetails = [];
|
|
7880
|
+
for (const entry of backtestEntries) {
|
|
7735
7881
|
const replayScope = replayScopeByStrategySymbol.get(
|
|
7736
7882
|
`${entry.strategy}::${entry.symbol}`
|
|
7737
7883
|
);
|
|
7738
7884
|
const window = replayScope ? deploymentWindows.get(replayScope) : null;
|
|
7739
7885
|
const signalTimestamp = entry.signalTimestamp ?? entry.timestamp;
|
|
7740
|
-
|
|
7741
|
-
|
|
7886
|
+
if (window != null && signalTimestamp >= window.firstTimestamp && signalTimestamp <= window.lastTimestamp) {
|
|
7887
|
+
comparableBacktestEntries.push(entry);
|
|
7888
|
+
continue;
|
|
7889
|
+
}
|
|
7890
|
+
const reason = !replayScope ? "replay_scope_missing" : !window ? "runtime_scope_missing" : signalTimestamp < window.firstTimestamp ? "before_runtime_window" : "after_runtime_window";
|
|
7891
|
+
excludedBacktestEntryDetails.push({
|
|
7892
|
+
id: entry.id,
|
|
7893
|
+
strategy: entry.strategy,
|
|
7894
|
+
symbol: entry.symbol,
|
|
7895
|
+
direction: entry.direction,
|
|
7896
|
+
...entry.qty != null ? { qty: entry.qty } : {},
|
|
7897
|
+
timestamp: entry.timestamp,
|
|
7898
|
+
...entry.signalTimestamp != null ? { signalTimestamp: entry.signalTimestamp } : {},
|
|
7899
|
+
price: entry.price,
|
|
7900
|
+
...entry.orderId ? { orderId: entry.orderId } : {},
|
|
7901
|
+
...entry.signalId ? { signalId: entry.signalId } : {},
|
|
7902
|
+
...entry.expectedPnl != null ? { expectedPnl: entry.expectedPnl } : {},
|
|
7903
|
+
reason,
|
|
7904
|
+
runtimeWindow: window ?? null
|
|
7905
|
+
});
|
|
7906
|
+
}
|
|
7742
7907
|
const comparableScopeKeys = new Set(deploymentWindows.keys());
|
|
7743
7908
|
return {
|
|
7744
7909
|
runtimeTrades: comparableRuntimeTrades,
|
|
@@ -7756,6 +7921,7 @@ var filterReplayComparisonByLineage = ({
|
|
|
7756
7921
|
excludedRuntimeLineageScopes: runtimeLineageScopes.length - comparableRuntimeLineageScopes.length,
|
|
7757
7922
|
excludedExchangeEntries: 0,
|
|
7758
7923
|
excludedBacktestEntries: backtestEntries.length - comparableBacktestEntries.length,
|
|
7924
|
+
excludedBacktestEntryDetails,
|
|
7759
7925
|
reason: comparableScopeKeys.size > 0 ? null : expectedByScope.size === 0 ? "replay_produced_no_lineage_scopes" : "no_runtime_artifacts_with_matching_lineage",
|
|
7760
7926
|
replay: [...expectedByScope.entries()].map(([scope, lineage]) => {
|
|
7761
7927
|
const [deploymentId, accountId, strategy, symbol] = scope.split("::");
|
|
@@ -8339,6 +8505,7 @@ var saveAndPrintReplayExchangeComparison = async ({
|
|
|
8339
8505
|
backtestEntries,
|
|
8340
8506
|
replaySignals,
|
|
8341
8507
|
replaySignalEvaluations,
|
|
8508
|
+
replayLineageScopes,
|
|
8342
8509
|
runtimeSignals,
|
|
8343
8510
|
runtimeSignalEvaluations,
|
|
8344
8511
|
runtimeLineageScopes,
|
|
@@ -8394,7 +8561,8 @@ var saveAndPrintReplayExchangeComparison = async ({
|
|
|
8394
8561
|
runtimeSignalEvaluations,
|
|
8395
8562
|
replaySignals,
|
|
8396
8563
|
replaySignalEvaluations,
|
|
8397
|
-
runtimeLineageScopes
|
|
8564
|
+
runtimeLineageScopes,
|
|
8565
|
+
replayLineageScopes
|
|
8398
8566
|
});
|
|
8399
8567
|
const emptyRowsByStrategy = new Map(
|
|
8400
8568
|
buildExchangeComparisonRows({
|
|
@@ -8451,7 +8619,8 @@ var saveAndPrintReplayExchangeComparison = async ({
|
|
|
8451
8619
|
runtimeSignalEvaluations,
|
|
8452
8620
|
replaySignals,
|
|
8453
8621
|
replaySignalEvaluations,
|
|
8454
|
-
runtimeLineageScopes
|
|
8622
|
+
runtimeLineageScopes,
|
|
8623
|
+
replayLineageScopes
|
|
8455
8624
|
});
|
|
8456
8625
|
const rows = buildExchangeComparisonRows({
|
|
8457
8626
|
liveStrategySummaries,
|
|
@@ -8489,6 +8658,7 @@ var saveAndPrintReplayRuntimeComparison = async ({
|
|
|
8489
8658
|
backtestEntries,
|
|
8490
8659
|
replaySignals,
|
|
8491
8660
|
replayLineages,
|
|
8661
|
+
replayLineageScopes,
|
|
8492
8662
|
runtimeEvidencePath
|
|
8493
8663
|
}) => {
|
|
8494
8664
|
const { connector, connectorName, window } = getRuntimeCompareContext();
|
|
@@ -8600,6 +8770,7 @@ var saveAndPrintReplayRuntimeComparison = async ({
|
|
|
8600
8770
|
backtestEntries: comparableBacktestEntries,
|
|
8601
8771
|
replaySignals,
|
|
8602
8772
|
replaySignalEvaluations,
|
|
8773
|
+
replayLineageScopes,
|
|
8603
8774
|
runtimeSignals: comparable.runtimeSignals,
|
|
8604
8775
|
runtimeSignalEvaluations: comparable.runtimeSignalEvaluations,
|
|
8605
8776
|
runtimeLineageScopes: comparable.runtimeLineageScopes,
|
|
@@ -8627,7 +8798,8 @@ var saveAndPrintReplayRuntimeComparison = async ({
|
|
|
8627
8798
|
runtimeSignalEvaluations: comparable.runtimeSignalEvaluations,
|
|
8628
8799
|
replaySignals,
|
|
8629
8800
|
replaySignalEvaluations,
|
|
8630
|
-
runtimeLineageScopes: comparable.runtimeLineageScopes
|
|
8801
|
+
runtimeLineageScopes: comparable.runtimeLineageScopes,
|
|
8802
|
+
replayLineageScopes
|
|
8631
8803
|
});
|
|
8632
8804
|
const parityRows = summarizeTradeParityByStrategy({
|
|
8633
8805
|
runtimeEntries: runtimeDedupe.entries,
|
|
@@ -8670,7 +8842,7 @@ var saveAndPrintReplayRuntimeComparison = async ({
|
|
|
8670
8842
|
// src/lib/replay/outputReport.ts
|
|
8671
8843
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
8672
8844
|
var import_node_path2 = __toESM(require("path"));
|
|
8673
|
-
var
|
|
8845
|
+
var import_data3 = require("@tradejs/core/data");
|
|
8674
8846
|
var formatMsk = (timestamp) => typeof timestamp === "number" && Number.isFinite(timestamp) ? new Intl.DateTimeFormat("ru-RU", {
|
|
8675
8847
|
timeZone: "Europe/Moscow",
|
|
8676
8848
|
dateStyle: "short",
|
|
@@ -9077,7 +9249,7 @@ var writeReplayOutputReport = async ({
|
|
|
9077
9249
|
];
|
|
9078
9250
|
await Promise.all([
|
|
9079
9251
|
import_promises2.default.writeFile(markdownPath, lines.join("\n"), "utf8"),
|
|
9080
|
-
import_promises2.default.writeFile(jsonPath, `${(0,
|
|
9252
|
+
import_promises2.default.writeFile(jsonPath, `${(0, import_data3.toJson)(report, true)}
|
|
9081
9253
|
`, "utf8")
|
|
9082
9254
|
]);
|
|
9083
9255
|
return {
|
|
@@ -9119,6 +9291,7 @@ var finishReplay = async ({
|
|
|
9119
9291
|
backtestEntries: replayStrategySnapshot.backtestEntries,
|
|
9120
9292
|
replaySignals: replayResult.signals,
|
|
9121
9293
|
replayLineages: replayResult.runtimeLineages,
|
|
9294
|
+
replayLineageScopes: replayResult.replayLineageScopes,
|
|
9122
9295
|
runtimeEvidencePath: replayRuntimeEvidencePath
|
|
9123
9296
|
});
|
|
9124
9297
|
const finishedAt = /* @__PURE__ */ new Date();
|
|
@@ -9285,7 +9458,7 @@ var replayBacktest = async () => {
|
|
|
9285
9458
|
deploymentId: deployment.id,
|
|
9286
9459
|
assetClasses: deployment.assetClasses,
|
|
9287
9460
|
deployment,
|
|
9288
|
-
closedIntervalMs: (0,
|
|
9461
|
+
closedIntervalMs: (0, import_data4.intervalToMs)(replayInterval)
|
|
9289
9462
|
});
|
|
9290
9463
|
if (!preparedRun || isReplayUpdateOnlyRun) {
|
|
9291
9464
|
return;
|
|
@@ -541,9 +541,21 @@ var summarizeReplayComparison = (runtimeComparison, strategies) => {
|
|
|
541
541
|
const replayLineage = asArray(comparisonLineage.replay).filter(
|
|
542
542
|
(entry) => !useFilter || strategySet.has(String(asRecord(entry).strategy ?? ""))
|
|
543
543
|
);
|
|
544
|
+
const hasExcludedBacktestEntryDetails = Array.isArray(
|
|
545
|
+
comparisonLineage.excludedBacktestEntryDetails
|
|
546
|
+
);
|
|
547
|
+
const excludedBacktestEntryDetails = asArray(
|
|
548
|
+
comparisonLineage.excludedBacktestEntryDetails
|
|
549
|
+
).filter(
|
|
550
|
+
(entry) => !useFilter || strategySet.has(String(asRecord(entry).strategy ?? ""))
|
|
551
|
+
);
|
|
544
552
|
return {
|
|
545
553
|
mode: comparison.mode ?? null,
|
|
546
|
-
lineage: comparisonLineage ? {
|
|
554
|
+
lineage: comparisonLineage ? {
|
|
555
|
+
...comparisonLineage,
|
|
556
|
+
replay: replayLineage,
|
|
557
|
+
...hasExcludedBacktestEntryDetails ? { excludedBacktestEntryDetails } : {}
|
|
558
|
+
} : null,
|
|
547
559
|
rows: asArray(comparison.rows).filter(
|
|
548
560
|
(row) => !useFilter || strategySet.has(String(row.strategyName ?? ""))
|
|
549
561
|
),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/cli",
|
|
3
|
-
"version": "3.1.27-beta.
|
|
3
|
+
"version": "3.1.27-beta.247",
|
|
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.
|
|
40
|
-
"@tradejs/core": "^3.1.27-beta.
|
|
41
|
-
"@tradejs/indicators": "^3.1.27-beta.
|
|
42
|
-
"@tradejs/infra": "^3.1.27-beta.
|
|
43
|
-
"@tradejs/node": "^3.1.27-beta.
|
|
39
|
+
"@tradejs/connectors": "^3.1.27-beta.247",
|
|
40
|
+
"@tradejs/core": "^3.1.27-beta.247",
|
|
41
|
+
"@tradejs/indicators": "^3.1.27-beta.247",
|
|
42
|
+
"@tradejs/infra": "^3.1.27-beta.247",
|
|
43
|
+
"@tradejs/node": "^3.1.27-beta.247",
|
|
44
44
|
"@tradejs/strategy-kit": "3.0.4",
|
|
45
|
-
"@tradejs/types": "^3.1.27-beta.
|
|
45
|
+
"@tradejs/types": "^3.1.27-beta.247",
|
|
46
46
|
"args": "^5.0.3",
|
|
47
47
|
"bcryptjs": "^2.4.3",
|
|
48
48
|
"chalk": "4.1.2",
|