@tradejs/cli 2.0.15 → 2.0.16
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 +2916 -978
- package/dist/lib/aiPocketSearch.js +493 -24
- package/dist/lib/aiTrainResearch.js +19 -2
- package/dist/lib/marketContextPrepare.js +85 -8
- 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 +83 -8
- package/dist/scripts/replay.js +92 -8
- package/dist/scripts/replayRunner.js +92 -8
- 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 +83 -8
- package/dist/scripts/runtimeScorecard.js +731 -0
- package/dist/scripts/signals.js +234 -142
- package/dist/scripts/signalsDaemon.js +234 -142
- package/dist/scripts/signalsSummary.js +9 -0
- package/dist/workers/testerWorker.js +2 -0
- package/package.json +11 -9
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/scripts/runtimeEvidenceSync.ts
|
|
31
|
+
var runtimeEvidenceSync_exports = {};
|
|
32
|
+
__export(runtimeEvidenceSync_exports, {
|
|
33
|
+
main: () => main,
|
|
34
|
+
runtimeEvidenceSync: () => runtimeEvidenceSync
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(runtimeEvidenceSync_exports);
|
|
37
|
+
var import_node_path3 = __toESM(require("path"));
|
|
38
|
+
var import_args = __toESM(require("args"));
|
|
39
|
+
var import_chalk = __toESM(require("chalk"));
|
|
40
|
+
|
|
41
|
+
// src/lib/runtimeEvidenceSync.ts
|
|
42
|
+
var import_node_child_process = require("child_process");
|
|
43
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
44
|
+
var import_node_path2 = __toESM(require("path"));
|
|
45
|
+
var import_node_util = require("util");
|
|
46
|
+
|
|
47
|
+
// src/lib/runtimeEvidenceArtifacts.ts
|
|
48
|
+
var import_node_crypto = require("crypto");
|
|
49
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
50
|
+
var import_node_path = __toESM(require("path"));
|
|
51
|
+
var RUNTIME_EVIDENCE_MANIFEST_FILE = "manifest.json";
|
|
52
|
+
var RUNTIME_EVIDENCE_PAYLOAD_FILE = "runtime-evidence.json";
|
|
53
|
+
var RUNTIME_EVIDENCE_COMPLETE_FILE = ".complete";
|
|
54
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
55
|
+
var sha256 = (value) => (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
|
|
56
|
+
var assertFiniteTimestamp = (value, label) => {
|
|
57
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
58
|
+
throw new Error(`Invalid runtime evidence ${label}`);
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
};
|
|
62
|
+
var parseManifest = (value) => {
|
|
63
|
+
const manifest = asRecord(value);
|
|
64
|
+
const window = asRecord(manifest?.window);
|
|
65
|
+
const payload = asRecord(manifest?.payload);
|
|
66
|
+
const counts = asRecord(manifest?.counts);
|
|
67
|
+
if (manifest?.schemaVersion !== 1 || manifest.reportType !== "runtime-evidence" || typeof manifest.artifactId !== "string" || typeof manifest.deploymentId !== "string" || typeof manifest.userName !== "string" || typeof manifest.createdAt !== "number" || payload?.file !== RUNTIME_EVIDENCE_PAYLOAD_FILE || typeof payload.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.sha256) || typeof payload.bytes !== "number" || !Array.isArray(manifest.lineageKeys)) {
|
|
68
|
+
throw new Error("Invalid runtime evidence manifest");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
schemaVersion: 1,
|
|
72
|
+
artifactId: manifest.artifactId,
|
|
73
|
+
reportType: "runtime-evidence",
|
|
74
|
+
deploymentId: manifest.deploymentId,
|
|
75
|
+
userName: manifest.userName,
|
|
76
|
+
createdAt: manifest.createdAt,
|
|
77
|
+
window: {
|
|
78
|
+
startTime: assertFiniteTimestamp(window?.startTime, "window.startTime"),
|
|
79
|
+
endTime: assertFiniteTimestamp(window?.endTime, "window.endTime")
|
|
80
|
+
},
|
|
81
|
+
payload: {
|
|
82
|
+
file: RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
83
|
+
sha256: payload.sha256,
|
|
84
|
+
bytes: payload.bytes
|
|
85
|
+
},
|
|
86
|
+
counts: Object.fromEntries(
|
|
87
|
+
Object.entries(counts ?? {}).filter(
|
|
88
|
+
(entry) => typeof entry[1] === "number" && Number.isFinite(entry[1])
|
|
89
|
+
)
|
|
90
|
+
),
|
|
91
|
+
lineageKeys: manifest.lineageKeys.filter(
|
|
92
|
+
(value2) => typeof value2 === "string" && value2.length > 0
|
|
93
|
+
)
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
var verifyRuntimeEvidenceBundle = async (bundleDir) => {
|
|
97
|
+
const manifestPath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_MANIFEST_FILE);
|
|
98
|
+
const payloadPath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_PAYLOAD_FILE);
|
|
99
|
+
const completePath = import_node_path.default.join(bundleDir, RUNTIME_EVIDENCE_COMPLETE_FILE);
|
|
100
|
+
const [manifestText, payload, completeText] = await Promise.all([
|
|
101
|
+
import_promises.default.readFile(manifestPath, "utf8"),
|
|
102
|
+
import_promises.default.readFile(payloadPath),
|
|
103
|
+
import_promises.default.readFile(completePath, "utf8")
|
|
104
|
+
]);
|
|
105
|
+
const manifest = parseManifest(JSON.parse(manifestText));
|
|
106
|
+
if (completeText.trim() !== manifest.artifactId) {
|
|
107
|
+
throw new Error(`Invalid completion marker in ${bundleDir}`);
|
|
108
|
+
}
|
|
109
|
+
if (payload.byteLength !== manifest.payload.bytes) {
|
|
110
|
+
throw new Error(`Runtime evidence size mismatch in ${bundleDir}`);
|
|
111
|
+
}
|
|
112
|
+
if (sha256(payload) !== manifest.payload.sha256) {
|
|
113
|
+
throw new Error(`Runtime evidence checksum mismatch in ${bundleDir}`);
|
|
114
|
+
}
|
|
115
|
+
const artifact = asRecord(JSON.parse(payload.toString("utf8")));
|
|
116
|
+
const artifactWindow = asRecord(artifact?.window);
|
|
117
|
+
if (artifact?.reportType !== "runtime-evidence" || artifactWindow?.startTime !== manifest.window.startTime || artifactWindow.endTime !== manifest.window.endTime) {
|
|
118
|
+
throw new Error(`Runtime evidence payload mismatch in ${bundleDir}`);
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
bundleDir,
|
|
122
|
+
manifestPath,
|
|
123
|
+
payloadPath,
|
|
124
|
+
manifest,
|
|
125
|
+
artifact
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
var discoverRuntimeEvidenceBundles = async (rootDir) => {
|
|
129
|
+
const bundles = [];
|
|
130
|
+
const visit = async (directory, depth) => {
|
|
131
|
+
if (depth > 8) return;
|
|
132
|
+
let entries;
|
|
133
|
+
try {
|
|
134
|
+
entries = await import_promises.default.readdir(directory, { withFileTypes: true });
|
|
135
|
+
} catch (error) {
|
|
136
|
+
if (error.code === "ENOENT") return;
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
140
|
+
if (names.has(RUNTIME_EVIDENCE_MANIFEST_FILE) && names.has(RUNTIME_EVIDENCE_PAYLOAD_FILE) && names.has(RUNTIME_EVIDENCE_COMPLETE_FILE)) {
|
|
141
|
+
bundles.push(directory);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
await Promise.all(
|
|
145
|
+
entries.filter(
|
|
146
|
+
(entry) => entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.includes(".tmp-")
|
|
147
|
+
).map((entry) => visit(import_node_path.default.join(directory, entry.name), depth + 1))
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
await visit(rootDir, 0);
|
|
151
|
+
return bundles.sort();
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// src/lib/runtimeEvidenceSync.ts
|
|
155
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
156
|
+
var isExistingDestinationError = (error) => {
|
|
157
|
+
const code = error.code;
|
|
158
|
+
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
159
|
+
};
|
|
160
|
+
var safeSegment = (value, fallback) => {
|
|
161
|
+
const normalized = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
162
|
+
return normalized && normalized !== "." && normalized !== ".." ? normalized : fallback;
|
|
163
|
+
};
|
|
164
|
+
var withTrailingSlash = (value) => value.endsWith("/") ? value : `${value}/`;
|
|
165
|
+
var dateParts = (timestamp) => {
|
|
166
|
+
const date = new Date(timestamp);
|
|
167
|
+
return [
|
|
168
|
+
String(date.getUTCFullYear()),
|
|
169
|
+
String(date.getUTCMonth() + 1).padStart(2, "0"),
|
|
170
|
+
String(date.getUTCDate()).padStart(2, "0")
|
|
171
|
+
];
|
|
172
|
+
};
|
|
173
|
+
var buildRuntimeEvidenceRsyncArgs = ({
|
|
174
|
+
source,
|
|
175
|
+
destination
|
|
176
|
+
}) => [
|
|
177
|
+
"--recursive",
|
|
178
|
+
"--times",
|
|
179
|
+
"--partial",
|
|
180
|
+
"--partial-dir=.rsync-partial",
|
|
181
|
+
"--prune-empty-dirs",
|
|
182
|
+
withTrailingSlash(source),
|
|
183
|
+
withTrailingSlash(destination)
|
|
184
|
+
];
|
|
185
|
+
var receiptPath = (receiptsRoot, artifactId) => import_node_path2.default.join(receiptsRoot, `${safeSegment(artifactId, "artifact")}.json`);
|
|
186
|
+
var listPendingRuntimeEvidenceBundles = async ({
|
|
187
|
+
evidenceRoot,
|
|
188
|
+
deploymentId
|
|
189
|
+
}) => {
|
|
190
|
+
const safeDeploymentId = safeSegment(deploymentId, "production");
|
|
191
|
+
const artifactsRoot = import_node_path2.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
192
|
+
const receiptsRoot = import_node_path2.default.join(evidenceRoot, "receipts", safeDeploymentId);
|
|
193
|
+
const bundles = await discoverRuntimeEvidenceBundles(artifactsRoot);
|
|
194
|
+
const pending = [];
|
|
195
|
+
for (const bundleDir of bundles) {
|
|
196
|
+
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
197
|
+
if (verified.manifest.deploymentId !== safeDeploymentId) continue;
|
|
198
|
+
try {
|
|
199
|
+
await import_promises2.default.access(receiptPath(receiptsRoot, verified.manifest.artifactId));
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (error.code !== "ENOENT") throw error;
|
|
202
|
+
pending.push(verified);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return pending.sort(
|
|
206
|
+
(left, right) => left.manifest.window.startTime - right.manifest.window.startTime || left.manifest.createdAt - right.manifest.createdAt
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
var syncRuntimeEvidenceBundles = async ({
|
|
210
|
+
source,
|
|
211
|
+
evidenceRoot,
|
|
212
|
+
deploymentId,
|
|
213
|
+
runRsync = async (args2) => {
|
|
214
|
+
const result = await execFileAsync("rsync", args2, {
|
|
215
|
+
maxBuffer: 10 * 1024 * 1024
|
|
216
|
+
});
|
|
217
|
+
return { stdout: result.stdout, stderr: result.stderr };
|
|
218
|
+
}
|
|
219
|
+
}) => {
|
|
220
|
+
const safeDeploymentId = safeSegment(deploymentId, "production");
|
|
221
|
+
const inboxRoot = import_node_path2.default.join(evidenceRoot, "inbox", safeDeploymentId);
|
|
222
|
+
const artifactsRoot = import_node_path2.default.join(evidenceRoot, "artifacts", safeDeploymentId);
|
|
223
|
+
await Promise.all([
|
|
224
|
+
import_promises2.default.mkdir(inboxRoot, { recursive: true }),
|
|
225
|
+
import_promises2.default.mkdir(artifactsRoot, { recursive: true })
|
|
226
|
+
]);
|
|
227
|
+
const rsyncArgs = buildRuntimeEvidenceRsyncArgs({
|
|
228
|
+
source,
|
|
229
|
+
destination: inboxRoot
|
|
230
|
+
});
|
|
231
|
+
const transfer = await runRsync(rsyncArgs);
|
|
232
|
+
const discovered = await discoverRuntimeEvidenceBundles(inboxRoot);
|
|
233
|
+
const received = [];
|
|
234
|
+
for (const bundleDir of discovered) {
|
|
235
|
+
const verified = await verifyRuntimeEvidenceBundle(bundleDir);
|
|
236
|
+
if (verified.manifest.deploymentId !== safeDeploymentId) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
`Artifact deployment mismatch: expected ${safeDeploymentId}, received ${verified.manifest.deploymentId}`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
const destinationDir = import_node_path2.default.join(
|
|
242
|
+
artifactsRoot,
|
|
243
|
+
...dateParts(verified.manifest.window.endTime),
|
|
244
|
+
safeSegment(verified.manifest.artifactId, "artifact")
|
|
245
|
+
);
|
|
246
|
+
await import_promises2.default.mkdir(import_node_path2.default.dirname(destinationDir), { recursive: true });
|
|
247
|
+
try {
|
|
248
|
+
await import_promises2.default.rename(bundleDir, destinationDir);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (!isExistingDestinationError(error)) throw error;
|
|
251
|
+
const existing = await verifyRuntimeEvidenceBundle(destinationDir);
|
|
252
|
+
if (existing.manifest.payload.sha256 !== verified.manifest.payload.sha256) {
|
|
253
|
+
throw new Error(
|
|
254
|
+
`Conflicting runtime evidence artifact ${verified.manifest.artifactId}`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
await import_promises2.default.rm(bundleDir, { recursive: true, force: true });
|
|
258
|
+
}
|
|
259
|
+
received.push(await verifyRuntimeEvidenceBundle(destinationDir));
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
rsyncArgs,
|
|
263
|
+
stdout: String(transfer.stdout ?? ""),
|
|
264
|
+
stderr: String(transfer.stderr ?? ""),
|
|
265
|
+
received,
|
|
266
|
+
pending: await listPendingRuntimeEvidenceBundles({
|
|
267
|
+
evidenceRoot,
|
|
268
|
+
deploymentId: safeDeploymentId
|
|
269
|
+
})
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// src/scripts/runtimeEvidenceSync.ts
|
|
274
|
+
import_args.default.option(
|
|
275
|
+
"source",
|
|
276
|
+
"Rsync source ending at the deployment ready directory",
|
|
277
|
+
process.env.RUNTIME_EVIDENCE_RSYNC_SOURCE
|
|
278
|
+
);
|
|
279
|
+
import_args.default.option(
|
|
280
|
+
"deployment",
|
|
281
|
+
"Deployment id expected in artifact manifests",
|
|
282
|
+
process.env.RUNTIME_EVIDENCE_DEPLOYMENT_ID || "production"
|
|
283
|
+
);
|
|
284
|
+
import_args.default.option(
|
|
285
|
+
"dir",
|
|
286
|
+
"Local evidence storage root",
|
|
287
|
+
process.env.RUNTIME_EVIDENCE_LOCAL_DIR || "data/runtime-evidence"
|
|
288
|
+
);
|
|
289
|
+
var flags = import_args.default.parse(process.argv);
|
|
290
|
+
var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
|
|
291
|
+
var runtimeEvidenceSync = async () => {
|
|
292
|
+
const source = String(flags.source ?? "").trim();
|
|
293
|
+
if (!source) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
"Provide --source or RUNTIME_EVIDENCE_RSYNC_SOURCE for runtime evidence sync."
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
const evidenceRoot = import_node_path3.default.resolve(projectRoot, String(flags.dir));
|
|
299
|
+
const result = await syncRuntimeEvidenceBundles({
|
|
300
|
+
source,
|
|
301
|
+
evidenceRoot,
|
|
302
|
+
deploymentId: String(flags.deployment)
|
|
303
|
+
});
|
|
304
|
+
console.log(
|
|
305
|
+
import_chalk.default.green(
|
|
306
|
+
`Runtime evidence sync completed: received=${result.received.length} pending=${result.pending.length}`
|
|
307
|
+
)
|
|
308
|
+
);
|
|
309
|
+
console.log(
|
|
310
|
+
JSON.stringify(
|
|
311
|
+
{
|
|
312
|
+
evidenceRoot,
|
|
313
|
+
received: result.received.map((bundle) => ({
|
|
314
|
+
artifactId: bundle.manifest.artifactId,
|
|
315
|
+
bundleDir: bundle.bundleDir,
|
|
316
|
+
payloadPath: bundle.payloadPath
|
|
317
|
+
})),
|
|
318
|
+
pending: result.pending.map((bundle) => ({
|
|
319
|
+
artifactId: bundle.manifest.artifactId,
|
|
320
|
+
bundleDir: bundle.bundleDir,
|
|
321
|
+
payloadPath: bundle.payloadPath,
|
|
322
|
+
window: bundle.manifest.window
|
|
323
|
+
}))
|
|
324
|
+
},
|
|
325
|
+
null,
|
|
326
|
+
2
|
|
327
|
+
)
|
|
328
|
+
);
|
|
329
|
+
};
|
|
330
|
+
var main = runtimeEvidenceSync;
|
|
331
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
332
|
+
0 && (module.exports = {
|
|
333
|
+
main,
|
|
334
|
+
runtimeEvidenceSync
|
|
335
|
+
});
|
|
@@ -2351,6 +2351,8 @@ var timeOperation = async (label, operation, log = console.log) => {
|
|
|
2351
2351
|
|
|
2352
2352
|
// src/lib/marketContextPrepare.ts
|
|
2353
2353
|
var import_chalk4 = __toESM(require("chalk"));
|
|
2354
|
+
var import_timescale5 = require("@tradejs/infra/timescale");
|
|
2355
|
+
var import_registry = require("@tradejs/node/registry");
|
|
2354
2356
|
|
|
2355
2357
|
// src/lib/binanceMarketContextBackfill.ts
|
|
2356
2358
|
var import_progress = __toESM(require("progress"));
|
|
@@ -5592,6 +5594,9 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
5592
5594
|
};
|
|
5593
5595
|
|
|
5594
5596
|
// src/lib/marketContextPrepare.ts
|
|
5597
|
+
var uniqueReasons = (reasons) => [
|
|
5598
|
+
...new Set(reasons)
|
|
5599
|
+
];
|
|
5595
5600
|
var shouldPrepareDerivativesContextForRun = (params) => {
|
|
5596
5601
|
if (params.universe === "tradfi") return false;
|
|
5597
5602
|
if (params.mode === "signals") {
|
|
@@ -5599,6 +5604,9 @@ var shouldPrepareDerivativesContextForRun = (params) => {
|
|
|
5599
5604
|
cacheOnly: params.cacheOnly
|
|
5600
5605
|
});
|
|
5601
5606
|
}
|
|
5607
|
+
if (params.mode === "backtest" && !params.aiEnabled && !params.mlEnabled) {
|
|
5608
|
+
return false;
|
|
5609
|
+
}
|
|
5602
5610
|
return shouldBackfillDerivativesContextForBacktest({
|
|
5603
5611
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5604
5612
|
cacheOnly: params.cacheOnly,
|
|
@@ -5608,6 +5616,7 @@ var shouldPrepareDerivativesContextForRun = (params) => {
|
|
|
5608
5616
|
var shouldPrepareBinanceMarketContextForRun = (params) => {
|
|
5609
5617
|
if (params.universe === "tradfi") return false;
|
|
5610
5618
|
if (params.mode === "backtest") {
|
|
5619
|
+
if (!params.aiEnabled && !params.mlEnabled) return false;
|
|
5611
5620
|
return shouldBackfillBinanceMarketContextForBacktest({
|
|
5612
5621
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5613
5622
|
cacheOnly: params.cacheOnly,
|
|
@@ -5626,6 +5635,7 @@ var shouldPrepareBinanceMarketContextForRun = (params) => {
|
|
|
5626
5635
|
var shouldPrepareCoinMarketCapContextForRun = (params) => {
|
|
5627
5636
|
if (params.universe === "tradfi") return false;
|
|
5628
5637
|
if (params.mode === "backtest") {
|
|
5638
|
+
if (!params.aiEnabled && !params.mlEnabled) return false;
|
|
5629
5639
|
return shouldBackfillCoinMarketCapContextForBacktest({
|
|
5630
5640
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5631
5641
|
cacheOnly: params.cacheOnly,
|
|
@@ -5641,10 +5651,8 @@ var shouldPrepareCoinMarketCapContextForRun = (params) => {
|
|
|
5641
5651
|
cacheOnly: params.cacheOnly
|
|
5642
5652
|
});
|
|
5643
5653
|
};
|
|
5644
|
-
var shouldPrepareHyperliquidWhaleContextForRun = (params) => {
|
|
5645
|
-
const strategyRequiresContext =
|
|
5646
|
-
"HyperliquidConsensus"
|
|
5647
|
-
);
|
|
5654
|
+
var shouldPrepareHyperliquidWhaleContextForRun = (params, coreContextSources = []) => {
|
|
5655
|
+
const strategyRequiresContext = coreContextSources.includes("hyperliquidWhales");
|
|
5648
5656
|
if (params.universe === "tradfi" || params.mode === "signals" || params.cacheOnly || !params.aiEnabled && !params.mlEnabled && !strategyRequiresContext) {
|
|
5649
5657
|
return false;
|
|
5650
5658
|
}
|
|
@@ -5655,6 +5663,64 @@ var shouldPrepareHyperliquidWhaleContextForRun = (params) => {
|
|
|
5655
5663
|
if (strategyRequiresContext) return true;
|
|
5656
5664
|
return ["1", "true", "yes", "on"].includes(configured);
|
|
5657
5665
|
};
|
|
5666
|
+
var resolveCoreContextSources = async (params) => {
|
|
5667
|
+
const strategyNames = [...new Set(params.strategyNames ?? [])];
|
|
5668
|
+
if (!strategyNames.length) return [];
|
|
5669
|
+
await (0, import_registry.ensureStrategyPluginsLoaded)(params.projectRoot);
|
|
5670
|
+
return [
|
|
5671
|
+
...new Set(
|
|
5672
|
+
strategyNames.flatMap(
|
|
5673
|
+
(strategyName) => (0, import_registry.getStrategyManifest)(strategyName, params.projectRoot)?.contextRequirements?.core ?? []
|
|
5674
|
+
)
|
|
5675
|
+
)
|
|
5676
|
+
];
|
|
5677
|
+
};
|
|
5678
|
+
var resolveMarketContextRunRequirements = async (params) => {
|
|
5679
|
+
const coreContextSources = await resolveCoreContextSources(params);
|
|
5680
|
+
const paramsWithCoreDemand = (source) => coreContextSources.includes(source) ? { ...params, aiEnabled: true } : params;
|
|
5681
|
+
const isCrypto = params.universe !== "tradfi";
|
|
5682
|
+
const capturesPayload = Boolean(params.aiEnabled || params.mlEnabled);
|
|
5683
|
+
const runtimeReadsContext = params.mode !== "backtest";
|
|
5684
|
+
const reasonsFor = (source) => uniqueReasons([
|
|
5685
|
+
...coreContextSources.includes(source) ? ["core"] : [],
|
|
5686
|
+
...params.aiEnabled ? ["ai"] : [],
|
|
5687
|
+
...params.mlEnabled ? ["ml"] : [],
|
|
5688
|
+
...runtimeReadsContext ? ["runtime"] : []
|
|
5689
|
+
]);
|
|
5690
|
+
const readsStandardContext = isCrypto && (capturesPayload || runtimeReadsContext);
|
|
5691
|
+
const readsHyperliquid = isCrypto && (readsStandardContext || coreContextSources.includes("hyperliquidWhales"));
|
|
5692
|
+
return {
|
|
5693
|
+
binance: {
|
|
5694
|
+
read: readsStandardContext || coreContextSources.includes("binance"),
|
|
5695
|
+
backfill: shouldPrepareBinanceMarketContextForRun(
|
|
5696
|
+
paramsWithCoreDemand("binance")
|
|
5697
|
+
),
|
|
5698
|
+
requiredBy: reasonsFor("binance")
|
|
5699
|
+
},
|
|
5700
|
+
coinmarketcap: {
|
|
5701
|
+
read: readsStandardContext || coreContextSources.includes("coinmarketcap"),
|
|
5702
|
+
backfill: shouldPrepareCoinMarketCapContextForRun(
|
|
5703
|
+
paramsWithCoreDemand("coinmarketcap")
|
|
5704
|
+
),
|
|
5705
|
+
requiredBy: reasonsFor("coinmarketcap")
|
|
5706
|
+
},
|
|
5707
|
+
derivatives: {
|
|
5708
|
+
read: readsStandardContext || coreContextSources.includes("derivatives"),
|
|
5709
|
+
backfill: shouldPrepareDerivativesContextForRun(
|
|
5710
|
+
paramsWithCoreDemand("derivatives")
|
|
5711
|
+
),
|
|
5712
|
+
requiredBy: reasonsFor("derivatives")
|
|
5713
|
+
},
|
|
5714
|
+
hyperliquidWhales: {
|
|
5715
|
+
read: readsHyperliquid,
|
|
5716
|
+
backfill: shouldPrepareHyperliquidWhaleContextForRun(
|
|
5717
|
+
params,
|
|
5718
|
+
coreContextSources
|
|
5719
|
+
),
|
|
5720
|
+
requiredBy: reasonsFor("hyperliquidWhales")
|
|
5721
|
+
}
|
|
5722
|
+
};
|
|
5723
|
+
};
|
|
5658
5724
|
var resolveCoinMarketCapBackfillForMode = (mode) => mode === "backtest" ? backfillCoinMarketCapContextForBacktest : mode === "signals" ? backfillCoinMarketCapContextForSignals : backfillCoinMarketCapContextForReplay;
|
|
5659
5725
|
var buildCoinMarketCapBackfillParams = (params) => ({
|
|
5660
5726
|
userName: params.userName,
|
|
@@ -5683,7 +5749,15 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5683
5749
|
console.log(import_chalk4.default.gray(message));
|
|
5684
5750
|
});
|
|
5685
5751
|
const timeOperation2 = (label, operation) => timeOperation(label, operation, log);
|
|
5686
|
-
|
|
5752
|
+
const requirements = await resolveMarketContextRunRequirements(params);
|
|
5753
|
+
const readableSources = Object.entries(requirements).filter(([, requirement]) => requirement.read).map(([source]) => source);
|
|
5754
|
+
if (readableSources.length) {
|
|
5755
|
+
await timeOperation2(
|
|
5756
|
+
"market context schema ensure",
|
|
5757
|
+
() => (0, import_timescale5.ensureMarketContextSchemas)(readableSources)
|
|
5758
|
+
);
|
|
5759
|
+
}
|
|
5760
|
+
if (requirements.derivatives.backfill) {
|
|
5687
5761
|
await timeOperation2(
|
|
5688
5762
|
"derivatives context backfill",
|
|
5689
5763
|
() => (params.mode === "signals" ? backfillDerivativesContextForSignals : backfillDerivativesContextForBacktest)(
|
|
@@ -5691,7 +5765,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5691
5765
|
)
|
|
5692
5766
|
);
|
|
5693
5767
|
}
|
|
5694
|
-
if (
|
|
5768
|
+
if (requirements.hyperliquidWhales.backfill) {
|
|
5695
5769
|
await timeOperation2(
|
|
5696
5770
|
"hyperliquid whale context backfill",
|
|
5697
5771
|
() => backfillHyperliquidWhaleContext({
|
|
@@ -5703,13 +5777,13 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5703
5777
|
})
|
|
5704
5778
|
);
|
|
5705
5779
|
}
|
|
5706
|
-
if (
|
|
5780
|
+
if (requirements.binance.backfill) {
|
|
5707
5781
|
await timeOperation2("binance market context backfill", () => {
|
|
5708
5782
|
const backfill = params.mode === "backtest" ? backfillBinanceMarketContextForBacktest : params.mode === "signals" ? backfillBinanceMarketContextForSignals : backfillBinanceMarketContextForReplay;
|
|
5709
5783
|
return backfill(buildBinanceMarketBackfillParams(params));
|
|
5710
5784
|
});
|
|
5711
5785
|
}
|
|
5712
|
-
if (
|
|
5786
|
+
if (requirements.coinmarketcap.backfill) {
|
|
5713
5787
|
await timeOperation2(
|
|
5714
5788
|
"coinmarketcap historical context backfill",
|
|
5715
5789
|
() => resolveCoinMarketCapBackfillForMode(params.mode)(
|
|
@@ -5717,6 +5791,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5717
5791
|
)
|
|
5718
5792
|
);
|
|
5719
5793
|
}
|
|
5794
|
+
return requirements;
|
|
5720
5795
|
};
|
|
5721
5796
|
|
|
5722
5797
|
// src/lib/marketData/historyPrepare.ts
|