@tradejs/cli 2.0.15 → 2.0.17
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 +2982 -994
- package/dist/lib/aiPocketSearch.js +493 -24
- package/dist/lib/aiTrainResearch.js +19 -2
- package/dist/lib/hyperliquidWhaleBackfill.js +37 -1
- package/dist/lib/marketContextPrepare.js +112 -9
- package/dist/lib/researchAgent.js +3 -30
- package/dist/lib/runtimeDebugEvidence.js +76 -1
- package/dist/lib/runtimeEvidenceArtifacts.js +255 -0
- package/dist/lib/runtimeEvidenceSync.js +308 -0
- package/dist/lib/runtimeRedis.js +25 -0
- package/dist/lib/runtimeScorecard.js +442 -0
- package/dist/lib/runtimeTradeSync.js +9 -0
- package/dist/scripts/agentRun.js +16 -31
- package/dist/scripts/aiPocketSearch.js +717 -29
- package/dist/scripts/aiTrain.js +32 -2
- package/dist/scripts/backtest.js +136 -11
- package/dist/scripts/hyperliquidWhaleBackfill.js +27 -1
- package/dist/scripts/hyperliquidWhalesUpdate.js +1 -0
- package/dist/scripts/replay.js +122 -12
- package/dist/scripts/replayRunner.js +122 -12
- package/dist/scripts/replayRuntimeEvidence.js +68 -161
- package/dist/scripts/runtimeEvidence.js +316 -161
- package/dist/scripts/runtimeEvidenceSync.js +335 -0
- package/dist/scripts/runtimeParity.js +110 -9
- package/dist/scripts/runtimeScorecard.js +731 -0
- package/dist/scripts/signals.js +263 -145
- package/dist/scripts/signalsDaemon.js +263 -145
- package/dist/scripts/signalsSummary.js +9 -0
- package/dist/workers/testerWorker.js +2 -0
- package/package.json +11 -9
|
@@ -2349,6 +2349,8 @@ var prepareRunEnvironment = async ({
|
|
|
2349
2349
|
|
|
2350
2350
|
// src/lib/marketContextPrepare.ts
|
|
2351
2351
|
var import_chalk7 = __toESM(require("chalk"));
|
|
2352
|
+
var import_timescale5 = require("@tradejs/infra/timescale");
|
|
2353
|
+
var import_registry = require("@tradejs/node/registry");
|
|
2352
2354
|
|
|
2353
2355
|
// src/lib/binanceMarketContextBackfill.ts
|
|
2354
2356
|
var import_progress = __toESM(require("progress"));
|
|
@@ -5184,6 +5186,7 @@ var backfillCoinMarketCapContextForReplay = backfillCoinMarketCapContext;
|
|
|
5184
5186
|
var backfillCoinMarketCapContextForSignals = (params) => backfillCoinMarketCapContext({ ...params, refreshStaleFearGreed: true });
|
|
5185
5187
|
|
|
5186
5188
|
// src/lib/hyperliquidWhaleBackfill.ts
|
|
5189
|
+
var import_progress3 = __toESM(require("progress"));
|
|
5187
5190
|
var import_timescale4 = require("@tradejs/infra/timescale");
|
|
5188
5191
|
var import_strategies2 = require("@tradejs/node/strategies");
|
|
5189
5192
|
|
|
@@ -5558,11 +5561,36 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
5558
5561
|
toMs,
|
|
5559
5562
|
...identity
|
|
5560
5563
|
});
|
|
5564
|
+
const totalCoverageBuckets = Math.ceil(
|
|
5565
|
+
(toMs - fromMs) / HYPERLIQUID_WHALE_BUCKET_MS
|
|
5566
|
+
);
|
|
5567
|
+
const coverageBar = new import_progress3.default(
|
|
5568
|
+
"Hyperliquid coverage :current/:total [:bar][:percent] :eta(s) rows=:rows chunk=:chunk",
|
|
5569
|
+
{
|
|
5570
|
+
total: Math.max(1, totalCoverageBuckets),
|
|
5571
|
+
width: 24
|
|
5572
|
+
}
|
|
5573
|
+
);
|
|
5574
|
+
let displayedCoverageBuckets = 0;
|
|
5561
5575
|
const coverageBuckets = await (0, import_timescale4.rebuildHyperliquidWhaleCoverageRows)({
|
|
5562
5576
|
fromMs,
|
|
5563
5577
|
toMs,
|
|
5564
5578
|
expectedWhales: whales.addresses.length,
|
|
5565
|
-
...identity
|
|
5579
|
+
...identity,
|
|
5580
|
+
onProgress: (progress) => {
|
|
5581
|
+
const next = Math.max(
|
|
5582
|
+
displayedCoverageBuckets,
|
|
5583
|
+
Math.min(progress.completedBuckets, coverageBar.total)
|
|
5584
|
+
);
|
|
5585
|
+
const delta = next - displayedCoverageBuckets;
|
|
5586
|
+
if (delta > 0) {
|
|
5587
|
+
coverageBar.tick(delta, {
|
|
5588
|
+
rows: progress.rows,
|
|
5589
|
+
chunk: `${progress.chunkIndex}/${progress.totalChunks}`
|
|
5590
|
+
});
|
|
5591
|
+
displayedCoverageBuckets = next;
|
|
5592
|
+
}
|
|
5593
|
+
}
|
|
5566
5594
|
});
|
|
5567
5595
|
const result = {
|
|
5568
5596
|
cached: false,
|
|
@@ -5590,6 +5618,9 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
5590
5618
|
};
|
|
5591
5619
|
|
|
5592
5620
|
// src/lib/marketContextPrepare.ts
|
|
5621
|
+
var uniqueReasons = (reasons) => [
|
|
5622
|
+
...new Set(reasons)
|
|
5623
|
+
];
|
|
5593
5624
|
var shouldPrepareDerivativesContextForRun = (params) => {
|
|
5594
5625
|
if (params.universe === "tradfi") return false;
|
|
5595
5626
|
if (params.mode === "signals") {
|
|
@@ -5597,6 +5628,9 @@ var shouldPrepareDerivativesContextForRun = (params) => {
|
|
|
5597
5628
|
cacheOnly: params.cacheOnly
|
|
5598
5629
|
});
|
|
5599
5630
|
}
|
|
5631
|
+
if (params.mode === "backtest" && !params.aiEnabled && !params.mlEnabled) {
|
|
5632
|
+
return false;
|
|
5633
|
+
}
|
|
5600
5634
|
return shouldBackfillDerivativesContextForBacktest({
|
|
5601
5635
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5602
5636
|
cacheOnly: params.cacheOnly,
|
|
@@ -5606,6 +5640,7 @@ var shouldPrepareDerivativesContextForRun = (params) => {
|
|
|
5606
5640
|
var shouldPrepareBinanceMarketContextForRun = (params) => {
|
|
5607
5641
|
if (params.universe === "tradfi") return false;
|
|
5608
5642
|
if (params.mode === "backtest") {
|
|
5643
|
+
if (!params.aiEnabled && !params.mlEnabled) return false;
|
|
5609
5644
|
return shouldBackfillBinanceMarketContextForBacktest({
|
|
5610
5645
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5611
5646
|
cacheOnly: params.cacheOnly,
|
|
@@ -5624,6 +5659,7 @@ var shouldPrepareBinanceMarketContextForRun = (params) => {
|
|
|
5624
5659
|
var shouldPrepareCoinMarketCapContextForRun = (params) => {
|
|
5625
5660
|
if (params.universe === "tradfi") return false;
|
|
5626
5661
|
if (params.mode === "backtest") {
|
|
5662
|
+
if (!params.aiEnabled && !params.mlEnabled) return false;
|
|
5627
5663
|
return shouldBackfillCoinMarketCapContextForBacktest({
|
|
5628
5664
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5629
5665
|
cacheOnly: params.cacheOnly,
|
|
@@ -5639,10 +5675,8 @@ var shouldPrepareCoinMarketCapContextForRun = (params) => {
|
|
|
5639
5675
|
cacheOnly: params.cacheOnly
|
|
5640
5676
|
});
|
|
5641
5677
|
};
|
|
5642
|
-
var shouldPrepareHyperliquidWhaleContextForRun = (params) => {
|
|
5643
|
-
const strategyRequiresContext =
|
|
5644
|
-
"HyperliquidConsensus"
|
|
5645
|
-
);
|
|
5678
|
+
var shouldPrepareHyperliquidWhaleContextForRun = (params, coreContextSources = []) => {
|
|
5679
|
+
const strategyRequiresContext = coreContextSources.includes("hyperliquidWhales");
|
|
5646
5680
|
if (params.universe === "tradfi" || params.mode === "signals" || params.cacheOnly || !params.aiEnabled && !params.mlEnabled && !strategyRequiresContext) {
|
|
5647
5681
|
return false;
|
|
5648
5682
|
}
|
|
@@ -5653,6 +5687,64 @@ var shouldPrepareHyperliquidWhaleContextForRun = (params) => {
|
|
|
5653
5687
|
if (strategyRequiresContext) return true;
|
|
5654
5688
|
return ["1", "true", "yes", "on"].includes(configured);
|
|
5655
5689
|
};
|
|
5690
|
+
var resolveCoreContextSources = async (params) => {
|
|
5691
|
+
const strategyNames = [...new Set(params.strategyNames ?? [])];
|
|
5692
|
+
if (!strategyNames.length) return [];
|
|
5693
|
+
await (0, import_registry.ensureStrategyPluginsLoaded)(params.projectRoot);
|
|
5694
|
+
return [
|
|
5695
|
+
...new Set(
|
|
5696
|
+
strategyNames.flatMap(
|
|
5697
|
+
(strategyName) => (0, import_registry.getStrategyManifest)(strategyName, params.projectRoot)?.contextRequirements?.core ?? []
|
|
5698
|
+
)
|
|
5699
|
+
)
|
|
5700
|
+
];
|
|
5701
|
+
};
|
|
5702
|
+
var resolveMarketContextRunRequirements = async (params) => {
|
|
5703
|
+
const coreContextSources = await resolveCoreContextSources(params);
|
|
5704
|
+
const paramsWithCoreDemand = (source) => coreContextSources.includes(source) ? { ...params, aiEnabled: true } : params;
|
|
5705
|
+
const isCrypto = params.universe !== "tradfi";
|
|
5706
|
+
const capturesPayload = Boolean(params.aiEnabled || params.mlEnabled);
|
|
5707
|
+
const runtimeReadsContext = params.mode !== "backtest";
|
|
5708
|
+
const reasonsFor = (source) => uniqueReasons([
|
|
5709
|
+
...coreContextSources.includes(source) ? ["core"] : [],
|
|
5710
|
+
...params.aiEnabled ? ["ai"] : [],
|
|
5711
|
+
...params.mlEnabled ? ["ml"] : [],
|
|
5712
|
+
...runtimeReadsContext ? ["runtime"] : []
|
|
5713
|
+
]);
|
|
5714
|
+
const readsStandardContext = isCrypto && (capturesPayload || runtimeReadsContext);
|
|
5715
|
+
const readsHyperliquid = isCrypto && (readsStandardContext || coreContextSources.includes("hyperliquidWhales"));
|
|
5716
|
+
return {
|
|
5717
|
+
binance: {
|
|
5718
|
+
read: readsStandardContext || coreContextSources.includes("binance"),
|
|
5719
|
+
backfill: shouldPrepareBinanceMarketContextForRun(
|
|
5720
|
+
paramsWithCoreDemand("binance")
|
|
5721
|
+
),
|
|
5722
|
+
requiredBy: reasonsFor("binance")
|
|
5723
|
+
},
|
|
5724
|
+
coinmarketcap: {
|
|
5725
|
+
read: readsStandardContext || coreContextSources.includes("coinmarketcap"),
|
|
5726
|
+
backfill: shouldPrepareCoinMarketCapContextForRun(
|
|
5727
|
+
paramsWithCoreDemand("coinmarketcap")
|
|
5728
|
+
),
|
|
5729
|
+
requiredBy: reasonsFor("coinmarketcap")
|
|
5730
|
+
},
|
|
5731
|
+
derivatives: {
|
|
5732
|
+
read: readsStandardContext || coreContextSources.includes("derivatives"),
|
|
5733
|
+
backfill: shouldPrepareDerivativesContextForRun(
|
|
5734
|
+
paramsWithCoreDemand("derivatives")
|
|
5735
|
+
),
|
|
5736
|
+
requiredBy: reasonsFor("derivatives")
|
|
5737
|
+
},
|
|
5738
|
+
hyperliquidWhales: {
|
|
5739
|
+
read: readsHyperliquid,
|
|
5740
|
+
backfill: shouldPrepareHyperliquidWhaleContextForRun(
|
|
5741
|
+
params,
|
|
5742
|
+
coreContextSources
|
|
5743
|
+
),
|
|
5744
|
+
requiredBy: reasonsFor("hyperliquidWhales")
|
|
5745
|
+
}
|
|
5746
|
+
};
|
|
5747
|
+
};
|
|
5656
5748
|
var resolveCoinMarketCapBackfillForMode = (mode) => mode === "backtest" ? backfillCoinMarketCapContextForBacktest : mode === "signals" ? backfillCoinMarketCapContextForSignals : backfillCoinMarketCapContextForReplay;
|
|
5657
5749
|
var buildCoinMarketCapBackfillParams = (params) => ({
|
|
5658
5750
|
userName: params.userName,
|
|
@@ -5681,7 +5773,15 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5681
5773
|
console.log(import_chalk7.default.gray(message));
|
|
5682
5774
|
});
|
|
5683
5775
|
const timeOperation3 = (label, operation) => timeOperation(label, operation, log);
|
|
5684
|
-
|
|
5776
|
+
const requirements = await resolveMarketContextRunRequirements(params);
|
|
5777
|
+
const readableSources = Object.entries(requirements).filter(([, requirement]) => requirement.read).map(([source]) => source);
|
|
5778
|
+
if (readableSources.length) {
|
|
5779
|
+
await timeOperation3(
|
|
5780
|
+
"market context schema ensure",
|
|
5781
|
+
() => (0, import_timescale5.ensureMarketContextSchemas)(readableSources)
|
|
5782
|
+
);
|
|
5783
|
+
}
|
|
5784
|
+
if (requirements.derivatives.backfill) {
|
|
5685
5785
|
await timeOperation3(
|
|
5686
5786
|
"derivatives context backfill",
|
|
5687
5787
|
() => (params.mode === "signals" ? backfillDerivativesContextForSignals : backfillDerivativesContextForBacktest)(
|
|
@@ -5689,7 +5789,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5689
5789
|
)
|
|
5690
5790
|
);
|
|
5691
5791
|
}
|
|
5692
|
-
if (
|
|
5792
|
+
if (requirements.hyperliquidWhales.backfill) {
|
|
5693
5793
|
await timeOperation3(
|
|
5694
5794
|
"hyperliquid whale context backfill",
|
|
5695
5795
|
() => backfillHyperliquidWhaleContext({
|
|
@@ -5701,13 +5801,13 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5701
5801
|
})
|
|
5702
5802
|
);
|
|
5703
5803
|
}
|
|
5704
|
-
if (
|
|
5804
|
+
if (requirements.binance.backfill) {
|
|
5705
5805
|
await timeOperation3("binance market context backfill", () => {
|
|
5706
5806
|
const backfill = params.mode === "backtest" ? backfillBinanceMarketContextForBacktest : params.mode === "signals" ? backfillBinanceMarketContextForSignals : backfillBinanceMarketContextForReplay;
|
|
5707
5807
|
return backfill(buildBinanceMarketBackfillParams(params));
|
|
5708
5808
|
});
|
|
5709
5809
|
}
|
|
5710
|
-
if (
|
|
5810
|
+
if (requirements.coinmarketcap.backfill) {
|
|
5711
5811
|
await timeOperation3(
|
|
5712
5812
|
"coinmarketcap historical context backfill",
|
|
5713
5813
|
() => resolveCoinMarketCapBackfillForMode(params.mode)(
|
|
@@ -5715,6 +5815,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5715
5815
|
)
|
|
5716
5816
|
);
|
|
5717
5817
|
}
|
|
5818
|
+
return requirements;
|
|
5718
5819
|
};
|
|
5719
5820
|
|
|
5720
5821
|
// src/lib/backtest/runState.ts
|
|
@@ -5987,7 +6088,7 @@ var compactReplaySignal = (signal) => {
|
|
|
5987
6088
|
|
|
5988
6089
|
// src/lib/replay/historicalSignalsReplay.ts
|
|
5989
6090
|
var import_chalk9 = __toESM(require("chalk"));
|
|
5990
|
-
var
|
|
6091
|
+
var import_progress4 = __toESM(require("progress"));
|
|
5991
6092
|
var import_backtest = require("@tradejs/core/backtest");
|
|
5992
6093
|
var import_strategies4 = require("@tradejs/core/strategies");
|
|
5993
6094
|
var import_time3 = require("@tradejs/core/time");
|
|
@@ -6871,7 +6972,7 @@ var runHistoricalSignalsReplay = async ({
|
|
|
6871
6972
|
const sharedReplayKeyPrefixes = [];
|
|
6872
6973
|
let preparedSymbols = 0;
|
|
6873
6974
|
let skippedSymbols = 0;
|
|
6874
|
-
const prepareBar = new
|
|
6975
|
+
const prepareBar = new import_progress4.default(
|
|
6875
6976
|
"prepare :current/:total [:bar][:percent] skipped=:skipped :etas(s) :symbol",
|
|
6876
6977
|
{
|
|
6877
6978
|
total: preparedRun.tickers.length,
|
|
@@ -6993,7 +7094,7 @@ var runHistoricalSignalsReplay = async ({
|
|
|
6993
7094
|
interval
|
|
6994
7095
|
});
|
|
6995
7096
|
let abortedCycles = 0;
|
|
6996
|
-
const cycleBar = new
|
|
7097
|
+
const cycleBar = new import_progress4.default(
|
|
6997
7098
|
"cycles :current/:total [:bar][:percent] sig=:signals abort=:aborted :etas(s) :ts",
|
|
6998
7099
|
{
|
|
6999
7100
|
total: orderedTimestamps.length,
|
|
@@ -7963,6 +8064,15 @@ var syncRuntimeTrades = async ({
|
|
|
7963
8064
|
nextTrade,
|
|
7964
8065
|
{ expire: import_constants5.TTL_1M }
|
|
7965
8066
|
),
|
|
8067
|
+
(0, import_redis5.setHashJsonField)(
|
|
8068
|
+
import_redis5.redisKeys.runtimeClosedTradeBucket(
|
|
8069
|
+
userName,
|
|
8070
|
+
(0, import_time5.getRuntimeStorageDayKey)(nextTrade.exitTimestamp)
|
|
8071
|
+
),
|
|
8072
|
+
trade.orderId,
|
|
8073
|
+
nextTrade,
|
|
8074
|
+
{ expire: import_constants5.TTL_1M }
|
|
8075
|
+
),
|
|
7966
8076
|
...isCurrentActiveTrade ? [(0, import_redis5.delKey)(activeTradeKey)] : []
|
|
7967
8077
|
]);
|
|
7968
8078
|
syncedTrades.push(nextTrade);
|
|
@@ -135,6 +135,29 @@ var loadRuntimeTrades = async (userName, {
|
|
|
135
135
|
const trades = await Promise.all(keys.map((key) => (0, import_redis.getData)(key, null)));
|
|
136
136
|
return trades.filter(isRuntimeTradeRecord).filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
|
|
137
137
|
};
|
|
138
|
+
var loadRuntimeClosedTrades = async (userName, {
|
|
139
|
+
startTime,
|
|
140
|
+
endTime
|
|
141
|
+
}) => {
|
|
142
|
+
const dayKeys = (0, import_time.getRuntimeStorageDayKeys)(startTime, endTime);
|
|
143
|
+
const trades = (await Promise.all(
|
|
144
|
+
dayKeys.map(
|
|
145
|
+
(dayKey) => (0, import_redis.getHashJsonValues)(
|
|
146
|
+
import_redis.redisKeys.runtimeClosedTradeBucket(userName, dayKey)
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
)).flat();
|
|
150
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
151
|
+
for (const trade of trades) {
|
|
152
|
+
if (!isRuntimeTradeRecord(trade) || trade.status !== "closed" || !Number.isFinite(trade.exitTimestamp) || trade.exitTimestamp < startTime || trade.exitTimestamp >= endTime) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
deduped.set(trade.orderId, trade);
|
|
156
|
+
}
|
|
157
|
+
return [...deduped.values()].sort(
|
|
158
|
+
(left, right) => left.exitTimestamp - right.exitTimestamp
|
|
159
|
+
);
|
|
160
|
+
};
|
|
138
161
|
|
|
139
162
|
// src/lib/runtimeSignalsLoader.ts
|
|
140
163
|
var import_redis2 = require("@tradejs/infra/redis");
|
|
@@ -299,11 +322,6 @@ var formatRuntimeDebugDateTime = (timestamp) => new Intl.DateTimeFormat("ru-RU",
|
|
|
299
322
|
minute: "2-digit",
|
|
300
323
|
hour12: false
|
|
301
324
|
}).format(new Date(timestamp));
|
|
302
|
-
var buildRuntimeDebugEvaluationId = ({
|
|
303
|
-
strategy,
|
|
304
|
-
symbol,
|
|
305
|
-
timestamp
|
|
306
|
-
}) => `${strategy}:${symbol}:${timestamp}`;
|
|
307
325
|
var filterByStrategies = (values, strategies) => {
|
|
308
326
|
if (!strategies?.length) {
|
|
309
327
|
return values;
|
|
@@ -319,13 +337,30 @@ var collectRuntimeDebugEvidence = async ({
|
|
|
319
337
|
}) => {
|
|
320
338
|
const dayKeys = (0, import_time2.getRuntimeStorageDayKeys)(startTime, endTime);
|
|
321
339
|
const dayKeySet = new Set(dayKeys);
|
|
322
|
-
const [
|
|
340
|
+
const [
|
|
341
|
+
entryTrades,
|
|
342
|
+
closedTrades,
|
|
343
|
+
signals,
|
|
344
|
+
evaluations,
|
|
345
|
+
evaluationStatsBuckets,
|
|
346
|
+
configs
|
|
347
|
+
] = await Promise.all([
|
|
323
348
|
loadRuntimeTrades(userName, { startTime, endTime }),
|
|
349
|
+
loadRuntimeClosedTrades(userName, { startTime, endTime }),
|
|
324
350
|
loadRuntimeSignals(userName, { startTime, endTime }),
|
|
325
351
|
loadRuntimeSignalEvaluations(userName, { startTime, endTime }),
|
|
326
352
|
loadRuntimeSignalEvaluationStatsBuckets(userName),
|
|
327
353
|
loadRuntimeStrategyConfigs(userName)
|
|
328
354
|
]);
|
|
355
|
+
const tradesByOrderId = new Map(
|
|
356
|
+
entryTrades.map((trade) => [trade.orderId, trade])
|
|
357
|
+
);
|
|
358
|
+
for (const trade of closedTrades) {
|
|
359
|
+
tradesByOrderId.set(trade.orderId, trade);
|
|
360
|
+
}
|
|
361
|
+
const trades = [...tradesByOrderId.values()].sort(
|
|
362
|
+
(left, right) => left.entryTimestamp - right.entryTimestamp
|
|
363
|
+
);
|
|
329
364
|
const filteredStats = evaluationStatsBuckets.filter(
|
|
330
365
|
(entry) => dayKeySet.has(entry.dayKey) && (!strategies?.length || strategies.includes(entry.strategy))
|
|
331
366
|
);
|
|
@@ -340,7 +375,7 @@ var collectRuntimeDebugEvidence = async ({
|
|
|
340
375
|
)
|
|
341
376
|
};
|
|
342
377
|
};
|
|
343
|
-
var
|
|
378
|
+
var buildRuntimeEvidenceReportPayload = ({
|
|
344
379
|
userName,
|
|
345
380
|
startTime,
|
|
346
381
|
endTime,
|
|
@@ -349,159 +384,30 @@ var buildRuntimeDebugReportPayload = async ({
|
|
|
349
384
|
trades,
|
|
350
385
|
strategyConfigs,
|
|
351
386
|
evaluationStatsBuckets
|
|
352
|
-
}) => {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const signalDayKey = signal != null ? (0, import_time2.getRuntimeStorageDayKey)(signal.timestamp) : tradeDayKey;
|
|
377
|
-
const evaluationDayKey = knownEvaluation != null ? (0, import_time2.getRuntimeStorageDayKey)(knownEvaluation.timestamp) : signalDayKey;
|
|
378
|
-
const tradeKey = import_redis3.redisKeys.runtimeTrade(userName, trade.orderId);
|
|
379
|
-
const tradeBucketKey = import_redis3.redisKeys.runtimeTradeBucket(
|
|
380
|
-
userName,
|
|
381
|
-
tradeDayKey
|
|
382
|
-
);
|
|
383
|
-
const activeTradeKey = import_redis3.redisKeys.runtimeActiveTrade(
|
|
384
|
-
userName,
|
|
385
|
-
trade.symbol,
|
|
386
|
-
trade.deploymentId ?? trade.accountId
|
|
387
|
-
);
|
|
388
|
-
const signalKey = trade.signalId != null ? import_redis3.redisKeys.storeSignal(trade.symbol, trade.signalId) : null;
|
|
389
|
-
const evaluationBucketKey = import_redis3.redisKeys.runtimeSignalEvaluationBucket(
|
|
390
|
-
userName,
|
|
391
|
-
evaluationDayKey,
|
|
392
|
-
knownEvaluation?.strategy ?? trade.strategy
|
|
393
|
-
);
|
|
394
|
-
const evaluationField = knownEvaluation?.evaluationId ?? evaluationId;
|
|
395
|
-
const evaluationKey = import_redis3.redisKeys.runtimeSignalEvaluation(
|
|
396
|
-
userName,
|
|
397
|
-
evaluationField
|
|
398
|
-
);
|
|
399
|
-
const [
|
|
400
|
-
tradeValue,
|
|
401
|
-
activeTradeValue,
|
|
402
|
-
signalValue,
|
|
403
|
-
directEvaluationValue,
|
|
404
|
-
bucketEvaluationValue
|
|
405
|
-
] = await Promise.all([
|
|
406
|
-
(0, import_redis3.getData)(tradeKey, null),
|
|
407
|
-
(0, import_redis3.getData)(activeTradeKey, null),
|
|
408
|
-
signalKey ? (0, import_redis3.getData)(signalKey, null) : Promise.resolve(null),
|
|
409
|
-
(0, import_redis3.getData)(evaluationKey, null),
|
|
410
|
-
knownEvaluation ? Promise.resolve(knownEvaluation) : (0, import_redis3.getHashJsonField)(
|
|
411
|
-
evaluationBucketKey,
|
|
412
|
-
evaluationField,
|
|
413
|
-
null
|
|
414
|
-
)
|
|
415
|
-
]);
|
|
416
|
-
const evaluationValue = directEvaluationValue ?? bucketEvaluationValue ?? knownEvaluation ?? null;
|
|
417
|
-
return {
|
|
418
|
-
redisDebug: {
|
|
419
|
-
trade: tradeKey,
|
|
420
|
-
tradeBucket: {
|
|
421
|
-
key: tradeBucketKey,
|
|
422
|
-
field: trade.orderId
|
|
423
|
-
},
|
|
424
|
-
activeTrade: activeTradeKey,
|
|
425
|
-
signal: signalKey,
|
|
426
|
-
evaluation: {
|
|
427
|
-
key: evaluationBucketKey,
|
|
428
|
-
field: evaluationField,
|
|
429
|
-
directKey: evaluationKey
|
|
430
|
-
}
|
|
431
|
-
},
|
|
432
|
-
trade,
|
|
433
|
-
redisValues: {
|
|
434
|
-
trade: tradeValue,
|
|
435
|
-
tradeBucket: trade,
|
|
436
|
-
activeTrade: activeTradeValue,
|
|
437
|
-
signal: signalValue ?? signal ?? null,
|
|
438
|
-
evaluation: evaluationValue ?? knownEvaluation ?? null
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
})
|
|
442
|
-
);
|
|
443
|
-
const linkedEvaluations = /* @__PURE__ */ new Map();
|
|
444
|
-
for (const trade of debugTrades) {
|
|
445
|
-
const evaluation = trade.redisValues.evaluation;
|
|
446
|
-
if (evaluation && typeof evaluation === "object" && "evaluationId" in evaluation && typeof evaluation.evaluationId === "string") {
|
|
447
|
-
linkedEvaluations.set(
|
|
448
|
-
evaluation.evaluationId,
|
|
449
|
-
evaluation
|
|
450
|
-
);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
const reportEvaluations = evaluations.length > 0 ? evaluations : [...linkedEvaluations.values()];
|
|
454
|
-
return {
|
|
455
|
-
reportType: "runtime-daily-debug",
|
|
456
|
-
generatedAt: Date.now(),
|
|
457
|
-
generatedAtMsk: formatRuntimeDebugDateTime(Date.now()),
|
|
458
|
-
userName,
|
|
459
|
-
window: {
|
|
460
|
-
startTime,
|
|
461
|
-
endTime,
|
|
462
|
-
startMsk: formatRuntimeDebugDateTime(startTime),
|
|
463
|
-
endMsk: formatRuntimeDebugDateTime(endTime),
|
|
464
|
-
dayKeys
|
|
465
|
-
},
|
|
466
|
-
redisPrefixes: {
|
|
467
|
-
runtimeTrades: import_redis3.redisKeys.runtimeTrades(userName),
|
|
468
|
-
runtimeTradeBuckets: import_redis3.redisKeys.runtimeTradeBuckets(userName),
|
|
469
|
-
runtimeActiveTrades: import_redis3.redisKeys.runtimeActiveTrades(userName),
|
|
470
|
-
runtimeSignals: import_redis3.redisKeys.runtimeSignalBuckets(userName),
|
|
471
|
-
runtimeSignalEvaluations: import_redis3.redisKeys.runtimeSignalEvaluationBuckets(userName),
|
|
472
|
-
runtimeSignalEvaluationStats: import_redis3.redisKeys.runtimeSignalEvaluationStatsBuckets(userName)
|
|
473
|
-
},
|
|
474
|
-
counts: {
|
|
475
|
-
trades: trades.length,
|
|
476
|
-
signals: signals.length,
|
|
477
|
-
evaluations: reportEvaluations.length,
|
|
478
|
-
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
479
|
-
strategyConfigs: strategyConfigs?.length ?? 0
|
|
480
|
-
},
|
|
481
|
-
trades: debugTrades,
|
|
482
|
-
signals: signals.map((signal) => ({
|
|
483
|
-
redisKey: import_redis3.redisKeys.storeSignal(signal.symbol, signal.signalId),
|
|
484
|
-
signal
|
|
485
|
-
})),
|
|
486
|
-
evaluations: reportEvaluations.map((evaluation) => ({
|
|
487
|
-
redisDebug: {
|
|
488
|
-
key: import_redis3.redisKeys.runtimeSignalEvaluationBucket(
|
|
489
|
-
userName,
|
|
490
|
-
(0, import_time2.getRuntimeStorageDayKey)(evaluation.timestamp),
|
|
491
|
-
evaluation.strategy
|
|
492
|
-
),
|
|
493
|
-
field: evaluation.evaluationId,
|
|
494
|
-
directKey: import_redis3.redisKeys.runtimeSignalEvaluation(
|
|
495
|
-
userName,
|
|
496
|
-
evaluation.evaluationId
|
|
497
|
-
)
|
|
498
|
-
},
|
|
499
|
-
evaluation
|
|
500
|
-
})),
|
|
501
|
-
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
502
|
-
strategyConfigs: strategyConfigs ?? []
|
|
503
|
-
};
|
|
504
|
-
};
|
|
387
|
+
}) => ({
|
|
388
|
+
reportType: "runtime-daily-evidence",
|
|
389
|
+
generatedAt: Date.now(),
|
|
390
|
+
userName,
|
|
391
|
+
window: {
|
|
392
|
+
startTime,
|
|
393
|
+
endTime,
|
|
394
|
+
startMsk: formatRuntimeDebugDateTime(startTime),
|
|
395
|
+
endMsk: formatRuntimeDebugDateTime(endTime),
|
|
396
|
+
dayKeys: (0, import_time2.getRuntimeStorageDayKeys)(startTime, endTime)
|
|
397
|
+
},
|
|
398
|
+
counts: {
|
|
399
|
+
trades: trades.length,
|
|
400
|
+
signals: signals.length,
|
|
401
|
+
evaluations: evaluations.length,
|
|
402
|
+
evaluationStatsBuckets: evaluationStatsBuckets?.length ?? 0,
|
|
403
|
+
strategyConfigs: strategyConfigs?.length ?? 0
|
|
404
|
+
},
|
|
405
|
+
trades: trades.map((trade) => ({ trade })),
|
|
406
|
+
signals: signals.map((signal) => ({ signal })),
|
|
407
|
+
evaluations: evaluations.map((evaluation) => ({ evaluation })),
|
|
408
|
+
evaluationStatsBuckets: evaluationStatsBuckets ?? [],
|
|
409
|
+
strategyConfigs: strategyConfigs ?? []
|
|
410
|
+
});
|
|
505
411
|
|
|
506
412
|
// src/lib/replay/support.ts
|
|
507
413
|
var import_chalk = __toESM(require("chalk"));
|
|
@@ -659,6 +565,7 @@ var summarizeReplayComparison = (runtimeComparison, strategies) => {
|
|
|
659
565
|
].sort((left, right) => left.localeCompare(right));
|
|
660
566
|
return {
|
|
661
567
|
mode: comparison.mode ?? null,
|
|
568
|
+
lineage: comparison.lineage ?? null,
|
|
662
569
|
rows: asArray(comparison.rows).filter(
|
|
663
570
|
(row) => !useFilter || strategySet.has(String(row.strategyName ?? ""))
|
|
664
571
|
),
|
|
@@ -786,7 +693,7 @@ var loadRuntimePayload = async ({
|
|
|
786
693
|
return {
|
|
787
694
|
source: "local-redis",
|
|
788
695
|
path: null,
|
|
789
|
-
payload:
|
|
696
|
+
payload: buildRuntimeEvidenceReportPayload({
|
|
790
697
|
userName: flags.user,
|
|
791
698
|
startTime,
|
|
792
699
|
endTime,
|