@tradejs/cli 2.0.5 → 2.0.7
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 +3145 -1827
- package/dist/lib/aiExport.js +1822 -0
- package/dist/lib/binanceMarketContextBackfill.js +97 -88
- package/dist/lib/binanceMarketData.js +6 -3
- package/dist/lib/marketContextPrepare.js +149 -125
- package/dist/lib/runEnvironment.js +100 -55
- package/dist/lib/runFormatting.js +52 -37
- package/dist/lib/runtimeLineage.js +255 -0
- package/dist/lib/runtimeParityDetails.js +24 -1
- package/dist/lib/runtimeSignalsLoader.js +19 -0
- package/dist/lib/runtimeSignalsStorage.js +3 -0
- package/dist/lib/runtimeTradeSync.js +40 -11
- package/dist/lib/timeWindow.js +44 -16
- package/dist/scripts/aiExport.js +252 -125
- package/dist/scripts/aiPocketSearch.js +52 -37
- package/dist/scripts/aiTrain.js +52 -37
- package/dist/scripts/backtest.js +222 -144
- package/dist/scripts/binanceBreadthUniversesUpdate.js +120 -0
- package/dist/scripts/binanceMarketIngest.js +32 -33
- package/dist/scripts/candlesMigrateProvider.js +648 -419
- package/dist/scripts/doctor.js +648 -419
- package/dist/scripts/mlExport.js +57 -39
- package/dist/scripts/replay.js +1040 -255
- package/dist/scripts/replayRunner.js +1040 -255
- package/dist/scripts/replayRuntimeEvidence.js +3 -1
- package/dist/scripts/resolveExportStrategy.js +7 -2
- package/dist/scripts/results.js +52 -37
- package/dist/scripts/runtimeParity.js +193 -141
- package/dist/scripts/signals.js +433 -144
- package/dist/scripts/signalsDaemon.js +433 -144
- package/dist/scripts/signalsSummary.js +40 -11
- package/package.json +15 -14
|
@@ -34,9 +34,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
));
|
|
35
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
36
|
|
|
37
|
-
// ../../node_modules/
|
|
37
|
+
// ../../node_modules/ms/index.js
|
|
38
38
|
var require_ms = __commonJS({
|
|
39
|
-
"../../node_modules/
|
|
39
|
+
"../../node_modules/ms/index.js"(exports2, module2) {
|
|
40
40
|
"use strict";
|
|
41
41
|
var s = 1e3;
|
|
42
42
|
var m = s * 60;
|
|
@@ -151,9 +151,9 @@ var require_ms = __commonJS({
|
|
|
151
151
|
}
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
-
// ../../node_modules/debug/src/common.js
|
|
154
|
+
// ../../node_modules/list-it/node_modules/debug/src/common.js
|
|
155
155
|
var require_common = __commonJS({
|
|
156
|
-
"../../node_modules/debug/src/common.js"(exports2, module2) {
|
|
156
|
+
"../../node_modules/list-it/node_modules/debug/src/common.js"(exports2, module2) {
|
|
157
157
|
"use strict";
|
|
158
158
|
function setup(env) {
|
|
159
159
|
createDebug.debug = createDebug;
|
|
@@ -255,50 +255,64 @@ var require_common = __commonJS({
|
|
|
255
255
|
createDebug.namespaces = namespaces;
|
|
256
256
|
createDebug.names = [];
|
|
257
257
|
createDebug.skips = [];
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
258
|
+
const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean);
|
|
259
|
+
for (const ns of split) {
|
|
260
|
+
if (ns[0] === "-") {
|
|
261
|
+
createDebug.skips.push(ns.slice(1));
|
|
262
|
+
} else {
|
|
263
|
+
createDebug.names.push(ns);
|
|
264
264
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function matchesTemplate(search, template) {
|
|
268
|
+
let searchIndex = 0;
|
|
269
|
+
let templateIndex = 0;
|
|
270
|
+
let starIndex = -1;
|
|
271
|
+
let matchIndex = 0;
|
|
272
|
+
while (searchIndex < search.length) {
|
|
273
|
+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
|
|
274
|
+
if (template[templateIndex] === "*") {
|
|
275
|
+
starIndex = templateIndex;
|
|
276
|
+
matchIndex = searchIndex;
|
|
277
|
+
templateIndex++;
|
|
278
|
+
} else {
|
|
279
|
+
searchIndex++;
|
|
280
|
+
templateIndex++;
|
|
281
|
+
}
|
|
282
|
+
} else if (starIndex !== -1) {
|
|
283
|
+
templateIndex = starIndex + 1;
|
|
284
|
+
matchIndex++;
|
|
285
|
+
searchIndex = matchIndex;
|
|
268
286
|
} else {
|
|
269
|
-
|
|
287
|
+
return false;
|
|
270
288
|
}
|
|
271
289
|
}
|
|
290
|
+
while (templateIndex < template.length && template[templateIndex] === "*") {
|
|
291
|
+
templateIndex++;
|
|
292
|
+
}
|
|
293
|
+
return templateIndex === template.length;
|
|
272
294
|
}
|
|
273
295
|
function disable() {
|
|
274
296
|
const namespaces = [
|
|
275
|
-
...createDebug.names
|
|
276
|
-
...createDebug.skips.map(
|
|
297
|
+
...createDebug.names,
|
|
298
|
+
...createDebug.skips.map((namespace) => "-" + namespace)
|
|
277
299
|
].join(",");
|
|
278
300
|
createDebug.enable("");
|
|
279
301
|
return namespaces;
|
|
280
302
|
}
|
|
281
303
|
function enabled(name) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
let i;
|
|
286
|
-
let len;
|
|
287
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
|
288
|
-
if (createDebug.skips[i].test(name)) {
|
|
304
|
+
for (const skip of createDebug.skips) {
|
|
305
|
+
if (matchesTemplate(name, skip)) {
|
|
289
306
|
return false;
|
|
290
307
|
}
|
|
291
308
|
}
|
|
292
|
-
for (
|
|
293
|
-
if (
|
|
309
|
+
for (const ns of createDebug.names) {
|
|
310
|
+
if (matchesTemplate(name, ns)) {
|
|
294
311
|
return true;
|
|
295
312
|
}
|
|
296
313
|
}
|
|
297
314
|
return false;
|
|
298
315
|
}
|
|
299
|
-
function toNamespace(regexp) {
|
|
300
|
-
return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, "*");
|
|
301
|
-
}
|
|
302
316
|
function coerce(val) {
|
|
303
317
|
if (val instanceof Error) {
|
|
304
318
|
return val.stack || val.message;
|
|
@@ -315,9 +329,9 @@ var require_common = __commonJS({
|
|
|
315
329
|
}
|
|
316
330
|
});
|
|
317
331
|
|
|
318
|
-
// ../../node_modules/debug/src/browser.js
|
|
332
|
+
// ../../node_modules/list-it/node_modules/debug/src/browser.js
|
|
319
333
|
var require_browser = __commonJS({
|
|
320
|
-
"../../node_modules/debug/src/browser.js"(exports2, module2) {
|
|
334
|
+
"../../node_modules/list-it/node_modules/debug/src/browser.js"(exports2, module2) {
|
|
321
335
|
"use strict";
|
|
322
336
|
exports2.formatArgs = formatArgs;
|
|
323
337
|
exports2.save = save;
|
|
@@ -418,10 +432,11 @@ var require_browser = __commonJS({
|
|
|
418
432
|
if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
|
419
433
|
return false;
|
|
420
434
|
}
|
|
435
|
+
let m;
|
|
421
436
|
return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
|
|
422
437
|
typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
|
|
423
438
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
|
424
|
-
typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(
|
|
439
|
+
typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
|
|
425
440
|
typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
|
|
426
441
|
}
|
|
427
442
|
function formatArgs(args2) {
|
|
@@ -459,7 +474,7 @@ var require_browser = __commonJS({
|
|
|
459
474
|
function load() {
|
|
460
475
|
let r;
|
|
461
476
|
try {
|
|
462
|
-
r = exports2.storage.getItem("debug");
|
|
477
|
+
r = exports2.storage.getItem("debug") || exports2.storage.getItem("DEBUG");
|
|
463
478
|
} catch (error) {
|
|
464
479
|
}
|
|
465
480
|
if (!r && typeof process !== "undefined" && "env" in process) {
|
|
@@ -600,9 +615,9 @@ var require_supports_color = __commonJS({
|
|
|
600
615
|
}
|
|
601
616
|
});
|
|
602
617
|
|
|
603
|
-
// ../../node_modules/debug/src/node.js
|
|
618
|
+
// ../../node_modules/list-it/node_modules/debug/src/node.js
|
|
604
619
|
var require_node = __commonJS({
|
|
605
|
-
"../../node_modules/debug/src/node.js"(exports2, module2) {
|
|
620
|
+
"../../node_modules/list-it/node_modules/debug/src/node.js"(exports2, module2) {
|
|
606
621
|
"use strict";
|
|
607
622
|
var tty = require("tty");
|
|
608
623
|
var util = require("util");
|
|
@@ -743,7 +758,7 @@ var require_node = __commonJS({
|
|
|
743
758
|
return (/* @__PURE__ */ new Date()).toISOString() + " ";
|
|
744
759
|
}
|
|
745
760
|
function log(...args2) {
|
|
746
|
-
return process.stderr.write(util.
|
|
761
|
+
return process.stderr.write(util.formatWithOptions(exports2.inspectOpts, ...args2) + "\n");
|
|
747
762
|
}
|
|
748
763
|
function save(namespaces) {
|
|
749
764
|
if (namespaces) {
|
|
@@ -775,9 +790,9 @@ var require_node = __commonJS({
|
|
|
775
790
|
}
|
|
776
791
|
});
|
|
777
792
|
|
|
778
|
-
// ../../node_modules/debug/src/index.js
|
|
793
|
+
// ../../node_modules/list-it/node_modules/debug/src/index.js
|
|
779
794
|
var require_src = __commonJS({
|
|
780
|
-
"../../node_modules/debug/src/index.js"(exports2, module2) {
|
|
795
|
+
"../../node_modules/list-it/node_modules/debug/src/index.js"(exports2, module2) {
|
|
781
796
|
"use strict";
|
|
782
797
|
if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) {
|
|
783
798
|
module2.exports = require_browser();
|
|
@@ -1633,9 +1648,9 @@ var import_chalk7 = __toESM(require("chalk"));
|
|
|
1633
1648
|
var import_connectors6 = require("@tradejs/node/connectors");
|
|
1634
1649
|
var import_cli2 = require("@tradejs/node/cli");
|
|
1635
1650
|
var import_async3 = require("@tradejs/core/async");
|
|
1636
|
-
var
|
|
1651
|
+
var import_strategies3 = require("@tradejs/core/strategies");
|
|
1637
1652
|
var import_constants3 = require("@tradejs/core/constants");
|
|
1638
|
-
var
|
|
1653
|
+
var import_strategies4 = require("@tradejs/node/strategies");
|
|
1639
1654
|
var import_time3 = require("@tradejs/core/time");
|
|
1640
1655
|
var import_logger4 = require("@tradejs/infra/logger");
|
|
1641
1656
|
var import_redis5 = require("@tradejs/infra/redis");
|
|
@@ -1647,6 +1662,7 @@ var import_time = require("@tradejs/core/time");
|
|
|
1647
1662
|
var SECONDS_PER_DAY = 86400;
|
|
1648
1663
|
var RUNTIME_SIGNAL_RETENTION_DAYS_ENV = "RUNTIME_SIGNAL_RETENTION_DAYS";
|
|
1649
1664
|
var DEFAULT_RUNTIME_SIGNAL_RETENTION_TTL_SECONDS = import_constants.TTL_3D;
|
|
1665
|
+
var RUNTIME_LINEAGE_SCOPE_RETENTION_TTL_SECONDS = import_constants.TTL_1M;
|
|
1650
1666
|
var parsePositiveNumber = (value) => {
|
|
1651
1667
|
if (value == null || value === "") {
|
|
1652
1668
|
return null;
|
|
@@ -1808,6 +1824,7 @@ var import_progress = __toESM(require("progress"));
|
|
|
1808
1824
|
var import_chalk = __toESM(require("chalk"));
|
|
1809
1825
|
var import_connectors = require("@tradejs/connectors");
|
|
1810
1826
|
var import_connectors2 = require("@tradejs/node/connectors");
|
|
1827
|
+
var import_strategies = require("@tradejs/node/strategies");
|
|
1811
1828
|
var import_timescale = require("@tradejs/infra/timescale");
|
|
1812
1829
|
|
|
1813
1830
|
// src/lib/binanceMarketData.ts
|
|
@@ -1817,14 +1834,6 @@ var MARKET_FEATURE_INTERVAL_MS = {
|
|
|
1817
1834
|
"15m": 9e5,
|
|
1818
1835
|
"1h": 36e5
|
|
1819
1836
|
};
|
|
1820
|
-
var STABLE_QUOTE_SYMBOLS = /* @__PURE__ */ new Set([
|
|
1821
|
-
"USDCUSDT",
|
|
1822
|
-
"FDUSDUSDT",
|
|
1823
|
-
"TUSDUSDT",
|
|
1824
|
-
"BUSDUSDT",
|
|
1825
|
-
"USDPUSDT",
|
|
1826
|
-
"DAIUSDT"
|
|
1827
|
-
]);
|
|
1828
1837
|
var safeDivide = (num, den) => Number.isFinite(num) && Number.isFinite(den) && den !== 0 ? num / den : null;
|
|
1829
1838
|
var mean = (values) => values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : null;
|
|
1830
1839
|
var standardDeviation = (values) => {
|
|
@@ -1868,9 +1877,6 @@ var classifyBtcAltRegime = ({
|
|
|
1868
1877
|
if (btcVsAltReturn24h < -5e-3) return "alt_lead";
|
|
1869
1878
|
return "neutral";
|
|
1870
1879
|
};
|
|
1871
|
-
var selectBreadthUniverseFromTickers = (tickers, limit) => tickers.filter(
|
|
1872
|
-
(ticker) => ticker.symbol.endsWith("USDT") && ticker.symbol !== "BTCUSDT" && !STABLE_QUOTE_SYMBOLS.has(ticker.symbol) && Number.isFinite(ticker.turnover24h) && ticker.turnover24h > 0
|
|
1873
|
-
).sort((a, b) => b.turnover24h - a.turnover24h).slice(0, Math.max(0, limit)).map((ticker) => ticker.symbol);
|
|
1874
1880
|
var aggregateAggTradesToRows = ({
|
|
1875
1881
|
symbol,
|
|
1876
1882
|
interval: interval2,
|
|
@@ -2352,10 +2358,6 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2352
2358
|
process.env.BINANCE_MARKET_CONTEXT_TRADE_FLOW_SYMBOL_LIMIT,
|
|
2353
2359
|
2
|
|
2354
2360
|
);
|
|
2355
|
-
const breadthLimit = asInt(
|
|
2356
|
-
process.env.BINANCE_MARKET_CONTEXT_BREADTH_LIMIT,
|
|
2357
|
-
30
|
|
2358
|
-
);
|
|
2359
2361
|
const breadthChunkDays = asFloat(
|
|
2360
2362
|
process.env.BINANCE_MARKET_CONTEXT_BREADTH_CHUNK_DAYS,
|
|
2361
2363
|
30
|
|
@@ -2478,88 +2480,113 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2478
2480
|
}
|
|
2479
2481
|
}
|
|
2480
2482
|
if (includeBreadth) {
|
|
2481
|
-
const
|
|
2482
|
-
const breadthSymbols =
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
);
|
|
2486
|
-
const universe = `binance_top${breadthSymbols.length}_usdt`;
|
|
2487
|
-
const coverage = await (0, import_timescale.getMarketBreadthCoverage)({
|
|
2488
|
-
universe,
|
|
2489
|
-
interval: interval2,
|
|
2490
|
-
startMs: breadthStartMs,
|
|
2491
|
-
endMs
|
|
2492
|
-
});
|
|
2493
|
-
const hasBtcAltMetrics = (coverage?.btcAltMetricsRows ?? 0) >= Math.floor(Math.max(1, coverage?.rows ?? 0) * 0.9);
|
|
2494
|
-
if (!hasCoverage({
|
|
2495
|
-
coverage,
|
|
2483
|
+
const breadthUniverses = (0, import_strategies.getBinanceBreadthUniverses)();
|
|
2484
|
+
const breadthSymbols = breadthUniverses.at(-1)?.symbols ?? [];
|
|
2485
|
+
const connectorInterval = marketIntervalToConnectorInterval(interval2);
|
|
2486
|
+
const chunks = buildBreadthBackfillChunks({
|
|
2496
2487
|
startMs: breadthStartMs,
|
|
2497
2488
|
endMs,
|
|
2498
|
-
intervalMs: intervalMs2
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
chunks,
|
|
2509
|
-
coverage,
|
|
2510
|
-
intervalMs: intervalMs2
|
|
2511
|
-
});
|
|
2512
|
-
const bar = new import_progress.default(
|
|
2513
|
-
"breadth :current/:total [:bar][:percent] :etas(s) candles=:candles skip=:skip chunk=:chunk :symbol",
|
|
2514
|
-
{
|
|
2515
|
-
total: Math.max(1, missingChunks.length * breadthSymbols.length),
|
|
2516
|
-
width: 24
|
|
2517
|
-
}
|
|
2518
|
-
);
|
|
2519
|
-
let candlesRead = 0;
|
|
2520
|
-
let skippedBreadthChunks = chunks.length - missingChunks.length;
|
|
2521
|
-
if (!missingChunks.length) {
|
|
2522
|
-
bar.tick(1, {
|
|
2523
|
-
candles: 0,
|
|
2524
|
-
skip: skippedBreadthChunks,
|
|
2525
|
-
chunk: "cached",
|
|
2526
|
-
symbol: universe
|
|
2489
|
+
intervalMs: intervalMs2,
|
|
2490
|
+
chunkDays: breadthChunkDays
|
|
2491
|
+
});
|
|
2492
|
+
const plans = await Promise.all(
|
|
2493
|
+
breadthUniverses.map(async (definition) => {
|
|
2494
|
+
const coverage = await (0, import_timescale.getMarketBreadthCoverage)({
|
|
2495
|
+
universe: definition.universe,
|
|
2496
|
+
interval: interval2,
|
|
2497
|
+
startMs: breadthStartMs,
|
|
2498
|
+
endMs
|
|
2527
2499
|
});
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
candlesBySymbol[symbol] = candles;
|
|
2544
|
-
candlesRead += candles.length;
|
|
2545
|
-
bar.tick(1, {
|
|
2546
|
-
candles: candlesRead,
|
|
2547
|
-
skip: skippedBreadthChunks,
|
|
2548
|
-
chunk: `${originalChunkIndex + 1}/${chunks.length}`,
|
|
2549
|
-
symbol
|
|
2550
|
-
});
|
|
2500
|
+
const hasBtcAltMetrics = (coverage?.btcAltMetricsRows ?? 0) >= Math.floor(Math.max(1, coverage?.rows ?? 0) * 0.9);
|
|
2501
|
+
const missingChunks2 = !hasCoverage({
|
|
2502
|
+
coverage,
|
|
2503
|
+
startMs: breadthStartMs,
|
|
2504
|
+
endMs,
|
|
2505
|
+
intervalMs: intervalMs2
|
|
2506
|
+
}) || !hasBtcAltMetrics ? !hasBtcAltMetrics ? chunks : filterMissingBreadthBackfillChunks({
|
|
2507
|
+
chunks,
|
|
2508
|
+
coverage,
|
|
2509
|
+
intervalMs: intervalMs2
|
|
2510
|
+
}) : [];
|
|
2511
|
+
if (!missingChunks2.length) {
|
|
2512
|
+
console.log(
|
|
2513
|
+
import_chalk.default.gray(`breadth cached: universe=${definition.universe}`)
|
|
2514
|
+
);
|
|
2551
2515
|
}
|
|
2552
|
-
|
|
2553
|
-
|
|
2516
|
+
return {
|
|
2517
|
+
definition,
|
|
2518
|
+
missingChunkKeys: new Set(
|
|
2519
|
+
missingChunks2.map((chunk) => `${chunk.startMs}:${chunk.endMs}`)
|
|
2520
|
+
)
|
|
2521
|
+
};
|
|
2522
|
+
})
|
|
2523
|
+
);
|
|
2524
|
+
const missingChunks = chunks.filter((chunk) => {
|
|
2525
|
+
const key = `${chunk.startMs}:${chunk.endMs}`;
|
|
2526
|
+
return plans.some((plan) => plan.missingChunkKeys.has(key));
|
|
2527
|
+
});
|
|
2528
|
+
const bar = new import_progress.default(
|
|
2529
|
+
"breadth :current/:total [:bar][:percent] :etas(s) candles=:candles skip=:skip chunk=:chunk :symbol",
|
|
2530
|
+
{
|
|
2531
|
+
total: Math.max(1, missingChunks.length * breadthSymbols.length),
|
|
2532
|
+
width: 24
|
|
2533
|
+
}
|
|
2534
|
+
);
|
|
2535
|
+
let candlesRead = 0;
|
|
2536
|
+
const skippedBreadthChunks = chunks.length - missingChunks.length;
|
|
2537
|
+
if (!missingChunks.length) {
|
|
2538
|
+
bar.tick(1, {
|
|
2539
|
+
candles: 0,
|
|
2540
|
+
skip: skippedBreadthChunks,
|
|
2541
|
+
chunk: "cached",
|
|
2542
|
+
symbol: "top5/top10/top30/top50/top100"
|
|
2543
|
+
});
|
|
2544
|
+
}
|
|
2545
|
+
for (let chunkIndex = 0; chunkIndex < missingChunks.length; chunkIndex += 1) {
|
|
2546
|
+
const chunk = missingChunks[chunkIndex];
|
|
2547
|
+
const originalChunkIndex = chunks.findIndex(
|
|
2548
|
+
(item) => item.startMs === chunk.startMs && item.endMs === chunk.endMs
|
|
2549
|
+
);
|
|
2550
|
+
const candlesBySymbol = {};
|
|
2551
|
+
for (const symbol of breadthSymbols) {
|
|
2552
|
+
const candles = await connector.kline({
|
|
2553
|
+
symbol,
|
|
2554
2554
|
interval: connectorInterval,
|
|
2555
2555
|
start: chunk.fetchStartMs,
|
|
2556
2556
|
end: chunk.endMs,
|
|
2557
2557
|
silent: true
|
|
2558
2558
|
});
|
|
2559
|
+
candlesBySymbol[symbol] = candles;
|
|
2560
|
+
candlesRead += candles.length;
|
|
2561
|
+
bar.tick(1, {
|
|
2562
|
+
candles: candlesRead,
|
|
2563
|
+
skip: skippedBreadthChunks,
|
|
2564
|
+
chunk: `${originalChunkIndex + 1}/${chunks.length}`,
|
|
2565
|
+
symbol
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
const btcCandles = await connector.kline({
|
|
2569
|
+
symbol: "BTCUSDT",
|
|
2570
|
+
interval: connectorInterval,
|
|
2571
|
+
start: chunk.fetchStartMs,
|
|
2572
|
+
end: chunk.endMs,
|
|
2573
|
+
silent: true
|
|
2574
|
+
});
|
|
2575
|
+
const chunkKey = `${chunk.startMs}:${chunk.endMs}`;
|
|
2576
|
+
for (const plan of plans) {
|
|
2577
|
+
if (!plan.missingChunkKeys.has(chunkKey)) {
|
|
2578
|
+
continue;
|
|
2579
|
+
}
|
|
2580
|
+
const symbolSet = new Set(plan.definition.symbols);
|
|
2581
|
+
const universeCandles = Object.fromEntries(
|
|
2582
|
+
Object.entries(candlesBySymbol).filter(
|
|
2583
|
+
([symbol]) => symbolSet.has(symbol)
|
|
2584
|
+
)
|
|
2585
|
+
);
|
|
2559
2586
|
const rows = buildMarketBreadthRows({
|
|
2560
|
-
universe,
|
|
2587
|
+
universe: plan.definition.universe,
|
|
2561
2588
|
interval: interval2,
|
|
2562
|
-
candlesBySymbol,
|
|
2589
|
+
candlesBySymbol: universeCandles,
|
|
2563
2590
|
btcCandles
|
|
2564
2591
|
}).filter((row) => {
|
|
2565
2592
|
const ts = row.ts.getTime();
|
|
@@ -2568,8 +2595,6 @@ var backfillBinanceMarketContext = async (params, enabled) => {
|
|
|
2568
2595
|
await (0, import_timescale.upsertMarketBreadthRows)(rows);
|
|
2569
2596
|
breadthRows += rows.length;
|
|
2570
2597
|
}
|
|
2571
|
-
} else {
|
|
2572
|
-
console.log(import_chalk.default.gray(`breadth cached: universe=${universe}`));
|
|
2573
2598
|
}
|
|
2574
2599
|
}
|
|
2575
2600
|
console.log(
|
|
@@ -3794,27 +3819,27 @@ var createCoinMarketCapFetchStats = () => ({
|
|
|
3794
3819
|
totalCredits: 0,
|
|
3795
3820
|
byPath: /* @__PURE__ */ new Map()
|
|
3796
3821
|
});
|
|
3797
|
-
var getCoinMarketCapPathLabel = (
|
|
3798
|
-
if (
|
|
3799
|
-
if (
|
|
3800
|
-
if (
|
|
3801
|
-
if (
|
|
3802
|
-
if (
|
|
3803
|
-
if (
|
|
3804
|
-
return
|
|
3805
|
-
};
|
|
3806
|
-
var recordCoinMarketCapFetchStats = (stats,
|
|
3822
|
+
var getCoinMarketCapPathLabel = (path2) => {
|
|
3823
|
+
if (path2.includes("global-metrics")) return "global";
|
|
3824
|
+
if (path2.includes("cryptocurrency/quotes")) return "reference";
|
|
3825
|
+
if (path2.includes("exchange/quotes")) return "exchangeLiquidity";
|
|
3826
|
+
if (path2.includes("fear-and-greed")) return "fearGreed";
|
|
3827
|
+
if (path2.includes("cmc100")) return "cmc100";
|
|
3828
|
+
if (path2.includes("cmc20")) return "cmc20";
|
|
3829
|
+
return path2;
|
|
3830
|
+
};
|
|
3831
|
+
var recordCoinMarketCapFetchStats = (stats, path2, creditCount) => {
|
|
3807
3832
|
if (!stats) return;
|
|
3808
|
-
const existing = stats.byPath.get(
|
|
3833
|
+
const existing = stats.byPath.get(path2) ?? { requests: 0, credits: 0 };
|
|
3809
3834
|
existing.requests += 1;
|
|
3810
3835
|
existing.credits += creditCount ?? 0;
|
|
3811
3836
|
stats.requests += 1;
|
|
3812
3837
|
stats.totalCredits += creditCount ?? 0;
|
|
3813
|
-
stats.byPath.set(
|
|
3838
|
+
stats.byPath.set(path2, existing);
|
|
3814
3839
|
};
|
|
3815
3840
|
var formatCoinMarketCapFetchStats = (stats) => {
|
|
3816
3841
|
const byPath = [...stats.byPath.entries()].map(
|
|
3817
|
-
([
|
|
3842
|
+
([path2, item]) => `${getCoinMarketCapPathLabel(path2)}=${item.requests}req/${item.credits}cr`
|
|
3818
3843
|
).join(" ");
|
|
3819
3844
|
return `apiRequests=${stats.requests} apiCredits=${stats.totalCredits}${byPath ? ` ${byPath}` : ""}`;
|
|
3820
3845
|
};
|
|
@@ -4886,7 +4911,7 @@ var updateBtcReferenceHistory = async ({
|
|
|
4886
4911
|
var import_logger = require("@tradejs/infra/logger");
|
|
4887
4912
|
var import_redis2 = require("@tradejs/infra/redis");
|
|
4888
4913
|
var import_tradingAccounts = require("@tradejs/infra/tradingAccounts");
|
|
4889
|
-
var
|
|
4914
|
+
var import_strategies2 = require("@tradejs/node/strategies");
|
|
4890
4915
|
|
|
4891
4916
|
// src/lib/runtimeRedis.ts
|
|
4892
4917
|
var import_redis = require("@tradejs/infra/redis");
|
|
@@ -4986,7 +5011,7 @@ var loadRuntimeStrategies = async ({
|
|
|
4986
5011
|
});
|
|
4987
5012
|
const effectiveAccountId = resolvedAccount?.id ?? requestedAccountId;
|
|
4988
5013
|
const [strategyCreator, strategyResults] = await Promise.all([
|
|
4989
|
-
(0,
|
|
5014
|
+
(0, import_strategies2.getStrategyCreator)(strategyName, projectRoot2),
|
|
4990
5015
|
(0, import_redis2.getData)(import_redis2.redisKeys.strategyResults(userName, strategyName), {})
|
|
4991
5016
|
]);
|
|
4992
5017
|
if (!strategyCreator) {
|
|
@@ -5080,6 +5105,214 @@ var logStrategySkipStats = (runtimeStrategies, strategyStats) => {
|
|
|
5080
5105
|
|
|
5081
5106
|
// src/lib/signals/evaluations.ts
|
|
5082
5107
|
var import_redis3 = require("@tradejs/infra/redis");
|
|
5108
|
+
|
|
5109
|
+
// src/lib/runtimeLineage.ts
|
|
5110
|
+
var import_node_child_process = require("child_process");
|
|
5111
|
+
var import_node_crypto = require("crypto");
|
|
5112
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
5113
|
+
var import_node_path = __toESM(require("path"));
|
|
5114
|
+
var RUNTIME_CONTEXT_ENV_KEYS = [
|
|
5115
|
+
"AI_MODE",
|
|
5116
|
+
"MIN_AI_QUALITY",
|
|
5117
|
+
"INTERVAL",
|
|
5118
|
+
"DERIVATIVES_CONTEXT_ENABLED",
|
|
5119
|
+
"DERIVATIVES_CONTEXT_TARGET_ENABLED",
|
|
5120
|
+
"DERIVATIVES_CONTEXT_LOOKBACK_HOURS",
|
|
5121
|
+
"DERIVATIVES_CONTEXT_EXTRA_REFERENCE_SYMBOLS",
|
|
5122
|
+
"DERIVATIVES_CONTEXT_EXCHANGE_PRIORITY",
|
|
5123
|
+
"COINMARKETCAP_CONTEXT_ENABLED",
|
|
5124
|
+
"COINMARKETCAP_CONTEXT_MAX_AGE_MS",
|
|
5125
|
+
"COINMARKETCAP_CONTEXT_EXCHANGE_LIQUIDITY_ENABLED",
|
|
5126
|
+
"COINMARKETCAP_CONTEXT_EXCHANGE_SLUGS",
|
|
5127
|
+
"COINMARKETCAP_CONTEXT_FEAR_GREED_ENABLED",
|
|
5128
|
+
"COINMARKETCAP_CONTEXT_HISTORICAL_ACCESS_MONTHS",
|
|
5129
|
+
"COINMARKETCAP_CONTEXT_BACKFILL_ENABLED",
|
|
5130
|
+
"COINMARKETCAP_CONTEXT_BACKFILL_MAX_DAYS",
|
|
5131
|
+
"COINMARKETCAP_CONTEXT_BACKFILL_WARMUP_DAYS"
|
|
5132
|
+
];
|
|
5133
|
+
var RUNTIME_CONTEXT_DATA_MODEL = {
|
|
5134
|
+
derivativesSourceIntervals: "15m",
|
|
5135
|
+
derivativesDerivedIntervals: "1h",
|
|
5136
|
+
derivativesHourlyFallback: "stored-1h",
|
|
5137
|
+
derivativesDataModelVersion: 2,
|
|
5138
|
+
coinMarketCapAvailabilityModel: "closed-interval-all-daily",
|
|
5139
|
+
coinMarketCapDataModelVersion: 3,
|
|
5140
|
+
binanceBreadthUniverseModel: "fixed-versioned-top5-top10-top30-top50-top100",
|
|
5141
|
+
binanceBreadthDataModelVersion: 2
|
|
5142
|
+
};
|
|
5143
|
+
var normalizeForStableJson = (value) => {
|
|
5144
|
+
if (Array.isArray(value)) {
|
|
5145
|
+
return value.map(normalizeForStableJson);
|
|
5146
|
+
}
|
|
5147
|
+
if (value && typeof value === "object") {
|
|
5148
|
+
return Object.fromEntries(
|
|
5149
|
+
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, normalizeForStableJson(entry)])
|
|
5150
|
+
);
|
|
5151
|
+
}
|
|
5152
|
+
return value;
|
|
5153
|
+
};
|
|
5154
|
+
var fingerprintRuntimeValue = (value) => (0, import_node_crypto.createHash)("sha256").update(JSON.stringify(normalizeForStableJson(value))).digest("hex").slice(0, 16);
|
|
5155
|
+
var gitLineageCache = /* @__PURE__ */ new Map();
|
|
5156
|
+
var gateFingerprintCache = /* @__PURE__ */ new Map();
|
|
5157
|
+
var binanceBreadthFingerprintCache = /* @__PURE__ */ new Map();
|
|
5158
|
+
var resolveGitLineage = (projectRoot2) => {
|
|
5159
|
+
const cached = gitLineageCache.get(projectRoot2);
|
|
5160
|
+
if (cached) {
|
|
5161
|
+
return cached;
|
|
5162
|
+
}
|
|
5163
|
+
const envSha = String(process.env.TRADEJS_GIT_SHA ?? "").trim();
|
|
5164
|
+
if (envSha && envSha !== "unknown") {
|
|
5165
|
+
const result = {
|
|
5166
|
+
gitSha: envSha,
|
|
5167
|
+
gitDirty: false
|
|
5168
|
+
};
|
|
5169
|
+
gitLineageCache.set(projectRoot2, result);
|
|
5170
|
+
return result;
|
|
5171
|
+
}
|
|
5172
|
+
try {
|
|
5173
|
+
const gitSha = (0, import_node_child_process.execFileSync)("git", ["rev-parse", "HEAD"], {
|
|
5174
|
+
cwd: projectRoot2,
|
|
5175
|
+
encoding: "utf8",
|
|
5176
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5177
|
+
}).trim();
|
|
5178
|
+
const status = (0, import_node_child_process.execFileSync)(
|
|
5179
|
+
"git",
|
|
5180
|
+
["status", "--porcelain", "--untracked-files=normal"],
|
|
5181
|
+
{
|
|
5182
|
+
cwd: projectRoot2,
|
|
5183
|
+
encoding: "utf8",
|
|
5184
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5185
|
+
}
|
|
5186
|
+
).trim();
|
|
5187
|
+
const result = {
|
|
5188
|
+
gitSha: gitSha || null,
|
|
5189
|
+
gitDirty: status.length > 0
|
|
5190
|
+
};
|
|
5191
|
+
gitLineageCache.set(projectRoot2, result);
|
|
5192
|
+
return result;
|
|
5193
|
+
} catch {
|
|
5194
|
+
const result = {
|
|
5195
|
+
gitSha: null,
|
|
5196
|
+
gitDirty: null
|
|
5197
|
+
};
|
|
5198
|
+
gitLineageCache.set(projectRoot2, result);
|
|
5199
|
+
return result;
|
|
5200
|
+
}
|
|
5201
|
+
};
|
|
5202
|
+
var readOptionalFile = async (filePath) => {
|
|
5203
|
+
try {
|
|
5204
|
+
return await import_promises.default.readFile(filePath);
|
|
5205
|
+
} catch {
|
|
5206
|
+
return null;
|
|
5207
|
+
}
|
|
5208
|
+
};
|
|
5209
|
+
var resolveBinanceBreadthFingerprint = async (projectRoot2) => {
|
|
5210
|
+
if (binanceBreadthFingerprintCache.has(projectRoot2)) {
|
|
5211
|
+
return binanceBreadthFingerprintCache.get(projectRoot2) ?? null;
|
|
5212
|
+
}
|
|
5213
|
+
const content = await readOptionalFile(
|
|
5214
|
+
import_node_path.default.join(
|
|
5215
|
+
projectRoot2,
|
|
5216
|
+
"packages/node/src/config/binanceBreadthUniverses.json"
|
|
5217
|
+
)
|
|
5218
|
+
);
|
|
5219
|
+
let result = null;
|
|
5220
|
+
if (content) {
|
|
5221
|
+
try {
|
|
5222
|
+
const parsed = JSON.parse(content.toString("utf8"));
|
|
5223
|
+
result = typeof parsed.fingerprint === "string" && parsed.fingerprint.trim() ? parsed.fingerprint.trim() : null;
|
|
5224
|
+
} catch {
|
|
5225
|
+
result = null;
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
binanceBreadthFingerprintCache.set(projectRoot2, result);
|
|
5229
|
+
return result;
|
|
5230
|
+
};
|
|
5231
|
+
var resolveGateFingerprint = async ({
|
|
5232
|
+
projectRoot: projectRoot2,
|
|
5233
|
+
strategyName,
|
|
5234
|
+
gitSha
|
|
5235
|
+
}) => {
|
|
5236
|
+
const cacheKey = `${projectRoot2}:${strategyName}:${gitSha ?? "unknown"}`;
|
|
5237
|
+
const cached = gateFingerprintCache.get(cacheKey);
|
|
5238
|
+
if (cached) {
|
|
5239
|
+
return cached;
|
|
5240
|
+
}
|
|
5241
|
+
const relativeCandidates = [
|
|
5242
|
+
`packages/strategies/src/${strategyName}/adapters/ai.ts`,
|
|
5243
|
+
`packages/strategies/src/${strategyName}/guardrails.ts`,
|
|
5244
|
+
`packages/strategies/src/${strategyName}/pockets.ts`,
|
|
5245
|
+
`packages/strategies/src/${strategyName}/config.ts`,
|
|
5246
|
+
"packages/node/src/ai.ts"
|
|
5247
|
+
];
|
|
5248
|
+
const optionalEntries = await Promise.all(
|
|
5249
|
+
relativeCandidates.map(async (relativePath) => {
|
|
5250
|
+
const content = await readOptionalFile(
|
|
5251
|
+
import_node_path.default.join(projectRoot2, relativePath)
|
|
5252
|
+
);
|
|
5253
|
+
return content == null ? null : { relativePath, content };
|
|
5254
|
+
})
|
|
5255
|
+
);
|
|
5256
|
+
const sourceEntries = [];
|
|
5257
|
+
for (const entry of optionalEntries) {
|
|
5258
|
+
if (entry != null) {
|
|
5259
|
+
sourceEntries.push(entry);
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
5263
|
+
hash.update(strategyName);
|
|
5264
|
+
if (sourceEntries.length) {
|
|
5265
|
+
for (const entry of sourceEntries) {
|
|
5266
|
+
hash.update(entry.relativePath);
|
|
5267
|
+
hash.update(entry.content);
|
|
5268
|
+
}
|
|
5269
|
+
} else {
|
|
5270
|
+
hash.update(gitSha ?? "unknown-git-sha");
|
|
5271
|
+
}
|
|
5272
|
+
const fingerprint = hash.digest("hex").slice(0, 16);
|
|
5273
|
+
gateFingerprintCache.set(cacheKey, fingerprint);
|
|
5274
|
+
return fingerprint;
|
|
5275
|
+
};
|
|
5276
|
+
var buildRuntimeLineage = async ({
|
|
5277
|
+
projectRoot: projectRoot2,
|
|
5278
|
+
strategyName,
|
|
5279
|
+
config,
|
|
5280
|
+
runContext,
|
|
5281
|
+
env = process.env
|
|
5282
|
+
}) => {
|
|
5283
|
+
const git = resolveGitLineage(projectRoot2);
|
|
5284
|
+
const context = {
|
|
5285
|
+
...Object.fromEntries(
|
|
5286
|
+
RUNTIME_CONTEXT_ENV_KEYS.map((key) => [key, env[key] ?? null])
|
|
5287
|
+
),
|
|
5288
|
+
...RUNTIME_CONTEXT_DATA_MODEL,
|
|
5289
|
+
binanceBreadthUniverseFingerprint: await resolveBinanceBreadthFingerprint(projectRoot2),
|
|
5290
|
+
...runContext
|
|
5291
|
+
};
|
|
5292
|
+
return {
|
|
5293
|
+
schemaVersion: 1,
|
|
5294
|
+
...git,
|
|
5295
|
+
gateFingerprint: await resolveGateFingerprint({
|
|
5296
|
+
projectRoot: projectRoot2,
|
|
5297
|
+
strategyName,
|
|
5298
|
+
gitSha: git.gitSha
|
|
5299
|
+
}),
|
|
5300
|
+
configFingerprint: fingerprintRuntimeValue(config),
|
|
5301
|
+
contextFingerprint: fingerprintRuntimeValue(context)
|
|
5302
|
+
};
|
|
5303
|
+
};
|
|
5304
|
+
var runtimeLineageKey = (lineage) => [
|
|
5305
|
+
lineage.schemaVersion,
|
|
5306
|
+
lineage.gitSha ?? "unknown",
|
|
5307
|
+
lineage.gitDirty == null ? "unknown" : lineage.gitDirty ? "dirty" : "clean",
|
|
5308
|
+
lineage.gateFingerprint,
|
|
5309
|
+
lineage.configFingerprint,
|
|
5310
|
+
lineage.contextFingerprint
|
|
5311
|
+
].join(":");
|
|
5312
|
+
|
|
5313
|
+
// src/lib/signals/evaluations.ts
|
|
5314
|
+
var runtimeLineageScopeCache = /* @__PURE__ */ new Map();
|
|
5315
|
+
var runtimeLineageScopeCacheDayKey = "";
|
|
5083
5316
|
var buildRuntimeSignalEvaluationId = ({
|
|
5084
5317
|
strategyName,
|
|
5085
5318
|
symbol,
|
|
@@ -5088,7 +5321,46 @@ var buildRuntimeSignalEvaluationId = ({
|
|
|
5088
5321
|
}) => runtimeConfigId && runtimeConfigId !== "config" ? [strategyName, runtimeConfigId, symbol, timestamp].join(":") : [strategyName, symbol, timestamp].join(":");
|
|
5089
5322
|
var saveRuntimeSignalEvaluation = async (evaluation) => {
|
|
5090
5323
|
const dayKey = (0, import_time.getRuntimeStorageDayKey)(evaluation.timestamp);
|
|
5324
|
+
if (runtimeLineageScopeCacheDayKey !== dayKey) {
|
|
5325
|
+
runtimeLineageScopeCache.clear();
|
|
5326
|
+
runtimeLineageScopeCacheDayKey = dayKey;
|
|
5327
|
+
}
|
|
5091
5328
|
const runtimeSignalRetentionTtl = getRuntimeSignalRetentionTtlSeconds();
|
|
5329
|
+
if (evaluation.runtimeLineage) {
|
|
5330
|
+
const lineageField = [
|
|
5331
|
+
evaluation.strategy,
|
|
5332
|
+
evaluation.runtimeConfigId ?? "config",
|
|
5333
|
+
evaluation.symbol,
|
|
5334
|
+
runtimeLineageKey(evaluation.runtimeLineage)
|
|
5335
|
+
].join(":");
|
|
5336
|
+
const lineageBucket = import_redis3.redisKeys.runtimeLineageScopeBucket(
|
|
5337
|
+
evaluation.userName,
|
|
5338
|
+
dayKey
|
|
5339
|
+
);
|
|
5340
|
+
const cacheKey = `${lineageBucket}:${lineageField}`;
|
|
5341
|
+
const existing = runtimeLineageScopeCache.get(cacheKey) ?? await (0, import_redis3.getHashJsonField)(
|
|
5342
|
+
lineageBucket,
|
|
5343
|
+
lineageField
|
|
5344
|
+
);
|
|
5345
|
+
const scope = {
|
|
5346
|
+
strategy: evaluation.strategy,
|
|
5347
|
+
symbol: evaluation.symbol,
|
|
5348
|
+
runtimeConfigId: evaluation.runtimeConfigId,
|
|
5349
|
+
lineage: evaluation.runtimeLineage,
|
|
5350
|
+
firstTimestamp: Math.min(
|
|
5351
|
+
existing?.firstTimestamp ?? evaluation.timestamp,
|
|
5352
|
+
evaluation.timestamp
|
|
5353
|
+
),
|
|
5354
|
+
lastTimestamp: Math.max(
|
|
5355
|
+
existing?.lastTimestamp ?? evaluation.timestamp,
|
|
5356
|
+
evaluation.timestamp
|
|
5357
|
+
)
|
|
5358
|
+
};
|
|
5359
|
+
runtimeLineageScopeCache.set(cacheKey, scope);
|
|
5360
|
+
await (0, import_redis3.setHashJsonField)(lineageBucket, lineageField, scope, {
|
|
5361
|
+
expire: RUNTIME_LINEAGE_SCOPE_RETENTION_TTL_SECONDS
|
|
5362
|
+
});
|
|
5363
|
+
}
|
|
5092
5364
|
if (shouldStoreDetailedRuntimeSignalEvaluation(evaluation)) {
|
|
5093
5365
|
await (0, import_redis3.setHashJsonField)(
|
|
5094
5366
|
import_redis3.redisKeys.runtimeSignalEvaluationBucket(
|
|
@@ -5548,7 +5820,7 @@ var resolveSignalsKlineWsWaitMs = () => resolveNonNegativeInteger(process.env.SI
|
|
|
5548
5820
|
var createDefaultSignalsLifecycle = (runtimeInterval = interval) => createSignalsStrategyLifecycle({
|
|
5549
5821
|
intervalMs: Number(runtimeInterval) * 6e4,
|
|
5550
5822
|
maxLiveBars: resolveSignalsDaemonMaxLiveBars(runtimeInterval),
|
|
5551
|
-
releaseState:
|
|
5823
|
+
releaseState: import_strategies3.releaseStrategyReplayCache
|
|
5552
5824
|
});
|
|
5553
5825
|
var timeOperation2 = (label, operation) => timeOperation(
|
|
5554
5826
|
label,
|
|
@@ -5693,6 +5965,20 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5693
5965
|
interval: interval2,
|
|
5694
5966
|
makeOrders: flags.makeOrders
|
|
5695
5967
|
});
|
|
5968
|
+
const runtimeLineage = await buildRuntimeLineage({
|
|
5969
|
+
projectRoot,
|
|
5970
|
+
strategyName,
|
|
5971
|
+
config: {
|
|
5972
|
+
configId,
|
|
5973
|
+
strategyConfig,
|
|
5974
|
+
symbolResultConfig: strategyResults?.[symbol]?.config ?? null
|
|
5975
|
+
},
|
|
5976
|
+
runContext: {
|
|
5977
|
+
connectorName: connectorName.toLowerCase(),
|
|
5978
|
+
interval: String(interval2),
|
|
5979
|
+
universe
|
|
5980
|
+
}
|
|
5981
|
+
});
|
|
5696
5982
|
const lifecycleKey = buildSignalsStrategyLifecycleKey({
|
|
5697
5983
|
connectorName,
|
|
5698
5984
|
universe: runtimeScopeUniverse,
|
|
@@ -5774,6 +6060,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5774
6060
|
userName: flags.user,
|
|
5775
6061
|
strategy: strategyName,
|
|
5776
6062
|
runtimeConfigId: configId,
|
|
6063
|
+
runtimeLineage,
|
|
5777
6064
|
symbol,
|
|
5778
6065
|
interval: interval2,
|
|
5779
6066
|
universe,
|
|
@@ -5792,10 +6079,11 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5792
6079
|
stats.signals += 1;
|
|
5793
6080
|
}
|
|
5794
6081
|
signal.runtimeConfigId = configId;
|
|
6082
|
+
signal.runtimeLineage = runtimeLineage;
|
|
5795
6083
|
if (configId && configId !== "config" && !signal.signalId.endsWith(`:${configId}`)) {
|
|
5796
6084
|
signal.signalId = `${signal.signalId}:${configId}`;
|
|
5797
6085
|
}
|
|
5798
|
-
await (0,
|
|
6086
|
+
await (0, import_strategies4.enrichSignalWithBinanceMarketContext)({
|
|
5799
6087
|
signal,
|
|
5800
6088
|
env: "CRON"
|
|
5801
6089
|
});
|
|
@@ -5838,6 +6126,7 @@ var findSignals = async (symbol, connectorName, connector, btcBinanceData, btcCo
|
|
|
5838
6126
|
userName: flags.user,
|
|
5839
6127
|
strategy: strategyName,
|
|
5840
6128
|
runtimeConfigId: configId,
|
|
6129
|
+
runtimeLineage,
|
|
5841
6130
|
symbol,
|
|
5842
6131
|
interval: interval2,
|
|
5843
6132
|
universe,
|