@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.
@@ -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 = params.strategyNames?.includes(
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
- if (shouldPrepareDerivativesContextForRun(params)) {
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 (shouldPrepareHyperliquidWhaleContextForRun(params)) {
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 (shouldPrepareBinanceMarketContextForRun(params)) {
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 (shouldPrepareCoinMarketCapContextForRun(params)) {
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