@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
|
@@ -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"));
|
|
@@ -5186,6 +5188,7 @@ var backfillCoinMarketCapContextForReplay = backfillCoinMarketCapContext;
|
|
|
5186
5188
|
var backfillCoinMarketCapContextForSignals = (params) => backfillCoinMarketCapContext({ ...params, refreshStaleFearGreed: true });
|
|
5187
5189
|
|
|
5188
5190
|
// src/lib/hyperliquidWhaleBackfill.ts
|
|
5191
|
+
var import_progress3 = __toESM(require("progress"));
|
|
5189
5192
|
var import_timescale4 = require("@tradejs/infra/timescale");
|
|
5190
5193
|
var import_strategies2 = require("@tradejs/node/strategies");
|
|
5191
5194
|
|
|
@@ -5560,11 +5563,36 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
5560
5563
|
toMs,
|
|
5561
5564
|
...identity
|
|
5562
5565
|
});
|
|
5566
|
+
const totalCoverageBuckets = Math.ceil(
|
|
5567
|
+
(toMs - fromMs) / HYPERLIQUID_WHALE_BUCKET_MS
|
|
5568
|
+
);
|
|
5569
|
+
const coverageBar = new import_progress3.default(
|
|
5570
|
+
"Hyperliquid coverage :current/:total [:bar][:percent] :eta(s) rows=:rows chunk=:chunk",
|
|
5571
|
+
{
|
|
5572
|
+
total: Math.max(1, totalCoverageBuckets),
|
|
5573
|
+
width: 24
|
|
5574
|
+
}
|
|
5575
|
+
);
|
|
5576
|
+
let displayedCoverageBuckets = 0;
|
|
5563
5577
|
const coverageBuckets = await (0, import_timescale4.rebuildHyperliquidWhaleCoverageRows)({
|
|
5564
5578
|
fromMs,
|
|
5565
5579
|
toMs,
|
|
5566
5580
|
expectedWhales: whales.addresses.length,
|
|
5567
|
-
...identity
|
|
5581
|
+
...identity,
|
|
5582
|
+
onProgress: (progress) => {
|
|
5583
|
+
const next = Math.max(
|
|
5584
|
+
displayedCoverageBuckets,
|
|
5585
|
+
Math.min(progress.completedBuckets, coverageBar.total)
|
|
5586
|
+
);
|
|
5587
|
+
const delta = next - displayedCoverageBuckets;
|
|
5588
|
+
if (delta > 0) {
|
|
5589
|
+
coverageBar.tick(delta, {
|
|
5590
|
+
rows: progress.rows,
|
|
5591
|
+
chunk: `${progress.chunkIndex}/${progress.totalChunks}`
|
|
5592
|
+
});
|
|
5593
|
+
displayedCoverageBuckets = next;
|
|
5594
|
+
}
|
|
5595
|
+
}
|
|
5568
5596
|
});
|
|
5569
5597
|
const result = {
|
|
5570
5598
|
cached: false,
|
|
@@ -5592,6 +5620,9 @@ var backfillHyperliquidWhaleContext = async (params) => {
|
|
|
5592
5620
|
};
|
|
5593
5621
|
|
|
5594
5622
|
// src/lib/marketContextPrepare.ts
|
|
5623
|
+
var uniqueReasons = (reasons) => [
|
|
5624
|
+
...new Set(reasons)
|
|
5625
|
+
];
|
|
5595
5626
|
var shouldPrepareDerivativesContextForRun = (params) => {
|
|
5596
5627
|
if (params.universe === "tradfi") return false;
|
|
5597
5628
|
if (params.mode === "signals") {
|
|
@@ -5599,6 +5630,9 @@ var shouldPrepareDerivativesContextForRun = (params) => {
|
|
|
5599
5630
|
cacheOnly: params.cacheOnly
|
|
5600
5631
|
});
|
|
5601
5632
|
}
|
|
5633
|
+
if (params.mode === "backtest" && !params.aiEnabled && !params.mlEnabled) {
|
|
5634
|
+
return false;
|
|
5635
|
+
}
|
|
5602
5636
|
return shouldBackfillDerivativesContextForBacktest({
|
|
5603
5637
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5604
5638
|
cacheOnly: params.cacheOnly,
|
|
@@ -5608,6 +5642,7 @@ var shouldPrepareDerivativesContextForRun = (params) => {
|
|
|
5608
5642
|
var shouldPrepareBinanceMarketContextForRun = (params) => {
|
|
5609
5643
|
if (params.universe === "tradfi") return false;
|
|
5610
5644
|
if (params.mode === "backtest") {
|
|
5645
|
+
if (!params.aiEnabled && !params.mlEnabled) return false;
|
|
5611
5646
|
return shouldBackfillBinanceMarketContextForBacktest({
|
|
5612
5647
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5613
5648
|
cacheOnly: params.cacheOnly,
|
|
@@ -5626,6 +5661,7 @@ var shouldPrepareBinanceMarketContextForRun = (params) => {
|
|
|
5626
5661
|
var shouldPrepareCoinMarketCapContextForRun = (params) => {
|
|
5627
5662
|
if (params.universe === "tradfi") return false;
|
|
5628
5663
|
if (params.mode === "backtest") {
|
|
5664
|
+
if (!params.aiEnabled && !params.mlEnabled) return false;
|
|
5629
5665
|
return shouldBackfillCoinMarketCapContextForBacktest({
|
|
5630
5666
|
aiEnabled: Boolean(params.aiEnabled),
|
|
5631
5667
|
cacheOnly: params.cacheOnly,
|
|
@@ -5641,10 +5677,8 @@ var shouldPrepareCoinMarketCapContextForRun = (params) => {
|
|
|
5641
5677
|
cacheOnly: params.cacheOnly
|
|
5642
5678
|
});
|
|
5643
5679
|
};
|
|
5644
|
-
var shouldPrepareHyperliquidWhaleContextForRun = (params) => {
|
|
5645
|
-
const strategyRequiresContext =
|
|
5646
|
-
"HyperliquidConsensus"
|
|
5647
|
-
);
|
|
5680
|
+
var shouldPrepareHyperliquidWhaleContextForRun = (params, coreContextSources = []) => {
|
|
5681
|
+
const strategyRequiresContext = coreContextSources.includes("hyperliquidWhales");
|
|
5648
5682
|
if (params.universe === "tradfi" || params.mode === "signals" || params.cacheOnly || !params.aiEnabled && !params.mlEnabled && !strategyRequiresContext) {
|
|
5649
5683
|
return false;
|
|
5650
5684
|
}
|
|
@@ -5655,6 +5689,64 @@ var shouldPrepareHyperliquidWhaleContextForRun = (params) => {
|
|
|
5655
5689
|
if (strategyRequiresContext) return true;
|
|
5656
5690
|
return ["1", "true", "yes", "on"].includes(configured);
|
|
5657
5691
|
};
|
|
5692
|
+
var resolveCoreContextSources = async (params) => {
|
|
5693
|
+
const strategyNames = [...new Set(params.strategyNames ?? [])];
|
|
5694
|
+
if (!strategyNames.length) return [];
|
|
5695
|
+
await (0, import_registry.ensureStrategyPluginsLoaded)(params.projectRoot);
|
|
5696
|
+
return [
|
|
5697
|
+
...new Set(
|
|
5698
|
+
strategyNames.flatMap(
|
|
5699
|
+
(strategyName) => (0, import_registry.getStrategyManifest)(strategyName, params.projectRoot)?.contextRequirements?.core ?? []
|
|
5700
|
+
)
|
|
5701
|
+
)
|
|
5702
|
+
];
|
|
5703
|
+
};
|
|
5704
|
+
var resolveMarketContextRunRequirements = async (params) => {
|
|
5705
|
+
const coreContextSources = await resolveCoreContextSources(params);
|
|
5706
|
+
const paramsWithCoreDemand = (source) => coreContextSources.includes(source) ? { ...params, aiEnabled: true } : params;
|
|
5707
|
+
const isCrypto = params.universe !== "tradfi";
|
|
5708
|
+
const capturesPayload = Boolean(params.aiEnabled || params.mlEnabled);
|
|
5709
|
+
const runtimeReadsContext = params.mode !== "backtest";
|
|
5710
|
+
const reasonsFor = (source) => uniqueReasons([
|
|
5711
|
+
...coreContextSources.includes(source) ? ["core"] : [],
|
|
5712
|
+
...params.aiEnabled ? ["ai"] : [],
|
|
5713
|
+
...params.mlEnabled ? ["ml"] : [],
|
|
5714
|
+
...runtimeReadsContext ? ["runtime"] : []
|
|
5715
|
+
]);
|
|
5716
|
+
const readsStandardContext = isCrypto && (capturesPayload || runtimeReadsContext);
|
|
5717
|
+
const readsHyperliquid = isCrypto && (readsStandardContext || coreContextSources.includes("hyperliquidWhales"));
|
|
5718
|
+
return {
|
|
5719
|
+
binance: {
|
|
5720
|
+
read: readsStandardContext || coreContextSources.includes("binance"),
|
|
5721
|
+
backfill: shouldPrepareBinanceMarketContextForRun(
|
|
5722
|
+
paramsWithCoreDemand("binance")
|
|
5723
|
+
),
|
|
5724
|
+
requiredBy: reasonsFor("binance")
|
|
5725
|
+
},
|
|
5726
|
+
coinmarketcap: {
|
|
5727
|
+
read: readsStandardContext || coreContextSources.includes("coinmarketcap"),
|
|
5728
|
+
backfill: shouldPrepareCoinMarketCapContextForRun(
|
|
5729
|
+
paramsWithCoreDemand("coinmarketcap")
|
|
5730
|
+
),
|
|
5731
|
+
requiredBy: reasonsFor("coinmarketcap")
|
|
5732
|
+
},
|
|
5733
|
+
derivatives: {
|
|
5734
|
+
read: readsStandardContext || coreContextSources.includes("derivatives"),
|
|
5735
|
+
backfill: shouldPrepareDerivativesContextForRun(
|
|
5736
|
+
paramsWithCoreDemand("derivatives")
|
|
5737
|
+
),
|
|
5738
|
+
requiredBy: reasonsFor("derivatives")
|
|
5739
|
+
},
|
|
5740
|
+
hyperliquidWhales: {
|
|
5741
|
+
read: readsHyperliquid,
|
|
5742
|
+
backfill: shouldPrepareHyperliquidWhaleContextForRun(
|
|
5743
|
+
params,
|
|
5744
|
+
coreContextSources
|
|
5745
|
+
),
|
|
5746
|
+
requiredBy: reasonsFor("hyperliquidWhales")
|
|
5747
|
+
}
|
|
5748
|
+
};
|
|
5749
|
+
};
|
|
5658
5750
|
var resolveCoinMarketCapBackfillForMode = (mode) => mode === "backtest" ? backfillCoinMarketCapContextForBacktest : mode === "signals" ? backfillCoinMarketCapContextForSignals : backfillCoinMarketCapContextForReplay;
|
|
5659
5751
|
var buildCoinMarketCapBackfillParams = (params) => ({
|
|
5660
5752
|
userName: params.userName,
|
|
@@ -5683,7 +5775,15 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5683
5775
|
console.log(import_chalk4.default.gray(message));
|
|
5684
5776
|
});
|
|
5685
5777
|
const timeOperation2 = (label, operation) => timeOperation(label, operation, log);
|
|
5686
|
-
|
|
5778
|
+
const requirements = await resolveMarketContextRunRequirements(params);
|
|
5779
|
+
const readableSources = Object.entries(requirements).filter(([, requirement]) => requirement.read).map(([source]) => source);
|
|
5780
|
+
if (readableSources.length) {
|
|
5781
|
+
await timeOperation2(
|
|
5782
|
+
"market context schema ensure",
|
|
5783
|
+
() => (0, import_timescale5.ensureMarketContextSchemas)(readableSources)
|
|
5784
|
+
);
|
|
5785
|
+
}
|
|
5786
|
+
if (requirements.derivatives.backfill) {
|
|
5687
5787
|
await timeOperation2(
|
|
5688
5788
|
"derivatives context backfill",
|
|
5689
5789
|
() => (params.mode === "signals" ? backfillDerivativesContextForSignals : backfillDerivativesContextForBacktest)(
|
|
@@ -5691,7 +5791,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5691
5791
|
)
|
|
5692
5792
|
);
|
|
5693
5793
|
}
|
|
5694
|
-
if (
|
|
5794
|
+
if (requirements.hyperliquidWhales.backfill) {
|
|
5695
5795
|
await timeOperation2(
|
|
5696
5796
|
"hyperliquid whale context backfill",
|
|
5697
5797
|
() => backfillHyperliquidWhaleContext({
|
|
@@ -5703,13 +5803,13 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5703
5803
|
})
|
|
5704
5804
|
);
|
|
5705
5805
|
}
|
|
5706
|
-
if (
|
|
5806
|
+
if (requirements.binance.backfill) {
|
|
5707
5807
|
await timeOperation2("binance market context backfill", () => {
|
|
5708
5808
|
const backfill = params.mode === "backtest" ? backfillBinanceMarketContextForBacktest : params.mode === "signals" ? backfillBinanceMarketContextForSignals : backfillBinanceMarketContextForReplay;
|
|
5709
5809
|
return backfill(buildBinanceMarketBackfillParams(params));
|
|
5710
5810
|
});
|
|
5711
5811
|
}
|
|
5712
|
-
if (
|
|
5812
|
+
if (requirements.coinmarketcap.backfill) {
|
|
5713
5813
|
await timeOperation2(
|
|
5714
5814
|
"coinmarketcap historical context backfill",
|
|
5715
5815
|
() => resolveCoinMarketCapBackfillForMode(params.mode)(
|
|
@@ -5717,6 +5817,7 @@ var prepareMarketContextForRun = async (params) => {
|
|
|
5717
5817
|
)
|
|
5718
5818
|
);
|
|
5719
5819
|
}
|
|
5820
|
+
return requirements;
|
|
5720
5821
|
};
|
|
5721
5822
|
|
|
5722
5823
|
// src/lib/marketData/historyPrepare.ts
|