@tradejs/cli 2.0.18 → 2.0.20
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 +14522 -15704
- package/dist/lib/aiExport.js +15 -1608
- package/dist/lib/aiPocketSearch.js +499 -67
- package/dist/lib/aiPocketSearchCli.js +113 -0
- package/dist/lib/aiTrainCharts.js +14 -1
- package/dist/lib/aiTrainMetrics.js +4 -1
- package/dist/lib/aiTrainResearch.js +88 -54
- package/dist/lib/binanceMarketContextBackfill.js +7 -6
- package/dist/lib/coinMarketCapContextBackfill.js +19 -18
- package/dist/lib/coreResearch.js +2738 -0
- package/dist/lib/derivativesContextBackfill.js +10 -9
- package/dist/lib/executionCalibration.js +6 -3
- package/dist/lib/hyperliquidWhaleBackfill.js +8 -8
- package/dist/lib/hyperliquidWhaleStream.js +4 -4
- package/dist/lib/marketContextPrepare.js +83 -1686
- package/dist/lib/runEnvironment.js +14 -1666
- package/dist/lib/runFormatting.js +1 -1607
- package/dist/lib/runtimeDebugEvidence.js +2 -48
- package/dist/lib/runtimeLineage.js +81 -48
- package/dist/lib/runtimeRedis.js +6 -57
- package/dist/lib/runtimeScorecard.js +153 -10
- package/dist/lib/runtimeStrategyBacktest.js +2 -48
- package/dist/lib/strategyGateFingerprint.js +80 -0
- package/dist/lib/strategyRelease.js +1365 -0
- package/dist/scripts/aiExport.js +17 -1610
- package/dist/scripts/aiPocketSearch.js +1070 -1770
- package/dist/scripts/aiTrain.js +108 -1688
- package/dist/scripts/backtest.js +120 -1760
- package/dist/scripts/binanceMarketIngest.js +5 -4
- package/dist/scripts/candlesMigrateProvider.js +6 -5186
- package/dist/scripts/cleanupMarketContext.js +4 -3
- package/dist/scripts/continuity.js +4 -3
- package/dist/scripts/coreResearch.js +2830 -0
- package/dist/scripts/derivativesIngest.js +6 -4
- package/dist/scripts/derivativesIngestCoinalyzeAll.js +5 -4
- package/dist/scripts/doctor.js +2 -5184
- package/dist/scripts/executionCalibration.js +6 -3
- package/dist/scripts/hyperliquidWhaleBackfill.js +8 -8
- package/dist/scripts/hyperliquidWhaleIngest.js +4 -4
- package/dist/scripts/hyperliquidWhalesUpdate.js +1 -1
- package/dist/scripts/migration.js +3 -3
- package/dist/scripts/mlExport.js +1 -1607
- package/dist/scripts/replay.js +239 -1855
- package/dist/scripts/replayRunner.js +239 -1855
- package/dist/scripts/replayRuntimeEvidence.js +29 -62
- package/dist/scripts/researchAuto.js +3 -49
- package/dist/scripts/results.js +1 -1607
- package/dist/scripts/runtimeEvidence.js +18 -56
- package/dist/scripts/runtimeParity.js +121 -1746
- package/dist/scripts/runtimeScorecard.js +883 -29
- package/dist/scripts/signals.js +1178 -2724
- package/dist/scripts/signalsDaemon.js +1183 -2696
- package/dist/scripts/signalsSummary.js +4 -26
- package/dist/scripts/strategyRelease.js +1469 -0
- package/dist/workers/testerWorker.js +2 -2
- package/package.json +13 -9
|
@@ -22,9 +22,96 @@ var aiPocketSearchCli_exports = {};
|
|
|
22
22
|
__export(aiPocketSearchCli_exports, {
|
|
23
23
|
AI_POCKET_SEARCH_CLI_DECIMAL_DEFAULTS: () => AI_POCKET_SEARCH_CLI_DECIMAL_DEFAULTS,
|
|
24
24
|
readAiPocketSearchCliOption: () => readAiPocketSearchCliOption,
|
|
25
|
+
resolveAiPocketCadenceProfile: () => resolveAiPocketCadenceProfile,
|
|
26
|
+
sealAiPocketTestPartition: () => sealAiPocketTestPartition,
|
|
27
|
+
splitAiPocketCoverageRowsByTimestamp: () => splitAiPocketCoverageRowsByTimestamp,
|
|
25
28
|
splitAiPocketResearchRowsByTimestamp: () => splitAiPocketResearchRowsByTimestamp
|
|
26
29
|
});
|
|
27
30
|
module.exports = __toCommonJS(aiPocketSearchCli_exports);
|
|
31
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
32
|
+
var DEFAULT_MIN_SUPPORT = 20;
|
|
33
|
+
var LOW_CADENCE_EVENT_LIMIT = 200;
|
|
34
|
+
var LOW_CADENCE_MAX_EVENT_SHARE = 1 / 3;
|
|
35
|
+
var countIndependentEvents = (rows) => {
|
|
36
|
+
const timestampEvents = /* @__PURE__ */ new Set();
|
|
37
|
+
let rowsWithoutTimestamp = 0;
|
|
38
|
+
for (const row of rows) {
|
|
39
|
+
if (typeof row.timestamp === "number" && Number.isFinite(row.timestamp)) {
|
|
40
|
+
timestampEvents.add(row.timestamp);
|
|
41
|
+
} else {
|
|
42
|
+
rowsWithoutTimestamp += 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return timestampEvents.size + rowsWithoutTimestamp;
|
|
46
|
+
};
|
|
47
|
+
var getPeriodDays = (rows) => {
|
|
48
|
+
let minTimestamp = null;
|
|
49
|
+
let maxTimestamp = null;
|
|
50
|
+
for (const row of rows) {
|
|
51
|
+
const timestamp = row.timestamp;
|
|
52
|
+
if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
minTimestamp = minTimestamp == null ? timestamp : Math.min(minTimestamp, timestamp);
|
|
56
|
+
maxTimestamp = maxTimestamp == null ? timestamp : Math.max(maxTimestamp, timestamp);
|
|
57
|
+
}
|
|
58
|
+
if (minTimestamp == null || maxTimestamp == null) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return Math.max((maxTimestamp - minTimestamp) / DAY_MS, 1);
|
|
62
|
+
};
|
|
63
|
+
var clampInt = (value, minimum, maximum) => Math.max(minimum, Math.min(maximum, Math.ceil(value)));
|
|
64
|
+
var resolveAiPocketCadenceProfile = ({
|
|
65
|
+
trainRows,
|
|
66
|
+
validationRows = [],
|
|
67
|
+
testRows = [],
|
|
68
|
+
mode = "auto",
|
|
69
|
+
validationSplit = 0.25,
|
|
70
|
+
minSupport,
|
|
71
|
+
minEvents,
|
|
72
|
+
minValidationSupport,
|
|
73
|
+
minValidationEvents,
|
|
74
|
+
maxEventCountShare = 0.25,
|
|
75
|
+
explicitMaxEventCountShare = false
|
|
76
|
+
}) => {
|
|
77
|
+
const trainEvents = countIndependentEvents(trainRows);
|
|
78
|
+
const validationEvents = countIndependentEvents(validationRows);
|
|
79
|
+
const testEvents = countIndependentEvents(testRows);
|
|
80
|
+
const trainPeriodDays = getPeriodDays(trainRows);
|
|
81
|
+
const trainEventsPerDay = trainPeriodDays == null ? null : trainEvents / trainPeriodDays;
|
|
82
|
+
const sparseSample = trainEvents < LOW_CADENCE_EVENT_LIMIT;
|
|
83
|
+
const lowCadence = trainEventsPerDay != null && trainEventsPerDay < 0.25;
|
|
84
|
+
const adaptiveSample = mode === "auto" && sparseSample;
|
|
85
|
+
const adaptiveThresholds = adaptiveSample && (minSupport == null || minEvents == null || validationRows.length > 0 && (minValidationSupport == null || minValidationEvents == null) || !explicitMaxEventCountShare);
|
|
86
|
+
const resolvedMinSupport = minSupport ?? (adaptiveSample ? clampInt(trainEvents * 0.1, 3, DEFAULT_MIN_SUPPORT) : DEFAULT_MIN_SUPPORT);
|
|
87
|
+
const resolvedMinEvents = minEvents ?? (minSupport != null || !adaptiveSample ? Math.max(5, Math.ceil(resolvedMinSupport * 0.5)) : clampInt(resolvedMinSupport * 0.5, 3, 10));
|
|
88
|
+
const hasValidation = validationRows.length > 0;
|
|
89
|
+
const resolvedMinValidationSupport = minValidationSupport ?? (hasValidation ? Math.max(3, Math.ceil(resolvedMinSupport * validationSplit * 0.5)) : 0);
|
|
90
|
+
const resolvedMinValidationEvents = minValidationEvents ?? (hasValidation ? Math.max(
|
|
91
|
+
adaptiveSample ? 3 : 2,
|
|
92
|
+
Math.ceil(resolvedMinEvents * validationSplit * 0.5)
|
|
93
|
+
) : 0);
|
|
94
|
+
const resolvedMaxEventCountShare = adaptiveSample && !explicitMaxEventCountShare ? Math.max(maxEventCountShare, LOW_CADENCE_MAX_EVENT_SHARE) : maxEventCountShare;
|
|
95
|
+
return {
|
|
96
|
+
mode,
|
|
97
|
+
lowCadence,
|
|
98
|
+
sparseSample,
|
|
99
|
+
adaptiveThresholds,
|
|
100
|
+
trainRows: trainRows.length,
|
|
101
|
+
trainEvents,
|
|
102
|
+
trainPeriodDays,
|
|
103
|
+
trainEventsPerDay,
|
|
104
|
+
validationRows: validationRows.length,
|
|
105
|
+
validationEvents,
|
|
106
|
+
testRows: testRows.length,
|
|
107
|
+
testEvents,
|
|
108
|
+
minSupport: resolvedMinSupport,
|
|
109
|
+
minEvents: resolvedMinEvents,
|
|
110
|
+
minValidationSupport: resolvedMinValidationSupport,
|
|
111
|
+
minValidationEvents: resolvedMinValidationEvents,
|
|
112
|
+
maxEventCountShare: resolvedMaxEventCountShare
|
|
113
|
+
};
|
|
114
|
+
};
|
|
28
115
|
var AI_POCKET_SEARCH_CLI_DECIMAL_DEFAULTS = {
|
|
29
116
|
minProfitFactor: "1.2",
|
|
30
117
|
minWinRate: "0",
|
|
@@ -71,6 +158,29 @@ var splitAiPocketResearchRowsByTimestamp = (rows, validationSplit, testSplit = 0
|
|
|
71
158
|
testRows: rows.filter((row) => isIn(testTimestamps, row.timestamp))
|
|
72
159
|
};
|
|
73
160
|
};
|
|
161
|
+
var splitAiPocketCoverageRowsByTimestamp = (rows, family, validationSplit, testSplit = 0) => splitAiPocketResearchRowsByTimestamp(
|
|
162
|
+
rows.filter((row) => row.featureCoverage?.[family] === true),
|
|
163
|
+
validationSplit,
|
|
164
|
+
testSplit
|
|
165
|
+
);
|
|
166
|
+
var sealAiPocketTestPartition = (split, sealed) => {
|
|
167
|
+
const finiteTimestamps = split.testRows.map((row) => row.timestamp).filter((timestamp) => Number.isFinite(timestamp));
|
|
168
|
+
return {
|
|
169
|
+
discoveryRows: [
|
|
170
|
+
...split.trainRows,
|
|
171
|
+
...split.validationRows,
|
|
172
|
+
...sealed ? [] : split.testRows
|
|
173
|
+
],
|
|
174
|
+
searchTestRows: sealed ? [] : split.testRows,
|
|
175
|
+
evidence: {
|
|
176
|
+
sealed,
|
|
177
|
+
rows: split.testRows.length,
|
|
178
|
+
events: countIndependentEvents(split.testRows),
|
|
179
|
+
startTimestamp: finiteTimestamps.length ? Math.min(...finiteTimestamps) : null,
|
|
180
|
+
endTimestamp: finiteTimestamps.length ? Math.max(...finiteTimestamps) : null
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
};
|
|
74
184
|
var readAiPocketSearchCliOption = ({
|
|
75
185
|
argv,
|
|
76
186
|
longName,
|
|
@@ -92,5 +202,8 @@ var readAiPocketSearchCliOption = ({
|
|
|
92
202
|
0 && (module.exports = {
|
|
93
203
|
AI_POCKET_SEARCH_CLI_DECIMAL_DEFAULTS,
|
|
94
204
|
readAiPocketSearchCliOption,
|
|
205
|
+
resolveAiPocketCadenceProfile,
|
|
206
|
+
sealAiPocketTestPartition,
|
|
207
|
+
splitAiPocketCoverageRowsByTimestamp,
|
|
95
208
|
splitAiPocketResearchRowsByTimestamp
|
|
96
209
|
});
|
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/lib/aiTrainCharts.ts
|
|
21
21
|
var aiTrainCharts_exports = {};
|
|
22
22
|
__export(aiTrainCharts_exports, {
|
|
23
|
+
buildAiChartPersistenceReceipt: () => buildAiChartPersistenceReceipt,
|
|
23
24
|
buildAiChartSnapshot: () => buildAiChartSnapshot
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(aiTrainCharts_exports);
|
|
@@ -303,7 +304,10 @@ var getDirectionSortKey = (direction) => {
|
|
|
303
304
|
return 2;
|
|
304
305
|
};
|
|
305
306
|
var summarizeAiTrainEvaluationsByDirection = (evaluations) => {
|
|
306
|
-
const grouped = /* @__PURE__ */ new Map(
|
|
307
|
+
const grouped = /* @__PURE__ */ new Map([
|
|
308
|
+
["LONG", []],
|
|
309
|
+
["SHORT", []]
|
|
310
|
+
]);
|
|
307
311
|
for (const evaluation of evaluations) {
|
|
308
312
|
const direction = typeof evaluation.direction === "string" && evaluation.direction.trim() ? evaluation.direction : "UNKNOWN";
|
|
309
313
|
const bucket = grouped.get(direction) ?? [];
|
|
@@ -752,7 +756,16 @@ var buildAiChartSnapshot = (params) => {
|
|
|
752
756
|
strategies: cards
|
|
753
757
|
};
|
|
754
758
|
};
|
|
759
|
+
var buildAiChartPersistenceReceipt = (params) => ({
|
|
760
|
+
persisted: true,
|
|
761
|
+
mode: params.snapshot.mode,
|
|
762
|
+
datasetId: params.datasetId,
|
|
763
|
+
generatedAt: params.snapshot.generatedAt,
|
|
764
|
+
cardIds: params.snapshot.strategies.map((card) => card.cardId),
|
|
765
|
+
ttlMs: params.ttlMs
|
|
766
|
+
});
|
|
755
767
|
// Annotate the CommonJS export names for ESM import in node:
|
|
756
768
|
0 && (module.exports = {
|
|
769
|
+
buildAiChartPersistenceReceipt,
|
|
757
770
|
buildAiChartSnapshot
|
|
758
771
|
});
|
|
@@ -314,7 +314,10 @@ var isDirectionMatchAtThreshold = (evaluation, threshold) => {
|
|
|
314
314
|
return directionMatches === true && evaluation.quality != null && evaluation.quality >= threshold;
|
|
315
315
|
};
|
|
316
316
|
var summarizeAiTrainEvaluationsByDirection = (evaluations) => {
|
|
317
|
-
const grouped = /* @__PURE__ */ new Map(
|
|
317
|
+
const grouped = /* @__PURE__ */ new Map([
|
|
318
|
+
["LONG", []],
|
|
319
|
+
["SHORT", []]
|
|
320
|
+
]);
|
|
318
321
|
for (const evaluation of evaluations) {
|
|
319
322
|
const direction = typeof evaluation.direction === "string" && evaluation.direction.trim() ? evaluation.direction : "UNKNOWN";
|
|
320
323
|
const bucket = grouped.get(direction) ?? [];
|
|
@@ -39,9 +39,9 @@ __export(aiTrainResearch_exports, {
|
|
|
39
39
|
});
|
|
40
40
|
module.exports = __toCommonJS(aiTrainResearch_exports);
|
|
41
41
|
var import_node_child_process = require("child_process");
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var
|
|
42
|
+
var import_node_crypto2 = require("crypto");
|
|
43
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
44
|
+
var import_node_path2 = __toESM(require("path"));
|
|
45
45
|
|
|
46
46
|
// src/lib/aiTrainMetrics.ts
|
|
47
47
|
var divideOrNull = (num, denom) => {
|
|
@@ -312,10 +312,82 @@ var summarizeAiTrainEvaluations = (evaluations) => {
|
|
|
312
312
|
)
|
|
313
313
|
};
|
|
314
314
|
};
|
|
315
|
+
var getDirectionSortKey = (direction) => {
|
|
316
|
+
if (direction === "LONG") {
|
|
317
|
+
return 0;
|
|
318
|
+
}
|
|
319
|
+
if (direction === "SHORT") {
|
|
320
|
+
return 1;
|
|
321
|
+
}
|
|
322
|
+
return 2;
|
|
323
|
+
};
|
|
324
|
+
var summarizeAiTrainEvaluationsByDirection = (evaluations) => {
|
|
325
|
+
const grouped = /* @__PURE__ */ new Map([
|
|
326
|
+
["LONG", []],
|
|
327
|
+
["SHORT", []]
|
|
328
|
+
]);
|
|
329
|
+
for (const evaluation of evaluations) {
|
|
330
|
+
const direction = typeof evaluation.direction === "string" && evaluation.direction.trim() ? evaluation.direction : "UNKNOWN";
|
|
331
|
+
const bucket = grouped.get(direction) ?? [];
|
|
332
|
+
bucket.push(evaluation);
|
|
333
|
+
grouped.set(direction, bucket);
|
|
334
|
+
}
|
|
335
|
+
return [...grouped.entries()].sort(
|
|
336
|
+
([leftDirection], [rightDirection]) => getDirectionSortKey(leftDirection) - getDirectionSortKey(rightDirection) || leftDirection.localeCompare(rightDirection)
|
|
337
|
+
).map(([direction, directionEvaluations]) => ({
|
|
338
|
+
direction,
|
|
339
|
+
summary: summarizeAiTrainEvaluations(directionEvaluations)
|
|
340
|
+
}));
|
|
341
|
+
};
|
|
315
342
|
|
|
316
343
|
// src/lib/aiTrainResearch.ts
|
|
317
344
|
var import_strategies = require("@tradejs/node/strategies");
|
|
318
345
|
var import_types = require("@tradejs/types");
|
|
346
|
+
|
|
347
|
+
// src/lib/strategyGateFingerprint.ts
|
|
348
|
+
var import_node_crypto = require("crypto");
|
|
349
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
350
|
+
var import_node_path = __toESM(require("path"));
|
|
351
|
+
var gateFingerprintRelativePaths = (strategyName) => [
|
|
352
|
+
`packages/strategies/src/${strategyName}/adapters/ai.ts`,
|
|
353
|
+
`packages/strategies/src/${strategyName}/guardrails.ts`,
|
|
354
|
+
`packages/strategies/src/${strategyName}/pockets.ts`,
|
|
355
|
+
`packages/strategies/src/${strategyName}/config.ts`,
|
|
356
|
+
"packages/strategies/src/shared/localAiGate.ts",
|
|
357
|
+
"packages/node/src/ai.ts",
|
|
358
|
+
"packages/core/src/utils/strategyHelpers/signalBuilders.ts"
|
|
359
|
+
];
|
|
360
|
+
var resolveStrategyGateFingerprint = async ({
|
|
361
|
+
projectRoot,
|
|
362
|
+
strategyName,
|
|
363
|
+
gitSha
|
|
364
|
+
}) => {
|
|
365
|
+
const candidates = await Promise.all(
|
|
366
|
+
gateFingerprintRelativePaths(strategyName).map(async (relativePath) => {
|
|
367
|
+
const content = await import_promises.default.readFile(import_node_path.default.join(projectRoot, relativePath)).catch(() => null);
|
|
368
|
+
return content == null ? null : { relativePath, content };
|
|
369
|
+
})
|
|
370
|
+
);
|
|
371
|
+
const sourceEntries = candidates.filter(
|
|
372
|
+
(entry) => entry != null
|
|
373
|
+
);
|
|
374
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
375
|
+
hash.update(strategyName);
|
|
376
|
+
if (sourceEntries.length) {
|
|
377
|
+
for (const entry of sourceEntries) {
|
|
378
|
+
hash.update(entry.relativePath);
|
|
379
|
+
hash.update(entry.content);
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
hash.update(gitSha ?? "unknown-git-sha");
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
gateFingerprint: hash.digest("hex").slice(0, 16),
|
|
386
|
+
gateFingerprintFiles: sourceEntries.map((entry) => entry.relativePath)
|
|
387
|
+
};
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
// src/lib/aiTrainResearch.ts
|
|
319
391
|
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
320
392
|
var RESEARCH_CONTEXT_ENV_KEYS = [
|
|
321
393
|
"AI_MODE",
|
|
@@ -355,9 +427,9 @@ var writeAiTrainResearchSnapshot = async ({
|
|
|
355
427
|
outputPath,
|
|
356
428
|
result
|
|
357
429
|
}) => {
|
|
358
|
-
const resolvedPath =
|
|
359
|
-
await
|
|
360
|
-
await
|
|
430
|
+
const resolvedPath = import_node_path2.default.resolve(outputPath);
|
|
431
|
+
await import_promises2.default.mkdir(import_node_path2.default.dirname(resolvedPath), { recursive: true });
|
|
432
|
+
await import_promises2.default.writeFile(
|
|
361
433
|
resolvedPath,
|
|
362
434
|
`${JSON.stringify(result, null, 2)}
|
|
363
435
|
`,
|
|
@@ -376,7 +448,7 @@ var normalizeForStableJson = (value) => {
|
|
|
376
448
|
}
|
|
377
449
|
return value;
|
|
378
450
|
};
|
|
379
|
-
var fingerprintResearchValue = (value) => (0,
|
|
451
|
+
var fingerprintResearchValue = (value) => (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
380
452
|
var getTimestampRange = (evaluations) => {
|
|
381
453
|
let minTimestamp = null;
|
|
382
454
|
let maxTimestamp = null;
|
|
@@ -441,17 +513,11 @@ var summarizeAiTrainTerminalWindows = (evaluations, windowDays) => {
|
|
|
441
513
|
selected: selected.length,
|
|
442
514
|
approvedPerCalendarDay: outcome.approved / coverageDays,
|
|
443
515
|
outcome,
|
|
516
|
+
byDirection: summarizeAiTrainEvaluationsByDirection(selected),
|
|
444
517
|
topRejectReasons: summarizeAiTrainRejectReasons(selected)
|
|
445
518
|
};
|
|
446
519
|
});
|
|
447
520
|
};
|
|
448
|
-
var readOptionalFile = async (filePath) => {
|
|
449
|
-
try {
|
|
450
|
-
return await import_promises.default.readFile(filePath);
|
|
451
|
-
} catch {
|
|
452
|
-
return null;
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
521
|
var getGitLineage = (projectRoot) => {
|
|
456
522
|
try {
|
|
457
523
|
const gitSha = (0, import_node_child_process.execFileSync)("git", ["rev-parse", "HEAD"], {
|
|
@@ -473,53 +539,20 @@ var getGitLineage = (projectRoot) => {
|
|
|
473
539
|
return { gitSha: null, gitDirty: null };
|
|
474
540
|
}
|
|
475
541
|
};
|
|
476
|
-
var resolveGateFingerprint = async (projectRoot, strategyName, gitSha) => {
|
|
477
|
-
const relativeCandidates = [
|
|
478
|
-
`packages/strategies/src/${strategyName}/adapters/ai.ts`,
|
|
479
|
-
`packages/strategies/src/${strategyName}/guardrails.ts`,
|
|
480
|
-
`packages/strategies/src/${strategyName}/pockets.ts`,
|
|
481
|
-
`packages/strategies/src/${strategyName}/config.ts`,
|
|
482
|
-
"packages/strategies/src/shared/localAiGate.ts",
|
|
483
|
-
"packages/node/src/ai.ts"
|
|
484
|
-
];
|
|
485
|
-
const optionalSourceEntries = await Promise.all(
|
|
486
|
-
relativeCandidates.map(async (relativePath) => {
|
|
487
|
-
const content = await readOptionalFile(
|
|
488
|
-
import_node_path.default.join(projectRoot, relativePath)
|
|
489
|
-
);
|
|
490
|
-
return content == null ? null : { relativePath, content };
|
|
491
|
-
})
|
|
492
|
-
);
|
|
493
|
-
const sourceEntries = [];
|
|
494
|
-
for (const entry of optionalSourceEntries) {
|
|
495
|
-
if (entry != null) {
|
|
496
|
-
sourceEntries.push(entry);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
500
|
-
hash.update(strategyName);
|
|
501
|
-
if (sourceEntries.length) {
|
|
502
|
-
for (const entry of sourceEntries) {
|
|
503
|
-
hash.update(entry.relativePath);
|
|
504
|
-
hash.update(entry.content);
|
|
505
|
-
}
|
|
506
|
-
} else {
|
|
507
|
-
hash.update(gitSha ?? "unknown-git-sha");
|
|
508
|
-
}
|
|
509
|
-
return {
|
|
510
|
-
gateFingerprint: hash.digest("hex").slice(0, 16),
|
|
511
|
-
gateFingerprintFiles: sourceEntries.map((entry) => entry.relativePath)
|
|
512
|
-
};
|
|
513
|
-
};
|
|
514
542
|
var buildAiTrainLineage = async ({
|
|
515
543
|
projectRoot,
|
|
516
544
|
strategyName,
|
|
517
545
|
configIds,
|
|
518
546
|
runContext,
|
|
547
|
+
sourceSha256s = [],
|
|
519
548
|
env = process.env
|
|
520
549
|
}) => {
|
|
521
550
|
const { gitSha, gitDirty } = getGitLineage(projectRoot);
|
|
522
|
-
const gate = await
|
|
551
|
+
const gate = await resolveStrategyGateFingerprint({
|
|
552
|
+
projectRoot,
|
|
553
|
+
strategyName,
|
|
554
|
+
gitSha
|
|
555
|
+
});
|
|
523
556
|
const normalizedConfigIds = [...new Set(configIds.filter(Boolean))].sort();
|
|
524
557
|
const hyperliquidPerpUniverseFingerprint = typeof import_strategies.getHyperliquidPerpUniverseSnapshot === "function" ? (0, import_strategies.getHyperliquidPerpUniverseSnapshot)().fingerprint : null;
|
|
525
558
|
const hyperliquidWhaleRegistryFingerprint = typeof import_strategies.getHyperliquidWhaleRegistrySnapshot === "function" ? (0, import_strategies.getHyperliquidWhaleRegistrySnapshot)().fingerprint : null;
|
|
@@ -539,7 +572,8 @@ var buildAiTrainLineage = async ({
|
|
|
539
572
|
configIdsFingerprint: fingerprintResearchValue(normalizedConfigIds),
|
|
540
573
|
configIds: normalizedConfigIds,
|
|
541
574
|
contextFingerprint: fingerprintResearchValue(context),
|
|
542
|
-
context
|
|
575
|
+
context,
|
|
576
|
+
sourceSha256s: [...new Set(sourceSha256s.filter(Boolean))].sort()
|
|
543
577
|
};
|
|
544
578
|
};
|
|
545
579
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -47,7 +47,8 @@ var import_chalk = __toESM(require("chalk"));
|
|
|
47
47
|
var import_connectors = require("@tradejs/connectors");
|
|
48
48
|
var import_connectors2 = require("@tradejs/node/connectors");
|
|
49
49
|
var import_strategies = require("@tradejs/node/strategies");
|
|
50
|
-
var
|
|
50
|
+
var import_marketContext = require("@tradejs/infra/timescale/marketContext");
|
|
51
|
+
var import_client = require("@tradejs/infra/timescale/client");
|
|
51
52
|
|
|
52
53
|
// src/lib/binanceMarketData.ts
|
|
53
54
|
var MARKET_FEATURE_INTERVAL_MS = {
|
|
@@ -555,7 +556,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
555
556
|
if (endMs <= Math.min(breadthStartMs, tradeFlowStartMs)) {
|
|
556
557
|
return skippedBackfillResult();
|
|
557
558
|
}
|
|
558
|
-
await (0,
|
|
559
|
+
await (0, import_client.waitForDbReady)();
|
|
559
560
|
const connector = await getBinanceConnector({
|
|
560
561
|
projectRoot: params.projectRoot,
|
|
561
562
|
userName: params.userName
|
|
@@ -601,7 +602,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
601
602
|
)
|
|
602
603
|
);
|
|
603
604
|
if (includeTradeFlow && referenceSymbols.length) {
|
|
604
|
-
const coverage = await (0,
|
|
605
|
+
const coverage = await (0, import_marketContext.getMarketTradeFlowCoverage)({
|
|
605
606
|
symbols: referenceSymbols,
|
|
606
607
|
interval,
|
|
607
608
|
startMs: tradeFlowStartMs,
|
|
@@ -685,7 +686,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
685
686
|
const ts = row.ts.getTime();
|
|
686
687
|
return ts >= chunk.startMs && ts <= chunk.endMs;
|
|
687
688
|
});
|
|
688
|
-
await (0,
|
|
689
|
+
await (0, import_marketContext.upsertMarketTradeFlowRows)(boundedRows);
|
|
689
690
|
tradeFlowRows += boundedRows.length;
|
|
690
691
|
chunkBar?.tick(1, {
|
|
691
692
|
rows: tradeFlowRows,
|
|
@@ -713,7 +714,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
713
714
|
});
|
|
714
715
|
const plans = await Promise.all(
|
|
715
716
|
breadthUniverses.map(async (definition) => {
|
|
716
|
-
const coverage = await (0,
|
|
717
|
+
const coverage = await (0, import_marketContext.getMarketBreadthCoverage)({
|
|
717
718
|
universe: definition.universe,
|
|
718
719
|
interval,
|
|
719
720
|
startMs: breadthStartMs,
|
|
@@ -814,7 +815,7 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
814
815
|
const ts = row.ts.getTime();
|
|
815
816
|
return ts >= chunk.startMs && ts <= chunk.endMs;
|
|
816
817
|
});
|
|
817
|
-
await (0,
|
|
818
|
+
await (0, import_marketContext.upsertMarketBreadthRows)(rows);
|
|
818
819
|
breadthRows += rows.length;
|
|
819
820
|
}
|
|
820
821
|
}
|
|
@@ -49,7 +49,8 @@ __export(coinMarketCapContextBackfill_exports, {
|
|
|
49
49
|
module.exports = __toCommonJS(coinMarketCapContextBackfill_exports);
|
|
50
50
|
var import_chalk = __toESM(require("chalk"));
|
|
51
51
|
var import_async = require("@tradejs/core/async");
|
|
52
|
-
var
|
|
52
|
+
var import_marketContext = require("@tradejs/infra/timescale/marketContext");
|
|
53
|
+
var import_client = require("@tradejs/infra/timescale/client");
|
|
53
54
|
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
54
55
|
var DAY_MS = 864e5;
|
|
55
56
|
var DEFAULT_CONTEXT_MAX_AGE_MS = 48 * 60 * 6e4;
|
|
@@ -313,7 +314,7 @@ var logBackfillSourceDone = (params) => {
|
|
|
313
314
|
)
|
|
314
315
|
);
|
|
315
316
|
};
|
|
316
|
-
var markBackfillCoverage = (rows) => (0,
|
|
317
|
+
var markBackfillCoverage = (rows) => (0, import_marketContext.upsertMarketContextBackfillCoverage)(rows);
|
|
317
318
|
var coinMarketCapFetch = async (params) => {
|
|
318
319
|
const url = new URL(`${getBaseUrl()}${params.path}`);
|
|
319
320
|
for (const [key, value] of Object.entries(params.searchParams)) {
|
|
@@ -642,7 +643,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
642
643
|
if (toMs <= fromMs) return skippedResult();
|
|
643
644
|
const exchangeLiquidityEnabled = isExchangeLiquidityBackfillEnabled();
|
|
644
645
|
const fearGreedEnabled = isFearGreedBackfillEnabled();
|
|
645
|
-
await (0,
|
|
646
|
+
await (0, import_client.waitForDbReady)();
|
|
646
647
|
const [
|
|
647
648
|
globalDailyCoverage,
|
|
648
649
|
referenceDailyCoverage,
|
|
@@ -655,66 +656,66 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
655
656
|
fearGreedBackfillCoverage,
|
|
656
657
|
indexBackfillCoverage
|
|
657
658
|
] = await Promise.all([
|
|
658
|
-
(0,
|
|
659
|
+
(0, import_marketContext.getMarketGlobalContextCoverage)({
|
|
659
660
|
source: SOURCE_GLOBAL_DAILY,
|
|
660
661
|
startMs: fromMs,
|
|
661
662
|
endMs: toMs
|
|
662
663
|
}),
|
|
663
|
-
(0,
|
|
664
|
+
(0, import_marketContext.getMarketReferenceAssetContextCoverage)({
|
|
664
665
|
source: SOURCE_REFERENCE,
|
|
665
666
|
symbols: REFERENCE_ASSETS.map((item) => item.symbol),
|
|
666
667
|
interval: "1d",
|
|
667
668
|
startMs: fromMs,
|
|
668
669
|
endMs: toMs
|
|
669
670
|
}),
|
|
670
|
-
exchangeLiquidityEnabled ? (0,
|
|
671
|
+
exchangeLiquidityEnabled ? (0, import_marketContext.getMarketCmcExchangeLiquidityContextCoverage)({
|
|
671
672
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
672
673
|
interval: "1d",
|
|
673
674
|
startMs: fromMs,
|
|
674
675
|
endMs: toMs
|
|
675
676
|
}) : Promise.resolve(null),
|
|
676
|
-
fearGreedEnabled ? (0,
|
|
677
|
+
fearGreedEnabled ? (0, import_marketContext.getMarketCmcFearGreedContextCoverage)({
|
|
677
678
|
source: SOURCE_FEAR_GREED,
|
|
678
679
|
interval: "1d",
|
|
679
680
|
startMs: fromMs,
|
|
680
681
|
endMs: toMs
|
|
681
682
|
}) : Promise.resolve(null),
|
|
682
|
-
(0,
|
|
683
|
+
(0, import_marketContext.getMarketCmcIndexContextCoverage)({
|
|
683
684
|
source: SOURCE_INDEX,
|
|
684
685
|
indexSlugs: CMC_INDEXES.map((index) => index.slug),
|
|
685
686
|
interval: "1d",
|
|
686
687
|
startMs: fromMs,
|
|
687
688
|
endMs: toMs
|
|
688
689
|
}),
|
|
689
|
-
(0,
|
|
690
|
+
(0, import_marketContext.getMarketContextBackfillCoverage)({
|
|
690
691
|
source: SOURCE_GLOBAL_DAILY,
|
|
691
692
|
scopes: [COVERAGE_SCOPE_ALL],
|
|
692
693
|
interval: "1d",
|
|
693
694
|
fromMs,
|
|
694
695
|
toMs
|
|
695
696
|
}),
|
|
696
|
-
(0,
|
|
697
|
+
(0, import_marketContext.getMarketContextBackfillCoverage)({
|
|
697
698
|
source: SOURCE_REFERENCE,
|
|
698
699
|
scopes: REFERENCE_ASSETS.map((item) => item.symbol),
|
|
699
700
|
interval: "1d",
|
|
700
701
|
fromMs,
|
|
701
702
|
toMs
|
|
702
703
|
}),
|
|
703
|
-
exchangeLiquidityEnabled ? (0,
|
|
704
|
+
exchangeLiquidityEnabled ? (0, import_marketContext.getMarketContextBackfillCoverage)({
|
|
704
705
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
705
706
|
scopes: [COVERAGE_SCOPE_ALL],
|
|
706
707
|
interval: "1d",
|
|
707
708
|
fromMs,
|
|
708
709
|
toMs
|
|
709
710
|
}) : Promise.resolve([]),
|
|
710
|
-
fearGreedEnabled ? (0,
|
|
711
|
+
fearGreedEnabled ? (0, import_marketContext.getMarketContextBackfillCoverage)({
|
|
711
712
|
source: SOURCE_FEAR_GREED,
|
|
712
713
|
scopes: [COVERAGE_SCOPE_ALL],
|
|
713
714
|
interval: "1d",
|
|
714
715
|
fromMs,
|
|
715
716
|
toMs
|
|
716
717
|
}) : Promise.resolve([]),
|
|
717
|
-
(0,
|
|
718
|
+
(0, import_marketContext.getMarketContextBackfillCoverage)({
|
|
718
719
|
source: SOURCE_INDEX,
|
|
719
720
|
scopes: CMC_INDEXES.map((index) => index.slug),
|
|
720
721
|
interval: "1d",
|
|
@@ -905,7 +906,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
905
906
|
}
|
|
906
907
|
});
|
|
907
908
|
const rows = coinMarketCapGlobalPayloadToRows(payload, SOURCE_GLOBAL_DAILY);
|
|
908
|
-
await (0,
|
|
909
|
+
await (0, import_marketContext.upsertMarketGlobalContextRows)(rows);
|
|
909
910
|
await markBackfillCoverage([
|
|
910
911
|
{
|
|
911
912
|
source: SOURCE_GLOBAL_DAILY,
|
|
@@ -939,7 +940,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
939
940
|
}
|
|
940
941
|
});
|
|
941
942
|
const rows = coinMarketCapHistoricalQuotesPayloadToRows(payload, "1d");
|
|
942
|
-
await (0,
|
|
943
|
+
await (0, import_marketContext.upsertMarketReferenceAssetContextRows)(rows);
|
|
943
944
|
await markBackfillCoverage(
|
|
944
945
|
REFERENCE_ASSETS.map((asset) => ({
|
|
945
946
|
source: SOURCE_REFERENCE,
|
|
@@ -978,7 +979,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
978
979
|
payload,
|
|
979
980
|
"1d"
|
|
980
981
|
);
|
|
981
|
-
await (0,
|
|
982
|
+
await (0, import_marketContext.upsertMarketCmcExchangeLiquidityContextRows)(rows);
|
|
982
983
|
await markBackfillCoverage([
|
|
983
984
|
{
|
|
984
985
|
source: SOURCE_EXCHANGE_LIQUIDITY,
|
|
@@ -1023,7 +1024,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
1023
1024
|
const oldestPageTs = Math.min(...pageRows.map((row) => row.ts.getTime()));
|
|
1024
1025
|
if (oldestPageTs < fromMs || pageRows.length < pageSize) break;
|
|
1025
1026
|
}
|
|
1026
|
-
await (0,
|
|
1027
|
+
await (0, import_marketContext.upsertMarketCmcFearGreedContextRows)(rows);
|
|
1027
1028
|
await markBackfillCoverage([
|
|
1028
1029
|
{
|
|
1029
1030
|
source: SOURCE_FEAR_GREED,
|
|
@@ -1057,7 +1058,7 @@ var backfillCoinMarketCapContext = async (params) => {
|
|
|
1057
1058
|
}))
|
|
1058
1059
|
);
|
|
1059
1060
|
const rows = rowsByIndex.flatMap((item) => item.result.rows);
|
|
1060
|
-
await (0,
|
|
1061
|
+
await (0, import_marketContext.upsertMarketCmcIndexContextRows)(rows);
|
|
1061
1062
|
await markBackfillCoverage(
|
|
1062
1063
|
rowsByIndex.map(({ index, result }) => ({
|
|
1063
1064
|
source: SOURCE_INDEX,
|