@tradejs/cli 3.1.16 → 3.1.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.
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
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
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/lib/runtimeLineage.ts
@@ -32,111 +22,12 @@ var runtimeLineage_exports = {};
32
22
  __export(runtimeLineage_exports, {
33
23
  buildRuntimeLineage: () => buildRuntimeLineage,
34
24
  fingerprintRuntimeValue: () => fingerprintRuntimeValue,
35
- resetRuntimeLineageCachesForTests: () => resetRuntimeLineageCachesForTests,
36
25
  runtimeLineageKey: () => runtimeLineageKey,
37
26
  runtimeLineagesComparable: () => runtimeLineagesComparable,
38
27
  runtimeLineagesMatch: () => runtimeLineagesMatch
39
28
  });
40
29
  module.exports = __toCommonJS(runtimeLineage_exports);
41
- var import_node_child_process = require("child_process");
42
- var import_node_crypto2 = require("crypto");
43
- var import_promises2 = __toESM(require("fs/promises"));
44
- var import_node_path2 = __toESM(require("path"));
45
- var import_types = require("@tradejs/types");
46
- var import_strategies = require("@tradejs/node/strategies");
47
- var import_strategyReleaseEvidence = require("@tradejs/infra/strategyReleaseEvidence");
48
-
49
- // src/lib/strategyGateFingerprint.ts
50
30
  var import_node_crypto = require("crypto");
51
- var import_node_module = require("module");
52
- var import_promises = __toESM(require("fs/promises"));
53
- var import_node_path = __toESM(require("path"));
54
- var toPackageToken = (strategyName) => strategyName.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
55
- var getStrategyPackageName = (strategyName) => strategyName === "TrendLine" || strategyName === "ReverseTrendLine" ? "@tradejs/strategy-trend-line" : `@tradejs/strategy-${toPackageToken(strategyName)}`;
56
- var gateFingerprintSpecifiers = (strategyName) => [
57
- getStrategyPackageName(strategyName),
58
- "@tradejs/strategy-kit/ai-gate",
59
- "@tradejs/node/ai",
60
- "@tradejs/core/strategies"
61
- ];
62
- var resolveStrategyGateFingerprint = async ({
63
- projectRoot,
64
- strategyName,
65
- gitSha
66
- }) => {
67
- const projectManifestPath = import_node_path.default.join(projectRoot, "package.json");
68
- const projectExists = await import_promises.default.access(projectManifestPath).then(() => true).catch(() => false);
69
- const requireFromProject = projectExists ? (0, import_node_module.createRequire)(projectManifestPath) : null;
70
- const candidates = requireFromProject ? await Promise.all(
71
- gateFingerprintSpecifiers(strategyName).map(async (specifier) => {
72
- let resolvedPath;
73
- try {
74
- resolvedPath = requireFromProject.resolve(specifier);
75
- } catch {
76
- return null;
77
- }
78
- const content = await import_promises.default.readFile(resolvedPath).catch(() => null);
79
- return content == null ? null : { specifier, content };
80
- })
81
- ) : [];
82
- const sourceEntries = candidates.filter(
83
- (entry) => entry != null
84
- );
85
- const hash = (0, import_node_crypto.createHash)("sha256");
86
- hash.update(strategyName);
87
- if (sourceEntries.length) {
88
- for (const entry of sourceEntries) {
89
- hash.update(entry.specifier);
90
- hash.update(entry.content);
91
- }
92
- } else {
93
- hash.update(gitSha ?? "unknown-git-sha");
94
- }
95
- return {
96
- gateFingerprint: hash.digest("hex").slice(0, 16),
97
- gateFingerprintFiles: sourceEntries.map((entry) => entry.specifier)
98
- };
99
- };
100
-
101
- // src/lib/runtimeLineage.ts
102
- var RUNTIME_CONTEXT_ENV_KEYS = [
103
- "AI_MODE",
104
- "MIN_AI_QUALITY",
105
- "INTERVAL",
106
- "DERIVATIVES_CONTEXT_ENABLED",
107
- "DERIVATIVES_CONTEXT_TARGET_ENABLED",
108
- "DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
109
- "DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
110
- "DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
111
- "COINMARKETCAP_CONTEXT_ENABLED",
112
- "COINMARKETCAP_CONTEXT_MAX_AGE_MS",
113
- "COINMARKETCAP_CONTEXT_EXCHANGE_LIQUIDITY_ENABLED",
114
- "COINMARKETCAP_CONTEXT_EXCHANGE_SLUGS",
115
- "COINMARKETCAP_CONTEXT_FEAR_GREED_ENABLED",
116
- "COINMARKETCAP_CONTEXT_HISTORICAL_ACCESS_MONTHS",
117
- "COINMARKETCAP_CONTEXT_BACKFILL_ENABLED",
118
- "COINMARKETCAP_CONTEXT_BACKFILL_MAX_DAYS",
119
- "COINMARKETCAP_CONTEXT_BACKFILL_WARMUP_DAYS",
120
- "HYPERLIQUID_WHALE_CONTEXT_ENABLED",
121
- "HYPERLIQUID_WHALE_BACKFILL_ENABLED",
122
- "HYPERLIQUID_WHALE_MIN_COVERAGE_PCT",
123
- "HYPERLIQUID_WHALE_CONCURRENCY",
124
- "HYPERLIQUID_WHALE_RATE_LIMIT_WEIGHT"
125
- ];
126
- var RUNTIME_CONTEXT_DATA_MODEL = {
127
- derivativesSourceIntervals: "15m",
128
- derivativesDerivedIntervals: "1h",
129
- derivativesHourlyFallback: "stored-1h",
130
- derivativesDataModelVersion: 2,
131
- coinMarketCapAvailabilityModel: "closed-interval-all-daily",
132
- coinMarketCapDataModelVersion: 3,
133
- binanceBreadthUniverseModel: "fixed-versioned-top5-top10-top30-top50-top100",
134
- binanceBreadthDataModelVersion: 2,
135
- hyperliquidWhaleCanonicalInterval: "1m",
136
- hyperliquidWhaleGateMinNotionalUsd: 5e4,
137
- hyperliquidWhaleMinCoveragePct: 0.8,
138
- hyperliquidWhaleDataModelVersion: import_types.HYPERLIQUID_WHALE_DATA_MODEL_VERSION
139
- };
140
31
  var normalizeForStableJson = (value) => {
141
32
  if (Array.isArray(value)) {
142
33
  return value.map(normalizeForStableJson);
@@ -161,224 +52,55 @@ var resolveRuntimeMaxLossValue = (config) => {
161
52
  );
162
53
  return Number.isFinite(maxLossValue) ? maxLossValue : null;
163
54
  };
164
- var fingerprintRuntimeValue = (value) => (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
165
- var gitLineageCache = /* @__PURE__ */ new Map();
166
- var gateFingerprintCache = /* @__PURE__ */ new Map();
167
- var binanceBreadthFingerprintCache = /* @__PURE__ */ new Map();
168
- var snapshotFingerprintCache = /* @__PURE__ */ new Map();
169
- var resolveGitLineage = (projectRoot) => {
170
- const cached = gitLineageCache.get(projectRoot);
171
- if (cached) {
172
- return cached;
173
- }
174
- const envSha = String(process.env.TRADEJS_GIT_SHA ?? "").trim();
175
- if (envSha && envSha !== "unknown") {
176
- const result = {
177
- gitSha: envSha,
178
- gitDirty: false
179
- };
180
- gitLineageCache.set(projectRoot, result);
181
- return result;
182
- }
183
- try {
184
- const gitSha = (0, import_node_child_process.execFileSync)("git", ["rev-parse", "HEAD"], {
185
- cwd: projectRoot,
186
- encoding: "utf8",
187
- stdio: ["ignore", "pipe", "ignore"]
188
- }).trim();
189
- const status = (0, import_node_child_process.execFileSync)(
190
- "git",
191
- ["status", "--porcelain", "--untracked-files=normal"],
192
- {
193
- cwd: projectRoot,
194
- encoding: "utf8",
195
- stdio: ["ignore", "pipe", "ignore"]
196
- }
197
- ).trim();
198
- const result = {
199
- gitSha: gitSha || null,
200
- gitDirty: status.length > 0
201
- };
202
- gitLineageCache.set(projectRoot, result);
203
- return result;
204
- } catch {
205
- const result = {
206
- gitSha: null,
207
- gitDirty: null
208
- };
209
- gitLineageCache.set(projectRoot, result);
210
- return result;
211
- }
212
- };
213
- var readOptionalFile = async (filePath) => {
214
- try {
215
- return await import_promises2.default.readFile(filePath);
216
- } catch {
217
- return null;
218
- }
219
- };
220
- var resolveBinanceBreadthFingerprint = async (projectRoot) => {
221
- if (binanceBreadthFingerprintCache.has(projectRoot)) {
222
- return binanceBreadthFingerprintCache.get(projectRoot) ?? null;
223
- }
224
- const content = await readOptionalFile(
225
- import_node_path2.default.join(
226
- projectRoot,
227
- "packages/node/src/config/binanceBreadthUniverses.json"
228
- )
229
- );
230
- let result = null;
231
- if (content) {
232
- try {
233
- const parsed = JSON.parse(content.toString("utf8"));
234
- result = typeof parsed.fingerprint === "string" && parsed.fingerprint.trim() ? parsed.fingerprint.trim() : null;
235
- } catch {
236
- result = null;
237
- }
238
- }
239
- binanceBreadthFingerprintCache.set(projectRoot, result);
240
- return result;
241
- };
242
- var resolveSnapshotFingerprint = async (projectRoot, relativePath) => {
243
- const cacheKey = `${projectRoot}:${relativePath}`;
244
- if (snapshotFingerprintCache.has(cacheKey)) {
245
- return snapshotFingerprintCache.get(cacheKey) ?? null;
246
- }
247
- const content = await readOptionalFile(import_node_path2.default.join(projectRoot, relativePath));
248
- let result = null;
249
- if (content) {
250
- try {
251
- const parsed = JSON.parse(content.toString("utf8"));
252
- result = typeof parsed.fingerprint === "string" && parsed.fingerprint.trim() ? parsed.fingerprint.trim() : null;
253
- } catch {
254
- result = null;
255
- }
256
- }
257
- snapshotFingerprintCache.set(cacheKey, result);
258
- return result;
259
- };
260
- var resolveRuntimeGateFingerprint = async ({
261
- projectRoot,
262
- strategyName,
263
- gitSha
264
- }) => {
265
- const cacheKey = `${projectRoot}:${strategyName}:${gitSha ?? "unknown"}`;
266
- const cached = gateFingerprintCache.get(cacheKey);
267
- if (cached) return cached;
268
- const result = await resolveStrategyGateFingerprint({
269
- projectRoot,
270
- strategyName,
271
- gitSha
272
- });
273
- gateFingerprintCache.set(cacheKey, result);
274
- return result;
275
- };
276
- async function buildRuntimeLineage({
277
- projectRoot,
278
- strategyName,
279
- compositionId,
55
+ var fingerprintRuntimeValue = (value) => (0, import_node_crypto.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
56
+ var buildRuntimeLineage = async ({
280
57
  strategyRevision,
281
58
  deploymentCompositionId,
282
59
  strategyPackageVersion,
283
60
  strategyDependencyVersions,
284
61
  runtimePackageVersion,
285
- config,
286
- runContext,
287
- env = process.env
288
- }) {
289
- if (strategyRevision != null) {
290
- if (!/^sr1:[a-f0-9]{16}$/.test(strategyRevision)) {
291
- throw new Error(`Invalid strategy revision: ${strategyRevision}`);
292
- }
293
- if (typeof deploymentCompositionId !== "string" || !/^dc1:[a-f0-9]{16}$/.test(deploymentCompositionId)) {
294
- throw new Error(
295
- `Invalid deployment composition id: ${String(deploymentCompositionId)}`
296
- );
297
- }
298
- if (typeof strategyPackageVersion !== "string" || !strategyPackageVersion.trim() || typeof runtimePackageVersion !== "string" || !runtimePackageVersion.trim()) {
299
- throw new Error("Invalid revision package versions");
300
- }
301
- if (!strategyDependencyVersions || Object.keys(strategyDependencyVersions).length === 0 || Object.entries(strategyDependencyVersions).some(
302
- ([name, version]) => !name.startsWith("@tradejs/") || typeof version !== "string" || !version.trim()
303
- )) {
304
- throw new Error("Invalid strategy dependency versions");
305
- }
306
- return {
307
- schemaVersion: 3,
308
- strategyRevision,
309
- deploymentCompositionId,
310
- strategyPackageVersion,
311
- strategyDependencyVersions,
312
- runtimePackageVersion,
313
- maxLossValue: resolveRuntimeMaxLossValue(config)
314
- };
62
+ config
63
+ }) => {
64
+ if (!/^sr1:[a-f0-9]{16}$/.test(strategyRevision)) {
65
+ throw new Error(`Invalid strategy revision: ${strategyRevision}`);
66
+ }
67
+ if (!/^dc1:[a-f0-9]{16}$/.test(deploymentCompositionId)) {
68
+ throw new Error(
69
+ `Invalid deployment composition id: ${deploymentCompositionId}`
70
+ );
71
+ }
72
+ if (!strategyPackageVersion.trim() || !runtimePackageVersion.trim()) {
73
+ throw new Error("Invalid revision package versions");
74
+ }
75
+ if (Object.keys(strategyDependencyVersions).length === 0 || Object.entries(strategyDependencyVersions).some(
76
+ ([name, version]) => !name.startsWith("@tradejs/") || typeof version !== "string" || !version.trim()
77
+ )) {
78
+ throw new Error("Invalid strategy dependency versions");
315
79
  }
316
- const git = resolveGitLineage(projectRoot);
317
- const hyperliquidPerpUniverseFingerprint = typeof import_strategies.getHyperliquidPerpUniverseSnapshot === "function" ? (0, import_strategies.getHyperliquidPerpUniverseSnapshot)().fingerprint : await resolveSnapshotFingerprint(
318
- projectRoot,
319
- "packages/node/src/config/hyperliquidPerpUniverse.json"
320
- );
321
- const hyperliquidWhaleRegistryFingerprint = typeof import_strategies.getHyperliquidWhaleRegistrySnapshot === "function" ? (0, import_strategies.getHyperliquidWhaleRegistrySnapshot)().fingerprint : await resolveSnapshotFingerprint(
322
- projectRoot,
323
- "packages/node/src/config/hyperliquidWhales.json"
324
- );
325
- const context = {
326
- ...Object.fromEntries(
327
- RUNTIME_CONTEXT_ENV_KEYS.map((key) => [key, env[key] ?? null])
328
- ),
329
- ...RUNTIME_CONTEXT_DATA_MODEL,
330
- binanceBreadthUniverseFingerprint: await resolveBinanceBreadthFingerprint(projectRoot),
331
- hyperliquidPerpUniverseFingerprint,
332
- hyperliquidWhaleRegistryFingerprint,
333
- ...runContext
334
- };
335
80
  return {
336
- schemaVersion: 1,
337
- compositionId: compositionId?.trim() || null,
338
- ...git,
339
- gateFingerprint: (await resolveRuntimeGateFingerprint({
340
- projectRoot,
341
- strategyName,
342
- gitSha: git.gitSha
343
- })).gateFingerprint,
344
- // Position risk is tracked separately so changing trade size does not
345
- // masquerade as a change to the core + gate decision logic.
346
- configFingerprint: (0, import_strategyReleaseEvidence.strategyLogicConfigFingerprint)(config),
347
- contextFingerprint: fingerprintRuntimeValue(context),
81
+ schemaVersion: 3,
82
+ strategyRevision,
83
+ deploymentCompositionId,
84
+ strategyPackageVersion,
85
+ strategyDependencyVersions,
86
+ runtimePackageVersion,
348
87
  maxLossValue: resolveRuntimeMaxLossValue(config)
349
88
  };
350
- }
351
- var runtimeLineageKey = (lineage) => lineage.schemaVersion === 3 ? [
89
+ };
90
+ var runtimeLineageKey = (lineage) => [
352
91
  "v3",
353
92
  lineage.deploymentCompositionId,
354
93
  lineage.strategyRevision,
355
94
  lineage.strategyPackageVersion,
356
- `deps:${fingerprintRuntimeValue(
357
- lineage.strategyDependencyVersions
358
- ).slice(0, 16)}`,
95
+ `deps:${fingerprintRuntimeValue(lineage.strategyDependencyVersions).slice(0, 16)}`,
359
96
  lineage.runtimePackageVersion
360
- ].join(":") : [
361
- lineage.schemaVersion,
362
- lineage.compositionId ?? "unbound-composition",
363
- lineage.gitSha ?? "unknown",
364
- lineage.gitDirty == null ? "unknown" : lineage.gitDirty ? "dirty" : "clean",
365
- lineage.gateFingerprint,
366
- lineage.configFingerprint,
367
- lineage.contextFingerprint
368
97
  ].join(":");
369
98
  var runtimeLineagesMatch = (left, right) => left != null && right != null && runtimeLineageKey(left) === runtimeLineageKey(right);
370
99
  var runtimeLineagesComparable = (left, right) => runtimeLineagesMatch(left, right) && typeof left?.maxLossValue === "number" && Number.isFinite(left.maxLossValue) && typeof right?.maxLossValue === "number" && Number.isFinite(right.maxLossValue) && left.maxLossValue === right.maxLossValue;
371
- var resetRuntimeLineageCachesForTests = () => {
372
- gitLineageCache.clear();
373
- gateFingerprintCache.clear();
374
- binanceBreadthFingerprintCache.clear();
375
- snapshotFingerprintCache.clear();
376
- };
377
100
  // Annotate the CommonJS export names for ESM import in node:
378
101
  0 && (module.exports = {
379
102
  buildRuntimeLineage,
380
103
  fingerprintRuntimeValue,
381
- resetRuntimeLineageCachesForTests,
382
104
  runtimeLineageKey,
383
105
  runtimeLineagesComparable,
384
106
  runtimeLineagesMatch
@@ -71,9 +71,7 @@ var loadRuntimeTrades = async (userName, {
71
71
  dedupedBucketTrades.set(trade.orderId, trade);
72
72
  }
73
73
  const windowedTrades = [...dedupedBucketTrades.values()].filter(filterByWindow).sort((left, right) => left.entryTimestamp - right.entryTimestamp);
74
- if (windowedTrades.length > 0 || dayKeys.length === 0) {
75
- return windowedTrades;
76
- }
74
+ return windowedTrades;
77
75
  }
78
76
  const tradePrefix = import_redis.redisKeys.runtimeTrades(userName);
79
77
  const bucketPrefix = import_redis.redisKeys.runtimeTradeBuckets(userName);